/* =========================================================
   Yönetim paneli
   ========================================================= */

/*
 * Renk değişkenleri app.css'te tanımlıdır (iki tema için birden).
 * Burada YENİDEN tanımlanmamalı: koyu temanın değerlerini ezer ve panel
 * yarı açık yarı koyu kalırdı.
 */
:root {
    /*
     * Sidebar genişliği. 224px'ten 256px'e çıkarıldı: en uzun menü
     * etiketleri ("Düzeltme talepleri", "Ücret ve ödemeler") 224px'te
     * kesiliyor ya da iki satıra kırılıyordu. Etiketi kısaltmak yerine
     * menüyü genişletmek doğru çözüm: "Düzeltme talepleri" zaten
     * kısaltılmış hâli ve daha fazla kısalırsa ne olduğu anlaşılmaz.
     */
    --panel-sidebar: 256px;
}

/* ---------- İkonlar ---------- */

/*
 * İkon rengini içinde bulunduğu öğeden alır (currentColor); bu yüzden
 * menüde gri, aktif satırda mavi, uyarıda kırmızı olur ve koyu tema için
 * ayrıca elden geçirilmesi gerekmez.
 */
.ikon {
    width: 18px;
    height: 18px;
    flex-shrink: 0;
    display: block;
}

.ikon.buyuk {
    width: 22px;
    height: 22px;
}

.ikon.kucuk {
    width: 14px;
    height: 14px;
}

/* ---------- İkon düğmesi ---------- */

/*
 * Tek bir ikon taşıyan düğmelerin ortak biçimi: üst çubuktaki tema ve
 * bildirim düğmeleri, sidebar'daki çıkış, satır işlem menüsü.
 *
 * Hepsi AYNI boyutta (36×36) ve AYNI biçimdedir. Eskiden tema düğmesi
 * kare ve kenarlıklı, zil ise daire ve 38px'ti; yan yana duran iki
 * düğmenin farklı çizilmesi ikisini ilgisiz iki şey gibi gösteriyordu.
 * Kenarlık kaldırıldı: üst çubuk zaten kendi zeminini taşıyor, düğmelerin
 * ayrıca çerçevelenmesi gerekmiyor.
 *
 * Erişilebilirlik: her çağrı noktası aria-label ve title vermelidir —
 * ikon tek başına ne yaptığını söylemez.
 */
.panel-ikon-dugme {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    position: relative;
    flex-shrink: 0;
    width: 36px;
    height: 36px;
    padding: 0;
    /*
     * Kenarlık YOK. Bir ara eklenmişti (ikonlar çubuk zemininde yüzüyor
     * gibi duruyordu) ama iki kutu, yanlarındaki çerçevesiz araçlarla
     * birlikte çubuğu kalabalıklaştırıyordu.
     *
     * Düğme olduğu artık HOVER ile anlaşılıyor: yumuşak bir zemin belirir.
     * Bu, çerçevenin sürekli görünmesinden daha sessiz bir çözüm — ikon
     * durur hâlde ekranda yer kaplamaz, elin altına geldiğinde tepki verir.
     *
     * Kenarlık yerine aynı kalınlıkta saydam bir kenarlık bırakılmadı;
     * bunun yerine boyut `width`/`height` ile sabit, dolayısıyla hover'da
     * düğme kaymaz.
     */
    border: 0;
    border-radius: var(--radius);
    background: transparent;
    color: var(--color-muted);
    cursor: pointer;
    transition: background-color 0.15s ease, color 0.15s ease;
}

/*
 * Hover: yumuşak zemin, çerçeve değil. Geçiş `transition` ile
 * yumuşatılır — ani beliren bir kutu, çerçevenin yaptığı gürültüyü
 * hover anında tekrar üretirdi.
 */
.panel-ikon-dugme:hover {
    background: var(--color-surface-2);
    color: var(--color-text);
}

/* display:inline-flex bir yazar kuralı olduğu için [hidden]'ı ezer. */
.panel-ikon-dugme[hidden] {
    display: none;
}

/* ---------- Menü ikonları ve grup renkleri ---------- */

/*
 * Satır iki parçadır: solda ikon+başlık, sağda rozet. Ayrı bir sarmalayıcı
 * gerekiyor çünkü <a> zaten space-between ile hizalanıyor; ikon doğrudan
 * içine konsaydı rozetle arasında boşluk açılırdı.
 */
.panel-nav .nav-satir {
    display: flex;
    align-items: center;
    gap: 0.55rem;
    min-width: 0;
}

/*
 * Menü etiketi TEK SATIRDIR ve kırılmaz.
 *
 * Kural grup başlıklarını da kapsar: "Ücret ve ödemeler" iki satıra
 * kırıldığında altındaki satırlarla hizası bozuluyor ve menü düzensiz
 * görünüyordu. Sığmayan etiket kesilir ve tamamı ipucunda kalır — ama
 * asıl çözüm menüyü yeterince geniş tutmaktır (bkz. --panel-sidebar).
 */
.panel-nav .nav-satir span,
.panel-nav .nav-grup > span {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Rozet ve ok kısalmaz; yer daralınca etiket kısalır. */
.panel-nav .nav-grup > span:not(.nav-ok):not(.nav-rozet) {
    flex: 1;
    min-width: 0;
}

/*
 * MENÜDE RENK YALNIZCA SEÇİLİ SATIRDADIR.
 *
 * İkonlar ve grup başlıkları sessizdir (gri). Sebebi estetik değil
 * işlevsel: menüde tek bir renkli öğe varsa o öğe "buradasın" demektir;
 * yirmi üç tane varsa hiçbiri bir şey demez. Daha önce önce gruba göre
 * renk, sonra tek renk denendi — ikisinde de seçili satır kendi rengiyle
 * aynı renkteki yirmi iki ikonun arasında kayboluyordu.
 *
 * Menü bir gezinme aracıdır; dikkati kendine değil sağdaki içeriğe
 * bırakmalıdır.
 */
.panel-nav .nav-satir .ikon {
    color: var(--color-muted);
}

.panel-nav a:hover .nav-satir .ikon,
.panel-nav a.active .nav-satir .ikon {
    opacity: 1;
}

/*
 * Seçili satır menüdeki TEK renkli öğedir: ana rengin yumuşak tonunda bir
 * zemin, aynı renkte bir sol çubuk ve ana renge dönen bir ikon. Üç işaret
 * birlikte çalışır — renk körlüğünde ya da color-mix desteklemeyen eski
 * bir tarayıcıda zemin kaybolsa bile çubuk ve kalın yazı durur.
 *
 * color-mix zemini yüzey rengiyle karıştırdığı için iki tema için ayrı
 * tanım gerekmez.
 */
.panel-nav a.active {
    background: color-mix(in srgb, var(--color-primary) 12%, var(--color-surface));
    /*
     * Yazı rengi --color-vurgu-metin üzerinden gelir; iki temada FARKLI
     * değişkene bağlanır (bkz. app.css). Açık temada koyu ton (#1d4ed8)
     * okunur, ama koyu temada aynı ton zeminden DAHA KOYU kalıyor ve
     * kontrast 3.75'e düşüyordu — ölçülerek görüldü. Koyu temada açık ton
     * kullanılınca 5.42 oluyor.
     */
    color: var(--color-vurgu-metin);
    font-weight: 600;
    /*
     * Sol çubuk KALDIRILDI. Seçili öğe zaten üç işaretle belli oluyor:
     * zemin, kalın yazı ve vurgu rengindeki metin+ikon. Dördüncü olarak
     * çizilen çubuk, listenin kendi sol kenar çizgisiyle (.nav-liste
     * border-left) üst üste biniyor ve menüde ikinci bir dikey çizgi gibi
     * duruyordu.
     */
}

.panel-nav a.active .nav-satir .ikon {
    color: var(--color-primary);
}

/*
 * Grup başlığının rengi ve listenin sol kenar çizgisi aşağıdaki asıl
 * .nav-grup / .nav-liste kurallarında tanımlıdır: burada tekrar edilseydi
 * aynı özgüllükte iki kural olur, kaynak sırası nedeniyle aşağıdaki
 * kazanır ve buradaki sessizce etkisiz kalırdı.
 *
 * Grup başına renk ataması (.nav-bolum.grup-*) kaldırıldı: menü artık tek
 * renkli. app.css'teki --grup-* değişkenleri bilerek duruyor — gruba göre
 * renklendirmeye dönmek istenirse burada yeniden eşleme yapmak yeterli.
 */

/* ---------- Açılış splash'i ---------- */

.panel-splash {
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 100vh;
    background: var(--color-bg);
}

/*
 * display:flex bir yazar kuralı olduğu için tarayıcının varsayılan
 * [hidden] { display: none } kuralını ezer (bkz. .panel-nav .nav-liste[hidden]
 * için aşağıdaki aynı gerekçe). Bu olmadan splash gizlense bile sayfa
 * akışında bir viewport yüksekliği kadar boşluk bırakmaya devam eder ve
 * panelin altını iter.
 */
.panel-splash[hidden] {
    display: none;
}

.panel-splash-icerik {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.9rem;
    color: var(--color-muted);
    font-size: 0.9rem;
}

.panel-splash-spinner {
    width: 28px;
    height: 28px;
    border: 3px solid var(--color-border);
    border-top-color: var(--color-primary);
    border-radius: 50%;
    animation: panel-splash-donus 0.7s linear infinite;
}

@keyframes panel-splash-donus {
    to { transform: rotate(360deg); }
}

@media (prefers-reduced-motion: reduce) {
    .panel-splash-spinner {
        animation: none;
    }
}

/* ---------- Giriş ekranı ---------- */

body.admin-auth-page {
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 100vh;
    margin: 0;
    background: var(--color-bg);
}

/*
 * Giriş kartı panelin kart sözleşmesini kullanır: aynı köşe yarıçapı ve
 * gölge ölçeği. Eskiden kendi 8px köşesi vardı ve gölgesi yoktu; panele
 * girmeden önce görülen tek ekran, panelden başka bir ürüne aitmiş gibi
 * duruyordu.
 */
.auth-card {
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    box-shadow: var(--golge-2);
    padding: 2rem;
    width: 100%;
    max-width: 380px;
}

.auth-logo {
    display: block;
    width: 72px;
    height: 72px;
    margin: 0 auto 1rem;
    object-fit: contain;
}

.auth-card h1 {
    margin: 0 0 1.5rem;
    font-size: 1.25rem;
    text-align: center;
}

.auth-card form {
    display: flex;
    flex-direction: column;
    gap: 1rem;
}

/*
 * Alanlar panelin .field kalıbını kullanır (etiket + girdi + ipucu), düğme
 * .btn.primary'dir. Eskiden giriş ekranının kendi label/input/button
 * kuralları vardı ve panelden ayrı evrilmişti: odak halkası yoktu, girdi
 * yüksekliği tutmuyordu, düğme :disabled ve :hover durumlarını bilmiyordu.
 *
 * Burada kalan tek şey giriş ekranına özgü düzen: alanlar tam genişlik ve
 * alt alta.
 */
.auth-card .field {
    width: 100%;
}

.auth-card .btn {
    width: 100%;
    justify-content: center;
}

/* Logo altındaki tek satırlık tanıtım / yönlendirme metni. */
.auth-alt {
    margin: -0.75rem 0 1.25rem;
    font-size: 0.85rem;
    color: var(--color-muted);
    text-align: center;
}

/*
 * Şifre yardımı formun ALTINDA ve soluk durur: sık ihtiyaç duyulan bir
 * bilgi değil, takılan kullanıcının arayacağı bir not. Üstte dursaydı her
 * girişte okunan bir uyarı gibi görünürdü.
 */
.auth-yardim {
    margin: 1.25rem 0 0;
    padding-top: 1rem;
    border-top: 1px solid var(--color-border);
    font-size: 0.8rem;
    color: var(--color-muted);
    text-align: center;
}

.form-error {
    color: var(--color-danger);
    font-size: 0.85rem;
    margin: 0;
}

/*
 * hidden özelliği HER ZAMAN gizlesin.
 *
 * Tarayıcının varsayılanı `[hidden] { display: none }` bir kullanıcı-ajanı
 * kuralıdır ve `.field { display: flex }` gibi HERHANGİ bir yazar kuralı onu
 * yener. Sonuç sinsi: JavaScript `el.hidden = true` diyor, özellik gerçekten
 * true oluyor, ama eleman ekranda duruyor. Hata ancak gözle bakınca
 * anlaşılıyor — `el.hidden` okuyan bir test bunu yakalayamaz.
 *
 * Bu tuzağa projede beş kez düşüldü (panel-splash, nav-liste,
 * bildirim-dugme, bildirim-rozet ve çalışma düzeni formundaki .field
 * kutuları); her seferinde tek bir sınıf için yama yazıldı. Genel kural
 * hepsini birden kapatır ve yeni eklenen her flex/grid kutusu için aynı
 * hatanın tekrarlanmasını önler.
 *
 * !important gerekli: özgüllük yarışına girmeden her yazar kuralını yenmeli.
 * Bir elemanı "gizli ama yer kaplasın" yapmak gerekirse hidden değil,
 * visibility/opacity kullanılmalıdır.
 */
[hidden] {
    display: none !important;
}

/* ---------- Panel iskeleti ---------- */

body.panel {
    margin: 0;
    background: var(--color-bg);
}

.panel-shell {
    display: flex;
    min-height: 100vh;
}

.panel-sidebar {
    width: var(--panel-sidebar);
    flex-shrink: 0;
    background: var(--color-surface);
    border-right: 1px solid var(--color-border);
    display: flex;
    flex-direction: column;
    position: sticky;
    top: 0;
    height: 100vh;
}

.panel-brand {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    padding: 1.1rem 1.25rem;
    font-weight: 600;
    border-bottom: 1px solid var(--color-border);
    line-height: 1.3;
}

.panel-brand-logo {
    width: 32px;
    height: 32px;
    flex-shrink: 0;
    object-fit: contain;
}

.panel-brand small {
    display: block;
    font-weight: 400;
    font-size: 0.75rem;
    color: var(--color-muted);
}

/* ---------- Taraf geçişi ---------- */

/*
 * "Benim" ve "Yönetim" arasındaki geçiş (bkz. PLATFORM_BIRLESTIRME.md
 * Faz C0). Menünün üstünde, marka bloğunun hemen altında durur: geçiş
 * menünün İÇERİĞİNİ değiştirdiği için menüden önce gelmelidir.
 *
 * Ekran içi `.sekme-serit`ten ayrı bir kalıptır ve olmalıdır: o, alt
 * çizgiyle çalışan ve bir ekranın bölümleri arasında gezinen bir şerit.
 * Burada hareket çok daha büyük (panelin yarısı değişiyor), bu yüzden
 * seçili taraf dolgu rengiyle gösterilir — alt çizgi bu ölçekte yeterince
 * okunmuyordu.
 *
 * Kapsayıcı tek taraflı kullanıcıda [hidden] ile gizlenir; display:flex
 * bu yüzden :not([hidden]) ile verilir (gizli kapsayıcıya flex vermek,
 * [hidden] { display: none } kuralını ezip şeridi geri getirirdi — bu
 * tuzağa projede daha önce beş kez düşüldü, bkz. admin.css satır ~267).
 */
.panel-taraf:not([hidden]) {
    display: flex;
    gap: 0.25rem;
    padding: 0.6rem 0.6rem 0;
}

.panel-taraf-dugme {
    flex: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.35rem;
    padding: 0.45rem 0.5rem;
    border: 1px solid var(--color-border);
    border-radius: 6px;
    background: var(--color-surface-2);
    color: var(--color-muted);
    font: inherit;
    font-size: 0.82rem;
    font-weight: 500;
    cursor: pointer;
    /* Uzun etiket dar kenar çubuğunu taşırmasın. */
    min-width: 0;
    white-space: nowrap;
}

.panel-taraf-dugme .ikon {
    width: 15px;
    height: 15px;
    flex-shrink: 0;
}

.panel-taraf-dugme:hover {
    color: var(--color-text);
    border-color: var(--color-primary);
}

.panel-taraf-dugme.aktif {
    background: var(--color-primary);
    border-color: var(--color-primary);
    color: #fff;
    font-weight: 600;
}

/*
 * Koyu temada seçili düğmenin metni KOYU olur.
 *
 * Açık temada --color-primary #2563eb (koyu mavi) ve beyaz metin 8:1'in
 * üstünde kontrast verir. Koyu temada ise aynı değişken #60a5fa, yani
 * açık mavi: üstüne beyaz yazmak ~2.4:1 kontrastla WCAG'nin 4.5:1
 * eşiğinin altında kalır ve etiket okunmaz hâle gelir. Zemin koyu temada
 * açık olduğu için metin de ters çevrilir.
 *
 * Renk sabit yazılır, --color-bg ile değil: bu düğmenin zemini temanın
 * zeminini değil --color-primary'yi takip ediyor ve ikisinin birlikte
 * değişeceğinin garantisi yok.
 */
[data-tema="koyu"] .panel-taraf-dugme.aktif {
    color: #0f1420;
}

.panel-taraf-dugme.aktif .ikon {
    /* İkon currentColor kullanır; metin rengini kendiliğinden izler. */
    color: inherit;
}

/*
 * Seçili düğmenin zemini zaten --color-primary; odak halkası da aynı renk
 * olsaydı görünmezdi. Halka dışarı itilip metin rengine çekilir.
 */
.panel-taraf-dugme.aktif:focus-visible {
    outline-color: var(--color-text);
    outline-offset: 2px;
}

.panel-nav {
    flex: 1;
    overflow-y: auto;
    padding: 0.75rem 0.6rem;
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
}

.panel-nav a {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.4rem;
    padding: 0.5rem 0.7rem;
    border-radius: 6px;
    color: var(--color-text);
    text-decoration: none;
    font-size: 0.9rem;
}

/*
 * Okunmamış bildirim sayacı. Menü öğesinin sağ ucuna yaslanır; sayı
 * büyüdükçe (99+) genişleyebilmesi için sabit genişlik verilmez.
 */
.panel-nav .nav-rozet {
    flex-shrink: 0;
    min-width: 1.25rem;
    padding: 0.05rem 0.35rem;
    border-radius: 999px;
    background: var(--color-danger);
    color: #fff;
    font-size: 0.7rem;
    font-weight: 600;
    line-height: 1.5;
    text-align: center;
}

.panel-nav a:hover {
    background: var(--color-bg);
}

/* Aktif satırın görünümü yukarıdaki "Menü ikonları ve grup renkleri"
   bölümünde tanımlıdır: grup rengini okuduğu için orada durur. */

.nav-bolum + .nav-bolum {
    margin-top: 0.2rem;
}

.panel-nav .nav-grup {
    display: flex;
    align-items: center;
    gap: 0.45rem;
    width: 100%;
    padding: 0.55rem 0.7rem;
    border: none;
    border-radius: 6px;
    background: transparent;
    /*
     * Başlık sessizdir: rengi değil BİÇİMİ ayırt ettirir — küçük punto ve
     * daha soluk renk. Renk seçili satıra ayrıldığı için burada
     * kullanılmaz (bkz. yukarıdaki .nav-satir .ikon açıklaması).
     *
     * Büyük harf ve harf aralığı KALDIRILDI: "GÜNLÜK TAKİP" biçimindeki
     * başlıklar hem Türkçe'de okuma hızını düşürüyor hem de panelin geri
     * kalanıyla aynı dili konuşmuyordu. Ayrım artık punto ve renkle.
     */
    /*
     * Başlık GÖVDE METNİ rengindedir ve alt satırlarla aynı puntoyu
     * taşır. Eskiden hem soluk hem küçüktü ve grup mu bağlantı mı olduğu
     * anlaşılmıyordu — tıklanabilir bir öğenin, tıklanamayan bir etiketten
     * daha silik görünmemesi gerekir. Ayrımı artık ikon ve ok sağlıyor.
     */
    color: var(--color-text-2);
    font-family: inherit;
    font-size: 0.85rem;
    font-weight: 600;
    text-align: left;
    cursor: pointer;
}

.panel-nav .nav-grup:hover {
    color: var(--color-text);
}

/* Grup ikonu alt satırların ikon sütunuyla hizalanır. */
.panel-nav .nav-grup .ikon {
    width: 18px;
    height: 18px;
    color: var(--color-muted);
    flex-shrink: 0;
}

.panel-nav .nav-grup:hover {
    background: var(--color-bg);
}

/*
 * Grup başlığındaki toplam rozeti (yalnızca grup KAPALIYKEN görünür).
 *
 * .nav-grup bir flex satırıdır ve space-between kullanmaz; rozeti sağ uca
 * yaslamak için margin-left:auto gerekir — aksi hâlde grup adının hemen
 * yanında durur ve satır sonundaki alt öğe rozetleriyle hizalanmazdı.
 */
.panel-nav .nav-grup .nav-grup-rozet {
    margin-left: auto;
}

/* Ok, başlıktan da sessiz: yalnızca grubun açık/kapalı olduğunu söyleyen
   ikincil bir işaret, başlık metniyle dikkat yarışına girmemeli. */
/*
 * Açılma oku. Grup başlığının SAĞINDA durur ve açıkken 90° döner.
 * Solda dursaydı ikon sütununu ikiye böler, alt satırların ikonlarıyla
 * hizasını bozardı.
 */
.panel-nav .nav-ok {
    color: var(--color-muted);
    transition: transform 0.15s ease;
    display: inline-flex;
    margin-left: auto;
    flex-shrink: 0;
}

.panel-nav .nav-ok .ikon {
    width: 16px;
    height: 16px;
}

.panel-nav .nav-grup.acik .nav-ok {
    transform: rotate(90deg);
}

.panel-nav .nav-liste {
    display: flex;
    flex-direction: column;
    gap: 0.1rem;
    padding: 0.15rem 0 0.25rem 0.55rem;
    margin-left: 0.7rem;
    /* Kenar çizgisi grubun içeriğini başlığa bağlayan sessiz bir işaret:
       renk taşımaz, olağan kenarlık rengindedir. */
    border-left: 1px solid var(--color-border);
}

/*
 * display:flex bir yazar kuralı olduğu için tarayıcının varsayılan
 * [hidden] { display: none } kuralını ezer. Kapalı grubun gerçekten
 * gizlenmesi için burada açıkça belirtilmesi gerekir.
 */
/*
 * Grupsuz ekran (Genel Bakış): grup başlığı altında olmadığı için girinti
 * ve sol kenar çizgisi taşımaz, aksi hâlde başlığı olmayan boş bir grubun
 * içindeymiş gibi görünürdü.
 */
.panel-nav .nav-tek {
    padding-left: 0;
    margin-left: 0;
    border-left: none;
}

.panel-nav .nav-liste[hidden] {
    display: none;
}

@media (prefers-reduced-motion: reduce) {
    .panel-nav .nav-ok {
        transition: none;
    }
}

/*
 * Sidebar'ın alt bloğu: avatar + ad + kısa rol + çıkış ikonu, tek satırda.
 *
 * Eskiden ad ve uzun rol açıklaması alt alta, altlarında da tam genişlikte
 * bir "Çıkış Yap" düğmesi vardı: menünün en altındaki en geniş öğe, günde
 * bir kez kullanılan bir eylemdi. Rolün açıklaması ("tüm yetkilere
 * sahiptir") ipucuna taşındı.
 */
.panel-user {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    border-top: 1px solid var(--color-border);
    padding: 0.75rem 0.85rem 0.75rem 1rem;
    font-size: 0.85rem;
}

.panel-user-kim {
    flex: 1;
    min-width: 0;
}

.panel-user strong {
    display: block;
    font-size: 0.83rem;
    font-weight: 600;
    /* Uzun ad menüyü genişletmez, kısalır. */
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/*
 * Rol satırı. Seçici .panel-user-kim ile sınırlandırılmıştır: yalnızca
 * "span" denseydi yanındaki avatarı da yakalar, onun beyaz metnini griye
 * çevirir ve baş harfler renkli zeminde okunmaz olurdu.
 */
.panel-user-kim span {
    display: block;
    color: var(--color-muted);
    font-size: 0.76rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/*
 * Avatar: baş harfler, adın kendisinden türeyen sabit bir renkte.
 *
 * Renk rastgele değil addan hesaplanır (bkz. Ui.avatar): aynı kişi her
 * ekranda aynı rengi taşır ve göz, listedeki satırları adı okumadan
 * ayırt edebilir.
 */
.panel-avatar,
.avatar {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    width: 32px;
    height: 32px;
    border-radius: 50%;
    color: #fff;
    font-size: 0.72rem;
    font-weight: 600;
    line-height: 1;
    /* Baş harfler her zaman düz yazılır; ad küçük harfle kayıtlıysa da. */
    text-transform: uppercase;
    letter-spacing: 0.02em;
}

/* Tablo satırlarındaki kişi hücresi için biraz küçüğü. */
.avatar.kucuk {
    width: 28px;
    height: 28px;
    font-size: 0.68rem;
}

/*
 * İçerik sütunu. Üst çubuk ve içerik dikey olarak dizilir; iç boşluk
 * artık burada değil .panel-icerik'te, çünkü üst çubuk kenardan kenara
 * uzanmalı ve kendi alt çizgisi içerik boşluğuyla kesilmemelidir.
 */
.panel-main {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
}

.panel-icerik {
    padding: 1.75rem 1.75rem 4rem;
}

/*
 * Form ve ayar sayfaları okunur bir genişlikte durur; liste ve tablo
 * sayfaları ekranın tamamını kullanır.
 *
 * Sınıfı ekran kendi gövdesine koyar (bkz. Panel.formGenisligi). Bir
 * ayar formunun 1920px'lik ekranda satır boyu uzaması, göz için okunmaz
 * bir satır uzunluğu üretiyordu.
 */
.panel-icerik.dar > #panel-govde,
#panel-govde.dar {
    max-width: 960px;
}

/*
 * Mobil üst çubuk ve off-canvas perdesi: masaüstünde sidebar zaten sürekli
 * görünür olduğu için ikisi de gizlidir, yalnızca dar ekranlarda görünür
 * hâle gelir (bkz. @media (max-width: 1279px) aşağıda).
 */
/*
 * Menü (hamburger) düğmesi.
 *
 * Yalnızca sidebar çekmeceye dönüştüğünde görünür; daha geniş ekranlarda
 * menü zaten sürekli açıktır ve açma düğmesinin bir karşılığı yoktur.
 * Görünür olduğunda diğer ikon düğmeleriyle aynı 36×36 kutuyu paylaşır.
 */
.panel-menu-dugme {
    display: none;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 4px;
    width: 36px;
    height: 36px;
    padding: 0;
    border: 0;
    border-radius: var(--radius);
    background: transparent;
    color: var(--color-muted);
    cursor: pointer;
    flex-shrink: 0;
}

.panel-menu-dugme:hover {
    background: var(--color-surface-2);
    color: var(--color-text);
}

/* Çizgiler düğmenin rengini alır; hover'da onunla birlikte koyulaşır. */
.panel-menu-dugme span {
    display: block;
    width: 18px;
    height: 2px;
    margin: 0 auto;
    background: currentColor;
    border-radius: 1px;
}

.panel-sidebar-perde {
    display: none;
}

.panel-head {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 1rem;
    margin-bottom: 1.25rem;
    flex-wrap: wrap;
}

.panel-head > div:first-child {
    min-width: 0;
    flex: 1;
}

.panel-head h1 {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    margin: 0 0 0.25rem;
    font-size: 1.35rem;
    font-weight: 700;
    letter-spacing: -0.01em;
}

/*
 * Sayfa açıklaması TEK SATIRDIR.
 *
 * Eskiden 2–5 satıra yayılıyordu (en uzunu Çalışma düzenleri'nde beş
 * satırdı) ve başlıkla içerik arasına bir paragraf giriyordu. Uzun
 * işleyiş anlatımı başlığın yanındaki ⓘ düğmesine taşınır; oradan
 * okunması gereken bir metin, her açılışta okunmak zorunda değildir.
 *
 * Sığmayan metin kesilir ve tamamı ipucunda görünür.
 */
.panel-head p {
    margin: 0;
    color: var(--color-text-2);
    font-size: 0.88rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    max-width: 100ch;
}

.panel-head p:empty {
    display: none;
}

/*
 * Araç çubuğu: [ikincil eylemler…] [Dışa aktar] [Birincil eylem].
 *
 * Birincil eylem HER ZAMAN en sağdadır ve sayfada en fazla bir tane
 * bulunur. Eskiden sıra ekrandan ekrana değişiyordu; Bordro'da "Dönemi
 * hesapla" en soldaydı, Personel'de "Yeni personel" en solda.
 */
#panel-araclar {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    flex-wrap: wrap;
    justify-content: flex-end;
}

/* Başlığın yanındaki "bu ekran nasıl çalışır?" düğmesi. */
.panel-head .yardim-dugme {
    width: 26px;
    height: 26px;
    color: var(--color-muted);
}

.panel-head .yardim-dugme .ikon {
    width: 16px;
    height: 16px;
}

/* ---------- Bildirim zili ---------- */

/*
 * Üst çubuk.
 *
 * Sayfanın üstüne YAPIŞIR: uzun bir listede aşağı inildiğinde tema ve
 * bildirim düğmeleri ekrandan çıkmamalı. Eskiden içerikle birlikte
 * kayıyorlardı ve uzun sayfalarda "zil neredeydi?" diye yukarı dönmek
 * gerekiyordu.
 *
 * Yüksekliği sabittir (56px); içeriğin kendi iç boşluğu bu çubuğa
 * dahil değildir, bkz. .panel-icerik.
 */
.panel-ust-cubuk {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    height: 56px;
    flex-shrink: 0;
    padding: 0 1.75rem;
    background: var(--color-surface);
    border-bottom: 1px solid var(--color-border);
    position: sticky;
    top: 0;
    /* Tablo başlıklarının ve açılır menülerin üstünde kalmalı. */
    z-index: 20;
}

.panel-ust-araclar {
    display: flex;
    align-items: center;
    gap: 0.25rem;
    margin-left: auto;
}

/* ---------- Kırıntı yolu ---------- */

/*
 * "Yönetim › Günlük takip › Mesai takibi".
 *
 * Menüde grup kapalıyken kullanıcının hangi bölümde olduğunu söyler;
 * son parça (bulunulan ekran) vurgulu, öncekiler soluk durur. Tıklanabilir
 * DEĞİLDİR: gruplar birer sayfa değil, yalnızca menü başlığıdır —
 * bağlantı gibi görünüp hiçbir yere gitmemesi yanıltıcı olurdu.
 */
.panel-kirinti {
    display: flex;
    align-items: center;
    gap: 0.35rem;
    min-width: 0;
    font-size: 0.82rem;
    color: var(--color-muted);
}

.panel-kirinti .kirinti-ayrac {
    color: var(--color-border-strong);
    flex-shrink: 0;
}

.panel-kirinti .kirinti-son {
    color: var(--color-text);
    font-weight: 500;
    /* Uzun ekran adı çubuğu taşırmaz, kısalır. */
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Dar ekranda yalnızca bulunulan ekranın adı kalır. */
.panel-kirinti .kirinti-ust {
    white-space: nowrap;
}

.panel-bildirim {
    position: relative;
}

/*
 * Zil, biçimini .panel-ikon-dugme'den alır (tema düğmesiyle aynı 36×36
 * kare); burada yalnızca rozetin konumlanabilmesi için gereken şey var.
 * Eskiden daire ve 38px'ti, yanındaki kare tema düğmesiyle eşleşmiyordu.
 */

/*
 * Okunmamış sayısı. Düğmenin İÇİNE konumlanır (dışına taşmaz): kenarlık
 * kalktıktan sonra dışarı taşan rozet üst çubuğun kenarına değiyordu.
 * Çubuk zemininde kaybolmaması için zemin renginde ince bir halka taşır.
 */
.panel-bildirim-rozet {
    position: absolute;
    top: 3px;
    right: 3px;
    min-width: 16px;
    height: 16px;
    padding: 0 3px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 999px;
    background: var(--color-danger);
    border: 2px solid var(--color-surface);
    color: #fff;
    font-size: 0.65rem;
    font-weight: 600;
    line-height: 1;
}

/*
 * display:flex bir yazar kuralı olduğu için tarayıcının varsayılan
 * [hidden] { display: none } kuralını ezer (bkz. .panel-splash[hidden] için
 * aynı gerekçe yukarıda). Bu olmadan okunmamış sayısı 0 olsa ve JS
 * `rozet.hidden = true` yapsa bile rozet görünür kalmaya devam eder.
 */
.panel-bildirim-rozet[hidden] {
    display: none;
}

.panel-bildirim-dropdown {
    position: absolute;
    top: calc(100% + 8px);
    right: 0;
    /*
     * Genişlik: bildirim metinleri iki satıra sığsın diye 340px'ten
     * çıkarıldı. Ayarlanacak tek değer budur.
     *
     * `max-width` onu dar ekranda frenler: pencere sağ kenara yaslı
     * açıldığı için (right: 0) sabit bir genişlik, dar viewport'ta
     * ekranın soluna taşardı.
     */
    width: 420px;
    max-width: calc(100vw - 2rem);
    max-height: 70vh;
    overflow-y: auto;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: 10px;
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
    z-index: 50;
}

.panel-bildirim-baslik {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0.75rem 1rem;
    border-bottom: 1px solid var(--color-border);
    position: sticky;
    top: 0;
    background: var(--color-surface);
}

/*
 * Başlıktaki eylemler: "Tümünü okundu işaretle" (düğme) ve "Tümünü gör"
 * (bağlantı). İkisi de aynı görünümü taşır, çünkü kullanıcı açısından
 * ikisi de aynı ağırlıkta bir bağlantıdır; biri gezinir, biri iş yapar.
 * Düğme ayrı bir sınıf yerine bu kuralın kapsamına alındı: panele ileride
 * eklenecek üçüncü bir eylem de kendiliğinden aynı görünümü alır.
 */
.panel-bildirim-baslik a,
.panel-bildirim-baslik .panel-bildirim-eylem {
    font-size: 0.82rem;
    color: var(--color-primary);
    text-decoration: none;
    border: none;
    background: none;
    padding: 0;
    cursor: pointer;
    font-family: inherit;
}

.panel-bildirim-baslik a:hover,
.panel-bildirim-baslik .panel-bildirim-eylem:enabled:hover {
    text-decoration: underline;
}

/*
 * Okunmamış yokken düğme devre dışıdır. Gizlemek yerine soluklaştırılır:
 * panelin düzeni sabit kalır ve eylemin var olduğu ama şu an gereksiz
 * olduğu görünür.
 */
.panel-bildirim-baslik .panel-bildirim-eylem:disabled {
    color: var(--color-muted);
    cursor: default;
}

/*
 * Sekme çubuğu: "Yönetim 3" / "Benim 0".
 *
 * Yalnızca iki kapsam da varsa çizilir (bkz. K58); tek yetkisi olan
 * kullanıcı doğrudan listeyi görür.
 *
 * Segment görünümü kullanılır, alttan çizgili sekme değil: pencere dar
 * (360px) ve alttan çizgi bu genişlikte bir "aktif" işareti olarak zayıf
 * kalıyordu. Dolu bir kutu, hangi kapsamın açık olduğunu bir bakışta
 * verir.
 */
.panel-bildirim-sekmeler {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 0.25rem;
    padding: 0.5rem;
    border-bottom: 1px solid var(--color-border);
}

.panel-bildirim-sekme {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.4rem;
    padding: 0.45rem 0.5rem;
    border: 1px solid transparent;
    border-radius: 7px;
    background: none;
    color: var(--color-text-2);
    font-family: inherit;
    font-size: 0.85rem;
    font-weight: 600;
    cursor: pointer;
}

.panel-bildirim-sekme:hover {
    background: var(--color-bg);
}

.panel-bildirim-sekme.aktif {
    background: var(--color-surface);
    border-color: var(--color-border);
    color: var(--color-text);
    box-shadow: 0 1px 2px rgb(0 0 0 / 0.05);
}

/*
 * Sekmedeki sayı SIFIR olsa da yazılır ("Benim 0"): o kapsamda bekleyen
 * iş olmadığını açıkça söyler. Gizlemek, kullanıcıyı kontrol etmek için
 * sekmeye tıklamaya zorlardı.
 *
 * Renk yalnızca sıfırdan büyükken verilir; "0" nötr kalır, çünkü olmayan
 * bir durumu vurgulamak yanlış bir aciliyet üretir.
 */
.panel-bildirim-sekme-sayi {
    font-size: 0.78rem;
    font-weight: 700;
    color: var(--color-muted);
    font-variant-numeric: tabular-nums;
}

.panel-bildirim-sekme-sayi.dolu {
    color: var(--color-primary);
}

.panel-bildirim-yukleniyor {
    padding: 1.25rem 1rem;
    text-align: center;
}

/*
 * Boş durum: çift tik ikonu + tek cümle.
 *
 * Metin kapsama göre değişir ("Size ait yeni bildirim yok"); genel bir
 * "Bildirim yok", yönetim sekmesinde bildirim varken yanıltıcıydı.
 */
.panel-bildirim-bos {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.5rem;
    padding: 2rem 1rem;
    text-align: center;
}

.panel-bildirim-bos .ikon {
    width: 28px;
    height: 28px;
    color: var(--color-muted);
}

.panel-bildirim-bos p {
    margin: 0;
}

/*
 * "Tüm bildirimleri gör" ALTTA ve ortada durur.
 *
 * Eskiden başlıktaydı ve listeden önce göze çarpıyordu; oysa oraya
 * gitmek listeyi okuduktan SONRA verilen bir karardır. Yapışkan
 * konumlandırma ile uzun listede de görünür kalır.
 */
.panel-bildirim-tumu {
    display: block;
    padding: 0.7rem 1rem;
    border-top: 1px solid var(--color-border);
    background: var(--color-surface);
    color: var(--color-primary);
    font-size: 0.85rem;
    font-weight: 600;
    text-align: center;
    text-decoration: none;
    position: sticky;
    bottom: 0;
}

.panel-bildirim-tumu:hover {
    background: var(--color-bg);
}

.panel-bildirim-liste {
    display: flex;
    flex-direction: column;
}

/*
 * Satır DÖRT sütun: okunmamış noktası, tür ikonu, gövde, zaman.
 *
 * Nokta sütunu okunmuş satırlarda da YER KAPLAR (görünmez ama duruyor):
 * aksi hâlde okunmuş ve okunmamış satırların metinleri farklı yerden
 * başlar ve liste tararken göz sürekli sağa sola kayardı.
 *
 * Zaman AYRI BİR SÜTUNDUR, başlığın yanında değil. Önceden başlıkla
 * birlikte gövdenin içinde, bir flex şeridinde duruyordu; mesaj ise o
 * şeridin ALTINDA ve tam genişlikteydi. Sonuç: uzun bir mesaj, sağ üstteki
 * saatin altına kadar uzanıyor ve saatle aynı hizada bitiyordu. Zamanı
 * ızgaranın kendi sütununa almak, mesajın sağ sınırını saatin soluna
 * sabitler — metin artık saatin altına kaçamaz.
 */
.panel-bildirim-satir {
    display: grid;
    grid-template-columns: auto auto minmax(0, 1fr) auto;
    align-items: start;
    gap: 0.55rem;
    width: 100%;
    text-align: left;
    padding: 0.65rem 1rem;
    border: none;
    border-bottom: 1px solid var(--color-border);
    background: none;
    cursor: pointer;
    font-family: inherit;
}

/* Okunmamışlık işareti: küçük mavi nokta. */
.panel-bildirim-nokta {
    width: 7px;
    height: 7px;
    margin-top: 0.45rem;
    border-radius: 50%;
    background: transparent;
}

.panel-bildirim-satir.okunmamis .panel-bildirim-nokta {
    background: var(--color-primary);
}

/* Tür ikonu; renk seviyeden gelir (.t-warn, .t-info, .t-bad…). */
.panel-bildirim-satir-ikon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 30px;
    height: 30px;
    border-radius: 8px;
    background: var(--color-neutral-soft);
    color: var(--color-muted);
}

.panel-bildirim-satir-ikon .ikon {
    width: 16px;
    height: 16px;
}

.panel-bildirim-satir-govde {
    min-width: 0;
}

.panel-bildirim-satir:last-child {
    border-bottom: none;
}

/*
 * Hover renkleri Bildirimler EKRANIYLA aynıdır
 * (bkz. .bildirim-satir:hover). Aynı bildirim iki yerde görünüyor;
 * ikisinin farklı davranması, birini ötekinin devamı saymayı
 * engelliyordu.
 *
 * OKUNMUŞ satırın hover'ı nötrdür: `--color-surface-2`, yani pencere
 * yüzeyinden bir tık ayrışan gri. `--color-bg` DEĞİL — o, sayfa
 * zemininin kendisidir ve pencerenin içinde kullanılınca satır
 * pencerenin dışıyla aynı renge düşer; hover "vurgu" gibi değil "delik"
 * gibi görünür.
 */
.panel-bildirim-satir:hover {
    background: var(--color-surface-2);
}

.panel-bildirim-satir.okunmamis {
    background: var(--color-primary-soft);
}

/*
 * OKUNMAMIŞ satırın hover'ı MAVİ KALIR, yalnızca bir tık koyulaşır.
 * Griye düşmek, imlecin altındaki satırı bir anlığına okunmuş gibi
 * gösteriyordu — mavi bu listede "yeni" demektir ve hover o bilgiyi
 * silmemeli.
 *
 * Kural, yukarıdaki genel hover kuralıyla aynı özgüllükte olduğu için
 * ondan SONRA yazılmalıdır.
 */
.panel-bildirim-satir.okunmamis:hover {
    background: color-mix(in srgb, var(--color-primary) 14%, transparent);
}

/*
 * Başlık artık gövdenin doğrudan çocuğudur; zaman ayrı bir sütuna
 * taşındığı için aradaki flex şeridine (.panel-bildirim-satir-ust)
 * gerek kalmadı.
 */
.panel-bildirim-satir-govde strong {
    display: block;
    margin-bottom: 0.15rem;
    font-size: 0.88rem;
}

/*
 * Zaman sütunu: sarmaz ve küçülmez.
 *
 * `white-space: nowrap` olmasaydı "2 saat önce" dar pencerede iki satıra
 * bölünür ve satırın yüksekliğini oynatırdı. Sütun `auto` genişlikte
 * olduğu için metnin kendisi kadar yer kaplar; kalanı mesaja gider.
 */
.panel-bildirim-satir-zaman {
    color: var(--color-muted);
    font-size: 0.75rem;
    white-space: nowrap;
    /* Başlığın ilk satırıyla aynı hizada başlasın. */
    padding-top: 0.1rem;
}

.panel-bildirim-satir p {
    margin: 0;
    font-size: 0.82rem;
    color: var(--color-muted);
    overflow: hidden;
    text-overflow: ellipsis;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
}

/* ---------- Kartlar ve ızgara ---------- */

/*
 * `max-width: none` GEREKLİDİR ve silinmemelidir.
 *
 * `app.css` de bir `.card` tanımlar ve orada `max-width: 640px` vardır —
 * tanıtım sitesi ve giriş ekranı için doğru bir değer, çünkü oradaki
 * kartlar tek başına duran, okunur genişlikte metin kutularıdır. Ama iki
 * dosya da panelde yükleniyor (panel.php: önce app.css, sonra admin.css)
 * ve eşit özgüllükte olduklarından sonra geleni kazanır. Buradaki kural
 * `max-width` yazmadığı sürece 640px kısıtı panele SIZAR.
 *
 * Sızdığında ne olur: kart, kendisine ayrılan ızgara hücresinden dar
 * kalır ve sağında açıklanamayan bir boşluk bırakır. Bugünüm'ün iki
 * kolonlu üst bloğunda sol kart 904px'lik hücresinde 640px'te durup
 * arada 288px boşluk açıyordu; ızgara doğru hesaplanmış olmasına rağmen
 * ekran bozuk görünüyordu.
 *
 * Panelde kartın genişliğini kabı belirler — tablo kartı ekranın
 * tamamını, ızgaradaki kart kendi hücresini kaplar.
 */
.card {
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: 8px;
    padding: 1rem 1.15rem;
    max-width: none;
}

/*
 * Özet kartı ızgarası.
 *
 * Kolon sayısı KART SAYISINDAN türetilir, kart genişliğinden değil.
 *
 * Eskiden `repeat(auto-fit, minmax(190px, 1fr))` kullanılıyordu ve
 * kolon sayısını tarayıcı, "190px'lik kaç kolon sığar" sorusuna göre
 * hesaplıyordu. Sonuç, kart sayısına bağlı olmadığı için kırılgandı:
 * 1500px'lik bir pencerede ızgaraya 1188px düşüyor, altı kolon için
 * 6×190 + 5×14 = 1210px gerekiyor ve 22px eksik kalınca ızgara beşe
 * düşüp altıncı kartı alt satıra atıyordu — kullanıcının bildirdiği
 * "5 + 1" görünümü buydu. Aynı sayfa 1545px'te tek satır, 1500px'te
 * iki satır oluyordu.
 *
 * Kart sayısı `--kart-adet` ile JS'ten gelir (bkz. Ui.kartIzgarasi):
 * kartlar çizim anında filtreleniyor (sıfır olan kalem gizleniyor,
 * yetkiye göre kart ekleniyor) ve sayı CSS tarafından bilinemez.
 *
 * `min()` ile sınırlandırılır: dört kartlı bir ekranda altı kolon
 * açmak, ikisi boş iki hücre bırakırdı.
 */
.card-grid {
    display: grid;
    /* Değişken gelmezse (eski çağrı) 4 varsayılır; ızgara yine çizilir. */
    grid-template-columns: repeat(min(var(--kart-adet, 4), 7), minmax(0, 1fr));
    gap: 0.9rem;
    margin-bottom: 1.25rem;
}

/*
 * Orta ölçek: en çok 3 kolon — 6 kart 2 satıra iner.
 *
 * Kırılma noktaları kaç SATIR istendiğinden türetildi: altı kartlık
 * genel bakış ekranı geniş ekranda tek satır, orta boyda iki, mobilde
 * üç satır olmalı (proje sahibinin isteği).
 */
@media (max-width: 1200px) {
    .card-grid {
        grid-template-columns: repeat(min(var(--kart-adet, 3), 3), minmax(0, 1fr));
    }
}

/*
 * Mobil: en çok 2 kolon — 6 kart 3 satır olur.
 *
 * Tek kolona düşürülmedi: 6 kart 6 satır demekti ve telefonda sayfanın
 * tamamını özet kartları kaplardı. İki kolonda kart ~190px'e iner,
 * bu da "8" gibi kısa bir sayı ve tek satırlık etiket için yeterlidir.
 */
@media (max-width: 700px) {
    .card-grid {
        grid-template-columns: repeat(min(var(--kart-adet, 2), 2), minmax(0, 1fr));
        gap: 0.6rem;
    }
}

.stat {
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: 8px;
    padding: 0.9rem 1.05rem;
}

/*
 * Özet kartlarına renk, yalnızca DURUM anlatan değerlerde verilir.
 *
 * Her kartı renklendirmek renkten bilgi taşıma yeteneğini alır: hepsi
 * renkliyse hiçbiri dikkat çekmez. Bu yüzden nötr sayılar (toplam personel,
 * bugün gelen) normal metin rengindedir; yalnızca "iyi" (ok), "dikkat"
 * (warn) ve "sorun" (bad) durumları renk alır.
 */
.stat {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
    box-shadow: var(--golge-1);
}

.stat .label {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    font-size: 0.75rem;
    color: var(--color-muted);
}

.stat .label .ikon {
    color: var(--color-muted);
}

.stat .value.ok { color: var(--color-success); }
.stat .value.warn { color: var(--color-warning); }
.stat .value.bad { color: var(--color-danger); }

/*
 * Sol renkli şerit KALDIRILDI.
 *
 * Gerekçesi "göz önce kenar çizgisini yakalar" idi ama şerit, değeri
 * renkli olan HER kartta çıkıyordu — "0 gün" ve "Borcunuz yok" gibi
 * nötr değerler de renkli yazıldığı için kart ızgarası, hiçbir sorun
 * yokken kırmızı ve yeşil şeritlerle doluyordu. Renk artık yalnızca
 * gerçek bir durumu bildirir (bkz. .stat-kart ve analiz A7.3).
 */

.stat .value {
    font-size: 1.6rem;
    font-weight: 600;
    line-height: 1.2;
    font-variant-numeric: tabular-nums;
    margin-top: 0.15rem;
}

.stat .value.warn {
    color: var(--color-warning);
}

/*
 * Tıklanabilir sayaç (Genel Bakış → "Sizden bekleniyor").
 *
 * <a> olarak çizilir ki klavyeyle gezilebilsin ve orta tuşla yeni sekmede
 * açılabilsin; bu yüzden bağlantının varsayılan renk/altçizgi biçimi
 * sıfırlanır.
 */
.stat-tiklanabilir {
    display: block;
    color: inherit;
    text-decoration: none;
    transition: border-color 0.15s, transform 0.15s;
}

.stat-tiklanabilir:hover {
    border-color: var(--color-warning);
    transform: translateY(-1px);
}

/* Uyarı bölümü başlığı: metin ve sayı rozeti yan yana. */
.bolum-uyari {
    display: flex;
    align-items: center;
    gap: 0.55rem;
}

/*
 * Eksik yapılandırma listesi. Üç ayrı durumu tek kartta toplar; her madde
 * kendi başlığı, sonucu ve isim listesini taşıdığı için satır arası boşluk
 * madde içi boşluktan belirgin biçimde büyüktür.
 */
.uyari-listesi {
    list-style: none;
    margin: 0.6rem 0 0.9rem;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.8rem;
}

/*
 * Sol şerit yerine tam çerçeve: şeritli kutular sayfadaki kartlarla aynı
 * hizada durmuyor ve yarım bir öğe gibi görünüyorlardı (bkz. A7.4).
 */
.uyari-listesi > li {
    padding: 0.6rem 0.75rem;
    border: 1px solid var(--color-warning-border);
    border-radius: var(--radius);
    background: var(--color-warning-soft);
}

/*
 * Tablo satırındaki uyarı işareti (personel listesinde eksik yapılandırma).
 *
 * Ad ile işaret arasındaki boşluk gap ile verilir, boşluk karakteriyle
 * değil: metin kopyalandığında araya görünmez bir karakter girmemeli.
 */
.ad-uyari {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
}

/*
 * Satır uyarısı ve açıklama balonu.
 *
 * `title` özniteliği kullanılmaz: tarayıcılar çok satırlı title değerlerini
 * tutarsız gösterir (bazıları hiç göstermez), gecikmesi ayarlanamaz ve
 * biçimlendirilemez. Bu yüzden balon kendi öğesi olarak çizilir.
 */
.satir-uyari {
    display: inline-flex;
    align-items: center;
}

/*
 * cursor:help, açıklamanın fare üstüne gelince görüneceğini imleçle
 * duyurur — aksi hâlde kullanıcı işaretin üzerine gelmeyi denemez.
 */
/*
 * İşaret bir SVG ikondur, "⚠" karakteri değil: emoji sunumu işletim
 * sistemine göre değişiyor (kimi platformda renkli emoji, kimi platformda
 * ince siyah glif) ve panelin diğer ikonlarıyla aynı çizgiyi taşımıyordu.
 */
.satir-uyari-isaret {
    display: inline-flex;
    color: var(--color-warning);
    cursor: help;
    line-height: 1;
    user-select: none;
    /* Odak halkası balonu açar ama görsel çerçeve gereksiz; balon zaten
       görünür geri bildirim veriyor. */
    outline: none;
}

/*
 * Açıklama balonu. Sayfada TEK bir tane vardır ve body'nin doğrudan
 * çocuğudur (bkz. ui.js → Balon). Hem satır uyarı işareti hem de taşan
 * tablo hücreleri bu tek balonu paylaşır.
 *
 * fixed, absolute DEĞİL: .table-wrap yatay kaydırma için overflow-x:auto
 * taşır ve absolute konumlu bir balonu hücre sınırında keser. fixed
 * konumlandırma pencereye göre yerleşir, dolayısıyla hiçbir atanın taşma
 * kırpmasından etkilenmez — karşılığında koordinatı JS hesaplar.
 */
.uyari-balon {
    position: fixed;
    /* JS yerleştirene kadar ekranın dışında dursun. */
    left: -9999px;
    top: -9999px;
    z-index: 60;
    width: max-content;
    max-width: 20rem;
    padding: 0.55rem 0.7rem;
    border-radius: 8px;
    background: var(--color-text);
    color: var(--color-surface);
    font-size: 0.78rem;
    line-height: 1.45;
    font-weight: 400;
    text-transform: none;
    letter-spacing: normal;
    box-shadow: var(--golge-2);
    /*
     * Görünürlük opacity ile yönetilir, display ile değil: display:none olan
     * bir öğe geçiş (transition) alamaz ve balon anında zıplayarak açılırdı.
     * pointer-events:none ise kapalı balonun altındaki hücreyi tıklanamaz
     * hâle getirmesini önler.
     */
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
    transition: opacity 0.12s ease, visibility 0.12s ease;
}

/* Açık durum JS tarafından sınıfla verilir; konumu da orada hesaplanır. */
.uyari-balon.acik {
    opacity: 1;
    visibility: visible;
}

/* Çok maddeli balonda liste; tek maddede düz metin kullanılır. */
.uyari-balon ul {
    margin: 0.35rem 0 0;
    padding-left: 1.1rem;
    display: flex;
    flex-direction: column;
    gap: 0.3rem;
}

/*
 * `.bildirim-mesaj` ve yön oku KALDIRILDI: iki bildirim ekranı da artık
 * tablo yerine `Ui.bildirimListesi` kullanıyor ve mesaj bağlantısı
 * `.bildirim-satir-govde` içinde çiziliyor.
 */

/*
 * Bildirimden gelindiğinde vurgulanan satır.
 *
 * Vurgu geçicidir (JS 4 saniye sonra sınıfı kaldırır): kalıcı olsaydı
 * kullanıcı sonraki okumalarda hangi satırın neden seçili olduğunu
 * anlayamazdı.
 *
 * !important, zebra şeritleri ve :hover kuralları da tbody tr'ye arka plan
 * verdiği için gerekli — özgüllük yarışına girmek yerine niyet açıkça
 * belirtilir.
 */
/*
 * Odak vurgusu kendi renk değişkenini taşır: açık temada turuncunun
 * açık bir tonu, koyu temada aynı turuncunun saydam hâli. Sabit renk
 * yazılsaydı koyu temada göz alan açık bir şerit kalırdı.
 *
 * Renk uyarı ailesinden gelir ama --color-warning-softa BAĞLANMAZ:
 * satır vurgusu bir uyarı değil, "aradığınız kayıt bu" işaretidir ve
 * yanıp sönerken ikinci bir (daha doygun) tona ihtiyaç duyar.
 */
:root {
    --odak-vurgu: #ffedd5;
    --odak-vurgu-parlak: #fdba74;
}

[data-tema="koyu"] {
    --odak-vurgu: rgba(249, 115, 22, 0.22);
    --odak-vurgu-parlak: rgba(249, 115, 22, 0.4);
}

table.data tbody tr.satir-odak {
    background: var(--odak-vurgu) !important;
    box-shadow: inset 3px 0 0 var(--color-warning);
    animation: satir-odak-belir 0.6s ease;
}

@keyframes satir-odak-belir {
    0%, 100% { background: var(--odak-vurgu); }
    50% { background: var(--odak-vurgu-parlak); }
}

/* Hareketi azaltmayı tercih eden kullanıcıda yanıp sönme olmaz. */
@media (prefers-reduced-motion: reduce) {
    table.data tbody tr.satir-odak {
        animation: none;
    }
}

/*
 * Tıklanabilir satır (bkz. Ui.table opts.satiraTiklandi).
 *
 * Satırın tamamı bir eylemi tetikliyorsa bu görünürde belli olmalı; aksi
 * hâlde kullanıcı tıklanabileceğini keşfetmek için denemek zorunda kalır.
 * Satır içindeki düğmeler tıklamadan dışlandığı için onların üzerinde
 * imleç varsayılana döner.
 */
table.data tbody tr.tiklanabilir {
    cursor: pointer;
}

table.data tbody tr.tiklanabilir:hover {
    background: var(--color-primary-soft);
}

table.data tbody tr.tiklanabilir button,
table.data tbody tr.tiklanabilir a {
    cursor: pointer;
}

/* Klavyeyle gezen kullanıcı hangi satırda olduğunu görmeli: satır
   tabindex taşıdığı için odak halkası tarayıcı varsayılanına bırakılmaz,
   tablo hücrelerinde kırpılabildiği için içe doğru çizilir. */
table.data tbody tr.tiklanabilir:focus-visible {
    outline: 2px solid var(--color-primary);
    outline-offset: -2px;
}

/* Bildirim dropdown'ındaki başlık sağ tarafı: ses düğmesi + "Tümünü gör". */
.panel-bildirim-baslik-sag {
    display: inline-flex;
    align-items: center;
    gap: 0.6rem;
}

.panel-bildirim-ses {
    border: none;
    background: none;
    padding: 0;
    font-size: 0.95rem;
    line-height: 1;
    cursor: pointer;
    opacity: 0.75;
    transition: opacity 0.12s ease;
}

.panel-bildirim-ses:hover {
    opacity: 1;
}

/* ---------- Filtre çubuğu ---------- */

.filters {
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: 8px;
    padding: 0.85rem 1rem;
    margin-bottom: 1rem;
    display: flex;
    flex-wrap: wrap;
    gap: 0.75rem;
    align-items: flex-end;
}

.filters .field {
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
    min-width: 150px;
}

.filters label {
    font-size: 0.75rem;
    color: var(--color-muted);
}

/* ---------- Tablolar ---------- */

/*
 * Kart çerçevesi .table-wrap'te DEĞİL, onu saran .tablo-kutu'dadır.
 *
 * Sayfalama (.pager) kaydırma kutusunun dışına, bu kutunun içine alındı
 * (bkz. ui.js → table): .table-wrap overflow-x: auto taşıdığı için sayfalama
 * onun içindeyken tabloyla birlikte kayıyor ve geniş tablolarda ekrandan
 * çıkıyordu. Çerçeve dışta olmasaydı sayfalama kartın dışında, çerçevesiz
 * asılı kalırdı; böylece görünüm eskisiyle aynı kalır.
 */
/*
 * `overflow: hidden` YOK — bilinçli.
 *
 * Kart, tablonun köşelerini yuvarlak çerçevesine sığdırmak için
 * overflow'u kırpıyordu. Ama üst şeritte açılan paneller (dönem
 * seçicisinin özel aralık penceresi, sütun menüsü) kartın kenarını aşınca
 * kırpılıyor ya da kırpılma riski taşıyordu: kırpan bir kapsayıcının
 * içinden absolute konumlu bir çocuk dışarı çıkamaz.
 *
 * Köşe sığdırma işi, kırpmaya gerek kalmadan doğrudan köşeleri olan
 * parçalara verildi (aşağıya bkz.): kaydırma kutusu ve şeridin kendisi.
 * Böylece açılır paneller serbestçe taşabiliyor.
 */
.tablo-kutu {
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: 12px;
    box-shadow: var(--golge-1);
}

/*
 * Kartın ALT köşeleri buraya düşer: kaydırma kutusu kartın en alt
 * parçasıdır (sayfalama yoksa) ve yatay kaydırmada tablonun köşesi
 * çerçeveden taşmamalı.
 *
 * Sayfalama varsa alt köşeler ona ait olur; ikisine birden yuvarlaklık
 * vermek zararsızdır, görünen her zaman en alttakidir.
 */
.table-wrap {
    overflow-x: auto;
    border-radius: 0 0 12px 12px;
}

/*
 * Kartın üst köşeleri .tablo-serit'te, alt köşeleri .pager'da tanımlıdır
 * (kendi kural bloklarında, bu dosyanın ilerisinde): aynı seçiciyi burada
 * ikinci kez yazmak, biri değiştiğinde diğerinin sessizce geride
 * kalmasına yol açardı.
 */

/*
 * table-layout: fixed — sütun daraltmanın ÖN KOŞULU.
 *
 * Varsayılan `auto` yerleşimde tarayıcı sütunu içeriğe göre büyütür;
 * dolayısıyla hücre asla taşmaz, text-overflow:ellipsis hiç tetiklenmez ve
 * th üzerine yazılan genişlik içerik daha genişse yok sayılır. `fixed` ile
 * ilk satırın (thead) hücre genişlikleri tabloyu belirler, böylece hem
 * sürükleyerek daraltma hem de "..." çalışır.
 *
 * GENİŞLİK: durağan hâlde %100, sürükleme sırasında max-content.
 *
 * İkisi de gereklidir ve aynı anda olamazlar; ölçümle saptanan denge şudur:
 *
 * width: 100% (durağan hâl) → Sütunlara yazılan başlangıç tavanı ancak böyle
 *   bağlayıcı olur. max-content'te tablo, sarmayan uzun metnin tamamına göre
 *   boyutlanır ve th'ye yazılan 320px yok sayılır: adres sütunu 614px'te
 *   kalır, hücre hiç kırpılmaz, dolayısıyla ne "..." çıkar ne balon açılır.
 *   %100 ile aynı sütun 320px'e oturur ve içerik kırpılır.
 * Sürüklemenin komşuları oynatmaması ise CSS'le değil, HER sütuna açık
 *   genişlik yazılarak sağlanır (bkz. ui.js → asgariUygula): genişliği
 *   verilmemiş tek bir sütun kalsa table-layout:fixed artan alanı ona yığar
 *   ve komşular yine kayardı. Tablo max-content'e alınarak da çözülebilirdi
 *   ama o zaman sütunlara yazılan tavanlar yok sayılıyor ve uzun metinli
 *   sütun tabloyu yutuyordu.
 * min-width: 100% → Sütun toplamı dar kaldığında tablo kapsayıcıdan dar
 *   görünmesin.
 * .table-wrap overflow-x: auto → Toplam kapsayıcıyı aştığında kırpmak
 *   yerine yatay kaydırma verir.
 */
table.data {
    width: 100%;
    min-width: 100%;
    border-collapse: collapse;
    font-size: 0.88rem;
    table-layout: fixed;
}

table.data th {
    text-align: left;
    padding: 0.75rem 0.9rem;
    /* Tutamak th'ye göre konumlanır. */
    position: relative;
    background: var(--color-surface-2);
    border-bottom: 1px solid var(--color-border);
    font-size: 0.71rem;
    font-weight: 600;
    color: var(--color-muted);
    white-space: nowrap;
}

/*
 * Sığmayan metin "..." ile kesilir; tamamı üzerine gelince balonda görünür
 * (bkz. ui.js → tasmaBalonuBagla).
 *
 * Üç özellik birlikte çalışmak zorundadır: nowrap olmadan metin alta sarar
 * ve hiç taşmaz, overflow:hidden olmadan komşu hücrenin üstüne taşar,
 * text-overflow olmadan da sessizce kırpılır ve kullanıcı eksik metni fark
 * etmez.
 */
table.data td {
    padding: 0.6rem 0.9rem;
    /* Satır yüksekliği en az 52px: rozet ve avatar taşıyan hücreler
       sıkışmasın, göz satırları rahat ayırsın. */
    height: 52px;
    border-top: 1px solid var(--color-border);
    /*
     * Hücre içeriği DİKEY ORTALIDIR.
     *
     * Eskiden üstten hizalıydı; gerekçesi cokSatir sütunlarıydı (dört
     * satırlık bir açıklamanın yanındaki tarih ortada asılı kalmasın
     * diye). Ama bu, çok satırlı hücresi OLMAYAN tabloları da etkiliyordu:
     * isim ve "—" hücrenin üstünde, yanındaki rozet ve düğme ortasında
     * duruyordu (bkz. analiz A6.4).
     *
     * Kural tersine çevrildi: varsayılan ortalama, çok satırlı hücre
     * taşıyan SATIRLAR istisna (bkz. tr.cok-satirli aşağıda).
     */
    vertical-align: middle;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/*
 * Çok satırlı hücre taşıyan satırlarda üstten hizalama geri gelir:
 * uzun bir gerekçenin yanındaki tarih, hücrenin ortasında değil
 * metnin ilk satırıyla aynı hizada durmalıdır.
 */
table.data tbody tr.cok-satirli td {
    vertical-align: top;
}

/*
 * Tavana takılan sütun: metin KIRPILMAZ, sarar.
 *
 * Sınıf ui.js tarafından yalnızca içeriği tavandan geniş olan sütunlara
 * verilir (bkz. asgariUygula). Sütun genişliğinin kuralı "başlık dahil en
 * geniş hücre kadar"dır; sığmayan metni "..." ile kesip tamamını balona
 * saklamak bu kuralı çiğniyor ve kullanıcıyı okumak için fareyle
 * gezinmeye zorluyordu. Artık uzun bir ad ya da adres iki satıra sarar:
 * sütun tabloyu yutmaz ama hiçbir şey de gizlenmez.
 */
table.data td.sarmali {
    white-space: normal;
    overflow: visible;
    text-overflow: clip;
    /* Boşluksuz uzun değer (URL, e-posta) komşu sütuna binmesin. */
    overflow-wrap: anywhere;
}

/*
 * Saran hücrenin İÇİNDEKİ öğeler de kırpılmaz.
 *
 * Hücreye `white-space: normal` vermek tek başına yetmiyordu: içerideki
 * bileşenler kendi kırpma kurallarını taşıyor (`.kisi-ad`, `.kisi-metin
 * small` ve benzerleri "uzun ad sütunu genişletmesin" diye ellipsis
 * koyuyor). Sonuç, hücre sarmaya hazırken adın yine "Bayram Ali Gül ..."
 * diye kesilmesiydi.
 *
 * Kural tek tek bileşen adlarına göre değil, SARAN HÜCRENİN İÇİ olarak
 * yazıldı: yeni bir hücre bileşeni eklendiğinde aynı kusur geri
 * gelmesin (CLAUDE.md — "tabloya özel değil genel çözüm").
 *
 * Esnek kutu çocuklarının sarabilmesi için `min-width: 0` gerekir;
 * varsayılan `auto` değeri, flex öğesini içeriğinden daha dar olmaya
 * bırakmaz ve sarma hiç tetiklenmez.
 */
table.data td.sarmali *,
table.data td.col-satir * {
    overflow: visible;
    text-overflow: clip;
    white-space: normal;
    overflow-wrap: anywhere;
    min-width: 0;
}

/*
 * İstisna: rozet, düğme ve ikon saran hücrede de TEK SATIR kalır.
 *
 * "Yürürlükte" gibi bir rozetin iki satıra kırılması onu rozet olmaktan
 * çıkarır; ikonun sarması ise anlamsızdır. Bunlar zaten kısa ve sabit
 * genişlikte olduğu için sütunu zorlamazlar.
 */
table.data td.sarmali .badge,
table.data td.sarmali .btn,
table.data td.sarmali svg,
table.data td.col-satir .badge,
table.data td.col-satir .btn,
table.data td.col-satir svg {
    white-space: nowrap;
    flex-shrink: 0;
}

/*
 * Eylem sütunu kırpılmaz: içindeki düğmeler sabit sayıdadır ve yarısı
 * görünen bir "Sil" düğmesi kullanılamaz hâle gelir. Satır menüsü (⋮) da
 * taşma kırpmasıyla kaybolmamalı.
 */
table.data td.actions {
    overflow: visible;
    text-overflow: clip;
}

/*
 * Uzun metin sütunu: metin KAÇ SATIR tutuyorsa o kadar görünür.
 *
 * Tüm hücrelere uygulanan tek satır kuralı (white-space:nowrap) tarih, tutar
 * ve durum gibi kısa alanlar için doğrudur; ancak cümle taşıyan bir sütunda
 * ("Ne oldu", "Açıklama", "Gerekçe", "Adres") metnin neredeyse tamamını
 * gizler ve tabloyu okunamaz hâle getirir. Bu sütunlar ekran tarafından
 * `cokSatir: true` ile işaretlenir.
 *
 * Önce iki satırda kesip "..." koymak denendi (-webkit-line-clamp). İki
 * sorunu vardı: (1) hücre bir table-cell olduğu için display:-webkit-box
 * uygulanmıyor, clamp devreye girmiyor ve kırpma hücre YÜKSEKLİĞİNDE
 * gerçekleşiyordu — ekranda üçüncü satırın üst yarısı sızıyordu; (2) sızma
 * düzeltilse bile yönetici bildirimin yarısını okuyup gerisini balonda
 * aramak zorunda kalıyordu.
 *
 * Bu yüzden kırpma tamamen kaldırıldı: metin sarar, satır yüksekliği içeriğe
 * göre uzar ve hiçbir şey gizlenmez. Kısa sütunlar (tarih, tutar, durum) tek
 * satır kuralını korur; "..." ve balon yalnızca onlar için anlamlıdır.
 */
table.data td.col-satir {
    white-space: normal;
    overflow: visible;
    text-overflow: clip;
    /* Uzun kelime/URL hücreden taşıp komşu sütunun üstüne binmesin. */
    overflow-wrap: anywhere;
}


/*
 * Sürükleme tutamağı: başlığın sağ kenarında, sütunlar arası ayracın
 * üstünde durur. Kendi çizgisini çizmez — th+th border-left zaten orada.
 * Geniş tutma alanı (8px) fareyle yakalamayı kolaylaştırır; ince bir
 * 1px hedef kullanıcıyı kenarı aramaya zorlardı.
 */
/*
 * Tutamak hücrenin İÇİNDE kalır (right:0), dışına taşmaz.
 *
 * Önceki sürüm right:-4px ile 4px dışarı taşıyordu. Görsel olarak farkı yoktu
 * ama ölçülebilir bir zararı vardı: taşan mutlak konumlu çocuk, th'nin
 * scrollWidth'ini clientWidth'in 4px üstünde SABİT tutuyordu. Dolayısıyla
 * "içerik sığmıyor mu?" testi (scrollWidth > clientWidth) başlık ne kadar
 * geniş olursa olsun daima doğru dönüyor, başlık hiç kırpılmadığı hâlde
 * kırpık sanılıyordu. Sütun genişliği ne olursa olsun bitmeyen bir arama
 * hâline gelmişti (880px'te bile çözülmedi).
 *
 * right:0 ile tutamak kutunun içinde durur; 8px'lik yakalama alanı korunur,
 * ayraç çizgisinin üstüne denk gelmesi için hafifçe sağa yaslanır.
 */
.sutun-tutamak {
    position: absolute;
    top: 0;
    right: 0;
    width: 8px;
    height: 100%;
    cursor: col-resize;
    user-select: none;
    /* Başlık metninin üstünde kalsın. */
    z-index: 1;
}

.sutun-tutamak:hover,
body.sutun-suruklerken .sutun-tutamak {
    background: var(--color-primary);
    opacity: 0.35;
}

/*
 * Sürükleme sırasında tüm sayfada imleç sabitlenir ve metin seçimi kapanır:
 * aksi hâlde fare tutamaktan çıktığı anda imleç değişir ve sürükleme
 * yanlışlıkla tablo metnini seçmeye başlar.
 */
body.sutun-suruklerken {
    cursor: col-resize;
    user-select: none;
}

/*
 * Zebra şerit ve dikey ayraçlar KALDIRILDI.
 *
 * İkisi de satırı takip etmeyi kolaylaştırmak içindi ama birlikte
 * tabloyu bir ızgaraya çeviriyorlardı: on sütunlu bir listede göz, veriyi
 * değil çizgileri görüyordu. Satırları ayıran tek işaret artık yatay
 * çizgidir; hangi satıra bakıldığı hover ile belli olur.
 *
 * Hover rengi de ana renkten nötr yüzeye çekildi: mavi vurgu satırın
 * seçili olduğunu ima ediyordu, oysa yalnızca farenin üzerinde olduğunu
 * gösteriyor.
 */
table.data tbody tr:hover {
    background: var(--color-surface-2);
}

table.data td.num {
    font-variant-numeric: tabular-nums;
}

/*
 * th ve td aynı hizalamayı taşımalı: yalnızca td'ye uygulanan bir kural,
 * başlığı solda bırakıp altındaki sayı sütununu sağa kaydırır ve tablo
 * görsel olarak kaymış görünür.
 */
table.data th.num,
table.data td.num {
    text-align: right;
}

table.data th.actions,
table.data td.actions {
    white-space: nowrap;
    text-align: right;
}

/*
 * Rapor tablolarının toplam satırı.
 *
 * Başlık şeridiyle aynı zemini taşır: toplam bir VERİ SATIRI DEĞİLDİR,
 * tablonun çerçevesine aittir. Zebra ve hover kuralları tbody ile
 * sınırlı olduğu için buraya sızmaz — toplam satırının üzerine gelince
 * renk değiştirmesi, tıklanabilir olduğu izlenimi verirdi.
 *
 * Üstündeki çizgi normal satır ayracından kalın: gözün "buradan
 * sonrası veri değil" ayrımını yapması gerekiyor.
 */
table.data tfoot td {
    padding: 0.7rem 0.9rem;
    border-top: 2px solid var(--color-border);
    background: var(--color-surface-2);
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

/* Toplamın neyin toplamı olduğunu söyleyen ilk hücre vurgulanmaz. */
table.data tfoot td:first-child {
    font-weight: 500;
    color: var(--color-muted);
}

.empty {
    padding: 2rem 1rem;
    text-align: center;
    color: var(--color-muted);
    font-size: 0.9rem;
}

.pager {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    justify-content: flex-end;
    padding: 0.7rem 0.85rem;
    border-top: 1px solid var(--color-border);
    font-size: 0.85rem;
    color: var(--color-muted);
    /*
     * Kartın ALT köşeleri: sayfalama varsa kartın en alt parçası odur.
     * .tablo-kutu artık overflow:hidden taşımıyor (açılır paneller
     * kırpılmasın diye), dolayısıyla köşeleri parçaların kendisi verir.
     */
    border-radius: 0 0 12px 12px;
}

/* ---------- Butonlar ---------- */

/*
 * Düğme.
 *
 * Yüksekliği SABİTTİR (36px): dolgudan türeyen yükseklik, ikonlu ve
 * ikonsuz düğmeleri yan yana koyduğunda birkaç piksel kaydırıyor ve
 * araç çubuğundaki sıra dalgalı görünüyordu. Metin ortalanır.
 */
.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.45rem;
    height: 36px;
    padding: 0 0.85rem;
    border: 1px solid var(--color-border-strong);
    border-radius: var(--radius);
    background: var(--color-surface);
    color: var(--color-text);
    font-size: 0.85rem;
    font-weight: 500;
    font-family: inherit;
    white-space: nowrap;
    cursor: pointer;
    text-decoration: none;
}

.btn:hover {
    background: var(--color-surface-2);
}

/* Düğme ikonu metinden biraz küçüktür ve onunla aynı rengi taşır. */
.btn .ikon {
    width: 16px;
    height: 16px;
}

/*
 * Bugünüm'ün ana eylemi ("İşe giriş yap"): günde bir kez basılan ve
 * ekranda aranmaması gereken düğme.
 */
.btn-buyuk {
    height: 48px;
    padding: 0 1.4rem;
    font-size: 0.95rem;
    font-weight: 600;
}

.btn-buyuk .ikon {
    width: 18px;
    height: 18px;
}

/* Pasif düğme kuralı varyantlardan SONRA gelir (bkz. aşağısı). */

.btn.primary {
    background: var(--color-primary);
    border-color: var(--color-primary);
    color: #fff;
}

.btn.primary:hover {
    background: var(--color-primary-dark);
}

/*
 * Koyu temada birincil düğmenin metni KOYU olur.
 *
 * Koyu temada vurgu rengi bilerek açılır (#2563eb → #3b82f6) ve beyaz
 * metin o zeminde 3.68:1 veriyordu — AA eşiği 4.5:1 (ölçüm). Koyu metin
 * aynı zeminde 5.12:1 verir.
 *
 * Alternatif, koyu temada düğme zeminini yeniden koyulaştırmaktı; o zaman
 * düğme, aynı vurgu rengini taşıyan diğer öğelerden (bağlantılar, etkin
 * sekme) farklı bir tonda kalırdı. Açık zemin + koyu metin, koyu
 * temalarda olağan kalıptır.
 *
 * :hover'da zemin --color-primary-dark'a (daha da AÇIK bir ton) gittiği
 * için koyu metin orada da doğru taraftadır.
 */
/*
 * :not(:disabled) ZORUNLUDUR. Pasif düğme kuralı (aşağıda) rengi bırakıp
 * zemini --color-bg, metni --color-muted yapar; bu seçici ondan daha
 * yüksek özgüllükte olduğu için :not olmadan pasif düğmenin metnini de
 * koyuya çeviriyordu ve metin, koyu temada zaten koyu olan zeminle
 * birebir aynı renge geliyordu: kontrast 1.00:1, yani görünmez düğme.
 *
 * Bu, ölçümün kaçırdığı bir kırılmaydı — sınama sayfasında pasif birincil
 * düğme yoktu; ekran görüntüsü yakaladı.
 */
:root[data-tema="koyu"] .btn.primary:not(:disabled),
:root[data-tema="koyu"] .btn.primary:not(:disabled):hover {
    color: #0b1120;
}

.btn.danger {
    color: var(--color-danger);
    border-color: var(--color-danger);
    background: var(--color-danger-soft);
}

.btn.small {
    padding: 0.25rem 0.55rem;
    font-size: 0.78rem;
}

.btn.link {
    border-color: transparent;
    background: transparent;
    color: var(--color-primary);
    padding-left: 0;
    padding-right: 0;
}

.btn.link:hover {
    background: transparent;
    text-decoration: underline;
}

.btn + .btn {
    margin-left: 0.3rem;
}

/*
 * Pasif düğme RENGİNİ BIRAKIR.
 *
 * Yalnızca opaklık düşürmek yetmiyordu: soluk da olsa mavi kalan bir
 * birincil düğme, ekrandaki en dikkat çekici öğe olarak duruyor ve
 * basılabilirmiş gibi görünüyordu (Avanslarım'da "Avans talebi oluştur"
 * böyleydi). Üstelik %50 opaklıktaki beyaz metin mavi zeminde okunmuyor.
 *
 * Kural varyantlardan SONRA yazılır: `.btn:disabled` ile `.btn.primary`
 * aynı özgüllükte (0,2,0) ve kazananı kaynak sırası belirliyor. Daha
 * üstte durduğu sürece birincil düğme pasifken bile mavi kalıyordu.
 */
.btn:disabled,
.btn.primary:disabled,
.btn.danger:disabled {
    border-color: var(--color-border);
    background: var(--color-bg);
    color: var(--color-muted);
    cursor: not-allowed;
}

.btn:disabled .ikon {
    opacity: 0.6;
}

/* ---------- Rozetler ---------- */

/*
 * Rozetler. Renk SÜS DEĞİL ANLAMDIR ve ekranlar rengi kendileri seçmez:
 * hangi durumun hangi varyanta düştüğü tek bir eşlemede (durum.js)
 * yazılıdır. Beş varyant vardır ve beşi de ayrı bir soruya cevap verir:
 *
 *   ok      olumlu, tamamlanmış        Onaylandı, Aktif, Mesai bitti
 *   warn    bekleyen, dikkat isteyen   Beklemede, Geç kaldı
 *   bad     olumsuz, hata              Reddedildi, Giriş bildirilmedi
 *   info    bilgi, değişiklik          Değiştirildi, Fazla mesaiye kaldı
 *   mute    kategori (nötr)            Çalışan, Haftalık, Resmî tatil
 *
 * "mute" bir durum değil KATEGORİ rozetidir: rol, düzen tipi ve gün türü
 * gibi değerler iyi ya da kötü olmadığı için renk kodlanmaz. Eskiden
 * "Şirket Yöneticisi" rolü sarı, "Rotasyonlu" düzen yeşil görünüyordu ve
 * okuyan kişi olmayan bir uyarı arıyordu.
 */
/*
 * Gece vardiyasında ertesi güne taşan çıkış saatinin "+1" işareti.
 *
 * Saatin yanında küçük bir üst simge olarak durur: "10:47⁺¹". Rozet
 * yapılmadı — ertesi güne taşmak bir sapma değil, gece vardiyasının
 * olağan hâlidir ve rozet ona hak etmediği bir ağırlık verirdi.
 *
 * Hizalama sayı sütunuyla bozulmasın diye üst simge satır yüksekliğini
 * artırmaz (`line-height: 0`); aksi hâlde gece vardiyası olan satır
 * diğerlerinden bir iki piksel yüksek durur ve tablo dalgalı görünürdü.
 */
.saat-ertesi {
    white-space: nowrap;
}

.saat-ertesi .ertesi-gun {
    margin-left: 0.15em;
    color: var(--color-muted);
    font-size: 0.7em;
    font-weight: 600;
    line-height: 0;
}

.badge {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
    padding: 0.12rem 0.5rem;
    border-radius: 999px;
    font-size: 0.73rem;
    font-weight: 500;
    white-space: nowrap;
}

.badge.ok {
    background: var(--color-success-soft);
    color: var(--color-success);
}

.badge.warn {
    background: var(--color-warning-soft);
    color: var(--color-warning);
}

.badge.bad {
    background: var(--color-danger-soft);
    color: var(--color-danger);
}

.badge.info {
    background: var(--color-info-soft);
    color: var(--color-info);
}

.badge.mute {
    background: var(--color-neutral-soft);
    color: var(--color-neutral);
}

/* ---------- Formlar ---------- */

input, select, textarea {
    padding: 0.42rem 0.6rem;
    border: 1px solid var(--color-border);
    border-radius: 6px;
    font-size: 0.88rem;
    font-family: inherit;
    background: var(--color-surface);
    color: var(--color-text);
    width: 100%;
}

/*
 * Buradaki odak kuralı KALDIRILDI: app.css'teki genel `:focus-visible`
 * artık outline'ı da veriyor. Bu blok yalnızca sayılı öğelere (input,
 * select, textarea, .btn, .panel-nav a, .panel-taraf-dugme) outline
 * veriyordu; listede olmayan bağlantı, summary ve tabindex'li satırlar
 * yüksek kontrast modunda odaksız kalıyordu. Liste büyüterek değil
 * kuralı genele alarak çözüldü.
 */

textarea {
    min-height: 68px;
    resize: vertical;
}

/*
 * Gün + saat girişi (bkz. Ui.gunSaatAlani).
 *
 * Üç alan tek satırda durur: bir gün, iki saat. `form-grid`in
 * auto-fit ızgarası kullanılmadı — orada saat alanları 210px'lik
 * asgari genişliğe zorlanıp satırı gereksiz geniş yapıyordu; bir
 * saat girdisi 210px'e ihtiyaç duymaz.
 */
.gun-saat {
    display: grid;
    grid-template-columns: minmax(150px, 1.2fr) minmax(110px, 1fr) minmax(110px, 1fr);
    gap: 0.85rem;
    margin-bottom: 0.85rem;
}

/*
 * Dar ekranda alt alta: üç girdiyi 390px'e sıkıştırmak saat
 * alanlarını tarayıcının kendi asgarisinin altına iter ve
 * Chrome'da saat seçici ikonu metnin üstüne biner.
 */
@media (max-width: 560px) {
    .gun-saat {
        grid-template-columns: 1fr;
    }
}

/*
 * "Ertesi gün" işareti yalnızca gece vardiyasında belirir ve
 * uyarı rengindedir: bu, damganın tarihinin seçilen günden
 * farklı olduğu tek durumdur ve fark edilmezse kayıt yanlış güne
 * yazıldı sanılır.
 *
 * Rengi `.hint.warn`dan gelir (bkz. aşağısı), burada YENİDEN
 * TANIMLANMAZ: bu blok stil dosyasında `.hint`ten önce geldiği
 * için eşit özgüllükteki bir `color` kuralı sonradan geleni
 * kaybeder ve etiket siyah kalırdı. Ölçüldü: getComputedStyle
 * rgb(0,0,0) veriyordu.
 */
.gun-saat-ertesi {
    font-weight: 500;
}

.form-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
    gap: 0.85rem;
}

.form-grid .field.wide {
    grid-column: 1 / -1;
}

.field {
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
}

.field > label {
    font-size: 0.8rem;
    color: var(--color-muted);
}

/*
 * Zorunluluk YILDIZLA DEĞİL, tersinden işaretlenir: panelin formlarında
 * alanların ezici çoğunluğu zorunlu (63 alanın 49'u) ve her satıra bir
 * `*` koymak onu gürültüye çevirir. Ayrıca `*` kendi başına hiçbir şey
 * söylemez; açıklaması formların hiçbir yerinde yazmıyordu.
 *
 * İşaret, alan adını gölgelememek için etiketten de soluktur: okunması
 * gereken şey alanın ne olduğu, isteğe bağlılığı ikincil bilgidir.
 */
.field-istege-bagli {
    opacity: 0.75;
    font-weight: 400;
}

.field .hint {
    font-size: 0.75rem;
    color: var(--color-muted);
}

.field.check {
    flex-direction: row;
    align-items: center;
    gap: 0.45rem;
}

.field.check input {
    width: auto;
}

.field.check label {
    font-size: 0.85rem;
    color: var(--color-text);
}

/* ---------------- Switch (açık/kapalı ayar) ---------------- */

/*
 * Açık/kapalı ayarların görünümü. Metin solda, switch sağda: göz
 * ayarların adını soldan tarar, durumlarını sağdan; ikisi karışınca
 * "hangisi açık" sorusu her satırda ayrı ayrı okumayı gerektiriyordu.
 *
 * Hem form alanlarını (.field.switch-satir) hem ayar ekranını
 * (.ayar-satiri) kapsar: iki yerde iki ayrı switch görünümü çıkmasın.
 */
.field.switch-satir,
.ayar-satiri {
    display: flex;
    flex-direction: row;
    align-items: flex-start;
    gap: 1rem;
}

.field.switch-satir .switch-metin,
.ayar-satiri .ayar-satiri-metin {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
    flex: 1;
    min-width: 0;
}

.field.switch-satir .switch-metin label,
.ayar-satiri label {
    font-size: 0.88rem;
    color: var(--color-text);
    cursor: pointer;
}

/*
 * Switch'in kendisi bir <label>'dır ve içindeki checkbox'ı sarar:
 * tıklama alanı topuzun tamamı olur, ayrı bir `for` bağı gerekmez.
 */
.switch {
    position: relative;
    display: inline-block;
    width: 40px;
    height: 22px;
    flex-shrink: 0;
    cursor: pointer;
}

/*
 * Girdi GİZLENİR ama DOM'da kalır ve odaklanabilir olmayı sürdürür:
 * display:none ya da visibility:hidden onu klavye sırasından düşürür ve
 * ekran okuyucudan gizlerdi. Bu yüzden saydamlaştırılıp switch'in
 * üstüne yayılır.
 */
.switch .switch-girdi {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    margin: 0;
    opacity: 0;
    cursor: pointer;
}

.switch .switch-yol {
    position: absolute;
    inset: 0;
    border-radius: 999px;
    background: var(--color-border-strong);
    transition: background-color 0.15s ease;
    pointer-events: none;
}

.switch .switch-yol::after {
    content: "";
    position: absolute;
    top: 3px;
    left: 3px;
    width: 16px;
    height: 16px;
    border-radius: 50%;
    background: #fff;
    transition: transform 0.15s ease;
}

.switch .switch-girdi:checked + .switch-yol {
    background: var(--color-primary);
}

.switch .switch-girdi:checked + .switch-yol::after {
    transform: translateX(18px);
}

/*
 * Odak halkası switch'in kendisinde değil YOLUNDA gösterilir: girdi
 * saydam olduğu için onun üzerindeki halka görünmezdi.
 */
.switch .switch-girdi:focus-visible + .switch-yol {
    outline: 2px solid var(--color-primary);
    outline-offset: 2px;
}

@media (prefers-reduced-motion: reduce) {
    .switch .switch-yol,
    .switch .switch-yol::after {
        transition: none;
    }
}

/* ---------------- Girdi soneki (birim) ---------------- */

/*
 * Birim, girdinin sağ ucunda ayrı bir hücre olarak durur. Girdi ve
 * sonek tek bir çerçeve paylaşır; çerçeve dıştaki kutuya ait olduğu için
 * odak halkası da ikisini birden sarar.
 */
.girdi-sonekli {
    display: flex;
    align-items: stretch;
    border: 1px solid var(--color-border-strong);
    border-radius: var(--radius-sm);
    background: var(--color-surface);
    overflow: hidden;
}

.girdi-sonekli:focus-within {
    border-color: var(--color-primary);
}

.girdi-sonekli input {
    flex: 1;
    min-width: 0;
    border: none;
    background: none;
    outline: none;
}

.girdi-sonek {
    display: grid;
    place-items: center;
    padding: 0 0.65rem;
    /*
     * Sonek zemini nötr token'dan gelir, sabit griden değil: koyu temada
     * sabit #f8fafc girdinin yanında parlak bir şerit olarak kalırdı.
     */
    background: var(--color-neutral-soft);
    border-left: 1px solid var(--color-border);
    color: var(--color-muted);
    font-size: 0.82rem;
    white-space: nowrap;
}

.day-toggles {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem;
}

.day-toggles label {
    display: flex;
    align-items: center;
    gap: 0.3rem;
    padding: 0.3rem 0.55rem;
    border: 1px solid var(--color-border);
    border-radius: 6px;
    font-size: 0.82rem;
    cursor: pointer;
}

.day-toggles input {
    width: auto;
}

/* ---------- Rotasyon döngü günleri ---------- */

.rotasyon-listesi {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

.rotasyon-satir {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.6rem;
    padding: 0.5rem 0.7rem;
    border: 1px solid var(--color-border);
    border-radius: 8px;
}

.rotasyon-satir .rotasyon-gun-etiketi {
    flex: 0 0 64px;
    font-weight: 600;
    font-size: 0.85rem;
}

.rotasyon-satir select {
    flex: 0 0 140px;
    width: auto;
}

.rotasyon-satir input[type="time"] {
    flex: 0 0 110px;
    width: auto;
}

.rotasyon-satir input[type="number"] {
    flex: 0 0 90px;
    width: auto;
}

.rotasyon-satir .rotasyon-izin-notu {
    color: var(--color-muted);
    font-size: 0.82rem;
}

/*
 * Döngü deseninin görsel şeridi. Saat listesini okuyarak bir deseni
 * doğrulamak zordur; renkli kutucuklarda "üst üste dört gece" ya da
 * "hiç izin yok" gibi durumlar bakışta görünür.
 */
.rotasyon-onizleme {
    margin-top: 0.9rem;
}

.rotasyon-serit {
    display: flex;
    flex-wrap: wrap;
    gap: 0.35rem;
}

.rotasyon-kutu {
    display: flex;
    flex-direction: column;
    gap: 0.1rem;
    min-width: 76px;
    padding: 0.4rem 0.5rem;
    border-radius: 8px;
    border: 1px solid var(--color-border);
    font-size: 0.75rem;
    line-height: 1.25;
}

.rotasyon-kutu-gun {
    font-weight: 700;
    font-size: 0.72rem;
    opacity: 0.75;
}

.rotasyon-kutu-tip {
    font-weight: 600;
}

.rotasyon-kutu-saat {
    font-variant-numeric: tabular-nums;
    opacity: 0.8;
}

/*
 * Vardiya renkleri — rotasyon deseni, kişi/şablon takvimi, ekip ızgarası
 * ve renk açıklaması bu değişkenlerden okur; aynı vardiya her ekranda aynı
 * renktedir.
 *
 * Renk AİLELERİ mobildekiyle aynıdır (gündüz mavi, akşam amber, gece ters
 * renk, tatil gri, onaylı izin camgöbeği): aynı kavram iki uygulamada aynı
 * renkte görünmeli (MOBIL_EKIP.md madde 46).
 *
 * Tatil günü (koddaki `izin` tipi) bir süre camgöbeğiydi. Camgöbeği ise
 * panelin her yerinde izin HAKKININ rengidir; çizelge onaylı izni de
 * göstermeye başlayınca ikisi aynı görünecekti — "İzin" diye işaretlenen boş
 * günü izin hakkı sanan yöneticinin düştüğü karışıklık, bu kez renkte. Bu
 * yüzden tatil nötr griye döndü, camgöbeği onaylı izne kaldı. Gri, aşağıdaki
 * ilk sorunun geri gelmemesi için hafta sonu zemininden (--color-bg) ve
 * kenarlık çizgisinden belirgin biçimde koyudur.
 *
 * Eskiden web gündüzü yeşil, akşamı turuncu, izni gri gösteriyordu. Üç
 * sorun vardı:
 *  - Yeşil ve turuncu panelde "tamam" ve "uyarı" demek; vardiya hücresi
 *    bir durum bildirmiyor.
 *  - İzin, hafta sonu hücreleriyle aynı zemini (--color-bg) taşıyordu ve
 *    ayırt edilemiyordu.
 *  - Tonlar çok soluktu; ekip ızgarasının 28 piksellik hücrelerinde
 *    gündüz ile akşam neredeyse aynı görünüyordu.
 *
 * Tonlar mobilden BİR KADEME DOYGUNDUR (Tailwind 200 kademesi): mobilin
 * 100 kademesi büyük kartlarda yeterli, ızgaranın küçük hücrelerinde değil.
 *
 * Yazı her zeminde gövde metni rengidir, renkli değil: renkli yazının açık
 * zeminde kontrastı yetmiyordu (mobil de aynı kurala geçti). Gece zemini
 * ters renktir; koyu temada açık bir hücreye döner ve desende en çok göze
 * çarpan kutu olmaya devam eder.
 */
:root {
    --vardiya-gunduz: #bfdbfe;
    --vardiya-aksam: #fde68a;
    /* Tatil günü. Ad koddaki `izin` tipinden gelir ve İngilizce adlandırma
       işine kadar öyle kalır; anlamı "o gün çalışma yok"tur. */
    --vardiya-izin: #d4d4d8;
    /* Onaylı izin (İzinler modülü) ve tam gün resmî tatil çizelge satırının
       ÜSTÜNE geçer (bkz. VardiyaPlanlayici::oncelikliDurum). */
    --vardiya-izinli: #99f6e4;
    --vardiya-gece: var(--color-text);
    --vardiya-gece-yazi: var(--color-surface);
    --vardiya-yazi: var(--color-text);
}

[data-tema="koyu"] {
    --vardiya-gunduz: rgba(96, 165, 250, 0.32);
    --vardiya-aksam: rgba(251, 191, 36, 0.3);
    --vardiya-izin: rgba(161, 161, 170, 0.32);
    --vardiya-izinli: rgba(45, 212, 191, 0.28);
}

.rotasyon-kutu.gunduz {
    background: var(--vardiya-gunduz);
    color: var(--vardiya-yazi);
}

.rotasyon-kutu.aksam {
    background: var(--vardiya-aksam);
    color: var(--vardiya-yazi);
}

/* Gece vardiyası desende en dikkat çekmesi gereken kutudur: ardışık
   gece sayısı dinlenme kurallarının ilk ihlal edildiği yerdir. */
.rotasyon-kutu.gece {
    background: var(--vardiya-gece);
    color: var(--vardiya-gece-yazi);
    border-color: var(--vardiya-gece);
}

/* Tatil günü bir KARARDIR, boş kutudan ayrılır: kendi zemini vardır.
   Kesikli kenar yalnızca henüz tanımlanmamış (boş) kutuda kalır. */
.rotasyon-kutu.izin {
    background: var(--vardiya-izin);
    color: var(--vardiya-yazi);
}

.rotasyon-kutu.bos {
    background: var(--color-bg);
    color: var(--color-muted);
    border-style: dashed;
}

.rotasyon-uyarilar {
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
    margin-top: 0.7rem;
}

/* Uyarılar kaydı engellemez; hangi kuralın bağlayıcı olduğu şirkete göre
   değişir. Bu yüzden hata değil, dikkat çeken bir not gibi görünürler. */
.rotasyon-uyari {
    padding: 0.45rem 0.6rem;
    border: 1px solid var(--color-warning-border);
    background: var(--color-warning-soft);
    /* Metin gövde rengindedir: renkli zemin üstüne renkli metin okunmaz. */
    color: var(--color-text);
    border-radius: var(--radius);
    font-size: 0.82rem;
}

/* --- Vardiya çizelgesi (vardiya-cizelgesi.js) --- */

.cizelge-ay-gezgini {
    display: flex;
    align-items: center;
    gap: 0.7rem;
    margin-bottom: 0.8rem;
}

.cizelge-ay-etiketi {
    font-size: 1rem;
    text-transform: capitalize;
}

/*
 * Plan eksiği uyarısı TEK kutudur ve ortak Alert bileşenini kullanır
 * (.uyari-kutu). Eskiden üst üste iki tam genişlikte kutu vardı — kırmızı
 * "hiç planı olmayan" ve turuncu "planı bitmek üzere" — ve ikisi de aynı
 * şeyi söylüyordu. Burada yalnızca kutunun İÇİNDEKİ madde listesi
 * biçimlenir; zemin, kenarlık ve ikon bileşenden gelir.
 */
.cizelge-uyari-liste {
    display: flex;
    flex-direction: column;
    /* Ayırıcı çizgi yok: 4px boşluk satırları zaten ayırıyor ve çizgi,
       zaten kenarlıklı bir kutunun içinde ikinci bir ızgara kurardı. */
    gap: 4px;
    margin: 0.4rem 0 0;
    padding: 0;
    list-style: none;
}

/*
 * SATIRIN TAMAMI tıklanabilir.
 *
 * Eskiden sağ uçta ayrı bir "Planını aç" metin bağlantısı vardı ve geniş
 * ekranda metinle arasında uzun bir boşluk kalıyordu: göz her satırda
 * soldan sağa kat etmek zorundaydı. Satır zaten tek bir şeyi gösteriyor
 * ve tek bir sonraki adımı var; hedefi satırın kendisi yapmak hem yolu
 * kısaltır hem dokunma hedefini büyütür.
 */
.cizelge-uyari-satir {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    width: 100%;
    padding: 0.3rem 0.4rem;
    border: 0;
    border-radius: 8px;
    background: transparent;
    color: inherit;
    font: inherit;
    font-size: 0.85rem;
    text-align: left;
    cursor: pointer;
}

/*
 * Hover ve odakta zemin, kutunun *-soft zemininin bir tık üstüne çıkar.
 * Sabit bir renk verilemez: aynı satır danger ve warning kutularının
 * içinde yaşıyor ve ikisinin zemini farklı. `currentColor` ile karıştırmak
 * da olmaz — metin rengi her iki kutuda da gövde rengidir. Bu yüzden
 * kutunun kendi renginden pay alınır (aşağıda, ton başına).
 */
.cizelge-uyari-satir:hover,
.cizelge-uyari-satir:focus-visible {
    background: rgba(15, 23, 42, 0.06);
}

/* Odak halkası GÖRÜNÜR: satır klavyeyle gezilebilir bir hedef ve yalnızca
   zemin değişimi, yüksek kontrast ihtiyacı olan kullanıcı için yeterli
   bir işaret değil. */
.cizelge-uyari-satir:focus-visible {
    outline: 2px solid var(--color-primary);
    outline-offset: -2px;
}

/* Koyu temada karartma görünmez; aydınlatmaya çevrilir. Tema anahtarı
   projenin geri kalanıyla aynı: [data-tema="koyu"] (bkz. tema.js). */
[data-tema="koyu"] .cizelge-uyari-satir:hover,
[data-tema="koyu"] .cizelge-uyari-satir:focus-visible {
    background: rgba(255, 255, 255, 0.07);
}

/*
 * Nokta SATIRIN kendi tonunu taşır, kutunun tonunu değil.
 *
 * Karışık bir listede asıl mesele budur: kutu kırmızıyken "3 gün kaldı"
 * satırı da acil görünüyordu. Renk tek başına anlam taşımaz — durum metni
 * farkı zaten söylüyor — bu yüzden nokta ekran okuyucudan gizlenir
 * (aria-hidden, bkz. vardiya-cizelgesi.js).
 */
.cizelge-uyari-nokta {
    flex-shrink: 0;
    width: 8px;
    height: 8px;
    border-radius: 50%;
}

.cizelge-uyari-nokta.bad {
    background: var(--color-danger);
}

.cizelge-uyari-nokta.warn {
    background: var(--color-warning);
}

/* Metin sarar, chevron sağda kalır: 390px'te "feride egilmez · hiç planı
   yok" tek satıra sığmaz ve taşma yerine sarma istenir. */
.cizelge-uyari-metin {
    flex: 1;
    min-width: 0;
}

.cizelge-uyari-satir > .ikon {
    flex-shrink: 0;
    color: var(--color-muted);
}

/* Kesilen listenin devamı. Satırların hizasında durur ki listenin parçası
   olduğu görünsün. */
.cizelge-uyari-devami {
    margin: 0.35rem 0 0 0.4rem;
    font-size: 0.85rem;
}

/*
 * 7 sütunlu takvim ızgarası: haftalar alt alta.
 *
 * Kişi × gün matrisi yerine tek kişinin ayını göstermenin sebebi, bir
 * vardiya planına bakarken sorulan sorunun "bu hafta nasıl geçiyor?"
 * olmasıdır. Haftalar alt alta dizildiğinde hafta sonu sütunları hep aynı
 * yere düşer ve plandaki boşluk gözle görünür; 31 günü yan yana koyan bir
 * matris dar ekranda okunamıyordu.
 */
.takvim {
    border: 1px solid var(--color-border);
    border-radius: 10px;
    overflow: hidden;
}

.takvim-basliklar,
.takvim-govde {
    display: grid;
    grid-template-columns: repeat(7, minmax(0, 1fr));
}

.takvim-baslik {
    padding: 0.45rem 0.3rem;
    text-align: center;
    font-size: 0.78rem;
    font-weight: 600;
    color: var(--color-muted);
    background: var(--color-bg);
    border-bottom: 1px solid var(--color-border);
}

.takvim-hucre {
    position: relative;
    min-height: 74px;
    padding: 0.35rem 0.4rem;
    border-right: 1px solid var(--color-border);
    border-bottom: 1px solid var(--color-border);
    cursor: pointer;
    font-size: 0.75rem;
    line-height: 1.3;
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
}

/* Ayın dışına düşen yer tutucular tıklanamaz: o günler başka ayın
   planıdır ve buradan düzenlenmesi kafa karıştırırdı. */
/*
 * Seçili hücre. Vurgu, vardiya rengini EZMEZ (iç gölge kullanılır, zemin
 * değil): seçiliyken de o günün gündüz mü gece mi olduğu görünmeli, yoksa
 * yönetici neyi seçtiğini göremezdi.
 */
.takvim-hucre.secili {
    box-shadow: inset 0 0 0 2px var(--color-primary);
}

.takvim-secim-cubugu {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    margin-top: 0.6rem;
    padding: 0.55rem 0.75rem;
    border: 1px solid var(--color-border);
    border-radius: 8px;
    background: color-mix(in srgb, var(--color-primary) 8%, var(--color-surface));
}

.takvim-secim-cubugu[hidden] {
    display: none;
}

.takvim-secim-sayac {
    flex: 1;
    font-size: 0.85rem;
    font-weight: 600;
    color: var(--color-text);
}

.takvim-hucre.disari {
    background: var(--color-bg);
    cursor: default;
    pointer-events: none;
}

.takvim-hucre:not(.disari):hover {
    outline: 2px solid var(--color-primary);
    outline-offset: -2px;
}

.takvim-gun-no {
    font-weight: 700;
    font-size: 0.8rem;
    opacity: 0.8;
}

.takvim-saat {
    font-variant-numeric: tabular-nums;
    font-weight: 600;
}

.takvim-etiket {
    font-weight: 600;
}

/* Planlanmamış gün, boş bir hücreden ayırt edilebilmeli: tıklanabilir
   olduğunu belli eden soluk bir artı gösterilir. */
.takvim-etiket.bos {
    opacity: 0.35;
    font-size: 1rem;
}

.takvim-hucre.hafta-sonu,
.takvim-baslik.hafta-sonu {
    background: var(--color-bg);
}

/* Hücre renkleri rotasyon desen önizlemesiyle aynı değişkenlerden okur
   (bkz. --vardiya-*): aynı vardiya iki ekranda aynı renkte görünmelidir. */
.takvim-hucre.gunduz,
.cizelge-hucre-ornek.gunduz {
    background: var(--vardiya-gunduz);
    color: var(--vardiya-yazi);
}

.takvim-hucre.aksam,
.cizelge-hucre-ornek.aksam {
    background: var(--vardiya-aksam);
    color: var(--vardiya-yazi);
}

.takvim-hucre.gece,
.cizelge-hucre-ornek.gece {
    background: var(--vardiya-gece);
    color: var(--vardiya-gece-yazi);
}

/* Tatil hafta sonu zemininden AYRI bir renktir; eskiden ikisi de
   --color-bg idi ve cumartesiye düşen tatil görünmüyordu. */
.takvim-hucre.izin,
.cizelge-hucre-ornek.izin {
    background: var(--vardiya-izin);
    color: var(--vardiya-yazi);
}

/* Çizelge satırının üstüne geçen günler. Resmî tatil tatil ile aynı gridir
   (o gün de çalışma yoktur); adı hücrede ve ipucunda yazılıdır. */
.takvim-hucre.izinli,
.cizelge-hucre-ornek.izinli {
    background: var(--vardiya-izinli);
    color: var(--vardiya-yazi);
}

.takvim-hucre.resmi-tatil {
    background: var(--vardiya-izin);
    color: var(--vardiya-yazi);
}

.takvim-hucre.bos:not(.disari),
.cizelge-hucre-ornek.bos {
    background: repeating-linear-gradient(
        45deg,
        transparent,
        transparent 5px,
        var(--color-border) 5px,
        var(--color-border) 6px
    );
}

/*
 * Bağlam satırı: hangi düzenin planına bakıldığı + ekranın tek eylemi.
 *
 * Sekmelerin hemen altında, sayfa başlığı hizasında durur. Kontroller üç
 * role ayrılıp iki bloğa dağıtıldı: bağlam ve eylem burada, görünüm ve
 * dönem takvimin üstündeki araç şeridinde. Eskiden yedisi tek satırdaydı
 * ve hangisinin görünüm değiştirdiği, hangisinin kayıt oluşturduğu
 * anlaşılmıyordu.
 */
.cizelge-baglam {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 1rem;
    margin-bottom: 0.9rem;
}

.cizelge-baglam-metin {
    min-width: 0;
}

.cizelge-baglam-ozet {
    margin: 0.2rem 0 0;
    color: var(--color-muted);
    font-size: 0.813rem;
}

.cizelge-duzen-adi {
    margin: 0;
    font-size: 1.125rem;
    font-weight: 600;
    line-height: 1.3;
}

/*
 * Düzen seçici: başlığın KENDİSİ menü düğmesidir.
 *
 * Tek düzenden çok düzene geçildiğinde hiçbir kontrol yer değiştirmesin
 * diye böyle: başlık zaten orada duruyor, eklenen tek şey yanındaki ok.
 * Eskiden seçici satırın solunda ayrı bir <select>'ti ve belirdiği anda
 * yanındaki bütün düğmeleri sağa itiyordu.
 */
.cizelge-duzen-kutu {
    position: relative;
}

.cizelge-duzen-dugme {
    display: flex;
    align-items: center;
    gap: 0.35rem;
    padding: 0;
    border: 0;
    background: transparent;
    color: inherit;
    cursor: pointer;
    text-align: left;
}

.cizelge-duzen-dugme:hover .cizelge-duzen-adi {
    color: var(--color-primary);
}

.cizelge-duzen-dugme .ikon {
    color: var(--color-muted);
    flex-shrink: 0;
}

.cizelge-duzen-menu {
    position: absolute;
    top: calc(100% + 0.35rem);
    left: 0;
    z-index: 30;
    min-width: 260px;
    max-height: 22rem;
    overflow-y: auto;
    padding: 0.3rem;
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    background: var(--color-surface);
    /* Dönem menüsüyle aynı gölge: iki menü aynı katmanda duruyor,
       farklı derinlikte görünmeleri için bir sebep yok. */
    box-shadow: 0 8px 24px rgba(15, 23, 42, 0.14);
}

.cizelge-duzen-arama {
    width: 100%;
    margin-bottom: 0.3rem;
}

.cizelge-duzen-satir {
    display: flex;
    flex-direction: column;
    gap: 0.1rem;
    width: 100%;
    padding: 0.45rem 0.6rem;
    border: 0;
    border-radius: 6px;
    background: transparent;
    color: inherit;
    cursor: pointer;
    text-align: left;
}

.cizelge-duzen-satir:hover {
    background: var(--color-bg);
}

.cizelge-duzen-satir.aktif {
    background: var(--color-primary-soft);
}

.cizelge-duzen-satir-ad {
    font-weight: 500;
}

/* Kişi sayısı seçim anında gerekir: "hangi düzeni seçeceğim" sorusunun
   cevabı çoğu zaman "kalabalık olan"dır. */
.cizelge-duzen-satir-sayi {
    color: var(--color-muted);
    font-size: 0.78rem;
}

/*
 * Araç şeridi: dönem solda, görünüm ve o görünüme ait tek parametre sağda.
 *
 * Ay adımlayıcı burada durur çünkü ay düzenin değil TAKVİMİN özelliğidir.
 */
.cizelge-arac-serit {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 0.8rem;
    margin-bottom: 0.8rem;
}

.cizelge-gorunum-kutu {
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.cizelge-gorunum-etiketi {
    color: var(--color-muted);
    font-size: 0.813rem;
}

/*
 * Kişi seçici şeridin EN SAĞINDA: sağında hiçbir kontrol olmadığı için
 * görünüp kaybolması hiçbir şeyi kaydırmaz. Eskiden segmentin solunda
 * beliriyordu ve "Tek kişi"ye her geçişte düğmeleri sağa itiyordu.
 */
.cizelge-gorunum-kutu .combo {
    min-width: 200px;
}

/*
 * Şablon şeridi: açıklama solda, "uygula" düğmesi sağda, aynı kutuda.
 *
 * Düğmenin metinle aynı yerde durması bilinçli; ayrı durduğunda açıklama
 * ona "aşağıdaki düğme" diye yön tarif etmek zorunda kalıyordu ve tarif
 * yanlıştı.
 */
.cizelge-sablon-serit {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 0.8rem;
    margin-bottom: 0.8rem;
}

.cizelge-sablon-metin p {
    margin: 0.25rem 0 0;
    color: var(--color-muted);
}

/*
 * Özet ızgarası: seçili düzendeki HERKESİN ayı tek bakışta.
 *
 * Tek kişi takvimi "bu kişinin ayı nasıl?" sorusunu cevaplar; özet ise
 * "bu hafta kim nerede?" sorusunu. İkisi farklı sorulardır, bu yüzden iki
 * görünüm bir arada sunulur.
 *
 * Gün sütunları dar tutulur (28px): bir ay 31 sütun demek ve amaç saat
 * okumak değil, deseni ve boşluğu görmek.
 */
.ozet-kaydirma {
    overflow-x: auto;
    border: 1px solid var(--color-border);
    border-radius: 10px;
}

.ozet-tablo {
    border-collapse: separate;
    border-spacing: 0;
    width: max-content;
    min-width: 100%;
}

.ozet-tablo th,
.ozet-tablo td {
    border-bottom: 1px solid var(--color-border);
    border-right: 1px solid var(--color-border);
}

/* Ad sütunu kaydırırken sabit kalır; aksi hâlde sağa kaydırınca kimin
   satırına bakıldığı kaybolur. */
.ozet-ad-sutun {
    position: sticky;
    left: 0;
    z-index: 2;
    background: var(--color-surface);
    min-width: 170px;
    max-width: 170px;
    padding: 0.4rem 0.6rem;
    text-align: left;
    font-size: 0.84rem;
    font-weight: 600;
    cursor: pointer;
}

.ozet-ad-sutun:hover {
    background: var(--color-primary-soft);
    color: var(--color-primary-dark);
}

/*
 * İki satırlı gün başlığı: üstte ayın günü, altta hafta günü.
 *
 * Sütun 30px'e çıkarıldı — "Pzt" üç harfi 0.66rem'de bu genişliğe nefes
 * payıyla sığar. Bir ay 31 sütun demek ve ızgara zaten yatay kaydırmalı,
 * bu yüzden genişlik sorun değil; okunabilirlik daha önemli.
 */
.ozet-gun-basligi {
    min-width: 30px;
    padding: 0.2rem 0.1rem;
    background: var(--color-bg);
    text-align: center;
    line-height: 1.15;
}

.ozet-gun-no {
    display: block;
    font-size: 0.72rem;
    font-weight: 600;
}

.ozet-gun-adi {
    display: block;
    font-size: 0.62rem;
    font-weight: 500;
    color: var(--color-muted);
}

.ozet-gun-basligi.hafta-sonu,
.ozet-hucre.hafta-sonu {
    background: var(--color-bg);
}

.ozet-hucre {
    width: 28px;
    height: 30px;
    padding: 0;
    cursor: pointer;
}

.ozet-hucre:hover {
    outline: 2px solid var(--color-primary);
    outline-offset: -2px;
}

/* Renkler takvim ve rotasyon önizlemesiyle aynı değişkenlerden okur. */
.ozet-hucre.gunduz { background: var(--vardiya-gunduz); }
.ozet-hucre.aksam  { background: var(--vardiya-aksam); }
.ozet-hucre.gece   { background: var(--vardiya-gece); }
.ozet-hucre.izin   { background: var(--vardiya-izin); }
.ozet-hucre.izinli { background: var(--vardiya-izinli); }
.ozet-hucre.resmi-tatil { background: var(--vardiya-izin); }

.ozet-hucre.bos {
    background: repeating-linear-gradient(
        45deg,
        transparent,
        transparent 4px,
        var(--color-border) 4px,
        var(--color-border) 5px
    );
}

/* Şablon kutusunda düzene kimse atanmamışken düğmenin yerini alan bilgi.
   Tıklandığında hiçbir şey yapmayacak bir düğme göstermektense, neyin
   eksik olduğunu söylemek. */
.cizelge-sablon-bos {
    font-size: 0.85rem;
}

/* Personel ata penceresinde, tek çizelge düzeni olan şirkette düzen
   alanının yerini alan salt okunur özet. Tek seçenekli açılır liste seçim
   sunmaz, yalnızca bir adım ekler. */
.cizelge-atama-ozet {
    margin-bottom: 0.7rem;
    font-size: 0.9rem;
}

.cizelge-gosterge {
    display: flex;
    flex-wrap: wrap;
    gap: 0.9rem;
    margin-top: 0.7rem;
    font-size: 0.78rem;
    color: var(--color-muted);
}

.cizelge-gosterge-oge {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
}

.cizelge-hucre-ornek {
    display: inline-block;
    width: 16px;
    height: 16px;
    border-radius: 4px;
    border: 1px solid var(--color-border);
}

/*
 * Dar ekran: iki şerit de alt alta yığılır.
 *
 * Yığılma sırası ekrandaki rol sırasını korur — önce bağlam (hangi
 * düzen), sonra eylem, sonra dönem, sonra görünüm. Düğme ve segment tam
 * genişliğe açılır: dar ekranda yan yana sıkışmış iki kontrol, ikisini de
 * dokunulamaz hâle getiriyordu.
 *
 * Ekip ızgarası burada ayrıca ele alınmaz: zaten yatay kaydırılıyor ve
 * personel sütunu `position: sticky` ile sabit (bkz. .ozet-ad-sutun).
 */
@media (max-width: 767px) {
    .cizelge-baglam {
        flex-direction: column;
        align-items: stretch;
        gap: 0.7rem;
    }

    .cizelge-baglam .btn {
        width: 100%;
        justify-content: center;
    }

    .cizelge-arac-serit {
        flex-direction: column;
        align-items: stretch;
    }

    .cizelge-gorunum-kutu {
        flex-wrap: wrap;
    }

    /* Segment tam genişlikte ve üç eşit parça: dar ekranda ikon+metin
       taşıyan üç düğme, içeriğe göre ölçüldüğünde eşit olmayan ve
       okunamayan genişliklere düşüyordu. */
    .cizelge-gorunum-kutu .segment {
        flex: 1 1 100%;
    }

    .cizelge-gorunum-kutu .segment .segment-dugme {
        flex: 1 1 0;
        justify-content: center;
    }

    .cizelge-gorunum-kutu .combo {
        flex: 1 1 100%;
        min-width: 0;
    }

    /* Menü, dar ekranda düğmenin soluna hizalı kalırsa sağdan taşabilir. */
    .cizelge-duzen-menu {
        min-width: 0;
        width: 100%;
    }
}

/* --- Belge yönetici (belge-yonetici.js) --- */

.belge-kutu {
    display: flex;
    flex-direction: column;
    gap: 0.7rem;
}

.belge-baslik {
    font-size: 0.9rem;
}

.belge-listesi {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
}

.belge-satir {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 0.6rem;
    padding: 0.5rem 0.7rem;
    border: 1px solid var(--color-border);
    border-radius: 8px;
}

.belge-bilgi {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
    min-width: 0;
}

/* Uzun dosya adları satırı taşırmasın; kesilen ad tam hâliyle title'da durur. */
/*
 * Dosya adı: solunda tür ikonu.
 *
 * İkon adın SOLUNDA durur çünkü uzun adlarda uzantı ("...rapor_2026.pdf")
 * kırpılan kısma düşüyor ve dosyanın ne olduğu okunamıyordu. İkon sabit
 * genişliktedir ve daralmaz (flex: none), yoksa dar sütunda adla birlikte
 * ezilirdi.
 */
.belge-ad {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    min-width: 0;
    font-weight: 600;
    font-size: 0.88rem;
}

.belge-ad svg {
    flex: none;
    color: var(--color-muted);
}

/* Ad kırpılır, ikon kalır — taşma balonu tam adı gösterir. */
.belge-ad > span {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.belge-yukle {
    padding-top: 0.6rem;
    border-top: 1px solid var(--color-border);
}

.perm-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
    gap: 0.35rem 1rem;
}

.perm-grid label {
    display: flex;
    align-items: flex-start;
    gap: 0.45rem;
    font-size: 0.85rem;
    padding: 0.2rem 0;
}

.perm-grid input {
    width: auto;
    margin-top: 0.2rem;
}

.perm-grid code {
    display: block;
    font-size: 0.72rem;
    color: var(--color-muted);
}

/*
 * Yetki penceresinde her yetkinin altında ne kapsadığını söyleyen bir
 * cümle ve, kilitliyse, hangi yetkiyle birlikte geldiği durur
 * (YETKI_REVIZYON.md Y4). Etiket, açıklama ve not alt alta dizilir.
 */
.perm-grid .yetki-metin {
    display: flex;
    flex-direction: column;
    gap: 0.1rem;
}

.perm-grid .yetki-aciklama,
.perm-grid .yetki-not {
    font-size: 0.75rem;
    color: var(--color-muted);
}

.perm-grid .yetki-not {
    font-style: italic;
}

/* ---------- Modal ---------- */

.modal-backdrop {
    position: fixed;
    inset: 0;
    background: rgba(15, 23, 42, 0.45);
    display: flex;
    align-items: flex-start;
    justify-content: center;
    padding: 3rem 1rem;
    overflow-y: auto;
    z-index: 50;
}

/*
 * Modal boyutu İÇERİĞE göre seçilir. Eskiden hepsi aynı genişlikteydi
 * ve tek cümlelik bir onay sorusu, yirmi alanlık bir formla aynı kutuyu
 * paylaşıyordu (bkz. analiz E1.1).
 */
.modal {
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: 14px;
    width: 100%;
    box-shadow: var(--golge-3);
}

/* sm — onay penceresi, tek alanlık form */
.modal-sm { max-width: 440px; }

/* md — altıya kadar alan (varsayılan) */
.modal-md { max-width: 560px; }

/* lg — on ikiye kadar alan, bölümlü form */
.modal-lg { max-width: 760px; }

/* Geriye uyumluluk: eski `genis` seçeneği lg'ye denktir. */
.modal.wide {
    max-width: 760px;
}

/*
 * Başlık artık iki öğe taşıyabiliyor (metin + çekmecenin kapat düğmesi),
 * bu yüzden flex. Pencerede ikinci öğe yok; flex tek öğeyi de aynı
 * hizada bırakır, dolayısıyla mevcut görünüm değişmez.
 */
.modal header {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    padding: 0.95rem 1.2rem;
    border-bottom: 1px solid var(--color-border);
    font-weight: 600;
}

.modal header > span {
    flex: 1;
    min-width: 0;
}

/* ---------------- Çekmece ---------------- */

/*
 * Sağdan açılan tam yükseklikte panel. Modalin bir sunum biçimidir;
 * davranışı (odak kapanı, Esc, backdrop) modalden gelir.
 *
 * Genişlik 640px ama `min(640px, 100vw)`: dar ekranda taşmak yerine
 * ekranı kaplar ve orada zaten tam ekran bir panel gibi davranır.
 */
.modal.cekmece {
    width: min(640px, 100vw);
    max-width: none;
    /*
     * Yükseklik backdrop'tan gelir (`align-items: stretch`), `100vh`
     * verilmez: mobil tarayıcılarda 100vh adres çubuğunu da sayar ve
     * panelin altı ekranın dışında kalırdı.
     */
    height: auto;
    margin-left: auto;
    border-radius: 0;
    border-right: 0;
    border-top: 0;
    border-bottom: 0;
    display: flex;
    flex-direction: column;
    animation: cekmece-gir 0.18s ease-out;
}

@keyframes cekmece-gir {
    from {
        transform: translateX(24px);
        opacity: 0.6;
    }
}

@media (prefers-reduced-motion: reduce) {
    .modal.cekmece {
        animation: none;
    }
}

/*
 * Backdrop, çekmece varken içeriği sağa yaslar.
 *
 * Sınıf JS'ten verilir, `:has(.cekmece)` ile DEĞİL: `:has()` bu depoda
 * başka hiçbir yerde kullanılmıyor ve desteklemeyen bir tarayıcıda
 * kural sessizce düşerdi — çekmece o zaman ekranın ortasında, yarım
 * yükseklikte bir kutu olarak açılırdı. Sınıf her yerde çalışır.
 */
.modal-backdrop.cekmece-arka {
    align-items: stretch;
    justify-content: flex-end;
    padding: 0;
    /*
     * Backdrop'ın kendi kaydırması KAPATILIR. Pencerede içerik uzayınca
     * backdrop kayar ve bu doğrudur; çekmecede ise kaydırma gövdeye
     * aittir. Açık kalırsa iki sonucu oluyordu (ölçüm): dikey kaydırma
     * çubuğu 5px taşma yaratıp çekmeceyi sağ kenardan ayırıyor, ve
     * çekmece `height: 100vh` yerine içeriği kadar uzayıp altbilgiyi
     * ekranın ortasında bırakıyordu.
     */
    overflow: hidden;
}

/* Çekmecede gövde kaydırılır, altbilgi dipte sabit kalır. */
.modal.cekmece > form {
    flex: 1;
    min-height: 0;
    display: flex;
    flex-direction: column;
}

.modal.cekmece .body {
    flex: 1;
    min-height: 0;
    overflow-y: auto;
    scrollbar-width: thin;
}

.cekmece-kapat {
    flex-shrink: 0;
}

.modal .body {
    padding: 1.2rem;
    display: flex;
    flex-direction: column;
    gap: 0.9rem;
    /*
     * Dikey flex'te varsayılan hizalama `stretch`tir ve gövdeye doğrudan
     * konan bir düğmeyi pencere genişliğinde bir bant hâline getiriyordu
     * (ölçüm: 720px). Bloklar (tablo, form ızgarası, uyarı kutusu) tam
     * genişlikte kalmalı ama düğme kendi içeriği kadar olmalı, bu yüzden
     * kural düğmelere özel yazılır — align-items'ı topluca değiştirmek
     * tabloları da içeriklerine daraltırdı.
     */
}

.modal .body > .btn {
    align-self: flex-start;
}

.modal form {
    display: flex;
    flex-direction: column;
}

.modal footer {
    padding: 0.85rem 1.2rem;
    border-top: 1px solid var(--color-border);
    display: flex;
    justify-content: flex-end;
    gap: 0.5rem;
}

.modal .form-error {
    margin: 0;
}

/* ---------- Platform paneli ---------- */

/*
 * Platform paneli MOR vurgu taşır. K2 kararı (panel genelinde tek vurgu
 * rengi) şirket paneli için geçerlidir; burada renk süs değil KİMLİK:
 * iki panel aynı kabuğu, aynı bileşenleri ve aynı maviyi kullandığı için
 * birbirinden ayırt edilemiyordu. Oysa buradaki işler tek bir kaydı
 * değil bütün bir müşteriyi etkiliyor (şirketi pasife almak, aboneliği
 * kapatmak).
 *
 * Yalnızca vurgu üçlüsü değişir; yüzey, kenarlık ve metin renkleri ortak
 * kalır. Böylece bileşenlerin hiçbiri yeniden tanımlanmaz.
 */
/*
 * Seçici `body.panel` ile DEĞİL yalnızca `[data-panel]` ile bağlanır:
 * giriş ekranının body sınıfı admin-auth-page'dir, panel değil. Kanca
 * sınıftan bağımsız olunca platform girişi ve platform paneli aynı vurgu
 * tanımını paylaşır ve ton değişirse tek yerde değişir.
 */
body[data-panel="platform"] {
    --color-primary: #7c3aed;
    --color-primary-dark: #6d28d9;
    --color-primary-soft: #f3eaff;
    /*
     * Vurgu METNİ de mora çekilmelidir; ilk yazımda unutulmuştu ve
     * platform panelinde seçili menü öğesinin ikonu mor, yazısı MAVİ
     * kalıyordu (ölçüm: ikon #7c3aed, metin #1d4ed8). Metin, vurgu
     * renginin kendisinden bir tık koyudur: menü zemini zaten vurgunun
     * %12'si ve aynı tonun üstünde aynı ton okunmaz.
     */
    --color-vurgu-metin: #6d28d9;
}

:root[data-tema="koyu"] body[data-panel="platform"] {
    --color-primary: #a78bfa;
    --color-primary-dark: #c4b5fd;
    --color-primary-soft: rgba(167, 139, 250, 0.16);
    /* Koyu temada vurgu metni AÇIK tondur (bkz. app.css'teki aynı gerekçe). */
    --color-vurgu-metin: #c4b5fd;
}

/*
 * Platform panelinde üst çubuk yok; tema düğmesi kenar çubuğundaki
 * kullanıcı bloğunda, çıkışın yanında durur. Ad ve rol .panel-user-kim
 * içinde sarılı ve o `flex: 1` taşıyor, bu yüzden burada ayrıca
 * `margin-left: auto` gerekmez.
 */
.panel-user-araclar {
    display: flex;
    align-items: center;
    gap: 0.25rem;
    flex-shrink: 0;
}

/*
 * İki satırlı hücreler: üstte ad, altta kod ya da tarih. Şirket kodu ve
 * paket kodu ayrı birer sütunken tablo gereksiz yere genişliyordu; kod
 * yalnızca ada bakarken gereken bir ayrıntı.
 */
.sirket-hucre,
.abonelik-hucre {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
}

.sirket-hucre small,
.abonelik-hucre small {
    color: var(--color-muted);
    font-size: 0.75rem;
}

/* Rozet, kendi içeriği kadar kalır; hücre genişliğine yayılmaz. */
.abonelik-hucre .badge {
    align-self: flex-start;
}

.paket-hucre {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    flex-wrap: wrap;
}

/* ---------- Form bölümleri ve adımlar ---------- */

/*
 * Bölüm, altı alanı geçen formlarda ilgili alanları bir başlık altında
 * toplar. Kendi kutusu YOKTUR: pencerenin içinde ikinci bir çerçeve,
 * çerçeve içinde çerçeve görünümü üretiyordu (aynı gerekçeyle 4.9'da
 * "Eksik yapılandırma" kartının dış sarmalayıcısı da kaldırılmıştı).
 * Ayrımı üstteki ince çizgi ve başlık kuruyor.
 */
.form-bolum + .form-bolum {
    margin-top: 1.25rem;
    padding-top: 1.25rem;
    border-top: 1px solid var(--color-border);
}

/*
 * Bölüm başlığı CÜMLE DÜZENİNDEDİR.
 *
 * Eskiden `text-transform: uppercase` ile "ÇALIŞMA SAATLERİ VE MOLALAR"
 * diye yazılıyordu. Büyük harf, Türkçede okunurluğu İngilizceden daha
 * çok düşürür (i/ı ve İ/I ayrımı büyük harfte kaybolur) ve panelin geri
 * kalanında hiçbir başlık büyük harfli değildir. Vurgu artık yalnızca
 * ağırlıkla verilir; boyut da 0.8rem'den 0.9rem'e çıkarıldı, çünkü
 * büyük harf kalkınca 0.8rem bir başlık gibi değil dipnot gibi duruyordu.
 */
.form-bolum-baslik {
    margin: 0 0 0.75rem;
    font-size: 0.9rem;
    font-weight: 600;
    color: var(--color-text-2);
}

.form-bolum-aciklama {
    margin: -0.5rem 0 0.75rem;
    font-size: 0.8rem;
    color: var(--color-muted);
}

/*
 * Adım şeridi. Adım ADLARINI yazar, "2 / 3" demez: kaç adım kaldığı
 * kullanıcıya ne dolduracağını söylemez ve formu yarıda bırakma kararı
 * çoğu zaman "sırada ne var" bilgisiyle verilir.
 */
.adim-seridi {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem 0.75rem;
    margin: 0 0 0.35rem;
    padding: 0;
    list-style: none;
    counter-reset: adim;
}

.adim-gosterge {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    font-size: 0.8rem;
    color: var(--color-muted);
    counter-increment: adim;
}

.adim-gosterge::before {
    content: counter(adim);
    display: grid;
    place-items: center;
    width: 1.35rem;
    height: 1.35rem;
    border: 1px solid var(--color-border);
    border-radius: 50%;
    font-size: 0.7rem;
    font-weight: 600;
    background: var(--color-surface-2);
}

.adim-gosterge.etkin {
    color: var(--color-text);
    font-weight: 600;
}

.adim-gosterge.etkin::before {
    background: var(--color-primary);
    border-color: var(--color-primary);
    color: #fff;
}

/*
 * Geçilen adım SOLUKLAŞMAZ, onay işareti alır: geri dönülebilir
 * olduğunu göstermesi gerekir. Soluk bir adım "burası kapandı" der.
 */
.adim-gosterge.gecildi {
    color: var(--color-text-2);
}

.adim-gosterge.gecildi::before {
    content: '✓';
    border-color: var(--color-success);
    color: var(--color-success);
    background: var(--color-surface);
}

/*
 * Uzun formda gövde kendi içinde kayar ve altbilgi yerinde kalır.
 * Ölçümde "Kaydet" düğmesi ekranın 396px altındaydı: kullanıcı formu
 * doldururken kaydedebileceğini göremiyordu. Sınır görünür alana
 * bağlanır (dvh, mobil tarayıcı çubuğu için); başlık ve altbilgi için
 * pay bırakılır.
 */
.modal .body {
    overflow-y: auto;
    max-height: calc(100dvh - 14rem);
}

/* ---------- Bildirim ---------- */

.toasts {
    position: fixed;
    right: 1rem;
    bottom: 1rem;
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    z-index: 60;
    /*
     * Sol sınır da verilir: yalnızca `right` varken uzun bir bildirim
     * sola doğru büyüyüp ekranın soluna YAPIŞIYORDU (390px'te ölçüm:
     * sol 0, genişlik 374). Panelin geri kalanı 16px'lik kenar boşluğu
     * taşırken bildirimin kenardan kenara oturması onu sayfanın bir
     * parçası değil, sistem bandı gibi gösteriyordu.
     *
     * Öğeler sağa yaslı kalır: geniş ekranda bildirim yine sağ alttadır,
     * sol sınır yalnızca dar ekranda devreye girer.
     */
    left: 1rem;
    align-items: flex-end;
}

/*
 * Toast: yüzey renginde, solda durum ikonu, sağda kapatma düğmesi.
 *
 * Eskiden koyu dolguluydu (yeşil/lacivert/kırmızı), ikonsuz ve
 * kapatılamazdı. Dolgu renk, metnin kendisini de renkli zemine
 * taşıdığı için panelin geri kalanıyla aynı dili konuşmuyordu.
 */
.toast {
    display: flex;
    align-items: flex-start;
    gap: 0.6rem;
    padding: 0.7rem 0.75rem 0.7rem 0.9rem;
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    font-size: 0.87rem;
    background: var(--color-surface);
    color: var(--color-text);
    box-shadow: var(--golge-3);
    max-width: 400px;
}

.toast > .ikon {
    margin-top: 1px;
    flex-shrink: 0;
}

.toast-metin {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
}

/*
 * Sunucu metnindeki satır sonu korunur. Birden çok bağımsız sebep taşıyan
 * mesajlar (örn. bordro kesinleştirme engeli: parametreler + T.C. Kimlik
 * No) sebepleri ayrı satırlara yazar. Tek paragrafa akınca sondaki sebep
 * gözden kaçıyordu. `pre-line` ardışık boşlukları yine birleştirir, yani
 * satır sonu taşımayan mesajların görünümü değişmez.
 */
.toast-metin > span {
    white-space: pre-line;
}

/* "Tekrar dene" gibi kurtarıcı eylem; hata toast'larında bulunur. */
.toast-eylem {
    align-self: flex-start;
    border: 0;
    background: transparent;
    padding: 0;
    color: var(--color-primary);
    font-weight: 500;
    cursor: pointer;
}

.toast-eylem:hover {
    text-decoration: underline;
}

.toast-kapat {
    flex-shrink: 0;
    display: grid;
    place-items: center;
    width: 24px;
    height: 24px;
    padding: 0;
    border: 0;
    border-radius: var(--radius-sm);
    background: transparent;
    color: var(--color-muted);
    cursor: pointer;
}

.toast-kapat:hover {
    background: var(--color-surface-2);
    color: var(--color-text);
}

/* Renk yalnızca ikonda; zemin her varyantta yüzey rengidir. */
.toast.bad > .ikon { color: var(--color-danger); }

.toast.ok > .ikon { color: var(--color-success); }
.toast.warn > .ikon { color: var(--color-warning); }
.toast.info > .ikon { color: var(--color-info); }

/* ---------- Yardımcılar ---------- */

.muted {
    color: var(--color-muted);
}

.small {
    font-size: 0.82rem;
}

/*
 * Rakam hizası. Adı tarihsel: eskiden gerçekten monospace bir yazı tipi
 * verirdi ve T.C. kimlik no, tarih, saat, koordinat, kullanıcı adı ile
 * log zaman damgaları panelin geri kalanından farklı bir yazı tipiyle
 * çizilirdi — "MOLA" başlığı bile diğer başlıklara benzemiyordu.
 *
 * Asıl istenen şey rakamların alt alta hizalanmasıydı; bunu
 * tabular-nums zaten sağlıyor ve yazı tipini değiştirmiyor. Sınıf adı
 * KORUNDU çünkü yirmiden fazla çağrı noktası var ve hepsinin amacı
 * buydu; yeni kodda tercih edilen ad .num'dur (bkz. app.css).
 */
.mono {
    font-variant-numeric: tabular-nums;
}

/*
 * Satır içi EYLEM düğmeleri: sağa hizalı, çünkü işlem sütunu tablonun
 * sağ ucundadır.
 */
.row-actions {
    display: flex;
    gap: 0.3rem;
    justify-content: flex-end;
    align-items: center;
}

/*
 * Satır içi ROZET listesi: sola hizalı.
 *
 * Bu içerikler bir süre .row-actions kullanıyordu ve sağa itiliyorlardı;
 * başlık solda kalınca sütun kaymış görünüyordu (bkz. analiz A6.5,
 * "Not" sütunu). Rozet bir eylem değil veridir ve sütunun diğer
 * verileriyle aynı kenardan başlar.
 */
.rozet-listesi {
    display: flex;
    flex-wrap: wrap;
    gap: 0.3rem;
    align-items: center;
}

/* ---------- Satır eylem menüsü ---------- */

/*
 * Kalabalık satırlarda eylemler bir "⋮" menüsüne toplanır (bkz.
 * Ui.satirMenusu). En sık kullanılan eylem satırda kalır, gerisi içeri
 * girer; böylece her satır aynı genişlikte olur ve düğmeler dikey olarak
 * hizalanır.
 */
.satir-menu-dugme {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    padding: 0;
    border: 1px solid var(--color-border);
    border-radius: 6px;
    background: var(--color-surface);
    color: var(--color-muted);
    font-size: 1rem;
    line-height: 1;
    cursor: pointer;
}

.satir-menu-dugme:hover,
.satir-menu-dugme[aria-expanded="true"] {
    background: var(--color-bg);
    color: var(--color-text);
    border-color: var(--color-border-strong);
}

/*
 * position: fixed — .table-wrap'in overflow'u tarafından kırpılmamak için.
 * Konumu açılırken JS hesaplar (düğmenin ekran koordinatı); bu yüzden
 * burada top/left verilmez.
 */
.satir-menu {
    position: fixed;
    z-index: 60;
    min-width: 180px;
    padding: 0.25rem;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: 8px;
    box-shadow: var(--golge-3);
}

.satir-menu[hidden] {
    display: none;
}

.satir-menu-oge {
    display: block;
    width: 100%;
    padding: 0.45rem 0.6rem;
    border: none;
    border-radius: 5px;
    background: transparent;
    color: var(--color-text);
    font: inherit;
    font-size: 0.85rem;
    text-align: left;
    cursor: pointer;
}

.satir-menu-oge:hover {
    background: var(--color-bg);
}

/* Yıkıcı eylem hem renkle hem de üstündeki ayraçla ayrılır: iki işaret
   birlikte, yanlışlıkla tıklanmasını zorlaştırır. */
.satir-menu-oge.yikici {
    color: var(--color-danger);
}

.satir-menu-oge.yikici:hover {
    background: var(--color-danger-soft);
}

.satir-menu-ayrac {
    height: 1px;
    margin: 0.25rem 0.3rem;
    background: var(--color-border);
}

.loading {
    padding: 2rem;
    text-align: center;
    color: var(--color-muted);
}

/*
 * Bilgi/uyarı kutusu.
 *
 * Sol kalın şerit KALDIRILDI ve kutu dört yandan çerçevelendi: şeritli
 * kutular sayfadaki kartlarla aynı hizada durmuyor, kesik köşeleri
 * yüzünden de yarım bir öğe gibi görünüyorlardı (bkz. analiz A7.4).
 *
 * Sınıf adı korundu; otuz sekiz çağrı noktası var ve hepsinin amacı
 * buydu. Yeni kodda tercih edilen bileşen Ui.uyari()'dir.
 */
.notice {
    display: flex;
    align-items: flex-start;
    gap: 0.6rem;
    border: 1px solid color-mix(in srgb, var(--color-info) 35%, transparent);
    background: var(--color-info-soft);
    color: var(--color-text);
    padding: 0.75rem 0.9rem;
    border-radius: var(--radius);
    font-size: 0.85rem;
}

.notice.warn {
    border-color: var(--color-warning-border);
    background: var(--color-warning-soft);
}

/*
 * Ayar ekranları (şirket ayarları gibi): birden çok bağımsız bölüm kartı,
 * her biri kendi başlık/açıklama/alan(lar)/kaydet düzeniyle. İleride yeni
 * bir ayar grubu eklendiğinde aynı .ayar-bolumu kalıbı tekrar kullanılır —
 * tek bir uzun form yerine büyüyebilen bir liste olsun diye.
 */
/*
 * İKİ SÜTUN: solda bölüm gezintisi, sağda kartlar.
 *
 * Gezinti bir SEKME ŞERİDİ DEĞİL, kaydırma kısayoludur — bölümlerin
 * hepsi aynı anda görünür durumda kalır (gerekçesi tanimlar.js →
 * ayarGezintisi).
 */
/*
 * GENİŞLİK SINIRI, ekranın tamamı DEĞİL.
 *
 * Sayfa 1160px'e kadar açılıyordu ve geniş bir ekranda kartlar kenardan
 * kenara uzanıyordu: mesai kuralları bölümündeki beş alan dört sütuna
 * dağılıyor, bir formdan çok bir tabloya benziyordu. Sayı girdilerinin
 * kendisi zaten dar (üç hane + birim); onları germek boşluğu alanların
 * arasına dağıtmaktan başka bir işe yaramıyor.
 *
 * 1040px: iki sütunluk ızgarayı rahat taşır, sağda gözle görülür bir
 * boşluk bırakır ama alanları sıkıştırmaz. Bir ara 920px denendi ve bu
 * kez fazla dar kaldı — kartlar ekranın solunda küçük bir şerit gibi
 * duruyordu. Sütun sayısı zaten ayrıca sabitlendiği için (aşağıya bkz.)
 * genişliğin tek işi, satırın göz taramasını zorlaştıracak kadar
 * uzamasını engellemek.
 */
.ayar-duzen {
    display: grid;
    grid-template-columns: 190px minmax(0, 1fr);
    gap: 1.75rem;
    align-items: start;
    max-width: 1040px;
}

/*
 * Gezinti kaydırırken ekranda kalır: üç bölümlük bir sayfada bile
 * kullanıcı aşağıdayken "hangi bölümdeyim" bilgisini kaybetmemeli ve
 * başka bir bölüme geçmek için başa dönmek zorunda olmamalı.
 */
.ayar-gezinti {
    position: sticky;
    top: 1rem;
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
}

.ayar-gezinti-oge {
    padding: 0.5rem 0.75rem;
    border: 0;
    /*
     * Sol şerit SEÇİLİ OLMAYANDA DA var, saydam: renk değişimi öğeyi
     * yerinden oynatmasın. Yalnızca seçilide çizilseydi her vurgu
     * değişiminde metin 3px kayardı.
     */
    border-left: 3px solid transparent;
    border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
    background: transparent;
    color: var(--color-text-2);
    font: inherit;
    font-size: 0.88rem;
    text-align: left;
    cursor: pointer;
}

.ayar-gezinti-oge:hover {
    background: var(--color-surface-2);
    color: var(--color-text);
}

.ayar-gezinti-oge.aktif {
    border-left-color: var(--color-primary);
    background: var(--color-surface);
    color: var(--color-primary);
    font-weight: 600;
}

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

.ayar-bolumu {
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: 8px;
}

/*
 * BAŞLIK ŞERİDİ gövdeden çizgiyle ayrılır.
 *
 * Eskiden başlık, açıklama ve alanlar tek bir kutunun içinde art arda
 * diziliydi; kart uzadıkça "bu alanlar neyin altında?" sorusu
 * kaydırırken cevapsız kalıyordu. Çizgi, kartın nerede başladığını
 * gövdeye bakarken de söyler.
 */
.ayar-bolumu-bas {
    padding: 1rem 1.25rem;
    border-bottom: 1px solid var(--color-border);
}

.ayar-bolumu-govde {
    padding: 1.15rem 1.25rem;
}

/*
 * Ayar kartında ızgara EN FAZLA İKİ SÜTUN.
 *
 * Genel .form-grid `auto-fit` kullanır ve sığdığı kadar sütun açar; bu,
 * bir modal formunda doğru (alan sayısı değişken, kutu dar). Ayar
 * kartında ise yanlış: beş alanlık bir bölüm üç sütuna dağılınca son
 * satırda tek alan asılı kalıyor ve altındaki açıklama cümleleri
 * birbirinden kopuk üç kolona bölünüyordu.
 *
 * İki sütun sabit: alan sayısı ne olursa olsun satırlar hizalı kalır ve
 * her alanın altındaki cümle okunabilir uzunlukta durur.
 */
.ayar-bolumu-govde .form-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 1rem 1.25rem;
}

@media (max-width: 640px) {
    .ayar-bolumu-govde .form-grid {
        grid-template-columns: minmax(0, 1fr);
    }
}

.ayar-bolumu h3 {
    margin: 0 0 0.25rem;
    font-size: 0.95rem;
}

.ayar-bolumu .ayar-aciklama {
    margin: 0;
    font-size: 0.82rem;
    color: var(--color-muted);
    line-height: 1.5;
}

.ayar-satirlari {
    display: flex;
    flex-direction: column;
    gap: 0.7rem;
}

/*
 * Dar ekranda gezinti gizlenir: üç bölümlük bir sayfada kaydırma zaten
 * kısa ve gezinti yatay bir şeride dönseydi ekranın üstünden kalıcı yer
 * alırdı. Kartlar tam genişliğe yayılır.
 */
@media (max-width: 900px) {
    .ayar-duzen {
        grid-template-columns: minmax(0, 1fr);
    }

    .ayar-gezinti {
        display: none;
    }
}

.ayar-satiri {
    display: flex;
    align-items: flex-start;
    gap: 0.65rem;
}

.ayar-satiri input[type="checkbox"] {
    margin-top: 0.2rem;
    width: auto;
    flex-shrink: 0;
}

.ayar-satiri .ayar-satiri-metin {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
}

.ayar-satiri label {
    font-size: 0.88rem;
    color: var(--color-text);
    cursor: pointer;
}

.ayar-satiri .hint {
    font-size: 0.78rem;
    color: var(--color-muted);
}

/*
 * İşlem kayıtlarının saklama süresi (Şirket ayarları).
 *
 * Diğer bölümler form alanı taşır; bu bölüm bir DURUM ve ona ait
 * eylemlerdir (bkz. tanimlar.js → saklamaBolumu): solda süre, sağda
 * düğmeler. Dar ekranda düğmeler alta iner.
 */
.saklama-satiri {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 1rem;
}

.saklama-deger {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
    min-width: 0;
}

.saklama-deger strong {
    font-size: 1.05rem;
}

.saklama-eylemler {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
}

/* Bekleyen kısaltma uyarısı süre satırının altında, ondan ayrık durur. */
.saklama-satiri + .uyari-kutu {
    margin-top: 1rem;
}

/* ---------------- Kısmi yenileme kabı ---------------- */

/*
 * Veriye bağlı bölüm (tablo + sayfalama). Filtre değişiminde yalnızca
 * burası tazelenir; filtre şeridi yerinde kalır, çünkü kullanıcı o anda
 * onunla etkileşiyordur.
 */
.ekran-veri {
    position: relative;
}

/*
 * Tazelenirken mevcut satırlar YERİNDE KALIR, yalnızca soluklaşır.
 * İskelete çevirmek ya da içeriği boşaltmak, aynı veriyi getiren bir
 * tazelemede bile tabloyu göz kırptırıyordu; solma "çalışıyor" bilgisini
 * verirken okunan satırı da ekranda tutar.
 *
 * `pointer-events: none`: yarı saydam bir tabloda satır menüsü açmak,
 * birazdan değişecek bir satıra tıklamak demektir.
 */
.ekran-veri[aria-busy="true"] {
    opacity: 0.6;
    pointer-events: none;
    transition: opacity 0.12s ease;
}

@media (prefers-reduced-motion: reduce) {
    .ekran-veri[aria-busy="true"] {
        transition: none;
    }
}

/* ---------------- Kaydet çubuğu ---------------- */

/*
 * Değişiklik varken sayfanın altında asılı duran tek kaydetme noktası.
 *
 * `position: sticky` ile kaydırmadan bağımsız görünür kalır: uzun bir
 * ayar sayfasında en alttaki kaydet düğmesine ulaşmak için sonuna kadar
 * kaydırmak gerekiyordu. `bottom` değeri sıfır değil — çubuğun sayfa
 * kenarına yapışması onu tarayıcı arayüzünün parçası gibi gösteriyordu.
 */
.kaydet-cubugu {
    position: sticky;
    bottom: 1rem;
    z-index: 20;
    display: flex;
    align-items: center;
    gap: 0.75rem;
    max-width: 960px;
    margin-top: 1rem;
    padding: 0.7rem 0.75rem 0.7rem 1.1rem;
    border-radius: 10px;
    background: var(--color-text);
    box-shadow: 0 10px 30px rgba(16, 24, 40, 0.25);
}

/*
 * Çubuğun zemini metin rengidir (koyu), bu yüzden üstündeki yazı
 * yüzey rengini alır — iki token da temayla birlikte döndüğü için
 * kontrast her iki temada da korunur.
 */
.kaydet-cubugu .kaydet-cubugu-metin {
    flex: 1;
    color: var(--color-surface);
    font-size: 0.85rem;
    font-weight: 500;
}

/* Vazgeç: koyu zeminde çerçevesiz, yalnızca hover'da belirir. */
.kaydet-cubugu .btn:not(.primary) {
    border-color: transparent;
    background: transparent;
    color: var(--color-surface);
}

.kaydet-cubugu .btn:not(.primary):hover {
    background: rgba(255, 255, 255, 0.14);
}

[data-tema="koyu"] .kaydet-cubugu .btn:not(.primary):hover {
    background: rgba(0, 0, 0, 0.12);
}

@media (max-width: 640px) {
    .kaydet-cubugu {
        flex-wrap: wrap;
    }

    .kaydet-cubugu .kaydet-cubugu-metin {
        flex-basis: 100%;
    }
}

/*
 * Eşik 860px değil 1279px'tir: ARADA İKON MODU YOKTUR.
 *
 * Eskiden 861–1279px arası menüyü 64px'lik bir ikon sütununa daraltıyordu.
 * O mod kaldırıldı — etiketsiz ikonlar tek başına okunmuyordu ve satırların
 * bir kısmı (grupsuz ve tek öğeli listeler) hizadan düşüp büsbütün
 * görünmez oluyordu. Menünün iki hâli vardır: tam genişlikte sürekli
 * görünür sütun (1280px ve üstü) ya da hamburgerle açılan çekmece (altı).
 * İkisinin arasındaki üçüncü hâl, ikisinin de sağladığı okunaklılığı
 * sağlamıyordu.
 */
@media (max-width: 1279px) {
    /*
     * Dar ekranda sidebar sürekli görünür bir sütun olmaktan çıkıp
     * off-canvas bir panele dönüşür: varsayılan olarak ekran dışında durur,
     * hamburger düğmesiyle üstüne kayarak açılır. Genişlik/pozisyon
     * masaüstündeki sticky/kalıcı davranışın üzerine yazılır.
     */
    .panel-sidebar {
        position: fixed;
        top: 0;
        left: 0;
        width: min(80vw, 300px);
        height: 100vh;
        z-index: 40;
        transform: translateX(-100%);
        transition: transform 0.2s ease;
        box-shadow: 2px 0 12px rgba(0, 0, 0, 0.15);
    }

    .panel-sidebar.acik {
        transform: translateX(0);
    }

    .panel-sidebar-perde {
        display: block;
        position: fixed;
        inset: 0;
        background: rgba(15, 23, 42, 0.45);
        z-index: 30;
        opacity: 0;
        pointer-events: none;
        transition: opacity 0.2s ease;
    }

    /* Perdenin görünürlüğü JS'den .gorunur sınıfıyla yönetilir (bkz.
       mobilMenuKur() router.js'de) — sidebar'dan DOM sırasında önce
       geldiği için kardeş seçici (~) burada işe yaramaz. */
    .panel-sidebar-perde.gorunur {
        opacity: 1;
        pointer-events: auto;
    }

    /* Menü düğmesi yalnızca çekmece modunda görünür. */
    .panel-menu-dugme {
        display: inline-flex;
    }

    .panel-icerik {
        padding: 1.1rem 1rem 3rem;
    }

    .panel-ust-cubuk {
        padding: 0 1rem;
    }

    /*
     * Dar ekranda kırıntı yolunun üst parçaları düşer, yalnızca bulunulan
     * ekranın adı kalır: üç parça 360px'lik bir çubukta zaten sığmıyor ve
     * asıl bilgi olan son parçayı kısaltıyordu.
     */
    .panel-kirinti .kirinti-ust,
    .panel-kirinti .kirinti-ayrac {
        display: none;
    }

    /*
     * Başlık eylemleri alt alta geçer ve TAM GENİŞLİK olur.
     *
     * Eskiden yan yana kalıp ekrandan taşıyorlardı: "Elle mesai gir"
     * düğmesinin yarısı görünmüyordu. Dar ekranda parmakla basılacak bir
     * hedefin kenara sıkışmaması gerekir.
     */
    .panel-head {
        flex-direction: column;
        align-items: stretch;
        gap: 0.75rem;
    }

    /*
     * Açıklama dar ekranda iki satıra kadar açılır. Tek satır kuralı
     * geniş ekran içindir; 390px'de neredeyse her açıklama kesilir ve
     * geriye anlamsız bir baş parça kalırdı.
     */
    .panel-head p {
        white-space: normal;
        display: -webkit-box;
        -webkit-line-clamp: 2;
        -webkit-box-orient: vertical;
    }

    #panel-araclar {
        justify-content: stretch;
    }

    #panel-araclar .btn {
        flex: 1;
        min-width: 0;
    }
}

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

    .panel-sidebar-perde {
        transition: none;
    }
}

/* ---------- Harita konum seçici ---------- */

.harita-arac {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem;
    margin-bottom: 0.5rem;
}

.harita-arac input[type="search"] {
    flex: 1 1 220px;
    min-width: 180px;
}

.harita-arac .btn {
    flex: none;
}

.harita {
    height: 340px;
    border: 1px solid var(--color-border);
    border-radius: 8px;
    overflow: hidden;
    background: var(--color-bg);
}

/* Leaflet, kapsayıcısına z-index verdiği için modal içinde üste çıkabiliyor. */
.harita .leaflet-pane,
.harita .leaflet-top,
.harita .leaflet-bottom {
    z-index: 1;
}

.harita-alt {
    display: flex;
    flex-wrap: wrap;
    gap: 0.3rem 0.9rem;
    align-items: baseline;
    margin-top: 0.45rem;
    min-height: 1.2rem;
}

.harita-alt .mono {
    color: var(--color-text);
}

.harita-yukleme {
    height: 3px;
    background: var(--color-border);
    border-radius: 2px;
    overflow: hidden;
    margin-bottom: 0.4rem;
}

.harita-yukleme-dolgu {
    height: 100%;
    width: 35%;
    background: var(--color-primary);
    border-radius: 2px;
    animation: harita-kayar 1.1s ease-in-out infinite;
}

@keyframes harita-kayar {
    0%   { transform: translateX(-100%); }
    100% { transform: translateX(320%); }
}

/*
 * Salt okunur haritadaki damga işaretleri (bkz. KonumSecici.gosterici).
 *
 * Leaflet işaret kutusunu sıfır boyutla, sol üst köşesi damga noktasına
 * oturacak biçimde yerleştirir; nokta ve etiket o köşeden taşarak çizilir.
 * Etiket girişte noktanın soluna, çıkışta sağına açılır: iki damga çoğu
 * gün birkaç metre arayla atılır ve aynı yöne açılan etiketler üst üste
 * binerdi.
 *
 * Renkler token'dır: harita karolarının üstünde okunması için zemin yüzey
 * rengi, kenar güçlü kenarlık rengidir; iki temada da kendiliğinden döner.
 * Giriş ile çıkış RENKLE ayrılmaz — ikisi de olağan birer damgadır,
 * ayrımı etiketin metni ve yönü taşır.
 */
.harita-damga-nokta {
    position: absolute;
    left: -6px;
    top: -6px;
    width: 12px;
    height: 12px;
    border-radius: 50%;
    background: var(--color-text);
    border: 2px solid var(--color-surface);
    box-shadow: 0 0 0 1px var(--color-text);
}

.harita-damga-etiket {
    position: absolute;
    top: 0;
    transform: translateY(-50%);
    white-space: nowrap;
    padding: 0.1rem 0.5rem;
    border-radius: 999px;
    font-size: 0.75rem;
    font-weight: 600;
    line-height: 1.4;
    background: var(--color-surface);
    color: var(--color-text);
    border: 1px solid var(--color-border-strong);
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.18);
}

.harita-damga.sol .harita-damga-etiket {
    right: 11px;
}

.harita-damga.sag .harita-damga-etiket {
    left: 11px;
}

/* Haritanın altındaki damga satırları: "Giriş 09:12 · şubeye 35 m". */
.harita-damga-listesi {
    display: grid;
    gap: 0.2rem;
    margin-top: 0.6rem;
}

.harita-damga-listesi strong {
    display: inline-block;
    min-width: 3.5rem;
}

/*
 * Tablodaki "Konum" hücresi: ikon + "35 m → 40 m", tıklanınca harita.
 *
 * Bağlantı görünümlü bir düğmedir; düğmenin sabit 36px yüksekliği ve
 * kendi yazı boyutu bırakılır, yoksa bu sütun yüzünden her satır
 * yükselir ve hücre metni komşu hücrelerden büyük görünürdü.
 */
.btn.link.konum-hucresi {
    height: auto;
    padding-top: 0;
    padding-bottom: 0;
    gap: 0.3rem;
    font-size: inherit;
    font-weight: inherit;
}

@media (prefers-reduced-motion: reduce) {
    .harita-yukleme-dolgu {
        animation: none;
        width: 100%;
        opacity: 0.6;
    }
}

/* Seçim alanının yanındaki "+ Yeni" kısayolu. Tanım listesi boşsa kullanıcının
   formu kapatıp başka ekrana gitmesini önler. */
.field.with-action {
    position: relative;
}

.field.with-action > .btn {
    position: absolute;
    top: 0;
    right: 0;
    padding: 2px 8px;
    font-size: 12px;
}

/* ---------- Sekme şeridi ---------- */

/*
 * Bir ekranın içindeki bölümler arası geçiş. Ayrı menü başlıkları yerine
 * sekme kullanmanın sebebi, aynı işin parçalarını aynı yerde tutmaktır:
 * çizelge tipinde bir çalışma düzeni tanımlayıp planını doldurmak tek bir
 * iştir, iki menü başlığı arasında gezinmeyi gerektirmemeli.
 */
.sekme-serit {
    display: flex;
    gap: 0.25rem;
    margin-bottom: 1rem;
    border-bottom: 1px solid var(--color-border);
}

.sekme {
    padding: 0.5rem 0.9rem;
    border: none;
    background: none;
    cursor: pointer;
    font: inherit;
    font-size: 0.88rem;
    font-weight: 500;
    color: var(--color-muted);
    border-bottom: 2px solid transparent;
    margin-bottom: -1px;
}

.sekme:hover {
    color: var(--color-text);
}

.sekme.aktif {
    color: var(--color-primary);
    border-bottom-color: var(--color-primary);
    font-weight: 600;
}

/* ---------- Rotasyon deseni (form içine gömülü) ---------- */

/*
 * Desen, düzenin bir ayarı değil kendisidir; bu yüzden ayrı bir pencere
 * yerine formun içinde, döngü uzunluğunun hemen altında durur. Çerçeve
 * onu formun geri kalanından görsel olarak ayırır.
 */
.rotasyon-desen {
    padding: 0.8rem;
    border: 1px solid var(--color-border);
    border-radius: 10px;
    background: var(--color-bg);
}

.rotasyon-desen-baslik {
    display: flex;
    flex-direction: column;
    gap: 0.2rem;
    margin-bottom: 0.7rem;
}

/* Mola pencereleri düzenleyicisi (Ui.molaListesi): satır başına iki saat
   seçici ve kaldırma düğmesi; altta ekleme düğmesi. Üç formda ortak. */
.mola-duzenleyici {
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
    width: 100%;
}

.mola-listesi {
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
}

.mola-satir {
    display: flex;
    align-items: center;
    gap: 0.4rem;
}

.mola-satir input[type="time"] {
    flex: 0 0 120px;
    width: auto;
}

.mola-satir .mola-ayrac {
    color: var(--color-muted, #888);
}

.mola-satir .mola-kaldir {
    padding: 0.1rem 0.5rem;
    line-height: 1.2;
    font-size: 1rem;
}

.mola-ekle {
    align-self: flex-start;
}

/* Rotasyon satırında mola listesi vardiya saatlerinin altında, tam genişlikte durur. */
.rotasyon-satir .mola-duzenleyici {
    flex-basis: 100%;
    padding-left: calc(64px + 0.6rem);
}

/* ---------- Bugünüm (çalışanın kendi ekranı) ---------- */

/*
 * Bu blok, panelin ilk "kendi verisi" ekranı için yazıldı. Yönetim
 * ekranları tablo odaklıdır; Bugünüm ise tek bir soruya cevap verir:
 * "şimdi ne yapmalıyım?". Bu yüzden düzen tabloya değil, tek bir büyük
 * eyleme göre kurulur.
 *
 * .hint burada genel hâline kavuşur: daha önce yalnızca .field ve
 * .ayar-satiri içinde tanımlıydı, dolayısıyla form dışında kullanılan
 * her ipucu metni sessizce gövde boyutunda çiziliyordu. Kural kapsayıcıdan
 * bağımsız hâle getirildi — ekrana özel bir kopya yazmak, aynı sorunu
 * bir sonraki ekranda tekrar üretirdi.
 */
.hint {
    font-size: 0.75rem;
    color: var(--color-muted);
}

.hint.warn {
    color: var(--color-warning);
}

/*
 * Üst blok: solda "şu an", sağda "bugünün planı".
 *
 * Sol kolon KALAN ALANIN TAMAMINI alır, sağ kolon sabit genişliktedir.
 *
 * Sağ kolonun büyümemesi bilinçlidir: plan kartının içeriği etiket-değer
 * çiftlerinden oluşur ve kolon genişledikçe "Vardiya" ile "20:00 – 08:00"
 * arasında göz taramasını zorlaştıran bir boşluk açılır. Solda ise canlı
 * saat ve üç sütunlu damga şeridi var; artan alan onlara gider ve
 * şeridin sütunları ferahlar.
 *
 * `1fr` yerine `minmax(0, 1fr)`: `1fr`in örtük alt sınırı `auto`dur, yani
 * kolon içeriğinden daha dar olamaz. Damga şeridindeki uzun bir değer
 * ("henüz yok") sol kolonu kendi genişliğine kilitler ve ızgara sağa
 * taşardı. Sıfır alt sınır, kolonun gerçekten esnemesini sağlar.
 *
 * Sağ kolon SABİT 360px'tir, yüzde DEĞİL.
 *
 * Önce `clamp(300px, 30%, 380px)` denendi ve ızgara bozuldu: yüzdeli bir
 * değer grid kolonunda kapsayıcının içerik kutusuna göre çözülür, ama
 * `gap` o hesaba dahil edilmez — iki kolon artı boşluk, kapsayıcıdan
 * taşar ve tarayıcı farkı kapatmak için kolonları kendi bildiği gibi
 * yeniden dağıtır. Sonuç, iki kartın arasında açılan büyük bir boşluktu.
 *
 * Sabit bir değerde böyle bir hesap yoktur: sağ kolon 360px alır, `gap`
 * 24px'i alır, kalan her şey sol kolona gider.
 *
 * Plan kartı yoksa (düzen atanmamış) ızgara tek kolona düşer ve sol kart
 * yanında boş bir sütun bırakmaz.
 */
.bugunum-ust {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 360px;
    gap: 1.5rem;
    align-items: start;
    margin-bottom: 1.1rem;
}

.bugunum-ust.tek-kolon {
    grid-template-columns: minmax(0, 1fr);
}

/*
 * Kartlar hücrelerini TAM doldurur.
 *
 * `min-width: 0` şart: ızgara öğesinin örtük en küçük genişliği `auto`dur
 * ve içerikten (damga şeridindeki uzun bir değer, taşmayan bir başlık)
 * hesaplanır. Sıfırlanmazsa kart hücresinden geniş kalır, ızgara sağa
 * taşar ve sol kolon esnemek yerine kendi içeriğine kilitlenir.
 */
.bugunum-ust > .card {
    min-width: 0;
    margin-bottom: 0;
}

/* ---------- Sol kart: şu an ---------- */

.bugunum-suan {
    display: flex;
    flex-direction: column;
    gap: 0.85rem;
}

/*
 * Tarih solda, lokasyon rozeti sağda. `space-between` yerine `auto`
 * sütunlu bir hizalama kullanılmıyor: tarih uzun bir metin ("16 Eylül
 * 2026, Çarşamba") ve dar ekranda rozetin altına sarması, rozeti
 * ortada bırakmaktan iyidir.
 */
.bugunum-suan-ust {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 0.75rem;
    flex-wrap: wrap;
}

.bugunum-tarih {
    font-size: 0.9rem;
    color: var(--color-muted);
}

/*
 * Lokasyon rozeti.
 *
 * Nötr renktedir: lokasyon bir durum değil bir olgudur ve renkli bir
 * rozet, damga atmayı etkileyen bir uyarı gibi okunurdu. Konum
 * zorunluluğu ihlali zaten damga anında sunucunun mesajıyla bildiriliyor.
 */
.bugunum-lokasyon {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    flex: none;
    padding: 0.3rem 0.6rem;
    border-radius: 999px;
    background: var(--color-neutral-soft);
    color: var(--color-muted);
    font-size: 0.78rem;
    font-weight: 600;
}

.bugunum-lokasyon .ikon {
    width: 14px;
    height: 14px;
}

/*
 * Duvar saati: ekranın en büyük rakamı.
 *
 * Saniye GÖSTERİLMEZ ve dakikada bir tazelenir; mesai dakika cinsinden
 * tutulduğu için saniyelik bir sayaç karşılığı olmayan bir hassasiyet
 * iddiası olurdu. tabular-nums, rakam değişirken satırın yatay olarak
 * zıplamasını önler.
 */
.bugunum-saat {
    font-size: 3.4rem;
    font-weight: 700;
    line-height: 1;
    letter-spacing: -0.02em;
    font-variant-numeric: tabular-nums;
}

/*
 * Durum satırı: renkli nokta + tek cümle.
 *
 * `.bugunum-durum-baslik` bunun yerini aldı. Eski başlık yalnızca giriş
 * yapılmamışken çiziliyordu ve diğer dört durumda ekranın en üstünde
 * durumu söyleyen hiçbir şey yoktu.
 *
 * Renk YALNIZCA noktadadır. Cümle gövde renginde kalır: durum bir uyarı
 * değil bir olgudur ve metni renklendirmek, ekranın en üst satırını bir
 * hata mesajı gibi gösterirdi.
 */
.bugunum-durum-satiri {
    display: flex;
    align-items: center;
    gap: 0.55rem;
}

.bugunum-durum-metin {
    font-size: 1.05rem;
    font-weight: 600;
}

/*
 * Nokta, çevresinde kendi renginin soluk bir halkasını taşır. Halka
 * olmadan 8px'lik bir daire, yanındaki 1.05rem'lik metnin yanında
 * kayboluyordu; box-shadow kullanılması düzeni etkilememesi içindir
 * (border ya da outline satır yüksekliğini oynatırdı).
 */
.bugunum-durum-nokta {
    width: 8px;
    height: 8px;
    flex: none;
    border-radius: 50%;
    background: var(--color-muted);
    box-shadow: 0 0 0 4px var(--color-neutral-soft);
}

.bugunum-durum-satiri.calisiyor .bugunum-durum-nokta {
    background: var(--color-success);
    box-shadow: 0 0 0 4px var(--color-success-soft);
}

.bugunum-durum-satiri.molada .bugunum-durum-nokta {
    background: var(--color-warning);
    box-shadow: 0 0 0 4px var(--color-warning-soft);
}

.bugunum-durum-satiri.fazla .bugunum-durum-nokta {
    background: var(--color-info);
    box-shadow: 0 0 0 4px var(--color-info-soft);
}

.bugunum-durum-satiri.bitti .bugunum-durum-nokta {
    background: var(--color-success);
    box-shadow: 0 0 0 4px var(--color-success-soft);
}

/*
 * Damga şeridi: Giriş / Mola / Çıkış.
 *
 * Üç EŞİT sütun ve üstünde bir ayırıcı çizgi. Sütunlar `flex` ile değil
 * `grid` ile dizilir: flex'te sütun genişliği içeriğe göre değişir ve
 * "09:00" ile "henüz yok" yan yana geldiğinde şerit gün içinde kayardı.
 * Eşit sütun, damgalar doldukça yerlerinin sabit kalmasını sağlar.
 */
.bugunum-damgalar {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 1rem;
    padding-top: 0.9rem;
    border-top: 1px solid var(--color-border);
}

.bugunum-damga {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    min-width: 0;
}

/*
 * Damga ikonu, DOLU olduğunda kendi rengini alır.
 *
 * Renk bir trafik ışığı değildir — çıkış "kötü", giriş "iyi" değil.
 * Taşıdığı bilgi şu: bu damga gerçekleşti mi? Boş damga nötr gri kalır,
 * dolan damga renklenir ve şerit soldan sağa dolan bir ilerleme gibi
 * okunur. Renk sınıfları (.t-ok, .t-warn, .t-info) panelin ortak
 * eşlemesinden gelir, burada yeniden tanımlanmaz.
 *
 * Varsayılan nötrdür ve `.t-*` yokken geçerlidir; bu yüzden `background`
 * ile `color` burada durur ama sınıf geldiğinde onun değerleri kazanır
 * (aynı özgüllük, sonra tanımlı).
 */
.bugunum-damga-ikon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: none;
    width: 30px;
    height: 30px;
    border-radius: 8px;
    background: var(--color-neutral-soft);
    color: var(--color-muted);
}

.bugunum-damga-ikon .ikon {
    width: 16px;
    height: 16px;
}

.bugunum-damga-govde {
    display: flex;
    flex-direction: column;
    min-width: 0;
}

.bugunum-damgalar .label {
    font-size: 0.72rem;
    color: var(--color-muted);
}

.bugunum-damgalar .value {
    font-size: 1rem;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
}

/* Açık mola: damga şeridinde de görünür olmalı, tek yer sağ kart olmasın. */
.bugunum-damgalar .value.vurgu {
    color: var(--color-warning);
}

/*
 * Damganın altındaki araç plakası.
 *
 * Saatten küçük ve soluk: şeridin asıl bilgisi damga SAATİDİR, plaka onu
 * niteleyen ikincil bir not. Aynı boyutta olsaydı iki değer birbiriyle
 * yarışır ve göz hangisine bakacağını bilemezdi.
 *
 * Satır yalnızca plaka varken basılır (bkz. damgaSeridi → plakaSatiri),
 * bu yüzden boş durumda yer kaplamaz ve şeridin yüksekliği araç kaydı
 * kapalı şirketlerde değişmez.
 */
.bugunum-damga-plaka {
    font-size: 0.72rem;
    color: var(--color-muted);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* ---------- Sağ kart: bugünün planı ---------- */

.bugunum-plan {
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
}

.bugunum-plan-baslik {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
}

.bugunum-plan-baslik h2 {
    margin: 0;
    font-size: 1.05rem;
}

/*
 * Etiket-değer satırı. Değer sağa yapışır ve tabular-nums taşır: saat
 * aralıkları ve süreler alt alta hizalanmalı, aksi hâlde "09:00 – 18:00"
 * ile "13:00 – 14:00" arasındaki rakam genişliği farkı sütunu titretir.
 */
.bugunum-plan-satir {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 1rem;
}

.bugunum-plan-satir .label {
    font-size: 0.85rem;
    color: var(--color-muted);
}

.bugunum-plan-satir .value {
    font-size: 0.95rem;
    font-weight: 600;
    text-align: right;
    font-variant-numeric: tabular-nums;
}

.bugunum-plan-satir .value.vurgu {
    color: var(--color-warning);
}

/* Değerin içindeki "/ 8 sa" kısmı: bölen, gerçekleşenden geri planda. */
.bugunum-plan-satir .value .muted {
    font-weight: 500;
    color: var(--color-muted);
}

/*
 * İlerleme satırı: etiket-değer + ince çubuk.
 *
 * Çubuk, plan satırlarından bir ayırıcıyla DEĞİL yalnızca boşlukla
 * ayrılır: bir çizgi daha eklemek, dört satırlık bir kartı beş çizgiyle
 * bölerdi.
 */
.bugunum-ilerleme {
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
    padding-top: 0.5rem;
    border-top: 1px solid var(--color-border);
}

.bugunum-cubuk {
    display: block;
    height: 6px;
    border-radius: 999px;
    background: var(--color-border);
    overflow: hidden;
}

.bugunum-cubuk i {
    display: block;
    height: 100%;
    background: var(--color-primary);
    transition: width 0.3s;
}

/*
 * Hak aşıldığında çubuk uyarı rengine döner ama %100'de DURUR: taşan bir
 * çubuk çizmek kalan hakkı okumayı zorlaştırırdı. Aşım, değerin
 * kendisinden okunur (kullanılan > hak).
 *
 * Renk `danger` değil `warning`: mola hakkını aşmak düzeltilmesi gereken
 * bir arıza değil, çalışma süresinden düşülen bir olgudur.
 */
.bugunum-cubuk i.asildi {
    background: var(--color-warning);
}

/*
 * Eylem düğmesi: ekranın tek birincil eylemi olduğu için alışılmış
 * .btn boyutundan belirgin biçimde büyüktür. Dokunmatik ekranda da
 * rahat basılmalı — çalışanların bir kısmı web paneline telefondan
 * girecek.
 */
/*
 * Eylem düğmeleri: çalışanın o an yapabileceği her şey, tek sırada.
 *
 * Serbest düzende iki düğme yan yana gelir ("Molaya çık", "İşten çıkış
 * yap"); diğer tiplerde tek düğme kalır. `flex-wrap`, dar bir sol
 * kolonda ikinci düğmenin alta inmesini sağlar — sığmadığında taşmak
 * yerine sarar.
 *
 * Genişlik İÇERİĞE göredir, tam genişlik değil: kartın tamamını kaplayan
 * bir düğme, altındaki damga şeridini ezip kartı tek bir eylemden ibaret
 * gösteriyordu. Telefonda tam genişliğe açılır (aşağıdaki media sorgusu).
 */
.bugunum-eylem-kutu {
    display: flex;
    flex-wrap: wrap;
    gap: 0.6rem;
}

/*
 * Düğmeler ÇERÇEVELİDİR, dolu değil.
 *
 * `.btn primary` kaldırıldı: serbest düzende iki düğme yan yana duruyor
 * ve ikisi de aynı ağırlıkta eylemler. Birini dolu mavi yapmak
 * aralarında olmayan bir öncelik kurar; ikisini birden dolu yapmak ise
 * kartın en dikkat çeken öğesini saatten alıp düğmelere verirdi.
 *
 * Alışılmış .btn'den daha yüksektir: dokunmatik ekranda rahat basılmalı,
 * çalışanların bir kısmı web paneline telefondan girecek.
 */
.bugunum-eylem {
    justify-content: center;
    gap: 0.5rem;
    padding: 0.75rem 1.2rem;
    font-size: 0.95rem;
    font-weight: 600;
}

.bugunum-eylem-yok {
    margin: 0;
}

/*
 * Gün kapandığında kutu bir açıklama metni ve bir düğme taşır.
 *
 * Dikey dizilir: metin ile düğme yan yana konsaydı metin düğmeyi dar bir
 * şeride sıkıştırır, dar pencerede de ikisi birbirine girerdi. Sıra da
 * anlamlıdır — önce durumun ne olduğu ("mesainiz kapandı"), sonra
 * yapılabilecek şey.
 */
.bugunum-kapandi {
    flex-direction: column;
    align-items: flex-start;
}

/*
 * Düzeltme düğmesi içeriği kadar geniştir, kartı kaplamaz.
 *
 * Diğer eylem düğmelerinden (giriş/çıkış/mola) ayrılır: onlar günün asıl
 * işidir, bu ise nadiren gereken bir düzeltme yoludur. Tam genişlik
 * vermek, kapanmış bir günde ekranın en dikkat çeken öğesini "bir
 * yanlışlık var" ihtimaline ayırmak olurdu. Telefonda yukarıdaki media
 * sorgusu yine tam genişliğe açar; orada dokunma hedefi önceliklidir.
 */
.bugunum-duzeltme {
    align-self: flex-start;
}

/* Alt sıradaki üç özet kartı: bu hafta, bu ay, kalan izin. */
.bugunum-ozet {
    margin-bottom: 1.25rem;
}

/*
 * İki kolon, SOL kolon okunabilir genişliğin altına düşmeden önce tek
 * kolona iner.
 *
 * Eşiği belirleyen şey sağ kart değil SOLDAKİDİR. Sağ kart 300px'e kadar
 * iniyor, ama o noktada kalan alan sol kolona yetmiyor: 1100px'lik bir
 * pencerede (kenar çubuğu ve boşluklar düşünce ~747px kapsayıcı) sola
 * 423px kalıyor, 1000px'te 323px'e, 950px'te 273px'e düşüyor — yani sol
 * kart sağdakinden dar oluyor ve içindeki üç sütunlu damga şeridi
 * sıkışıyor.
 *
 * 1100px eşiği, sol kolonun sağdakinden dar kalmaya başladığı noktadır.
 * Altında iki kart alt alta gelir ve ikisi de tam genişlik alır.
 */
@media (max-width: 1100px) {
    .bugunum-ust {
        grid-template-columns: minmax(0, 1fr);
    }
}

@media (max-width: 560px) {
    /*
     * Damga şeridi tek sütuna düşer.
     *
     * Telefonda üç sütun, her birine ~90px bırakıyor ve "henüz yok" gibi
     * bir değer ikonun altına sarıyordu. Alt alta üç satır, aynı bilgiyi
     * sarmadan verir.
     */
    .bugunum-damgalar {
        grid-template-columns: minmax(0, 1fr);
        gap: 0.75rem;
    }

    /* Saat telefonda da en büyük öğe kalır ama ekranı taşırmaz. */
    .bugunum-saat {
        font-size: 2.8rem;
    }

    /*
     * Düğmeler alt alta ve tam genişlik: dokunmatikte hedef büyüdükçe
     * iyi. Serbest düzende iki düğme var ve telefonda yan yana
     * konduklarında ikisi de metnini saracak kadar daralıyordu.
     *
     * `flex-direction: column` kullanılıyor, `display: block` değil:
     * kutunun `gap`i böylece korunur ve düğmeler arasına ayrıca margin
     * yazmak gerekmez.
     */
    .bugunum-eylem-kutu {
        flex-direction: column;
    }

    .bugunum-eylem {
        width: 100%;
    }
}

/* ---------- Bölüm başlığı ---------- */

/*
 * Bir ekranın içindeki mantıksal bölümleri ayırır: "Bugün", "Sizden
 * bekleniyor", "Mola", "Rotasyon deseni".
 *
 * Kural bugüne kadar EKSİKTİ: on ayrı yerde `.bolum-basligi` yazılmış ama
 * karşılığı hiç tanımlanmamıştı, dolayısıyla başlıklar tarayıcının
 * varsayılan h2 biçiminde (1.5em, geniş dış boşluk) çiziliyordu. Faz C2'de
 * dört yeni ekran aynı sınıfı kullandığı için ekrana özel bir yama yerine
 * kuralın kendisi yazıldı (bkz. CLAUDE.md: tabloya özel değil genel çözüm).
 *
 * `.bolum-uyari` bu sınıfın değiştiricisidir ve yukarıda tanımlıdır;
 * yalnızca yerleşim (flex) verdiği için buradaki tipografiyle çakışmaz.
 */
.bolum-basligi {
    margin: 1.4rem 0 0.7rem;
    font-size: 0.95rem;
    font-weight: 600;
}

/* Ekranın tepesindeki ilk başlık fazladan boşluk bırakmamalı. */
.bolum-basligi:first-child {
    margin-top: 0;
}

/* ---------- Özet listesi (etiket → değer) ---------- */

/*
 * Bir kaydın alanlarını "etiket: değer" çiftleri hâlinde gösteren tanım
 * listesi. İlk kullanan Vardiya Planım'daki çalışma düzeni kartıdır.
 *
 * `.ayar-satiri` ödünç alınmadı: o, onay kutulu AYAR listeleri içindir ve
 * açıklamayı etiketin altında, değeri de solda tutar. Buradaki ihtiyaç
 * farklı — etiket solda, değer sağda, açıklama etiketin altında — ve
 * yanlış bileşeni zorlamak ipucunun değerden önce görünmesine yol
 * açıyordu.
 *
 * `dl` seçildi çünkü içerik gerçekten bir tanım listesidir; ekran
 * okuyucu etiketle değeri eşleştirebilir.
 */
.ozet-liste {
    display: grid;
    grid-template-columns: minmax(9rem, auto) 1fr;
    gap: 0.55rem 1.2rem;
    margin: 0;
    align-items: baseline;
}

.ozet-liste dt {
    display: flex;
    flex-direction: column;
    gap: 0.1rem;
    font-size: 0.8rem;
    color: var(--color-muted);
}

.ozet-liste dd {
    margin: 0;
    font-weight: 600;
}

/* Dar ekranda iki sütun alt alta düşer; değer etiketin altında durur. */
@media (max-width: 560px) {
    .ozet-liste {
        grid-template-columns: 1fr;
        gap: 0.15rem;
    }

    .ozet-liste dd {
        margin-bottom: 0.5rem;
    }
}

/* ---------- Cari hareket tutarı ---------- */

/* ---------- Bordro net ödeme satırı ---------- */

/*
 * Bordro dökümünün cevapladığı asıl soru "elime ne geçti" ve o rakam
 * kalem listesinin içinde kaybolmamalı; bu yüzden kalemlerden ayrı, kendi
 * çerçevesinde ve büyük punto ile durur.
 */
.bordro-net {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 1rem;
    margin-top: 1rem;
    padding: 0.75rem 0.9rem;
    border: 1px solid var(--color-border);
    border-radius: 8px;
    background: var(--color-surface-2);
}

.bordro-net .label {
    font-size: 0.85rem;
    color: var(--color-muted);
}

.bordro-net .value {
    font-size: 1.15rem;
}

/* =========================================================
   Ortak bileşenler (Faz 3)
   ========================================================= */

/* ---------- Kişi hücresi ---------- */

/*
 * Tablo satırlarında kişi: avatar + ad. Avatarın rengi addan türer, bu
 * yüzden aynı kişi her ekranda aynı renkle görünür ve göz uzun bir
 * listede satırı adı okumadan bulabilir.
 */
.kisi {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    min-width: 0;
}

.kisi-metin {
    display: flex;
    flex-direction: column;
    min-width: 0;
    line-height: 1.25;
}

.kisi-ad {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.kisi-metin small {
    color: var(--color-muted);
    font-size: 0.75rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* ---------- Onay işareti ---------- */

/*
 * Evet/hayır sütunlarında "Evet" rozeti yerine onay işareti kullanılır:
 * rozet iki olgusal değeri bir uyarı ile bir duruma çeviriyordu. "Hayır"
 * için işaret YOKTUR — "—" ile geçilir; göz yalnızca işaretli satırları
 * tarar, bu da sütunu tek bakışta okunur kılar.
 */
.onay-isareti {
    display: inline-flex;
    color: var(--color-success);
}

/* ---------- Dönem gezgini ---------- */

/*
 * ‹ Eylül 2026 ›
 *
 * Ay/yıl seçimi panelde üç ayrı biçimde yapılıyordu; hepsi buna indi.
 * Etiket sabit genişliktedir: "Mayıs 2026" ile "Ağustos 2026" arasında
 * gidip gelirken okların yer değiştirmemesi gerekir, yoksa arka arkaya
 * iki kez tıklamak imleci kaçırır.
 */
.donem-gezgini {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
}

.donem-ok {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    padding: 0;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-sm);
    background: var(--color-surface);
    color: var(--color-text-2);
    cursor: pointer;
}

.donem-ok:hover {
    border-color: var(--color-text-2);
    color: var(--color-text);
}

.donem-etiket {
    min-width: 9rem;
    font-weight: 600;
    text-align: center;
}

/* ---------- Sayı bağlantısı ---------- */

/*
 * Tıklanabilir sayı (örn. departmandaki çalışan sayısı). Düğme DEĞİL:
 * eskiden `.btn small` ile çizilince her satırda bir eylem varmış gibi
 * duruyor ve rakamlar sütun boyunca hizasız kalıyordu. Sayı sayı gibi
 * yazılır; tıklanabilirliği yalnızca imleç ve üzerine gelince beliren
 * alt çizgi söyler.
 */
.sayi-baglanti {
    padding: 0;
    border: 0;
    background: none;
    color: var(--color-primary);
    cursor: pointer;
    font: inherit;
    font-variant-numeric: tabular-nums;
}

.sayi-baglanti:hover {
    text-decoration: underline;
}

/* ---------- Sütun görünürlüğü menüsü ---------- */

/*
 * Tablolar on bir sütuna çıkıp yatay taşıyordu ve işlem sütunu hiç
 * görünmüyordu. Çözüm sütunları silmek değil, varsayılan olarak az sütun
 * göstermek ve gerisini bu menüye almaktır.
 *
 * Menü kart çerçevesinin İÇİNDE ama kaydırma kutusunun DIŞINDA durur:
 * geniş bir tabloda sağa kaydırıldığında ekrandan çıkmamalı (sayfalamanın
 * dışarıda tutulmasıyla aynı gerekçe).
 */
/*
 * KENDİ ŞERİDİ YOKTUR: padding ve alt kenarlık artık onu saran
 * .tablo-serit'e aittir (bkz. ui.js → table). Eskiden menü tek başına bir
 * şeritti ve filtreler kartın DIŞINDA ayrı bir blok olduğu için ikisi
 * arasında boş bir bant kalıyordu. `position: relative` kalır, çünkü
 * açılan .sutun-menu-govde ona göre konumlanır.
 */
.sutun-menu {
    position: relative;
    display: flex;
}

.sutun-menu-dugme {
    gap: 0.375rem;
}

.sutun-menu-sayi {
    padding: 0 0.3rem;
    border-radius: 999px;
    background: var(--color-primary);
    color: #fff;
    font-size: 0.6875rem;
    font-style: normal;
}

/*
 * Sağ kenarı düğmeye hizalıdır (right: 0). Eskiden 0.75rem'di, çünkü
 * .sutun-menu'nün kendi yatay padding'ini telafi etmesi gerekiyordu; o
 * padding şeride taşındı ve telafi gereksizleşti.
 */
.sutun-menu-govde {
    position: absolute;
    top: calc(100% + 0.25rem);
    right: 0;
    z-index: 20;
    min-width: 13rem;
    max-height: 20rem;
    overflow-y: auto;
    padding: 0.375rem;
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    background: var(--color-surface);
    box-shadow: 0 8px 24px rgba(15, 23, 42, 0.14);
}

.sutun-menu-satir {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.375rem 0.5rem;
    border-radius: var(--radius-sm);
    cursor: pointer;
    /*
     * Metin hizası AÇIKÇA sola çekilir: menü, sağa hizalı bir başlık
     * hücresinin (th.actions) ve sağa yaslanmış bir şeridin içinde
     * duruyor ve miras alınan text-align etiketleri sağa itiyordu.
     */
    text-align: left;
}

.sutun-menu-satir:hover {
    background: var(--color-bg);
}

/*
 * Onay kutusu kendi boyutunda kalır.
 *
 * Paneldeki genel `input { width: 100% }` kuralı buna da uyguluyor ve
 * kutu 178px genişleyip satırın tamamını yiyordu: etiket 0 piksele
 * düşüyor, menüde yalnızca onay kutuları görünüyordu. Ölçmeden fark
 * edilmesi zor bir hata — kutunun kendisi doğru çiziliyor, yalnızca
 * tıklama alanı devasa oluyor.
 */
.sutun-menu-satir input[type="checkbox"] {
    flex: none;
    width: auto;
    margin: 0;
}

/*
 * Etiket daralmaz ve SARMAZ: varsayılan flex davranışı "T.C. Kimlik No"
 * gibi üç kelimelik bir başlığı alt alta üç satıra bölüyor, satır
 * yüksekliği 73px'e çıkıyordu. Sığmayan başlık "…" ile kesilir; tam adı
 * ipucunda durur.
 */
.sutun-menu-satir span {
    flex: 1 1 auto;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.sutun-menu-sifirla {
    width: 100%;
    margin-top: 0.25rem;
    padding: 0.375rem 0.5rem;
    border: 0;
    border-top: 1px solid var(--color-border);
    background: none;
    color: var(--color-primary);
    cursor: pointer;
    font: inherit;
    text-align: left;
}

.sutun-menu-sifirla:hover {
    text-decoration: underline;
}

/* ---------- Satır vurguları ---------- */

/*
 * Bugünün satırı: on dört satırlık bir planda "bugün hangisiydi" diye
 * saymak gerekmemeli. Vurgu satırın TAMAMINA verilir; tek hücreye
 * yazılan kalın metin, göz satırı sağa doğru takip ederken kayboluyordu.
 */
tbody tr.bugun {
    background: var(--color-primary-soft);
}

tbody tr.bugun:hover {
    background: var(--color-primary-soft);
}

/*
 * Hafta sonu soluk: çalışılmayan günler listede yer tutar ama göz
 * öncelikle çalışma günlerini arar.
 */
tbody tr.hafta-sonu td {
    color: var(--color-muted);
}

/* ---------- Kişi başlık kartı ---------- */

/*
 * Profil ve personel detayının tepesinde durur: "kim bu kayıt" sorusu,
 * alan listesine bakmadan cevaplanmalı. Eskiden ad, rol ve durum diğer
 * alanların arasında sıradan birer satırdı.
 */
.kisi-kart {
    display: flex;
    align-items: center;
    gap: 1rem;
    margin-bottom: 1rem;
    padding: 1.25rem;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg);
    background: var(--color-surface);
}

.kisi-kart h2 {
    margin: 0 0 0.375rem;
    font-size: 1.25rem;
}

.kisi-kart-alt {
    display: flex;
    flex-wrap: wrap;
    gap: 0.375rem;
}

.avatar.buyuk {
    width: 56px;
    height: 56px;
    font-size: 1.125rem;
}

/* ---------- Bilgi kartı (anahtar–değer) ---------- */

/*
 * "Etiket: değer" çiftleri panelde her ekranda başka türlü çiziliyordu:
 * kimi sayfaya gömülü bir <dl>, kimi başlıksız blok, kimi değeri
 * monospace yazan bir satır. Kart hepsini tek çerçeveye alır.
 */
.kart-ikili {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
    gap: 1rem;
    align-items: start;
}

.bilgi-kart {
    padding: 1.25rem;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg);
    background: var(--color-surface);
}

.bilgi-kart-ust {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    margin-bottom: 0.25rem;
}

.bilgi-kart-baslik {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    color: var(--color-muted);
}

.bilgi-kart-baslik h3 {
    margin: 0;
    color: var(--color-text);
    font-size: 0.9375rem;
}

.bilgi-kart-aciklama {
    margin: 0 0 0.75rem;
    color: var(--color-muted);
    font-size: 0.8125rem;
}

/*
 * Çiftler iki sütunlu bir ızgarada: etiketler solda hizalı durur, göz
 * değerleri tek bir dikey çizgide tarar. <dl>'in varsayılan akışı
 * etiketleri ve değerleri alt alta koyup listeyi iki katı uzatıyordu.
 */
.bilgi-liste {
    display: grid;
    grid-template-columns: minmax(7rem, auto) 1fr;
    gap: 0.5rem 1rem;
    margin: 0;
}

.bilgi-liste dt {
    color: var(--color-muted);
    font-size: 0.8125rem;
}

.bilgi-liste dd {
    margin: 0;
    overflow-wrap: anywhere;
}

/*
 * Doldurulabilir bir boşluk "—" ile geçiştirilmez: eksik telefon
 * numarası, kullanıcının kendi ekleyebileceği bir şeyse bağlantı olur.
 */
.bilgi-ekle {
    padding: 0;
    border: 0;
    background: none;
    color: var(--color-primary);
    cursor: pointer;
    font: inherit;
}

.bilgi-ekle:hover {
    text-decoration: underline;
}

/*
 * Profildeki araç satırı: açıklama solda, "Kaldır" sağ kenarda.
 *
 * Düğme metnin hemen yanında dursaydı, açıklaması olan ve olmayan
 * satırlarda farklı yerlere düşer ve göz onu her satırda yeniden
 * arardı. Sağa yaslamak sabit bir sütun oluşturur.
 */
.arac-satir {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 0.75rem;
    min-width: 0;
}

/*
 * Araç satırında ASIL bilgi plakadır, etiket değil.
 *
 * Kartın diğer satırlarında sol sütun bir alan adıdır ("Telefon") ve
 * soluk olması doğru; burada ise kaydın kendisi orada duruyor. Diğer
 * satırlarla aynı stilde kaldığında, açıklaması olmayan bir araç
 * satırında göz okunacak bir şey bulamıyordu.
 *
 * `:has()` ile kardeş dd'ye bakılır: sınıfı dt'ye JS'ten vermek, kartı
 * kuran ortak yardımcıya (bilgiKarti) yalnızca bu ekran için bir
 * parametre eklemek demekti. Desteklemeyen eski bir tarayıcıda kural
 * düşer ve satır soluk kalır — okunur, yalnızca daha az vurgulu.
 */
.bilgi-liste dt:has(+ dd .arac-satir) {
    color: var(--color-text);
    font-weight: 600;
    font-variant-numeric: tabular-nums;
}

/* ---------- Bildirim listesi ---------- */

/*
 * Bildirimler tablo değil liste olarak çizilir: tabloda "Tarih | Tür |
 * Ne oldu | düğmeler" diye bölününce tür rozeti mesajın söylediğini
 * tekrar ediyor, asıl bilgi ise dar bir sütuna sıkışıyordu.
 *
 * Satır ızgarası: ikon | mesaj (esner) | zaman | eylemler. Mesaj tam
 * genişlikte durur, zaman sağda sabit bir sütun oluşturur — göz "ne
 * zaman" sorusunu hep aynı yerde bulur.
 */
.bildirim-listesi {
    margin: 0;
    padding: 0;
    list-style: none;
}

/*
 * Gün ayraçları: "Bugün", "Dün", sonra tam tarih.
 *
 * Ayraç SIRALAMAYI DEĞİŞTİRMEZ (bkz. CLAUDE.md); liste yine en yeniden
 * eskiye akar, araya yalnızca okunabilir bir başlık girer. Uzun bir
 * listede her satırın "3 gün önce" demesi, göze hiçbir yerde durak
 * vermiyordu.
 *
 * Başlık YAPIŞKANDIR: kaydırırken hangi günün içinde olunduğu görünür
 * kalmalı. Üst konumu 0'dır — liste kartın içinde kaydığı için kartın
 * kendi üst kenarına yapışır.
 */
.bildirim-grup-baslik {
    position: sticky;
    top: 0;
    z-index: 1;
    margin: 0;
    padding: 0.5rem 1rem;
    background: var(--color-bg);
    border-bottom: 1px solid var(--color-border);
    color: var(--color-muted);
    font-size: 0.75rem;
    font-weight: 600;
    letter-spacing: 0.02em;
    text-transform: uppercase;
}

/*
 * Grubun İLK başlığının üst kenarlığı yoktur: kartın kendi kenarıyla
 * çakışıp iki piksellik bir çizgi oluşturuyordu.
 */
.bildirim-gruplu > .bildirim-grup-baslik:first-child {
    border-top: 0;
}


/*
 * `position: relative`, gövdenin tıklama kaplamasının (::after)
 * dayanacağı kutuyu verir; olmadan kaplama en yakın konumlandırılmış
 * ataya, yani sayfaya yayılırdı.
 */
.bildirim-satir {
    position: relative;
    display: grid;
    grid-template-columns: auto 1fr auto auto;
    align-items: center;
    gap: 0.75rem;
    padding: 0.75rem 1rem;
    border-bottom: 1px solid var(--color-border);
}

.bildirim-satir:last-child {
    border-bottom: 0;
}

/*
 * Gruplu listede yukarıdaki kural ARA GRUPLARIN sonunda da çalışırdı ve
 * bir sonraki gün başlığı kendinden önceki satıra yapışık görünürdü.
 * Kenarlık geri verilir; yalnızca SON grubun son satırında kaldırılır
 * (bkz. .bildirim-gruplu > .bildirim-listesi:last-child, yukarıda).
 */
.bildirim-gruplu > .bildirim-listesi > .bildirim-satir:last-child {
    border-bottom: 1px solid var(--color-border);
}

/*
 * …ama listenin EN SONUNDA kenarlık yine kalkar: orada bir sonraki
 * başlık yok, kartın kendi kenarı var. Bu kural yukarıdakinden SONRA
 * gelmek zorunda — ikisi aynı özgüllükte ve sonra yazılan kazanır.
 */
.bildirim-gruplu > .bildirim-listesi:last-child > .bildirim-satir:last-child {
    border-bottom: 0;
}

/*
 * Hover SATIRIN TAMAMINDA.
 *
 * Eskiden metin link gibi maviye dönüp altı çiziliyordu ve satırın geri
 * kalanı ölü alan gibi duruyordu. Artık zemin değişimi tıklanabilir
 * alanın gerçek sınırını gösterir. İmleç el işareti olur — hedefi olan
 * satırlarda; hedefsiz bir bildirimde (yalnız bilgi veren) gövde `<a>`
 * değil `<div>` çizilir ve kaplama hiç oluşmaz, dolayısıyla imleç de
 * değişmez.
 */
.bildirim-satir:has(.bildirim-satir-govde[href]) {
    cursor: pointer;
}

/*
 * OKUNMUŞ satırın hover'ı NÖTRDÜR: karttan bir tık ayrışan gri, mavi
 * değil.
 *
 * Mavi ton bu satırlara yakışmıyor çünkü mavi bu listede bir ANLAM
 * taşıyor: okunmamışlık. Hover'da da mavi kullanmak, imlecin altındaki
 * okunmuş satırı bir an için okunmamış gibi gösteriyordu. Renk ayrımı
 * "yeni mi" sorusuna ayrılmıştır; "imleç burada" bilgisi nötr bir tonla
 * verilir.
 *
 * Değer `--color-surface-2`'dir, `--color-bg` DEĞİL. `--color-bg` sayfa
 * zemininin kendisidir; kartın içinde kullanılınca satır kartın dışıyla
 * aynı renge düşüyor ve hover "vurgu" gibi değil "delik" gibi
 * görünüyordu. `--color-surface-2` iki temada da karttan ayrışır:
 * açık temada yüzey #ffffff iken #f8fafc (bir tık koyu), koyu temada
 * yüzey #111827 iken #172033 (bir tık açık). Yön değişir, ayrışma
 * korunur — sabit bir gri bunu veremezdi.
 */
.bildirim-satir:hover {
    background: var(--color-surface-2);
}

/*
 * Okunmamışlık SIRALAMAYI değil yalnızca görünümü değiştirir (bkz.
 * CLAUDE.md). Zemin mavi tonuna döner ve sol kenardaki çizgiyle
 * birleşir — zil penceresindeki satırlarla AYNI kalıp
 * (bkz. .panel-bildirim-satir.okunmamis): kullanıcı aynı bildirimi iki
 * yerde görüyor ve ikisinin farklı görünmesi, birini ötekinin devamı
 * saymasını engelliyordu.
 */
.bildirim-satir.okunmamis {
    background: var(--color-primary-soft);
    box-shadow: inset 2px 0 0 var(--color-primary);
}

/*
 * Okunmamış satırın hover'ı AYRI tanımlanır ve okunmamış zeminden bir
 * tık KOYUDUR. Yukarıdaki genel hover kuralıyla aynı özgüllükte olduğu
 * için sonra yazılmalıdır; yazılmasaydı `.okunmamis` zemini hover'da
 * daha açık bir tona düşer ve satır imlecin altında okunmuş gibi
 * görünürdü.
 */
.bildirim-satir.okunmamis:hover {
    background: color-mix(in srgb, var(--color-primary) 14%, transparent);
}

.bildirim-satir-ikon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    border-radius: 50%;
    background: var(--color-bg);
    color: var(--color-muted);
}

.bildirim-satir-ikon.t-ok {
    background: var(--color-success-soft);
    color: var(--color-success);
}

.bildirim-satir-ikon.t-warn {
    background: var(--color-warning-soft);
    color: var(--color-warning);
}

.bildirim-satir-ikon.t-bad {
    background: var(--color-danger-soft);
    color: var(--color-danger);
}

.bildirim-satir-ikon.t-info {
    background: var(--color-info-soft);
    color: var(--color-info);
}

/*
 * Gövde bir `<a>` olsa da LİNK GİBİ GÖRÜNMEZ.
 *
 * Etiketin `<a>` olması erişilebilirlik içindir: orta tuşla yeni sekmede
 * açılabilsin, hedef tarayıcının durum çubuğunda görünsün, klavyeyle
 * gezilebilsin. Ama tıklama hedefi metnin kendisi değil SATIRIN
 * TAMAMIDIR (bkz. .bildirim-satir-govde::after) ve metni maviye boyayıp
 * altını çizmek, yalnızca o kelimelerin tıklanabilir olduğunu söyleyen
 * yanlış bir işaretti — kullanıcı satırın boşluğuna tıkladığında bir şey
 * olmuyor sanıyordu.
 *
 * Geri bildirim artık satır düzeyinde verilir: imleç satırın üzerindeyken
 * zemin değişir (.bildirim-satir:hover) ve imleç el işaretine döner.
 */
.bildirim-satir-govde,
.bildirim-satir-govde:hover,
.bildirim-satir-govde:focus,
.bildirim-satir-govde:focus-visible,
.bildirim-satir-govde:active {
    min-width: 0;
    color: inherit;
    text-decoration: none;
}

/*
 * Durum seçicileri (`:hover`, `:focus`) YAZILMAK ZORUNDA.
 *
 * app.css'teki genel `a:hover { text-decoration: underline }` kuralı
 * (0,1,1) düz `.bildirim-satir-govde`den (0,1,0) daha özgüldür; admin.css
 * sonra yüklense bile özgüllük kazanır ve alt çizgi hover ile odakta geri
 * geliyordu. Sınıfı durumlarla birlikte saymak, ezme sırasını dosya
 * yükleme sırasına bırakmadan çözer.
 */

/*
 * Odak halkası METNİN DEĞİL SATIRIN etrafına çizilir.
 *
 * Odaklanan öğe gövdedir (`<a>`) ama o, satırın yalnızca orta sütunudur;
 * halka onun etrafına çizilince ikonu ve zamanı dışarıda bırakan, satırın
 * içinde asılı duran bir dikdörtgen çıkıyordu. Halka satıra taşınır:
 * klavyeyle gezen kullanıcı tıklayınca ne olacağını görür — tıklama
 * hedefi de zaten satırın tamamıdır (bkz. ::after kaplaması).
 *
 * `:focus-visible` kullanılır, `:focus` değil: fareyle tıklanan her
 * satırda halka çizilmemeli.
 */
.bildirim-satir-govde:focus-visible {
    outline: none;
    box-shadow: none;
}

.bildirim-satir:has(.bildirim-satir-govde:focus-visible) {
    outline: 2px solid var(--color-primary);
    outline-offset: -2px;
}

/*
 * Tıklama alanı satırın tamamına yayılır.
 *
 * Bağlantıyı `position: absolute` bir kaplamayla büyütmek, `<li>`yi
 * tıklanabilir yapıp içine gizli bir link koymaktan iyidir: etiket
 * semantiği bozulmaz, klavye odağı tek bir öğede kalır ve satırdaki
 * gerçek düğmeler (sil, okundu) kaplamanın ÜSTÜNDE kalarak kendi
 * tıklamalarını almaya devam eder.
 */
.bildirim-satir-govde::after {
    content: '';
    position: absolute;
    inset: 0;
}

.bildirim-satir-metin {
    display: flex;
    flex-direction: column;
    gap: 0.125rem;
    line-height: 1.4;
}

.bildirim-satir-metin small {
    color: var(--color-muted);
    font-size: 0.75rem;
}

/*
 * Zaman göreceleşir ("2 saat önce"): bildirimlerde sorulan şey tam
 * damga değil tazeliktir. Tam tarih başlık ipucunda durur.
 */
.bildirim-satir-zaman {
    color: var(--color-muted);
    font-size: 0.8125rem;
    white-space: nowrap;
}

/*
 * Eylemler normalde soluk: her satırda tam görünür iki düğme, listeyi
 * okunmaz hâle getiriyordu. Satıra gelince ya da klavyeyle odaklanınca
 * belirginleşir.
 *
 * `position: relative` ile satırı kaplayan tıklama katmanının (gövdenin
 * ::after'ı) ÜSTÜNDE kalırlar. Olmasaydı kaplama düğmeleri örter ve
 * "Sil"e basan kullanıcı bildirimi silmek yerine ona giderdi.
 */
.bildirim-satir-eylemler {
    position: relative;
    display: inline-flex;
    gap: 0.25rem;
    opacity: 0.35;
    transition: opacity 0.12s ease;
}

.bildirim-satir:hover .bildirim-satir-eylemler,
.bildirim-satir:focus-within .bildirim-satir-eylemler {
    opacity: 1;
}

/* ---------- Eski → yeni değişim ---------- */

/*
 * Bir düzeltme talebinde neyin neye dönüştüğü tek hücrede gösterilir.
 * İki ayrı sütun ("Kayıtlı" / "Talebiniz") kullanıldığında göz satır
 * boyunca gidip geliyor ve ilişki ancak başlıklara bakılarak
 * anlaşılıyordu.
 *
 * Eski değer soluk ve üstü çizili: neyin geçersizleştiği okunmadan
 * görülmeli. Yeni değer kalın — asıl sorulan odur.
 */
.degisim {
    display: inline-flex;
    align-items: center;
    gap: 0.375rem;
    white-space: nowrap;
}

.degisim-eski {
    color: var(--color-muted);
    text-decoration: line-through;
}

/*
 * Ortak tarih öneki: iki damga aynı güne düşüyorsa tarih bir kez yazılır
 * ve karşılaştırma yalnızca saatler arasında kalır. Tarih, kıyaslanan
 * şey olmadığı için soluktur.
 */
.degisim-tarih {
    color: var(--color-muted);
}

.degisim svg {
    flex: none;
    color: var(--color-muted);
}

/* ---------- Karar hücresi ---------- */

/*
 * Kim/ne zaman üstte, gerekçe altta. Üçünü " · " ile tek satıra dizmek,
 * cümle uzunluğundaki karar notu yüzünden tarihi ve adı okunmaz hâle
 * getiriyordu.
 */
.karar-hucre {
    display: flex;
    flex-direction: column;
    gap: 0.125rem;
}

.karar-kim {
    color: var(--color-text-2);
    font-size: 0.8125rem;
}

.karar-hucre small {
    color: var(--color-muted);
    font-size: 0.75rem;
    line-height: 1.4;
}

/* Hücre dikey bir sütundur; rozet sütun genişliğine yayılmasın. */
.karar-hucre .badge {
    align-self: flex-start;
}

/* ---------- Etiketsiz alan (filtre şeridi) ---------- */

/*
 * Filtre şeridindeki seçiciler etiketsizdir: şerit yatay ve dardır,
 * her alanın üstüne etiket koymak şeridin yüksekliğini iki katına
 * çıkarırdı. Alan adı aria-label olarak kalır.
 */
.field.etiketsiz {
    display: block;
    margin: 0;
}

.field.etiketsiz select,
.field.etiketsiz input {
    height: 36px;
    min-width: 10rem;
}

/*
 * BOŞ tarih girdisi soluk yazılır.
 *
 * Tarayıcı boş bir `input[type=date]` içine kendi biçim ipucunu basar
 * ("gg.aa.yyyy") ve bu metin dolu bir alanla aynı koyulukta çizilince
 * girilmiş bir değer gibi okunuyordu — şeritte dört alan varken hangisinin
 * seçili olduğu anlaşılmıyordu.
 *
 * Sınıf JS'ten verilir (bkz. Ui.field): `:placeholder-shown` tarih
 * girdilerinde EŞLEŞMEZ, `:invalid` ise boş bir isteğe bağlı alanda
 * geçerli sayıldığı için tutmaz. İkisi de denendi ve ölçümde boş alanla
 * dolu alan aynı renkte çıktı.
 */
.field input[type="date"].bos-tarih:not(:focus) {
    color: var(--color-muted);
}

/* ---------- Sütun başlığı ipucu ---------- */

/*
 * Bir sütunun anlamını açıklayan uzun cümle, başlığın yanındaki ⓘ
 * işaretinde durur. İşaret başlığın parçası gibi görünmemeli: bu yüzden
 * soluk çizilir ve yalnızca üzerine gelindiğinde belirginleşir.
 */
.baslik-ipucu {
    margin-left: 0.25rem;
    color: var(--color-muted);
    cursor: help;
    font-size: 0.8125rem;
    font-weight: 400;
}

.baslik-ipucu:hover {
    color: var(--color-text);
}

/* ---------- Bakiye hücresi ---------- */

/*
 * Tutar + altında yönü söyleyen tek kelime. Sütun sağa hizalı olduğu için
 * blok da sağa yaslanır; rakamlar tabular olduğundan basamaklar alt alta
 * gelir ve sütun okunurken göz kaymaz.
 */
.bakiye {
    display: inline-flex;
    flex-direction: column;
    align-items: flex-end;
    line-height: 1.3;
}

.bakiye strong {
    font-variant-numeric: tabular-nums;
    font-weight: 600;
}

.bakiye small {
    color: var(--color-muted);
    font-size: 0.75rem;
}

/*
 * Tutarın rengi yalnızca işaretini anlatır. Rozet değildir: zemin almaz,
 * çerçevesi yoktur — sayı olarak okunmalıdır.
 *
 * Borç ve alacak aynı sütunda durur (bkz. cari.js, cari-hesabim.js): iki
 * ayrı sütun açmak tabloyu genişletirdi ve her satırda biri daima boş
 * kalırdı. Ayrımı renk ve önek taşır.
 *
 * Renkler --color-* değişkenlerinden okunur, sabit yazılmaz: koyu temada
 * aynı kırmızı/yeşil tonları zemine karşı okunmuyor.
 */
.tutar-ok {
    color: var(--color-success);
    font-weight: 600;
}

.tutar-bad {
    color: var(--color-danger);
    font-weight: 600;
}

/* ---------- Boş durum ---------- */

/*
 * Tek gri cümle yerine ikonlu, başlıklı ve gerektiğinde eylemli bir blok.
 * Tablo sayfalarında tablo kartının İÇİNDE durur, kartın dışında ayrı bir
 * kutu olarak değil.
 */
.bos-durum {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.5rem;
    padding: 2.5rem 1.5rem;
    text-align: center;
}

.bos-ikon {
    display: grid;
    place-items: center;
    width: 44px;
    height: 44px;
    border-radius: 50%;
    background: var(--color-surface-2);
    color: var(--color-muted);
    margin-bottom: 0.2rem;
}

.bos-ikon .ikon {
    width: 22px;
    height: 22px;
}

.bos-durum strong {
    font-size: 0.95rem;
    font-weight: 600;
}

.bos-durum p {
    margin: 0;
    max-width: 46ch;
    color: var(--color-text-2);
    font-size: 0.86rem;
}

.bos-durum .btn {
    margin-top: 0.4rem;
}

/* ---------- Uyarı kutusu ---------- */

/*
 * Sol kalın şerit YOKTUR: kutu kendi yumuşak zeminini ve ince renkli
 * kenarlığını taşır, sayfadaki diğer kartlarla aynı hizada durur.
 */
.uyari-kutu {
    display: flex;
    align-items: flex-start;
    gap: 0.6rem;
    padding: 0.75rem 0.9rem;
    border: 1px solid;
    border-radius: var(--radius);
    font-size: 0.86rem;
    margin-bottom: 1rem;
}

/*
 * Kutunun KENDİ ikonu — doğrudan çocuk seçicisiyle.
 *
 * İç içe seçici (.uyari-kutu .ikon) kutunun içine konan her ikonu da
 * yakalıyordu; kutu gövdesine tıklanabilir satırlar eklenince (bkz.
 * vardiya planı uyarısı) satır sonundaki chevron'lar da bu boyutu ve
 * üst boşluğu alıyordu.
 */
.uyari-kutu > .ikon {
    width: 17px;
    height: 17px;
    margin-top: 1px;
    flex-shrink: 0;
}

.uyari-metin {
    flex: 1;
    min-width: 0;
}

.uyari-metin strong {
    font-weight: 600;
}

.uyari-metin strong + span {
    margin-left: 0.25rem;
}

/*
 * Metin GÖVDE rengindedir, uyarının kendi rengi değil: renkli zemin
 * üzerine renkli metin okunurluğu düşürür. Renk yalnızca ikonda ve
 * kenarlıkta durur.
 */
.uyari-kutu.info {
    background: var(--color-info-soft);
    border-color: color-mix(in srgb, var(--color-info) 35%, transparent);
    color: var(--color-text);
}

.uyari-kutu.info > .ikon { color: var(--color-info); }

.uyari-kutu.warn {
    background: var(--color-warning-soft);
    border-color: var(--color-warning-border);
    color: var(--color-text);
}

.uyari-kutu.warn > .ikon { color: var(--color-warning); }

.uyari-kutu.bad {
    background: var(--color-danger-soft);
    border-color: color-mix(in srgb, var(--color-danger) 35%, transparent);
    color: var(--color-text);
}

.uyari-kutu.bad > .ikon { color: var(--color-danger); }

.uyari-kutu.ok {
    background: var(--color-success-soft);
    border-color: color-mix(in srgb, var(--color-success) 35%, transparent);
    color: var(--color-text);
}

.uyari-kutu.ok > .ikon { color: var(--color-success); }

.uyari-eylem {
    flex-shrink: 0;
    border: 0;
    background: transparent;
    padding: 0;
    color: var(--color-primary);
    font-weight: 500;
    cursor: pointer;
    white-space: nowrap;
}

.uyari-eylem:hover {
    text-decoration: underline;
}

/* ---------- İstatistik kartı ---------- */

/*
 * Solda renkli ikon kutusu, yanında etiket ve değer. Sol kenar şeridi
 * yoktur; renk yalnızca ikon kutusunda ve gerçek bir durum bildiren
 * değerde bulunur.
 */
.stat-kart {
    display: flex;
    align-items: flex-start;
    gap: 0.75rem;
    padding: 1rem;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg);
    box-shadow: var(--golge-1);
    text-align: left;
    font: inherit;
    color: inherit;
}

/*
 * Dar masaüstünde (tipik dizüstü: 1366px) altı kart tek satırda kalır
 * ama etiket sığmaz: ölçümde "Çalışan personel" 101px istiyor, kartta
 * 78px kalıyordu ve "Çalışan perso…" diye kırpılıyordu. Kırpılma
 * 1440px'in altında başlıyor.
 *
 * Çözüm ızgarayı bölmek değil kartın içini sıkmaktır: ikon 40→34px,
 * yatay boşluklar kısalır. Böylece etikete ~20px açılır ve altı kart
 * tek satırda okunur kalır. Satırı ikiye bölmek, 1366px gibi yaygın bir
 * çözünürlükte üst şeridi iki kat yer kaplar hâle getirirdi.
 */
@media (max-width: 1440px) and (min-width: 701px) {
    .stat-kart {
        gap: 0.6rem;
        padding: 0.85rem 0.75rem;
    }

    .stat-ikon {
        width: 34px;
        height: 34px;
    }

    .stat-ikon svg {
        width: 17px;
        height: 17px;
    }
}

/*
 * Mobilde kart iki kolona sığmalı: 40px ikon + 1rem padding, 150px'lik
 * bir kartta etikete yer bırakmıyordu. İkon ve boşluklar küçülür, ikon
 * satır BAŞINA alınmaz — yan yana kalması, kartın ne olduğunu sayıya
 * bakmadan söyleyen tek işaret.
 */
@media (max-width: 700px) {
    .stat-kart {
        gap: 0.55rem;
        padding: 0.7rem;
    }

    .stat-ikon {
        width: 32px;
        height: 32px;
        border-radius: 8px;
    }

    .stat-ikon svg {
        width: 16px;
        height: 16px;
    }
}

.stat-kart.tiklanabilir {
    cursor: pointer;
}

.stat-kart.tiklanabilir:hover {
    border-color: var(--color-border-strong);
    background: var(--color-surface-2);
}

.stat-ikon {
    display: grid;
    place-items: center;
    width: 40px;
    height: 40px;
    border-radius: 10px;
    flex-shrink: 0;
}

.stat-govde {
    display: flex;
    flex-direction: column;
    gap: 0.1rem;
    min-width: 0;
    flex: 1;
}

/*
 * Etiket TEK SATIRA sığmalıdır. Sığmıyorsa etiketin kendisi kısaltılır
 * ve açıklaması ipucuna taşınır ("Hâlâ işte (çıkış yapmadı)" →
 * "Hâlâ işte"), iki satıra kırılmasına izin verilmez.
 */
.stat-etiket {
    font-size: 0.8rem;
    color: var(--color-text-2);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.stat-deger {
    font-size: 1.6rem;
    font-weight: 700;
    line-height: 1.2;
    letter-spacing: -0.01em;
    font-variant-numeric: tabular-nums;
}

/* Değer rengi yalnızca gerçek bir durum varsa değişir. */
.stat-deger.d-ok { color: var(--color-success); }
.stat-deger.d-warn { color: var(--color-warning); }
.stat-deger.d-bad { color: var(--color-danger); }
.stat-deger.d-info { color: var(--color-info); }

.stat-not {
    font-size: 0.75rem;
    color: var(--color-muted);
}

/* Oran/limit gösteren kartlarda ince ilerleme çubuğu ("8 / 100 çalışan"). */
.stat-cubuk {
    display: block;
    height: 5px;
    border-radius: 3px;
    background: var(--color-surface-2);
    overflow: hidden;
    margin: 0.4rem 0 0.15rem;
}

.stat-cubuk i {
    display: block;
    height: 100%;
    border-radius: 3px;
    background: var(--color-primary);
}

/* İkon kutusu tonları (rozet varyantlarıyla aynı adları taşır). */
.t-primary { background: var(--color-primary-soft); color: var(--color-primary); }
.t-ok { background: var(--color-success-soft); color: var(--color-success); }
.t-warn { background: var(--color-warning-soft); color: var(--color-warning); }
.t-bad { background: var(--color-danger-soft); color: var(--color-danger); }
.t-info { background: var(--color-info-soft); color: var(--color-info); }
.t-mute { background: var(--color-neutral-soft); color: var(--color-neutral); }

/*
 * KONU tonları: kartın ne anlattığına göre sabit renk (bkz. app.css'teki
 * --konu-* değişkenleri ve oradaki "durum rengi / konu rengi" ayrımı).
 *
 * `t-` öneki KULLANILMAZ, `k-` kullanılır. İkisi karışırsa bir kartın
 * rengi "durumu kötü" mü yoksa "konusu personel" mi demek istediği
 * anlaşılmaz olurdu; ayrı önek, hangi anlamda kullanıldığını okurken
 * belli eder.
 */
.k-mavi { background: var(--konu-mavi-soft); color: var(--konu-mavi); }
.k-yesil { background: var(--konu-yesil-soft); color: var(--konu-yesil); }
.k-mor { background: var(--konu-mor-soft); color: var(--konu-mor); }
.k-pembe { background: var(--konu-pembe-soft); color: var(--konu-pembe); }
.k-turuncu { background: var(--konu-turuncu-soft); color: var(--konu-turuncu); }
.k-camgobegi { background: var(--konu-camgobegi-soft); color: var(--konu-camgobegi); }
.k-kehribar { background: var(--konu-kehribar-soft); color: var(--konu-kehribar); }
.k-civit { background: var(--konu-civit-soft); color: var(--konu-civit); }

/* ---------- Durum segmenti ---------- */

/*
 * Sayılı sekmeler: [Tümü 12][Beklemede 2][Onaylandı 9]
 *
 * Durum filtresi için açılır liste yerine bu kullanılır; hangi durumda
 * kaç kayıt olduğunu filtrelemeden önce gösterir.
 */
/*
 * Kutu zemini SEÇİLİ DÜĞMEDEN belirgin biçimde koyudur.
 *
 * Eskiden zemin --color-surface-2 (#f8fafc), aktif düğme ise
 * --color-surface (#ffffff) idi: aradaki parlaklık farkı %2.7 ve gölge
 * neredeyse görünmezdi (alfa 0.05). Sonuç, hangi düğmenin seçili
 * olduğunun anlaşılmamasıydı — segment "hangisi açık?" sorusunu
 * cevaplamak için var, cevaplayamıyorsa işini yapmıyor demektir.
 *
 * Zemin bu yüzden bir ton daha koyuya (--color-bg) çekildi; aktif düğme
 * beyaz kalır ve üstünde bir kart gibi durur. Renk seçilmedi: segment bir
 * filtre kontrolü ve 13 ekranda birden yaşıyor — mavi bir öğe daha
 * eklemek, sayfadaki birincil eylem düğmeleriyle dikkat yarışına
 * girerdi.
 */
.segment {
    display: inline-flex;
    gap: 2px;
    padding: 3px;
    background: var(--color-bg);
    border: 1px solid var(--color-border);
    border-radius: 9px;
    /*
     * Dar ekranda şerit KENDİ İÇİNDE yatay kayar, sayfayı genişletmez.
     * Dört seçenekli bir filtre 390px'te 396px yer kaplıyor ve tüm
     * sayfaya yatay kaydırma ekliyordu (ölçüm: taşma 21px).
     *
     * Düğmeler alt satıra SARMAZ: segment "bir arada tek bir kontrol"
     * olduğunu biçimiyle söyler ve iki satıra bölünmüş bir şerit iki
     * ayrı kontrol gibi görünür. Kaydırma, seçeneklerin sırasını ve
     * tek parça oluşunu korur.
     *
     * max-width, inline-flex'in içeriği kadar genişleme eğilimini
     * kapsayıcıyla sınırlar; onsuz overflow hiç devreye girmez.
     */
    max-width: 100%;
    overflow-x: auto;
    /* Kaydırılabilir şeritte düğmeler sıkışmamalı. */
    flex-shrink: 0;
    scrollbar-width: thin;
}

/*
 * Kaydırma çubuğu şeridi kalınlaştırmasın: WebKit'te varsayılan çubuk
 * 15px yer kaplıyor ve 28px'lik şeridin yarısını yiyordu.
 */
.segment::-webkit-scrollbar {
    height: 4px;
}

.segment::-webkit-scrollbar-thumb {
    background: var(--color-border);
    border-radius: 2px;
}

.segment > * {
    flex-shrink: 0;
}

.segment-dugme {
    display: flex;
    align-items: center;
    gap: 0.35rem;
    height: 28px;
    padding: 0 0.6rem;
    /* Kenarlık PASİFTE DE var, yalnızca saydam: aktiflik onu renklendirir.
       Sıfırdan kenarlık eklemek düğmeyi 2px büyütür ve seçim her
       değiştiğinde şerit zıplardı. */
    border: 1px solid transparent;
    border-radius: var(--radius-sm);
    background: transparent;
    color: var(--color-text-2);
    font-size: 0.82rem;
    cursor: pointer;
    white-space: nowrap;
}

/*
 * AĞIRLIK HER DURUMDA 600 — aktiflikle değişmez.
 *
 * Kalın metin ince metinden geniştir ve ağırlığı yalnızca aktif düğmede
 * artırmak, seçim değiştikçe şeridi oynatıyordu (ölçüm: 221.44 → 221.63
 * px). Fark gözle görülmeyecek kadar küçük ama ardışık tıklamalarda
 * komşu düğmeler yerinden kayar; bir kontrolün kendi genişliği, içindeki
 * seçime göre değişmemeli.
 *
 * Ağırlığı sabitleyip ayrımı RENKLE kurmak hem bu sorunu ortadan kaldırır
 * hem de daha okunaklıdır: pasif düğmeler --color-text-2, aktif olan
 * --color-text ve arkasında beyaz bir kart.
 */
.segment-dugme > span {
    font-weight: 600;
}

/*
 * Seçilmemiş düğmeler biraz daha soluk: aradaki fark yalnızca seçili
 * olanın öne çıkmasıyla değil, diğerlerinin geri çekilmesiyle de kurulur.
 * Fare üstüne gelince tam kontrasta döner — tıklanabilir olduğu orada
 * görünür.
 */
.segment-dugme:hover:not(.aktif) {
    color: var(--color-text);
    background: color-mix(in srgb, var(--color-text) 6%, transparent);
}

/*
 * Aktif düğme, koyu zemin üstünde duran BEYAZ BİR KART gibi okunur.
 *
 * Üç işaret birlikte çalışır ve hiçbiri tek başına yeterli değildir:
 * zemin farkı (kutu --color-bg, düğme --color-surface), belirgin bir
 * gölge ve ince bir kenarlık, artı 600 ağırlıkta metin. Eskiden yalnızca
 * %2.7'lik bir zemin farkı ve alfa 0.05'lik bir gölge vardı; ikisi de
 * ölçülebilir ama görülemez düzeydeydi.
 *
 * Ağırlık farkı ayrıca renkten bağımsız bir işarettir: renk körlüğü olan
 * ya da düşük parlaklıkta bakan kullanıcı için seçili olanı ayıran şey
 * budur.
 */
.segment-dugme.aktif {
    background: var(--color-surface);
    color: var(--color-text);
    border-color: var(--color-border);
    box-shadow: 0 1px 3px rgba(16, 24, 40, 0.12);
    cursor: default;
}

/*
 * Koyu temada yüzey renkleri birbirine çok yakın (#0b1120 ve #111827:
 * kontrast 1.06:1) ve tek başına zemin farkı seçili düğmeyi göstermeye
 * yetmiyor. Bu yüzden aktif düğme bir tık daha açık bir yüzeye oturur ve
 * kenarlık güçlü tona çekilir; gölge de koyu zeminde opaklıktan çok
 * yayılımla iş görür.
 */
[data-tema="koyu"] .segment-dugme.aktif {
    /* Yüzey token'ları koyu temada birbirine çok yakın (#0b1120, #111827,
       #172033 — en iyi ihtimalle 1.16:1). Hiçbiri tek başına seçili
       düğmeyi göstermeye yetmediği için yüzeyin üstüne beyaz bir perde
       konur: zemin neyse ondan belirgin biçimde açık olması garanti. */
    background: color-mix(in srgb, #fff 11%, var(--color-surface-2));
    border-color: var(--color-border-strong);
    box-shadow: 0 1px 4px rgba(0, 0, 0, 0.45);
}

/*
 * Anahtar düğmesi (Ui.anahtarDugmesi) seçiliyken de TIKLANABİLİR: segmentte
 * seçili düğmeye yeniden basmak bir şey yapmaz, anahtarda ise süzgeci
 * kapatır. İmleç bunu söylemeli; `default` kalsaydı kullanıcı kapatmanın
 * yolunu "Filtreleri temizle"de arardı.
 */
.segment-dugme.anahtar.aktif {
    cursor: pointer;
}

/* Sayı, etiketten soluk durur: önce ne olduğu, sonra kaç tane olduğu. */
.segment-dugme em {
    font-style: normal;
    font-size: 0.78rem;
    color: var(--color-muted);
    font-variant-numeric: tabular-nums;
}

.segment-dugme.aktif em {
    color: var(--color-primary);
}

/* ---------- Tablo üst şeridi ---------- */

/*
 * Kartın üst şeridi: solda filtreler, sağda araçlar (sütun menüsü ve
 * ekrana özgü düğmeler). Bkz. ui.js → table.
 *
 * Eskiden bu iki grup AYRI yerlerde duruyordu: filtreler kartın DIŞINDA
 * bağımsız bir blok, sütun menüsü kartın içinde kendi şeridi. Aralarında
 * kartın üst kenarı ve iki ayrı padding olduğu için gözle görülür bir boş
 * bant kalıyordu — kartın ilk satırı yalnızca sağa yaslı bir düğme
 * taşıyordu. Tek şeride indirilince o bant kapandı.
 *
 * Alt kenarlık ve yatay padding ARTIK BURADA: .filtre-serit ve
 * .sutun-menu kendi çerçevelerini bıraktı, yoksa şeridin içinde ikinci
 * bir çizgi görünürdü.
 */
.tablo-serit {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem;
    padding: 0.625rem 0.9rem;
    border-bottom: 1px solid var(--color-border);
    /*
     * Kartın ÜST köşeleri: şerit kartın en üst parçasıdır. .tablo-kutu
     * artık overflow:hidden taşımıyor (şeritte açılan paneller
     * kırpılmasın diye), dolayısıyla köşeleri parçaların kendisi verir.
     */
    border-radius: 12px 12px 0 0;
}

/*
 * Araçlar sağa itilir; aradaki tüm boşluk filtrelerin olur.
 *
 * `margin-left: auto` tercih edildi, `justify-content: space-between`
 * değil: şerit sarmalandığında (flex-wrap) space-between son satırı da
 * iki uca yayar ve tek kalan filtre kutusu ekranın ortasında asılı
 * kalırdı. auto-margin yalnızca araç grubunu iter.
 *
 * `flex-shrink: 0` — ARAÇLAR ASLA ALT SATIRA DÜŞMEZ.
 *
 * Ölçüm: filtre bloğu bir "Filtreleri temizle" düğmesi kadar (104px)
 * büyüyünce toplam genişlik şeridi aşıyor ve sarmalama sırasında ALT
 * SATIRA İTİLEN, araç grubu oluyordu — şerit 57px'ten 101px'e çıkıyor ve
 * "Sütunlar" düğmesi kartın ortasında tek başına bir satır açıyordu.
 * Sığmayan bir şey olacaksa, o filtrelerin kendi içinden sarmalanmalı;
 * araçlar sabit kalmalı (bkz. .filtre-serit'in min-width: 0 kuralı).
 */
.tablo-serit-araclar {
    margin-left: auto;
    flex-shrink: 0;
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

/*
 * Filtreler artık .tablo-serit'in içindedir ve KENDİ ÇERÇEVESİ YOKTUR:
 * padding ile alt kenarlık şeride taşındı. `display: contents` ile de
 * çözülebilirdi ama o zaman "Filtreleri temizle" düğmesi araç grubuyla
 * aynı flex bağlamına düşer ve margin-left:auto ikisini birbirine
 * yapıştırırdı.
 */
.filtre-serit {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem;
    /* Şeridin kendi gap'i ile çakışmaması için dış boşluk yok. */
    margin: 0;
    /*
     * BÜYÜMEZ, DARALIR: `flex: 0 1 auto` (varsayılan).
     *
     * `flex-grow: 1` bir ara denendi ve ters etki yaptı: blok şeridin
     * tamamını kaplayınca araç grubuna yer kalmadı ve araçlar alt satıra
     * düştü — tam engellenmek istenen durum. Filtre bloğu yalnızca
     * içeriği kadar yer alır; artan alan, araçları sağa iten
     * `margin-left: auto`'nun payıdır.
     *
     * `min-width: 0` ise şart: olmadan flex öğesi min-content
     * genişliğinin altına inmez ve filtreler sığmadığında blok bir bütün
     * olarak taşıp araçları yine alt satıra iterdi. Sıfır ile sarmalama
     * bloğun KENDİ İÇİNDE olur: sığmayan filtre alta geçer, araçlar ilk
     * satırda kalır.
     */
    min-width: 0;
}

/* ---------- Dönem seçici ---------- */

/*
 * Ui.tarihAraligiSecici'nin sıkıştırılmış hâli: tek bir açılır liste ve
 * yalnızca "Özel aralık…" seçilince beliren iki tarih girdisi. Gerekçesi
 * bileşenin doc-block'unda.
 *
 * Kutu, girdiler açıldığında yan yana değil ALT ALTA dizilir: filtre
 * şeridinin yüksekliği artar ama şerit yatayda taşmaz ve yanındaki
 * filtreler kullanıcının altında kaymaz.
 */
/*
 * Kutu artık dikey DEĞİL: özel aralık penceresi akıştan çıkarıldığı için
 * (aşağıya bkz.) kutunun içinde yalnızca menü duruyor. `position:
 * relative` pencerenin konumlanma çıpasıdır.
 */
/*
 * Kutu, açılır menünün konumlanma çıpasıdır. Menü akıştan çıkarıldığı
 * için (aşağıya bkz.) kutunun kendisi yalnızca düğme kadar yer kaplar.
 */
.donem-kutu {
    position: relative;
    display: inline-flex;
}

/*
 * Yükseklik .field.etiketsiz select ile AYNI (36px): seçici şeritte tür
 * ve personel seçicilerinin yanında duruyor ve bir piksel fark hemen
 * görülüyor.
 *
 * Genişlik SABİT DEĞİL, içeriğe göre büyür: düğme metni "Bu ay" kadar
 * kısa da olabilir, "01.09.2026 – 18.09.2026" kadar uzun da. Sabit bir
 * min-width kısa metinde boşluk, uzun metinde kırpma üretirdi.
 */
.donem-dugme {
    height: 36px;
    gap: 0.375rem;
    /* Metin tek satırda kalsın; şerit sarmalanırken düğme bölünmesin. */
    white-space: nowrap;
}

.donem-dugme-metin {
    font-weight: 500;
}

/*
 * AÇILIR MENÜ AKIŞTAN ÇIKARILIR.
 *
 * Girdiler bir ara şeridin içinde, seçicinin altında açılıyordu ve
 * şeridin yüksekliğini ~44px artırıyordu: altındaki tablo aşağı kayıyor,
 * kullanıcının bakmakta olduğu ilk satır imlecin altından çekiliyor,
 * kapanınca da tablo geri zıplıyordu.
 *
 * `position: absolute` ile menü tabloya BİNER ve şerit hiç oynamaz. Aynı
 * çözüm sütun menüsünde (.sutun-menu-govde) ve satır menüsünde de
 * kullanılıyor; z-index onlarla aynı mertebede tutulur ki ikisi birden
 * açıldığında hangisinin üstte kalacağı belirsiz olmasın.
 *
 * Menünün kırpılmaması için .tablo-kutu'nun overflow:hidden'ı
 * kaldırılmıştır (bkz. oradaki not).
 */
.donem-menu {
    position: absolute;
    top: calc(100% + 0.25rem);
    left: 0;
    z-index: 20;
    min-width: 12rem;
    padding: 0.375rem;
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    background: var(--color-surface);
    box-shadow: 0 8px 24px rgba(15, 23, 42, 0.14);
}

.donem-menu[hidden] {
    display: none;
}

/* Seçenekler tam genişlikte satırlar: hedef alanı metin kadar değil satır kadar. */
.donem-secenek {
    display: block;
    width: 100%;
    padding: 0.375rem 0.5rem;
    border: 0;
    border-radius: var(--radius-sm);
    background: transparent;
    color: inherit;
    font: inherit;
    text-align: left;
    white-space: nowrap;
    cursor: pointer;
}

.donem-secenek:hover {
    background: var(--color-surface-2);
}

/*
 * Seçili seçenek: mavi zemin ve kalın yazı.
 *
 * Burada mavi ANLAM taşıyor (hangi dönem yürürlükte) ve hover nötr bir
 * tonla anlatılıyor — ikisinin karışmaması için hover'da marka rengi
 * kullanılmaz (bkz. bildirim listesinde aynı ayrım).
 */
.donem-secenek.aktif {
    background: var(--color-primary-soft);
    color: var(--color-primary);
    font-weight: 600;
}

.donem-secenek.aktif:hover {
    background: color-mix(in srgb, var(--color-primary) 14%, transparent);
}

/*
 * Serbest tarih bölümü menünün içinde, seçeneklerin ALTINDA durur ve
 * üstten bir çizgiyle ayrılır: hazır seçeneklerle aynı listenin parçası
 * değil, onların alternatifi.
 */
.donem-ozel {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    margin-top: 0.375rem;
    padding-top: 0.5rem;
    border-top: 1px solid var(--color-border);
}

.donem-ozel[hidden] {
    display: none;
}

.donem-ozel-girdiler {
    display: flex;
    align-items: center;
    gap: 0.4rem;
}

.donem-ozel-ayrac {
    color: var(--color-muted);
}

/* "Uygula" sağa yaslanır: onay noktası, okuma yönünün sonunda. */
.donem-ozel-ayak {
    display: flex;
    justify-content: flex-end;
}

/*
 * Menü dar ekranda sağ kenardan taşmasın: soldan hizalı açılır ama
 * gerekirse sağa yaslanır.
 */
@media (max-width: 520px) {
    .donem-menu {
        left: auto;
        right: 0;
    }
}

/* ---------------- Aranabilir seçim (combobox) ---------------- */

.combo {
    position: relative;
    display: inline-block;
    min-width: 12rem;
}

/*
 * Native select DOM'da kalır ama görünmez: readForm onu okur ve form
 * gönderimi kendiliğinden çalışır. display:none KULLANILMAZ — bazı
 * tarayıcılar gizlenmiş alanı form doğrulamasında atlar.
 */
.combo .combo-gizli {
    position: absolute;
    width: 1px;
    height: 1px;
    opacity: 0;
    pointer-events: none;
}

.combo .combo-girdi {
    width: 100%;
    padding: 0.35rem 0.6rem;
    border: 1px solid var(--color-border-strong);
    border-radius: var(--radius-sm);
    background: var(--color-surface);
    color: var(--color-text);
    font-family: inherit;
    font-size: 0.85rem;
}

.combo .combo-girdi:focus {
    outline: none;
    border-color: var(--color-primary);
}

/*
 * Liste SABİT konumludur; top/left/width ve (yer darsa) daraltılmış
 * max-height, açılırken JavaScript'le yazılır (bkz. ui.js,
 * aranabilirSecim). `absolute` iken pencere gövdesinin kaydırma kutusu
 * onu kırpıyordu. Buradaki max-height yalnızca TAVANDIR.
 *
 * border-box: JS yüksekliği kenarlık dahil hesaplar; content-box'ta
 * liste ekran kenarına ayrılan paya 2px taşardı.
 */
.combo-liste {
    position: fixed;
    box-sizing: border-box;
    z-index: 30;
    max-height: 16rem;
    overflow-y: auto;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-sm);
    box-shadow: 0 8px 24px rgba(16, 24, 40, 0.12);
    scrollbar-width: thin;
}

.combo-satir {
    padding: 0.4rem 0.6rem;
    font-size: 0.85rem;
    color: var(--color-text);
    cursor: pointer;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/*
 * Vurgulu satır klavye gezinmesinin imlecidir, seçili satır ise o an
 * kayıtlı değer. İkisi ayrı gösterilir: ok tuşlarıyla gezerken seçimin
 * nerede olduğu kaybolmamalı.
 */
.combo-satir.vurgulu {
    background: var(--color-neutral-soft);
}

.combo-satir[aria-selected="true"] {
    color: var(--color-vurgu-metin);
    font-weight: 500;
}

.combo-bos {
    padding: 0.6rem;
    font-size: 0.82rem;
    color: var(--color-muted);
    text-align: center;
}

/* ---------------- Tarih aralığı ---------------- */

/*
 * İki tarih girdisi tek bir çerçeveyi paylaşır: aralık olduğu
 * görünsün. Ayrı ayrı çerçeveli iki kutu, aralarındaki tireye rağmen iki
 * bağımsız filtre gibi okunuyordu.
 */
.tarih-araligi-kutu {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.4rem;
}

.tarih-araligi {
    display: flex;
    align-items: center;
    gap: 0.35rem;
    padding: 0 0.5rem;
    border: 1px solid var(--color-border-strong);
    border-radius: var(--radius-sm);
    background: var(--color-surface);
}

.tarih-araligi:focus-within {
    border-color: var(--color-primary);
}

/* Girdiler kendi çerçevelerini bırakır; çerçeve dıştaki kutuya ait. */
.tarih-araligi .aralik-girdi {
    border: none;
    background: none;
    outline: none;
    padding: 0.35rem 0;
    font-size: 0.85rem;
    color: var(--color-text);
    font-family: inherit;
}

.tarih-araligi .aralik-ayrac {
    color: var(--color-muted);
    flex-shrink: 0;
}

.aralik-hazirlar {
    display: flex;
    flex-wrap: wrap;
    gap: 0.25rem;
}

.aralik-hazir {
    border: 1px solid var(--color-border);
    background: var(--color-surface);
    border-radius: 999px;
    padding: 0.2rem 0.6rem;
    font-size: 0.78rem;
    font-family: inherit;
    color: var(--color-muted);
    cursor: pointer;
    white-space: nowrap;
    transition: background-color 0.12s ease, color 0.12s ease;
}

.aralik-hazir:hover {
    background: var(--color-neutral-soft);
    color: var(--color-text);
}

.aralik-hazir.aktif {
    background: var(--color-primary-soft);
    border-color: var(--color-primary);
    color: var(--color-vurgu-metin);
}

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

/*
 * `margin-left: auto` YALNIZCA filtrelerin içinde kaldığında geçerlidir
 * (şeridi tabloya vermeyen ekranlar): orada düğmeyi filtre bloğunun sağ
 * ucuna iter. Araç grubuna taşındığında (bkz. ui.js → ustSeridiKur) bu
 * itme istenmez — grup zaten sağda ve auto-margin düğmeyi "Sütunlar"dan
 * koparıp aralarında boşluk açardı.
 */
.filtre-serit > .filtre-temizle {
    margin-left: auto;
}

.filtre-temizle {
    border: 0;
    background: transparent;
    padding: 0;
    color: var(--color-primary);
    font-size: 0.85rem;
    font-weight: 500;
    cursor: pointer;
    white-space: nowrap;
}

.filtre-temizle:hover {
    text-decoration: underline;
}

/* ---------- Arama kutusu ---------- */

.arama-kutu {
    position: relative;
    display: inline-flex;
    align-items: center;
}

.arama-kutu .ikon {
    position: absolute;
    left: 0.6rem;
    color: var(--color-muted);
    pointer-events: none;
}

.arama-kutu input {
    height: 34px;
    width: 240px;
    padding: 0 0.7rem 0 2.1rem;
    border: 1px solid var(--color-border-strong);
    border-radius: var(--radius);
    background: var(--color-surface);
}

/* Tarayıcının kendi temizleme çarpısı temayla uyumsuz; gizlenir. */
.arama-kutu input::-webkit-search-cancel-button {
    display: none;
}

/* ---------- Sayfalama ---------- */

.pager-toplam {
    margin-right: auto;
    color: var(--color-text-2);
    font-variant-numeric: tabular-nums;
}

.pager-dugmeler {
    display: flex;
    align-items: center;
    gap: 2px;
}

.pager-dugme {
    display: grid;
    place-items: center;
    min-width: 32px;
    height: 32px;
    padding: 0 0.35rem;
    border: 1px solid transparent;
    border-radius: var(--radius-sm);
    background: transparent;
    color: var(--color-text-2);
    font-size: 0.85rem;
    font-variant-numeric: tabular-nums;
    cursor: pointer;
}

.pager-dugme:hover:not(.aktif):not(:disabled) {
    background: var(--color-surface-2);
    color: var(--color-text);
}

.pager-dugme.aktif {
    background: var(--color-primary);
    border-color: var(--color-primary);
    color: #fff;
    font-weight: 600;
    cursor: default;
}

.pager-dugme:disabled {
    opacity: 0.4;
    cursor: not-allowed;
}

.pager-bosluk {
    padding: 0 0.15rem;
    color: var(--color-muted);
}

/* ---------- Yükleme iskeleti ---------- */

/*
 * İçeriğin şeklini taklit eden gri bloklar. Tek satırlık "Yükleniyor…"
 * metni yerine kullanılır: kullanıcı ne geleceğini bilir ve içerik
 * yerleştiğinde sayfa zıplamaz.
 */
.iskelet {
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
    padding: 1rem;
}

.iskelet-blok {
    display: block;
    height: 44px;
    border-radius: var(--radius);
    background: linear-gradient(
        90deg,
        var(--color-surface-2) 25%,
        var(--color-border) 50%,
        var(--color-surface-2) 75%
    );
    background-size: 400% 100%;
    animation: iskelet-parla 1.4s ease-in-out infinite;
}

.iskelet-kart {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
}

.iskelet-kart .iskelet-blok {
    height: 88px;
}

.iskelet-satir .iskelet-blok {
    height: 20px;
}

@keyframes iskelet-parla {
    0% { background-position: 100% 0; }
    100% { background-position: 0 0; }
}

/*
 * Hareketi azaltılmış modda parlama durur ama bloklar kalır: yükleniyor
 * bilgisi kaybolmamalı, yalnızca hareket etmemeli.
 */
@media (prefers-reduced-motion: reduce) {
    .iskelet-blok {
        animation: none;
    }
}

/*
 * ---------------------------------------------------------------------
 * Bordro detay penceresi
 * ---------------------------------------------------------------------
 *
 * Net ödeme, kazanç ve kesinti tablolarının ALTINDA kendi şeridinde
 * durur. Eskiden bir .notice kutusundaydı ve bir uyarı/bilgilendirme
 * gibi okunuyordu; oysa bordronun sonucu odur ve kalemlerden çıkar.
 */
.bordro-durum {
    margin-bottom: 0.9rem;
}

.bordro-net {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 1rem;
    margin-top: 1.1rem;
    padding: 0.9rem 1rem;
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    background: var(--color-surface-2);
}

.bordro-net-etiket {
    font-size: 0.88rem;
    font-weight: 600;
    color: var(--color-text-2);
}

.bordro-net-tutar {
    font-size: 1.25rem;
    font-variant-numeric: tabular-nums;
}

/*
 * Parametre geçerlilik hücresi: üstte durum rozeti, altında tarih.
 *
 * Tarih rozetin İÇİNDE dururken sığmıyor ve kırpılıyordu; rozet kendi
 * kenarlığıyla tamamlanmış bir bilgi izlenimi verdiği için yarım bir
 * tarih orada özellikle yanıltıcıydı.
 */
.gecerlilik-hucre {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 0.25rem;
    min-width: 0;
}

.gecerlilik-hucre small {
    font-size: 0.75rem;
    color: var(--color-muted);
    white-space: nowrap;
}

/*
 * İki satırlı tanım hücreleri: üstte asıl değer, altında onu tamamlayan
 * ikincil bilgi.
 *
 * Şube konumu ile çalışma düzeni vardiyası aynı sorunu paylaşıyordu:
 * birbirini tamamlayan üç dört alan ayrı sütunlara bölününce kopuk
 * okunuyor, üstelik her satır tipine göre çoğu hücre "—" kalıyordu.
 * Tek hücrede toplandıklarında hangi bilginin hangisini nitelediği
 * görünür oluyor.
 */
.konum-hucre,
.duzen-hucre,
/* Birden çok plaka alt alta: yan yana virgülle dizmek dar sütunda tek
   plakayı bile kırpıyordu. */
.plaka-hucre {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 0.15rem;
    min-width: 0;
}

.konum-hucre small,
.duzen-hucre small {
    font-size: 0.75rem;
    color: var(--color-muted);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    max-width: 100%;
}

/*
 * Katlanabilir alan yardımı.
 *
 * Uzun açıklamalar girdinin kendisinden kat kat yer kaplıyordu (ölçüm:
 * girdi 13px, en uzun ipucu 139px) ve sekiz alanlık bir ayar bölümü
 * 747px sürüyordu. Metin GİZLENMEZ, katlanır: bir ayarın ne işe
 * yaradığını anlatan tek kaynak bu açıklamalar.
 */
.hint-kutu {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 0.15rem;
}

.hint-ac {
    padding: 0;
    border: 0;
    background: none;
    color: var(--color-primary);
    font: inherit;
    font-size: 0.75rem;
    cursor: pointer;
}

.hint-ac:hover {
    text-decoration: underline;
}

/*
 * --focus bir GÖLGE değeridir (0 0 0 3px rgba(...)) ve `outline` kısayoluna
 * verilemez; öyle yazılınca bildirim geçersiz sayılıp outline hiç
 * çizilmiyordu (ölçüm: outlineStyle "none"). Genel kuraldaki halka yeterli,
 * burada yalnızca yarıçap ve boşluk ayarlanır.
 */
.hint-ac:focus-visible {
    outline-offset: 2px;
    border-radius: 3px;
}

/*
 * ---------------------------------------------------------------------
 * Seçim penceresi (Ui.secim)
 * ---------------------------------------------------------------------
 *
 * Her seçenek tıklanabilir bir satırdır ve sonucunu kendi altında yazar.
 * Onay kutusundan farkı: işaretlenmemiş bir kutu ne olacağını söylemez,
 * yalnızca ne olmayacağını ima eder.
 */
.secim-listesi {
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
}

.secim-oge {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    width: 100%;
    padding: 0.85rem 1rem;
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    background: var(--color-surface);
    font: inherit;
    text-align: left;
    cursor: pointer;
}

.secim-oge:hover {
    border-color: var(--color-primary);
    background: var(--color-surface-2);
}

/* Bkz. .hint-ac:focus-visible — `outline: var(--focus)` geçersizdi. */
.secim-oge:focus-visible {
    outline-offset: 2px;
}

/* Sağdaki ok sona itilir; ilk ikon sabit kalır. */
.secim-oge > svg:first-child {
    flex: none;
    color: var(--color-muted);
}

.secim-oge > svg:last-child {
    flex: none;
    margin-left: auto;
    color: var(--color-muted);
}

.secim-metin {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
    min-width: 0;
}

.secim-metin small {
    font-size: 0.8rem;
    color: var(--color-muted);
}

/*
 * Yıkıcı seçenek kırmızı çerçeve ALMAZ: liste içinde tek kırmızı satır,
 * diğerini "güvenli olan" diye işaretleyip kullanıcıyı ona iter. Ayrım
 * üzerine gelindiğinde belli olur.
 */
.secim-oge.yikici:hover {
    border-color: var(--color-danger);
}

/*
 * Gün seçici: düzeltme talebi açılırken "hangi gün?" penceresi.
 *
 * Ay gezgini listenin ÜSTÜNDE ve ondan ayrı durur: liste ay değiştikçe
 * yenilenir, gezgin yerinde kalır. Aynı kutunun içine alınsaydı her
 * yüklemede yeniden çizilir ve tıklanan ok kullanıcının altından
 * kaybolurdu.
 */
.gun-secici-gezgin {
    display: flex;
    justify-content: center;
    margin: 0.75rem 0;
}

/*
 * Liste yüksekliği SINIRLIDIR.
 *
 * Bir ayda 30 kayıt olabilir ve hepsi birden çizilince pencere ekranı
 * aşıyor, alttaki "Vazgeç" düğmesi görünmez oluyordu. Kaydırma listeye
 * verilir, pencereye değil: gezgin ve başlık sabit kalmalı, yoksa
 * kullanıcı ay değiştirmek için yukarı kaydırmak zorunda kalır.
 */
.gun-secici-gezgin + .secim-listesi {
    max-height: 22rem;
    overflow-y: auto;
}

/* ==========================================================================
   Genel bakış ekranı (Faz 13)
   ========================================================================== */

/*
 * Sağ üstteki tarih.
 *
 * Ekranın başlığıyla aynı hizada, sağa yaslı durur: "bugün" diyen bir
 * ekranın hangi güne baktığını söylemesi gerekir — özellikle sekme açık
 * bırakılıp ertesi gün dönüldüğünde.
 */
.ozet-baslik-serit {
    display: flex;
    justify-content: flex-end;
    margin: -2.2rem 0 1rem;
}

.ozet-tarih {
    font-size: 0.9rem;
}

/*
 * Dar ekranda başlığın üstüne binmemeli: negatif üst boşluk, başlığın
 * yanına oturtmak içindir ve yalnızca yan yana sığdıklarında doğrudur.
 */
@media (max-width: 720px) {
    .ozet-baslik-serit {
        margin-top: 0;
        justify-content: flex-start;
    }
}

.ozet-sayaclar {
    margin-bottom: 1.1rem;
}

/* ---------- İki kolonlu düzen ---------- */

.ozet-duzen {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 380px;
    gap: 1.25rem;
    align-items: start;
}

/*
 * Sağ kolonda gösterilecek bir şey yoksa sol kolon tam genişliğe yayılır.
 * Boş bir "dikkat gerektirenler" kutusu ayırmak yer kaplar ama bilgi
 * taşımaz (bkz. ozet.js, K85).
 */
.ozet-duzen.tek-kolon {
    grid-template-columns: minmax(0, 1fr);
}

/*
 * `min-width: 0` şart: ızgara öğesinin örtük en küçük genişliği `auto`dur
 * ve içerikten hesaplanır. Sıfırlanmazsa geniş bir tablo hücresinden
 * taşar ve sol kolon esnemek yerine kendi içeriğine kilitlenir.
 */
.ozet-sol,
.ozet-sag {
    min-width: 0;
}

.ozet-sol > * {
    margin-bottom: 1.1rem;
}

.ozet-sol > *:last-child {
    margin-bottom: 0;
}

/*
 * Dar ekranda alt alta. Sıra korunur: bugünün akışı üstte, bekleyen işler
 * altta — dar ekranda da ilk bakılan yer aynı kalmalı.
 */
@media (max-width: 1100px) {
    .ozet-duzen {
        grid-template-columns: minmax(0, 1fr);
    }
}

/* ---------- Kart içi başlık (tablo şeridinde) ---------- */

.kutu-basligi {
    margin: 0;
    font-size: 0.95rem;
    font-weight: 600;
}

.kutu-basligi + p {
    margin: 0.2rem 0 0;
}

/* ---------- Dikkat gerektirenler ---------- */

.dikkat-kutu {
    padding: 0;
    overflow: hidden;
}

.dikkat-bas {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
    padding: 0.9rem 1rem;
    border-bottom: 1px solid var(--color-border);
}

.dikkat-bas h2 {
    margin: 0;
    font-size: 0.95rem;
    font-weight: 600;
}

.dikkat-liste {
    display: flex;
    flex-direction: column;
}

/*
 * Her satır bir düğmedir: tıklanınca işin yapılacağı ekrana gider.
 * `text-align: left` ve `background: none` gerekli — tarayıcının kendi
 * düğme biçimi ortalar ve gri bir zemin verir.
 */
.dikkat-oge {
    display: flex;
    align-items: center;
    gap: 0.7rem;
    width: 100%;
    padding: 0.75rem 1rem;
    border: 0;
    border-bottom: 1px solid var(--color-border);
    background: none;
    font: inherit;
    color: inherit;
    text-align: left;
    cursor: pointer;
    transition: background-color 0.12s ease;
}

/* Son satır kartın alt kenarını ikinci kez çizmemeli. */
.dikkat-oge:last-child {
    border-bottom: 0;
}

/*
 * Vurgu NÖTR bir tondur, satırın kendi anlam rengi değil.
 *
 * Kırmızı bir satırın üzerine gelince daha da kırmızılaşması, geçici bir
 * durumu (fare nerede) kalıcı bir durumla (bu iş kritik) karıştırır.
 * Aynı ayrım bildirim listesinde de yapılmıştı.
 */
.dikkat-oge:hover,
.dikkat-oge:focus-visible {
    background: var(--color-surface-2);
}

.dikkat-ikon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    width: 34px;
    height: 34px;
    border-radius: 9px;
}

.dikkat-ikon svg {
    width: 17px;
    height: 17px;
}

.dikkat-govde {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
    min-width: 0;
    flex: 1 1 auto;
}

.dikkat-baslik {
    font-size: 0.88rem;
    font-weight: 600;
    line-height: 1.3;
}

.dikkat-aciklama {
    font-size: 0.8rem;
    color: var(--color-muted);
    line-height: 1.35;
}

/*
 * Ok soluk durur ve yalnızca satırın tıklanabilir olduğunu söyler.
 * Renkli olsaydı satırdaki asıl bilgiyle (ikonun anlam rengi) yarışırdı.
 */
.dikkat-ok {
    display: inline-flex;
    flex-shrink: 0;
    color: var(--color-muted);
}

.dikkat-ok svg {
    width: 16px;
    height: 16px;
}

/* ---------- Bugün gelmeyenler ---------- */

.gelmeyen-kutu {
    padding: 0;
    overflow: hidden;
}

.gelmeyen-bas {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 0.75rem;
    padding: 0.9rem 1rem;
    border-bottom: 1px solid var(--color-border);
}

.gelmeyen-bas h2 {
    margin: 0;
    font-size: 0.95rem;
    font-weight: 600;
}

.gelmeyen-bas p {
    margin: 0.2rem 0 0;
}

.gelmeyen-liste {
    display: flex;
    flex-direction: column;
}

/*
 * Satır bir TABLO DEĞİL: tek bilgisi vardiya saati olan bir tabloda
 * sütunlar boş yer kaplıyordu ve asıl soru ("ne yapayım?") satırın
 * dışında kalıyordu. Eylem artık kişinin yanında duruyor.
 */
.gelmeyen-satir {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    padding: 0.7rem 1rem;
    border-bottom: 1px solid var(--color-border);
}

.gelmeyen-satir:last-child {
    border-bottom: 0;
}

/*
 * Kişi bloğu esnemez, vardiya metni esner: ad kısaldığında satır
 * dağılmamalı. `min-width: 0` metnin kırpılabilmesi için gerekli.
 */
.gelmeyen-satir > .kisi {
    flex-shrink: 0;
}

.gelmeyen-vardiya {
    flex: 1 1 auto;
    min-width: 0;
}

.gelmeyen-eylem {
    flex-shrink: 0;
    margin-left: auto;
}

/*
 * Dar ekranda ad ve vardiya alt alta, düğme sağda kalır: düğmeyi de alta
 * almak, listeyi iki katına çıkarıp taranamaz hâle getirirdi.
 */
@media (max-width: 560px) {
    .gelmeyen-satir {
        flex-wrap: wrap;
    }

    .gelmeyen-vardiya {
        flex-basis: 100%;
        order: 3;
    }
}
