/* Safran Labs yönetim paneli — tek stil dosyası.
 *
 * Token'lar ve tipografi sitenin koyu temasından birebir alındı
 * (site/public/index.html içindeki :root bloğu): panel siteye yabancı
 * görünmesin. Font yerel woff2, dış istek yok — nginx CSP'si de buna dayanıyor.
 *
 * ── İki tema ─────────────────────────────────────────────────────────────
 * Her renk token'ı `light-dark(aydınlık, koyu)` ile TEK yerde tanımlı; ikinci
 * bir palet bloğu yok, dolayısıyla bir token'ın iki temasının birbirinden
 * kopması mümkün değil. Hangi tema geçerli, `color-scheme`'in belirlediği:
 *
 *   :root                       → `light dark`  (işletim sisteminin tercihi)
 *   :root[data-theme='light']   → `light`       (kullanıcı seçti)
 *   :root[data-theme='dark']    → `dark`        (kullanıcı seçti)
 *
 * `data-theme` özniteliğini `assets/theme.js` ilk boyamadan önce koyar.
 * `color-scheme` ayrıca kaydırma çubuğu ve açılır listeler gibi tarayıcının
 * kendi çizdiği parçaları da temaya uyduruyor — bedava gelen kısım.
 *
 * `light-dark()` yalnızca RENK değerlerinde çalışır. Renk olmayan değerler için
 * (filtre miktarı, iki görsel arasında geçiş) tek bir anahtar var: `--is-dark`
 * 1/0. Tema koşulu yalnızca onun tanımında yazılı — yeni bir @media bloğu
 * eklemek yerine `--is-dark`'ı kullanın.
 */

@font-face {
  font-family: 'Archivo';
  src: url('archivo-latin.woff2') format('woff2');
  font-weight: 100 900;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191,
    U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Archivo';
  src: url('archivo-latin-ext.woff2') format('woff2');
  font-weight: 100 900;
  font-display: swap;
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+1E00-1EFF, U+2020,
    U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

:root {
  color-scheme: light dark;

  /*              aydınlık   koyu (site paleti) */
  --bg: light-dark(#fbfaf9, #17171b);
  --surface: light-dark(#f2efec, #212127);
  --text: light-dark(#1b1a1f, #f2eff5);
  --divider: light-dark(rgba(27, 26, 31, 0.16), rgba(242, 239, 245, 0.14));

  /* Aydınlık temada marka kırmızısı beyaz zeminde koyulaştırıldı: #f32e00 ile
     beyaz metnin kontrastı 4.3:1'de kalıyor, düğme yazısı okunmuyor. */
  --accent: light-dark(#d92800, #f32e00);
  --accent-100: light-dark(#ffece6, #351d18);
  --accent-600: light-dark(#b81f00, #ff5330);
  --accent-700: light-dark(#bd2400, #ff7c5c);
  /* accent-800 = accent-100 zemininde okunan ton; koyuda açılır, aydınlıkta koyulaşır. */
  --accent-800: light-dark(#8a2100, #ffab93);
  --neutral-100: light-dark(#eae8e4, #2c2c33);
  --neutral-300: light-dark(#c9c6c1, #414149);
  --neutral-700: light-dark(#7a7780, #b0aeb8);
  --neutral-800: light-dark(#3b3941, #d6d4da);
  /* Şeritteki kalın yazı: her iki temada da gövdeden bir adım daha kuvvetli. */
  --strong: light-dark(#0d0c11, #ffffff);

  --muted: color-mix(in srgb, var(--text) 62%, transparent);
  --sidebar-w: 232px;
  /* Ayarlar alt menüsü — kenar çubuğunun sağındaki ikinci sütun. */
  --radius: 4px;
  --heading: 'Archivo', system-ui, sans-serif;

  /* Renk OLMAYAN tek tema anahtarı: `light-dark()` sayı kabul etmiyor, o yüzden
     "koyu tema mı?" sorusu bir kez burada 1/0 olarak yazılıyor ve ona ihtiyaç
     duyan her kural bunu kullanıyor (amblem filtresi, logo/negatif geçişi).
     Üç yerde tekrarlanan tema koşulu böylece tek yerde kalıyor. */
  --is-dark: 1;
  /* Amblem koyu zeminde beyaza çevrilir, aydınlıkta siyah kalır. */
  --emblem-invert: var(--is-dark);

  /* Logosu olmayan projenin baş harfi — plaka değil, ince çerçeveli bir yer
     tutucu (bkz. `.mark b`). */
  --mark-ink: light-dark(#8b8894, #7d7a86);
}

:root[data-theme='light'] {
  color-scheme: light;
  --is-dark: 0;
}
:root[data-theme='dark'] {
  color-scheme: dark;
}
@media (prefers-color-scheme: light) {
  :root:not([data-theme='dark']) {
    --is-dark: 0;
  }
}

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

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: 'Archivo', system-ui, sans-serif;
  font-size: 15px;
  line-height: 26px;
  -webkit-font-smoothing: antialiased;
}

a {
  color: var(--accent-700);
}
h1,
h2,
h3 {
  font-family: var(--heading);
  font-weight: 800;
  letter-spacing: -0.015em;
  margin: 0;
}

/* ── İskelet ───────────────────────────────────────────────────────────── */
.shell {
  display: grid;
  grid-template-columns: var(--sidebar-w) minmax(0, 1fr);
  min-height: 100vh;
}

.sidebar {
  background: var(--surface);
  border-right: 2px solid var(--divider);
  padding: 28px 0;
  display: flex;
  flex-direction: column;
  gap: 32px;
  position: sticky;
  top: 0;
  height: 100vh;
}

/* Telefonun üst barı ve çekmece perdesi: kabuk ikisini her sayfada üretiyor
   (kabuk.js), masaüstünde ikisi de YOK. Varsayılan `display: none` burada —
   `<header>` ve `<div>` aksi hâlde geniş ekranda da çizilirdi. Görünür hâlleri
   `@media (max-width: 860px)` bloğunda. */
.topbar,
.nav-scrim {
  display: none;
}
/* Üst barın yüksekliği bir TOKEN: sayfa İÇİNDEKİ yapışkan şeritler (kılavuz
   sayfalarının içindekiler şeridi — `urun.css`) onun altına oturmak için bu
   değeri okuyor. Masaüstünde üst bar yok, o yüzden 0. Ölçü: 8px dolgu + 44px
   düğme + 8px dolgu + 2px kenar. Üst barın dolgusu/düğmesi değişirse burası da
   değişir — iki yerde ayrı sayı tutmamak için token. */
:root {
  --topbar-h: 0px;
}

.brand {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 0 24px;
}
.brand img {
  width: 30px;
  height: auto;
  display: block;
  /* Kaynak amblem gri; koyu zeminde soluk kalıyor. brightness(0) tüm opak
     pikselleri siyaha çeker, invert onları beyaza — alfa korunduğu için çizimin
     kendisi bozulmaz, yalnızca rengi beyaz olur. Aydınlık temada invert 0:
     siyah amblem açık zeminde olduğu gibi duruyor. */
  filter: brightness(0) invert(var(--emblem-invert));
  opacity: 0.92;
}
.brand b {
  font-family: var(--heading);
  font-weight: 800;
  font-size: 15px;
  line-height: 18px;
  display: block;
  /* Gizle düğmesi markanın sağına girdi: sarma olursa "SAFRAN LABS" iki satıra
     bölünüyor ve amblemle hizası kayıyor. */
  white-space: nowrap;
}
.brand span {
  display: block;
  font-size: 11px;
  line-height: 14px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted);
}

/* ── Ana menü ──────────────────────────────────────────────────────────────
   Üç grup ve on iki madde bir arada durunca çubuk okunmaz olmuştu; düzeltme üç
   parça (2026-08-06): gruplar KATLANIYOR, satırlar arasına ayırıcı çizgi girdi
   ve her alt maddeye ikon kondu. Satır yüksekliği de düştü (10px → 6px dolgu):
   listeyi kısaltmak ayırıcı çizgilerin işe yaraması için şart, yoksa çubuk
   çizgi yığınına dönüyor. */
.nav {
  display: grid;
  gap: 0;
}
.nav a {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 7px 20px 7px 22px;
  border-left: 2px solid transparent;
  border-top: 1px solid transparent;
  color: var(--muted);
  text-decoration: none;
  font-size: 12.5px;
  /* Satır yüksekliği AÇIKÇA yazılı: gövdeden miras alınan 1.7 değeri satırı
     41px'e çıkarıyordu, oysa gezinme listesinde okunan şey satırın kendisi. */
  line-height: 18px;
  letter-spacing: 0.01em;
  font-weight: 600;
}
.nav a:hover {
  color: var(--text);
  background: color-mix(in srgb, var(--text) 4%, transparent);
}
.nav a[aria-current='page'] {
  color: var(--text);
  border-left-color: var(--accent);
  background: color-mix(in srgb, var(--accent) 10%, transparent);
}
/* İkon satırın rengini alıyor (currentColor) ama bir kademe soluk: asıl bilgi
   metin, ikon onu tanımaya yardım eden ikincil işaret. Seçili satırda tam
   opaklığa çıkıyor. */
.nav .ico {
  flex: 0 0 auto;
  opacity: 0.6;
}
.nav a[aria-current='page'] .ico,
.nav a:hover .ico {
  opacity: 1;
}

/* Grup başlığı: bağlantı değil, KATLAMA düğmesi (bkz. kabuk.js → navItem).
   Grubun gideceği bir yer yok; işi altındaki maddeleri açıp kapamak. */
.nav .nav-group {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  background: none;
  border: 0;
  border-top: 2px solid var(--divider);
  border-left: 2px solid transparent;
  padding: 9px 20px 9px 22px;
  font: inherit;
  font-size: 11px;
  line-height: 15px;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  font-weight: 700;
  color: var(--muted);
  text-align: left;
  cursor: pointer;
}
.nav > a {
  border-top-color: var(--divider);
  border-top-width: 2px;
}
.nav > .nav-group:first-child,
.nav > a:first-child {
  border-top: 0;
}
.nav .nav-group:hover {
  color: var(--text);
  background: color-mix(in srgb, var(--text) 4%, transparent);
}
.nav .nav-group[data-here] {
  color: var(--text);
}
.nav .nav-group:focus-visible {
  outline: none;
  box-shadow: inset 0 0 0 2px color-mix(in srgb, var(--accent) 45%, transparent);
}
/* Ok sağa bakar, grup açıkken aşağıya döner — kapalıyken "burada devamı var". */
.nav .nav-group .ico {
  margin-left: auto;
  opacity: 0.5;
  transition: transform 0.14s ease;
}
.nav .nav-group[aria-expanded='true'] .ico {
  transform: rotate(90deg);
}
.nav-children {
  display: grid;
  gap: 0;
}
/* `display: grid`, `[hidden]`in getirdiği `display: none`u EZER — kapalı grubun
   maddeleri açık kalırdı — `display` yazan her sınıf için `[hidden]` kuralını da yaz. */
.nav-children[hidden] {
  display: none;
}
/* Alt maddeler girintili ve ARALARINDA ince çizgi: grup ayrımı kalın (2px),
   satır ayrımı ince (1px) — hiyerarşi çizginin kalınlığından da okunuyor. */
.nav a.nav-sub {
  padding-left: 22px;
  padding-right: 16px;
  border-top-color: color-mix(in srgb, var(--divider) 60%, transparent);
}
.nav-children > a.nav-sub:first-child {
  border-top-color: transparent;
}

/* Gezinmeyi gizleyen düğme markanın sağında; geri açan düğme ekranın sol üst
   köşesinde (bkz. .nav-opener). */
.nav-hide {
  margin-left: auto;
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: none;
  border: 0;
  padding: 4px;
  border-radius: var(--radius);
  color: var(--muted);
  cursor: pointer;
}
.nav-hide:hover {
  color: var(--text);
  background: color-mix(in srgb, var(--text) 6%, transparent);
}
.nav-hide:focus-visible {
  outline: none;
  box-shadow: inset 0 0 0 2px color-mix(in srgb, var(--accent) 45%, transparent);
}

/* ── Gezinme gizli ─────────────────────────────────────────────────────────
   Tek anahtar (`<html data-nav="hidden">`) hem kenar çubuğunu hem de kabuğun
   ızgarasındaki alt menü sütunlarını düşürüyor; içerik tam genişliğe yayılıyor.
   Geri açan düğme SABİT köşede duruyor: gizlemek geri dönüşü olmayan bir kapı
   olmasın. `main`in sol dolgusu o düğmeye yer açacak kadar büyüyor. */
html[data-nav='hidden'] .sidebar {
  display: none;
}
html[data-nav='hidden'] .shell {
  grid-template-columns: minmax(0, 1fr);
}
html[data-nav='hidden'] .main {
  padding-left: 64px;
}
.nav-opener {
  position: fixed;
  top: 16px;
  left: 14px;
  z-index: 40;
  display: none;
  align-items: center;
  justify-content: center;
  padding: 7px;
  background: var(--surface);
  border: 2px solid var(--divider);
  border-radius: var(--radius);
  color: var(--muted);
  cursor: pointer;
}
html[data-nav='hidden'] .nav-opener {
  display: inline-flex;
}
.nav-opener:hover {
  color: var(--text);
  border-color: color-mix(in srgb, var(--accent) 45%, var(--divider));
}

/* ── Tema anahtarı ─────────────────────────────────────────────────────── */
/* Kenar çubuğunun dibinde: gezinme değil, görünüm ayarı. `margin-top: auto`
   burada; alt bilgi de onun arkasından sürüklendiği için ikisi birlikte
   aşağıya yapışıyor. Etiketi ve ikonu theme.js seçiyor — öznitelik konmadan
   düğme gizli, çünkü etiketsiz bir kutu hiçbir şey anlatmaz. */
.theme-toggle {
  margin: auto 24px 0;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  align-self: flex-start;
  background: none;
  border: 2px solid var(--divider);
  border-radius: var(--radius);
  padding: 7px 12px;
  color: var(--muted);
  font: inherit;
  font-size: 11.5px;
  line-height: 16px;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  font-weight: 600;
  white-space: nowrap;
  cursor: pointer;
}
.theme-toggle:not([data-mode]) {
  display: none;
}
.theme-toggle:hover {
  color: var(--text);
  border-color: var(--neutral-300);
}
.theme-toggle:focus-visible {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 25%, transparent);
}
.theme-toggle svg {
  display: none;
  flex: 0 0 auto;
}
/* Gösterilen ikon, basınca GİDİLECEK temanın ikonu. */
.theme-toggle[data-mode='dark'] .i-sun,
.theme-toggle[data-mode='light'] .i-moon {
  display: block;
}

.sidebar footer {
  padding: 0 24px;
  font-size: 11px;
  line-height: 17px;
  color: var(--muted);
}
.sidebar footer a {
  color: var(--muted);
}

.main {
  padding: 40px clamp(24px, 4vw, 56px) 72px;
  max-width: 1080px;
}

/* ── Sayfa başlığı ─────────────────────────────────────────────────────── */
.eyebrow {
  display: block;
  font-size: 12px;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--accent-700);
  margin-bottom: 10px;
}
/* Kırıntıdaki proje adı marka yazımını korur: `text-transform: uppercase` tr
   yerelinde "QRindex"i "QRİNDEX" yapıyor (i → İ) ve marka yanlış görünüyor. */
.eyebrow #crumb {
  text-transform: none;
  letter-spacing: 0.04em;
}
.page-head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 20px;
  flex-wrap: wrap;
  margin-bottom: 8px;
}
.page-head h1 {
  font-size: clamp(28px, 3vw, 38px);
  line-height: 1.08;
  margin-left: -0.04em;
}
.lede {
  color: var(--muted);
  max-width: 62ch;
  margin: 6px 0 32px;
}

/* ── Durum şeridi ──────────────────────────────────────────────────────── */
/* Panelin şu an ne YAPMADIĞINI söyler. Çalışmayan bir "Yayınla" düğmesi
   koymak yerine durumu açıkça yazıyoruz. */
.band {
  display: flex;
  gap: 12px;
  align-items: flex-start;
  background: var(--accent-100);
  border-left: 3px solid var(--accent);
  border-radius: 0 var(--radius) var(--radius) 0;
  padding: 14px 18px;
  margin-bottom: 32px;
  font-size: 13.5px;
  line-height: 22px;
  /* Gövde metni salt turuncu olunca uyarı fazla yüksek sesle konuşuyor; vurgu
     kalın kısımda ve sol şeritte kalsın. */
  color: color-mix(in srgb, var(--accent-800) 45%, var(--text));
}
/* Yazar kuralındaki `display: flex`, `[hidden]`'ın tarayıcı varsayılanını
   (display: none) EZER — koşullu bir şerit (ör. ayarlar sayfasındaki taslak
   uyarısı) `hidden` ile gizlenemez, boş bir kutu olarak görünürdü. Aynı tuzak
   `.hint` için de yazılı (bkz. dosyanın sonu). */
.band[hidden] {
  display: none;
}
.band strong {
  color: var(--strong);
}
.band a {
  color: var(--accent-800);
}
.band svg {
  flex: 0 0 auto;
  margin-top: 3px;
}

/* ── Sayaç kutuları ────────────────────────────────────────────────────── */
.stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 2px;
  background: var(--divider);
  border: 2px solid var(--divider);
  margin-bottom: 40px;
}
.stat {
  background: var(--bg);
  padding: 18px 20px;
}
.stat b {
  font-family: var(--heading);
  font-weight: 800;
  font-size: 34px;
  line-height: 1;
  display: block;
  font-feature-settings: 'tnum' 1;
}
.stat span {
  display: block;
  font-size: 11.5px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
  margin-top: 8px;
}

/* ── Etiketler ─────────────────────────────────────────────────────────── */
.tag {
  display: inline-block;
  padding: 3px 10px;
  border-radius: 100px;
  font-size: 11.5px;
  line-height: 18px;
  font-weight: 600;
  letter-spacing: 0.02em;
  white-space: nowrap;
}
.tag-yayinda {
  background: var(--accent-100);
  color: var(--accent-800);
}
.tag-mutfakta {
  background: var(--neutral-100);
  color: var(--neutral-800);
}

/* ── Proje listesi ─────────────────────────────────────────────────────── */
.list {
  border-top: 2px solid var(--divider);
}
/* Sütunlar: numara · logo · ad + açıklama. Ayrı bir "eylem" sütunu YOK: satırın
   kendisi zaten proje sayfasına giden bir bağlantı, sağdaki "Düzenle →" aynı
   şeyi ikinci kez söylüyordu. Logo kendi sütununda:
   ada yapıştırılsa oranları farklı logolar adları farklı yerden başlatırdı.
   Logo sütunu 40px'lik bir ikon yuvası değil, gerçek bir sütun — logolar
   projelerin kimliği, tam hâlleriyle okunmaları gerekiyor. Ölçü `minmax`, `vw`
   DEĞİL: sütun yer varsa 188px'e (en yatık logonun 44px yükseklikte kapladığı
   genişlik) açılıyor, ana kolon daraldığında 112px'e kadar çekiliyor. `vw` bunu
   yapamıyordu — ayarlar sütunu açıldığında ada yer bırakmıyordu. */
.row {
  display: grid;
  grid-template-columns: 44px minmax(112px, 188px) minmax(0, 1fr);
  gap: 4px 20px;
  align-items: center;
  padding: 20px 4px;
  border-bottom: 2px solid var(--divider);
  text-decoration: none;
  color: inherit;
}
.row:hover {
  background: color-mix(in srgb, var(--text) 4%, transparent);
}
.row-no {
  font-family: var(--heading);
  font-weight: 800;
  font-size: 14px;
  color: var(--accent);
  font-feature-settings: 'tnum' 1;
}
.row-name {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
}
.row-name h2 {
  font-size: 20px;
  line-height: 24px;
}
.row-desc {
  grid-column: 3;
  color: var(--muted);
  font-size: 13.5px;
  line-height: 21px;
  margin: 4px 0 0;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.row-links {
  grid-column: 3;
  display: flex;
  gap: 14px;
  flex-wrap: wrap;
  font-size: 12.5px;
  color: var(--accent-700);
  margin-top: 6px;
}

/* Proje işareti — projenin kendi sitesinin başlık logosu (bkz. panel.js
   `projectMark`). Üç karar:

   1. PLAKA YOK. Logo doğrudan satırın zemininde duruyor; beyaz bir kutu hem
      satır ritmini bozuyor hem de logoyu "ikon" boyutuna hapsediyordu.
   2. TAM HÂLİ görünüyor: `contain` + sola yaslı, kırpma yok. Sütun geniş
      (bkz. `.row`), en yatık logo (STK Kurumsal 5.6:1) bile sığıyor.
   3. Koyu tema için `-negatif.png` varsa ona geçiliyor. Geçiş `opacity` ile,
      `--is-dark` üzerinden: iki görsel üst üste duruyor, hangisinin görüneceğini
      tek sayı belirliyor (`display` bir sayıyla anahtarlanamaz).

   Harf en altta: logo 404 alıp DOM'dan düşerse kendiliğinden ortaya çıkıyor,
   kutunun ölçüsü değişmediği için düzen kaymıyor. */
/* Bir projenin markaları alt alta (Seteka · STK Kurumsal). Tek markalı projede
   yığın tek çocuklu — görünüm değişmiyor. İki logo varken her biri kısalıyor:
   44px + 44px satırı gereksiz uzatıyordu, 34px ikisini de okunur bırakıp satır
   yüksekliğini metnin yanında tutuyor. */
.mark-stack {
  display: grid;
  gap: 10px;
  align-content: center;
  min-width: 0;
}
.mark-stack:has(.mark + .mark) .mark {
  height: 34px;
}
.mark {
  position: relative;
  display: grid;
  place-items: center start;
  width: 100%;
  height: 44px;
}
/* Logosu olmayan proje: ince çerçeveli, plakasız bir yer tutucu. Logo yüklenince
   (`[data-logo]`) tamamen gizleniyor — üstünde saydam bir logo dururken çerçeve
   sızmasın diye görünürlük değil `display` ile. */
.mark b {
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  border: 2px solid var(--divider);
  border-radius: 9px;
  font-family: var(--heading);
  font-weight: 800;
  font-size: 16px;
  line-height: 1;
  color: var(--mark-ink);
}
.mark[data-logo] b {
  display: none;
}
.mark img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: contain;
  object-position: left center;
}
/* Negatif yalnızca koyu temada; yoksa dosya 404 alıp DOM'dan düşmüş olur. */
.mark .logo-neg {
  opacity: var(--is-dark);
}
/* Negatifi OLAN projede aydınlık temada asıl logo görünür, koyu temada çekilir.
   Negatifi olmayanda bu kural hiç devreye girmez: aynı logo iki temada da kalır. */
.mark[data-neg] .logo-base {
  opacity: calc(1 - var(--is-dark));
}

.empty {
  padding: 48px 4px;
  color: var(--muted);
  border-bottom: 2px solid var(--divider);
}

/* ── Form ──────────────────────────────────────────────────────────────── */
.cols {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 420px);
  gap: clamp(28px, 4vw, 56px);
  align-items: start;
}

.field {
  display: block;
  margin-bottom: 22px;
}
.field > span {
  display: block;
  font-size: 11.5px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
  font-weight: 600;
  margin-bottom: 7px;
}
.field .hint {
  display: block;
  font-size: 12px;
  line-height: 18px;
  color: var(--muted);
  letter-spacing: 0;
  text-transform: none;
  font-weight: 400;
  margin-top: 6px;
}

/* Site kimliği formu (Ayarlar). Proje formundaki `.cols` gibi iki kolonlu
   değil: burada önizlenecek bir kart yok, alanlar tek sütun ama geniş ekranda
   ikiye bölünüyor — on bir kısa alanı alt alta dizmek sayfayı gereksiz uzatır. */
.site-form {
  max-width: 720px;
}
/* Ölçü `@media`, `@container` DEĞİL: `container: panel` yalnızca proje
   sayfasında tanımlı (`.tab-panels`), Ayarlar sayfasında kapsayıcı yok ve
   container sorgusu hiç eşleşmezdi — bu tuzağa daha önce de düşülmüştü
   (bkz. tasks/lessons.md, "kapsayıcısı olmayan sayfada @container"). */
@media (min-width: 1040px) {
  .site-form {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    column-gap: 20px;
  }
  /* Uzun metin ve eylem satırı tam genişlikte. */
  .site-form > label:has(textarea),
  .site-form > .actions {
    grid-column: 1 / -1;
  }
}

/* ── Marka logosu kutuları (proje formu) ───────────────────────────────────
   Marka başına iki yuva: renkli ve koyu tema. Önizleme kutusu kasten KÜÇÜK —
   burada logonun kalitesi değil VARLIĞI sınanıyor; büyük önizleme formu
   uzatırdı. Zemin şeffaf logolarda kontrast versin diye nötr. */
.logo-marka {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 6px;
  padding: 12px 0;
  border-bottom: 1px solid var(--divider);
}
.logo-marka:last-child {
  border-bottom: 0;
}
.logo-marka > b {
  font-size: 12px;
  font-family: ui-monospace, 'SF Mono', Menlo, monospace;
  color: var(--muted);
}
.logo-slot {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 64px auto auto;
  align-items: center;
  gap: 10px;
}
.logo-slot-ad {
  display: grid;
  font-size: 12px;
  color: var(--text);
}
.logo-slot-ad code {
  font-size: 11px;
  color: var(--muted);
}
.logo-slot-on {
  display: grid;
  place-items: center;
  height: 34px;
  border: 1px dashed var(--divider);
  border-radius: 4px;
  background: var(--surface);
}
.logo-slot-on.var {
  border-style: solid;
}
.logo-slot-on img {
  max-width: 56px;
  max-height: 26px;
  object-fit: contain;
}
.logo-slot-on i {
  font-size: 11px;
  font-style: normal;
  color: var(--muted);
}
/* Dosya seçici bir <label> içinde gizli input: `.btn` görünümünü koruyor. */
.logo-slot label.btn {
  cursor: pointer;
}
@container panel (max-width: 620px) {
  .logo-slot {
    grid-template-columns: minmax(0, 1fr) auto auto;
  }
  .logo-slot-on {
    grid-column: 1 / -1;
    order: 3;
  }
}

/* Onay kutulu alan (ör. "yalnızca panelde görünsün"). `.field`in blok başlığı
   burada yanlış olurdu: okunacak şey kutunun ne anlama geldiği, üstünde duran
   bir etiket değil — bu yüzden yazı kutunun SAĞINDA, ipucu ikisinin altında. */
.field-switch {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: center;
  gap: 0 10px;
}
.field-switch input {
  width: 18px;
  height: 18px;
  margin: 0;
  accent-color: var(--accent);
}
.field-switch > span:not(.hint) {
  margin-bottom: 0;
  font-size: 14px;
  font-weight: 500;
  letter-spacing: 0;
  text-transform: none;
  color: var(--text);
}
.field-switch .hint {
  grid-column: 2;
}

input[type='text'],
input[type='url'],
input[type='password'],
textarea,
select {
  width: 100%;
  background: var(--surface);
  color: var(--text);
  border: 2px solid var(--divider);
  border-radius: var(--radius);
  padding: 10px 12px;
  font: inherit;
  font-size: 14px;
  line-height: 24px;
}
textarea {
  resize: vertical;
  min-height: 96px;
}
input:focus-visible,
textarea:focus-visible,
select:focus-visible {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 25%, transparent);
}
select {
  appearance: none;
  background-image: linear-gradient(45deg, transparent 50%, var(--neutral-700) 50%),
    linear-gradient(135deg, var(--neutral-700) 50%, transparent 50%);
  background-position:
    calc(100% - 19px) calc(50% + 1px),
    calc(100% - 13px) calc(50% + 1px);
  background-size: 6px 6px;
  background-repeat: no-repeat;
  padding-right: 38px;
}

.pair {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.4fr) auto;
  gap: 8px;
  margin-bottom: 8px;
  align-items: center;
}

.btn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  border: 2px solid transparent;
  border-radius: var(--radius);
  padding: 9px 16px;
  font: inherit;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.02em;
  cursor: pointer;
  text-decoration: none;
  background: none;
  color: var(--text);
}
.btn-primary {
  background: var(--accent);
  color: #fff;
}
.btn-primary:hover {
  background: var(--accent-600);
}
.btn-ghost {
  border-color: var(--divider);
}
.btn-ghost:hover {
  background: color-mix(in srgb, var(--text) 7%, transparent);
}
.btn-mini {
  padding: 6px 10px;
  font-size: 12px;
  border-color: var(--divider);
  color: var(--muted);
}
.btn-mini:hover {
  color: var(--text);
  border-color: var(--neutral-300);
}
.actions {
  display: flex;
  gap: 12px;
  flex-wrap: wrap;
  margin-top: 32px;
  padding-top: 24px;
  border-top: 2px solid var(--divider);
}

/* ── Önizleme ──────────────────────────────────────────────────────────── */
/* Kartı sitenin kendi ölçüleriyle çizer — panelde gördüğün, yayında göreceğin. */
.preview {
  position: sticky;
  top: 40px;
}
.preview > span {
  display: block;
  font-size: 11.5px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
  font-weight: 600;
  margin-bottom: 10px;
}
/* Önizleme HER İKİ TEMADA DA KOYU: site tek temalı (koyu), dolayısıyla panel
   aydınlıkken kartı aydınlık göstermek yalan olur — "yayında böyle görünecek"
   iddiasını bozar. Token'lar burada birebir site değerleriyle yeniden
   tanımlanıyor, alt öğelere miras kalıyor. */
.preview-frame {
  color-scheme: dark;
  --bg: #17171b;
  --text: #f2eff5;
  --divider: rgba(242, 239, 245, 0.14);
  --accent: #f32e00;
  --accent-100: #351d18;
  --accent-700: #ff7c5c;
  --accent-800: #ffab93;
  --neutral-100: #2c2c33;
  --neutral-800: #d6d4da;

  border: 2px solid var(--divider);
  border-radius: var(--radius);
  padding: 26px 24px;
  background: var(--bg);
  color: var(--text);
}
.pv-card {
  display: grid;
  grid-template-columns: 40px minmax(0, 1fr);
  gap: 12px 20px;
  align-items: baseline;
}
.pv-no {
  font-family: var(--heading);
  font-weight: 800;
  font-size: 14px;
  line-height: 26px;
  margin: 0;
  font-feature-settings: 'tnum' 1;
  position: relative;
}
.pv-no::before {
  content: '';
  position: absolute;
  left: -14px;
  top: 8px;
  width: 8px;
  height: 8px;
  background: var(--accent);
}
.pv-body {
  display: grid;
  gap: 12px;
}
.pv-title {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
}
.pv-title h3 {
  font-size: 24px;
  line-height: 26px;
}
.pv-title h3.dim {
  color: color-mix(in srgb, var(--text) 55%, transparent);
}
.pv-desc {
  font-size: 14.5px;
  line-height: 26px;
  margin: 0;
  color: color-mix(in srgb, var(--text) 78%, transparent);
}
.pv-links {
  display: flex;
  gap: 20px;
  flex-wrap: wrap;
  font-size: 13px;
  margin: 0;
}
.pv-links a {
  color: var(--accent-700);
  font-weight: 600;
  text-decoration: none;
}

/* ── Tanım listesi (ayarlar) ───────────────────────────────────────────── */
.defs {
  border-top: 2px solid var(--divider);
  margin: 0 0 36px;
}
.defs > div {
  display: grid;
  grid-template-columns: minmax(140px, 220px) minmax(0, 1fr);
  gap: 8px 24px;
  padding: 14px 4px;
  border-bottom: 2px solid var(--divider);
}
.defs dt {
  font-size: 11.5px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
  font-weight: 600;
  line-height: 24px;
}
.defs dd {
  margin: 0;
  overflow-wrap: anywhere;
}
/* Bir tanımın altındaki çok satırlı değer (proje detayındaki bağlantı ve
   kuruluş listeleri). Madde işareti yok: satırlar zaten etiketli adresler. */
.defs-liste {
  list-style: none;
  margin: 0;
  padding: 0;
}
.defs-liste li + li {
  margin-top: 4px;
}

/* `pre.json` ve `.steps` 2026-09-01'de kalktı: ikisi de Ayarlar sayfasındaki
   "JSON'u kopyala → dosyaya yapıştır → deploy.sh" yönergesine aitti, o akış
   panelin kendi yazma yoluna dönüştü (assets/veri.js). */
p code,
dd code {
  background: var(--surface);
  border: 1px solid var(--divider);
  border-radius: 3px;
  padding: 1px 6px;
  font-family: ui-monospace, 'SF Mono', Menlo, monospace;
  font-size: 12.5px;
}

.toast {
  position: fixed;
  bottom: 24px;
  left: 50%;
  transform: translateX(-50%) translateY(8px);
  background: var(--text);
  color: var(--bg);
  font-size: 13px;
  font-weight: 600;
  padding: 10px 18px;
  border-radius: 100px;
  opacity: 0;
  transition:
    opacity 0.18s,
    transform 0.18s;
  pointer-events: none;
}
.toast.on {
  opacity: 1;
  transform: translateX(-50%) translateY(0);
}

/* ── Sekmeler: proje sayfasının sol sütunu ─────────────────────────────── */
/* Görünüm bölümlerinin kapsayıcısı. Görünüm seçimi 2026-08-06'da kenar
   çubuğuna, proje seçimi ikinci sütuna taşındı (transpoze gezinme) — sayfanın
   içinde artık şerit yok, `main` sadece seçili bölümü gösteriyor.

   Alan bir CSS KAPSAYICISI: içindeki iki kolonlu düzenler (form + kart
   önizlemesi) viewport'a değil buraya bakıyor. Sütunlar 2026-09-01'de kalktı
   ama kapsayıcı KALIYOR: kenar çubuğu gizlenebiliyor ve alan hâlâ viewport'la
   aynı şey değil (aynı gerekçe `vw` yasağında: CLAUDE.md §5). */
.tab-panels {
  container: panel / inline-size;
  min-width: 0;
  margin-top: 22px;
}

/* ── Sayfa şeritleri: proje seçimi + görünüm sekmeleri ─────────────────────
   2026-09-01: ikisi de kenar çubuğundan/sütundan buraya döndü (bkz. proje.html).
   Yatay kaydırma bilinçli: proje sayısı artınca şerit uzuyor, sarmak yerine
   kayıyor — sarılan bir "sekme şeridi" sekme olmaktan çıkar. Kaydırma çubuğu
   ince ve şeridin altında; `scroll-snap` YOK, çünkü şerit bir galeri değil,
   içindeki hedefe tıklanacak bir liste. */
.proje-serit,
.gorunum-serit {
  display: flex;
  gap: 4px;
  overflow-x: auto;
  /* `overflow-x: auto` yazınca öteki eksen de `visible` kalamaz, `auto`ya
     düşer — sekme şeridinde kaydıracak bir şey olmadığı hâlde ince bir DİKEY
     çubuk çıkıyordu. Açıkça kapatılıyor. */
  overflow-y: hidden;
  overscroll-behavior-x: contain;
  scrollbar-width: thin;
}
.proje-serit {
  align-items: center;
  gap: 6px;
  padding-bottom: 10px;
  margin-top: 18px;
  border-bottom: 2px solid var(--divider);
}
/* Ayırıcı çizgi `border` DEĞİL zemine çizilmiş 2px'lik bir şerit: seçili
   sekmenin alt çizgisi onun ÜSTÜNE binecek. Border olsaydı binmesi için negatif
   kenar boşluğu gerekirdi, o da `overflow-y: hidden` altında kırpılırdı. */
.gorunum-serit {
  align-items: stretch;
  margin-top: 12px;
  background: linear-gradient(var(--divider), var(--divider)) 0 100% / 100% 2px no-repeat;
}

/* Proje çipi: logo + ad. Logo `projectMark(p, {limit: 1})` — şeritte yalnızca
   ilk marka, ikisini alt alta koymak satırı yükseltirdi. */
.serit-chip {
  display: flex;
  align-items: center;
  gap: 8px;
  flex: 0 0 auto;
  max-width: 210px;
  padding: 7px 12px 7px 8px;
  border: 2px solid transparent;
  border-radius: var(--radius);
  color: var(--muted);
  font-size: 13px;
  font-weight: 500;
  text-decoration: none;
  white-space: nowrap;
}
.serit-chip > span {
  overflow: hidden;
  text-overflow: ellipsis;
}
.serit-chip:hover {
  color: var(--text);
  background: color-mix(in srgb, var(--text) 6%, transparent);
}
.serit-chip.on {
  color: var(--text);
  border-color: var(--divider);
  background: var(--surface);
}
/* Çipteki logo kutusu liste satırındakinden küçük: orada gerçek bir sütun var,
   burada tek satırlık bir şerit. */
.serit-chip .mark-stack {
  flex: 0 0 auto;
}
.serit-chip .mark {
  width: 26px;
  height: 22px;
}
.serit-chip .mark b {
  font-size: 12px;
}
/* `panelOnly` projeler listede "Sitede listelenmez" rozeti taşıyor; şeritte
   yer yok, o yüzden sessiz bir nokta + `title`. */
.chip-nokta {
  width: 5px;
  height: 5px;
  flex: 0 0 auto;
  border-radius: 50%;
  background: var(--muted);
}
.serit-yeni {
  padding: 7px 12px;
  color: var(--accent);
  font-weight: 600;
}

/* Görünüm sekmesi: alt çizgiyle işaretlenen klasik sekme. */
.serit-tab {
  flex: 0 0 auto;
  padding: 9px 13px 7px;
  border-bottom: 2px solid transparent;
  color: var(--muted);
  font-size: 13px;
  font-weight: 500;
  text-decoration: none;
  white-space: nowrap;
}
.serit-tab:hover {
  color: var(--text);
}
.serit-tab.on {
  color: var(--text);
  border-bottom-color: var(--accent);
  font-weight: 600;
}

/* Ayarlar maddelerinin altındaki rol satırı (menu.js) — sütun kalkınca
   `.submenu-foot`un yerini aldı. */
.nav-rol {
  margin: 6px 0 0;
  padding: 0 18px 0 34px;
  font-size: 11px;
  line-height: 16px;
  color: var(--muted);
}
@container panel (max-width: 860px) {
  .cols {
    grid-template-columns: minmax(0, 1fr);
  }
  .preview {
    position: static;
  }
}

/* ── Karşılama ─────────────────────────────────────────────────────────── */
/* Proje adı sayfa başlığında; hero onu tekrarlamaz, tek cümlelik teknik kimliği
   ve olgunluğu öne alır. Sol taraftaki numara sitedeki kart numarasıyla aynı. */
.hero {
  display: grid;
  grid-template-columns: 44px minmax(0, 1fr) auto;
  gap: 8px 20px;
  align-items: start;
  background: var(--surface);
  border-left: 3px solid var(--accent);
  border-radius: 0 var(--radius) var(--radius) 0;
  padding: 26px 28px;
}
.hero-no {
  font-family: var(--heading);
  font-weight: 800;
  font-size: 14px;
  line-height: 28px;
  color: var(--accent);
  font-feature-settings: 'tnum' 1;
  position: relative;
}
.hero-no::before {
  content: '';
  position: absolute;
  left: -14px;
  top: 10px;
  width: 8px;
  height: 8px;
  background: var(--accent);
}
.hero-body {
  display: grid;
  gap: 14px;
}
.hero-lede {
  font-family: var(--heading);
  font-weight: 800;
  font-size: clamp(18px, 2vw, 22px);
  line-height: 1.3;
  letter-spacing: -0.012em;
  margin: 0;
}
.hero-links {
  display: flex;
  gap: 18px;
  flex-wrap: wrap;
  font-size: 13px;
  margin: 0;
}
.hero-links a {
  font-weight: 600;
  text-decoration: none;
}
.hero-links a:hover {
  text-decoration: underline;
}

.summary {
  max-width: 68ch;
  margin: 28px 0 32px;
  font-size: 15px;
  line-height: 27px;
  color: color-mix(in srgb, var(--text) 82%, transparent);
}

/* Karşılamada altı kutu var (listede dört): 150px'lik ortak alt sınır sayıyı iki
   satıra kırıyordu. Sütun sayısı burada SABİT üç — `auto-fit` genişliğe göre dört
   sütun seçip son satırda boş hücre bırakıyor, ızgara boşluğu zemin rengiyle
   çizildiği için o boşluk gri bir blok olarak görünüyor. Bu yüzden tech.json'daki
   `metrics` üçün katı olmalı. */
.overview .stats {
  grid-template-columns: repeat(3, minmax(0, 1fr));
}

/* Sayaç kutularının altına düşen ince ipucu satırı (kaynak/kapsam). */
.stat small {
  display: block;
  font-size: 11px;
  line-height: 16px;
  color: var(--muted);
  margin-top: 4px;
}

.block {
  margin-bottom: 36px;
}
.block h3,
.stack-group h3 {
  font-size: 12px;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--muted);
  font-weight: 600;
  margin-bottom: 14px;
}

/* Öne çıkanlar — madde işareti yerine turuncu kare, sitenin kart dili. */
.marks {
  list-style: none;
  padding: 0;
  margin: 0;
  display: grid;
  gap: 14px;
  max-width: 74ch;
}
.marks li {
  position: relative;
  padding-left: 22px;
  font-size: 14px;
  line-height: 24px;
  color: color-mix(in srgb, var(--text) 84%, transparent);
}
.marks li::before {
  content: '';
  position: absolute;
  left: 0;
  top: 9px;
  width: 7px;
  height: 7px;
  background: var(--accent);
}
.marks code,
.stack code {
  font-family: ui-monospace, 'SF Mono', Menlo, monospace;
  font-size: 12px;
}

.note {
  border: 2px solid var(--divider);
  border-radius: var(--radius);
  padding: 16px 18px;
  font-size: 13.5px;
  line-height: 22px;
  color: var(--muted);
  max-width: 70ch;
}
.note b {
  color: var(--text);
}

.analysis-meta {
  margin: 36px 0 0;
  padding-top: 18px;
  border-top: 2px solid var(--divider);
  font-size: 12px;
  color: var(--muted);
}

/* ── Olgunluk ──────────────────────────────────────────────────────────── */
.meter {
  display: inline-flex;
  gap: 3px;
}
.meter i {
  width: 16px;
  height: 6px;
  background: var(--neutral-300);
  border-radius: 1px;
}
.meter i.on {
  background: var(--accent);
}

.maturity-label {
  display: block;
  font-size: 11px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
  font-weight: 600;
}
.maturity b,
.hero-maturity b {
  display: block;
  font-family: var(--heading);
  font-weight: 800;
  font-size: 14px;
  line-height: 20px;
  margin: 6px 0 8px;
}
.maturity-scale {
  display: flex;
  align-items: center;
  gap: 8px;
}
.maturity-num {
  font-size: 11.5px;
  color: var(--muted);
  font-feature-settings: 'tnum' 1;
}

/* Hero içinde: gerekçe metni yok, yalnız durum + ölçek. */
.hero-maturity {
  text-align: right;
  min-width: 150px;
}
.hero-maturity .maturity-scale {
  justify-content: flex-end;
}
.hero-maturity p {
  display: none;
}

/* Tech Stack başlığında: gerekçesiyle birlikte. */
.maturity p {
  margin: 10px 0 0;
  font-size: 12.5px;
  line-height: 20px;
  color: var(--muted);
  max-width: 46ch;
}

/* ── Tech Stack ────────────────────────────────────────────────────────── */
.stack-head {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 320px);
  gap: 24px 40px;
  align-items: start;
  padding-bottom: 28px;
  margin-bottom: 8px;
  border-bottom: 2px solid var(--divider);
}
.stack-count {
  display: block;
  font-size: 11.5px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--accent-700);
  font-weight: 600;
}
.stack-head > div > p {
  margin: 10px 0 0;
  font-size: 14.5px;
  line-height: 25px;
  max-width: 58ch;
  color: color-mix(in srgb, var(--text) 84%, transparent);
}

.stack-group {
  padding: 28px 0;
  border-bottom: 2px solid var(--divider);
}
.stack-note {
  margin: -6px 0 16px;
  font-size: 12.5px;
  line-height: 20px;
  color: var(--muted);
  max-width: 68ch;
}
.stack-group ul {
  list-style: none;
  padding: 0;
  margin: 0;
  display: grid;
  gap: 2px;
}
/* Ad | ne için | nerede — üç sütun. Amaç metni asıl bilgi, o yüzden en geniş. */
.stack-group li {
  display: grid;
  grid-template-columns: minmax(180px, 260px) minmax(0, 1fr);
  gap: 4px 24px;
  padding: 12px 4px;
  border-top: 1px solid var(--divider);
}
.stack-group li:first-child {
  border-top: 0;
}
.stack-group li:hover {
  background: color-mix(in srgb, var(--text) 4%, transparent);
}
.stack-name {
  font-weight: 600;
  font-size: 13.5px;
  line-height: 22px;
  overflow-wrap: anywhere;
}
.stack-name em {
  display: inline-block;
  margin-left: 8px;
  font-style: normal;
  font-weight: 600;
  font-size: 11px;
  line-height: 18px;
  padding: 0 7px;
  border-radius: 100px;
  background: var(--neutral-100);
  color: var(--neutral-800);
  font-feature-settings: 'tnum' 1;
  white-space: nowrap;
}
.stack-group li p {
  margin: 0;
  font-size: 13.5px;
  line-height: 22px;
  color: color-mix(in srgb, var(--text) 80%, transparent);
}
/* Yol BAŞTAN SONA yazılı: bu kural yalnızca grubun kendi satırındaki `code`
   içindir. Gevşek bir `li code` (hatta `li > code`) yazmak, iç içe gelen
   listelerin `code`'unu da kapsıyor ve sarmalayıcıda olmayan bir ikinci sütun
   açarak içeriği yanlış hücreye atıyor — Yapı ve Sunucu sekmelerinde tam bu
   oldu (bkz. tasks/lessons.md). */
.stack-group > ul > li > code {
  grid-column: 2;
  color: var(--muted);
  overflow-wrap: anywhere;
}

/* Sinyaller: durum rengi etikette, satırda değil — liste alacalı olmasın. */
.signals li {
  grid-template-columns: minmax(200px, 300px) minmax(0, 1fr);
}
.signal-strong .signal-tag {
  background: var(--accent-100);
  color: var(--accent-800);
}
.signal-ok .signal-tag {
  background: var(--neutral-100);
  color: var(--neutral-800);
}
.signal-gap .signal-tag {
  background: none;
  border: 1px solid var(--neutral-300);
  color: var(--muted);
}

/* ── Yapı sekmesi ─────────────────────────────────────────────────────────
   Satır ızgarası Tech Stack'ten miras: ad | gövde. Yapı satırının gövdesi üç
   katmanlı (rol · kitle+adres · dizin), bu yüzden tek bir kapsayıcıya alındı;
   böylece satır ızgarası iki sütunlu kalıyor ve mobilde tek sütuna inişi
   kendiliğinden doğru çalışıyor. */
.parts .part-body {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 3px;
}
/* Kitle ve adres yan yana; ikisi de rol metninden bir kademe geride durur. */
.parts .part-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 2px 16px;
  margin: 1px 0 0;
  font-size: 12.5px;
  line-height: 20px;
  color: var(--muted);
}
.parts .part-meta a {
  font-weight: 600;
  text-decoration: none;
}
.parts .part-meta a:hover {
  text-decoration: underline;
}

/* ── Sunucu sekmesi ───────────────────────────────────────────────────────
   Yapı satırının üzerine iki katman biner: makinede koşan servislerin listesi
   ve makineye özgü not. Satır ızgarası aynı, bu yüzden ek kural az. */
.servers .host-address code {
  color: var(--text);
}
.servers .host-runs {
  list-style: none;
  margin: 6px 0 2px;
  padding: 0;
  display: grid;
  gap: 4px;
}
/* Servis adı sabit genişlikte bir sütun: portlar alt alta okunabilsin. */
.servers .host-runs li {
  display: grid;
  grid-template-columns: minmax(140px, 210px) minmax(0, 1fr);
  gap: 2px 16px;
  padding: 0;
  border: 0;
  font-size: 13px;
  line-height: 21px;
}
.servers .host-runs li:hover {
  background: none;
}
.servers .host-runs code {
  color: var(--accent-700);
  overflow-wrap: anywhere;
}
.servers .host-runs span {
  color: color-mix(in srgb, var(--text) 78%, transparent);
}
.servers .host-note {
  margin: 8px 0 0;
  font-size: 12.5px;
  line-height: 20px;
  color: var(--muted);
  max-width: 78ch;
}

.stack-empty {
  padding: 40px 0;
  color: var(--muted);
}
.stack-empty p {
  margin: 0 0 8px;
}
.hint-block {
  font-size: 12.5px;
}

/* ── Plan sekmesi (plans/*.md) ─────────────────────────────────────────── */
/* Belge deposu markdown'dan DOM üretilerek çiziliyor (assets/plan.js) —
   buradaki kurallar yalnızca .plan-doc altında yaşar, panelin geri kalanına
   sızmaz. Renkler token; sabit renk yok (iki tema kuralı, CLAUDE.md §5). */

.plan-meta {
  margin: 0 0 18px;
  font-size: 12px;
  color: var(--muted);
}
.plan-meta code {
  font-size: 11.5px;
}

.plan-doc {
  max-width: 76ch;
  font-size: 13.5px;
  line-height: 1.65;
  color: var(--text);
}
/* Belgenin kendi H1'i sayfa başlığıyla yarışmasın: bir kademe küçük. */
.plan-doc h1 {
  margin: 0 0 6px;
  font-family: var(--heading);
  font-size: 19px;
  line-height: 1.3;
  color: var(--strong);
}
.plan-doc h2 {
  margin: 30px 0 10px;
  font-family: var(--heading);
  font-size: 15.5px;
  color: var(--strong);
}
.plan-doc h3 {
  margin: 22px 0 8px;
  font-family: var(--heading);
  font-size: 13.5px;
  color: var(--strong);
}
.plan-doc h4 {
  margin: 16px 0 6px;
  font-family: var(--heading);
  font-size: 12.5px;
  color: var(--strong);
}
.plan-doc p {
  margin: 0 0 12px;
}
.plan-doc hr {
  margin: 24px 0;
  border: 0;
  border-top: 1px solid var(--divider);
}
.plan-doc ul,
.plan-doc ol {
  margin: 0 0 12px;
  padding-left: 22px;
}
.plan-doc li {
  margin-bottom: 5px;
}
.plan-doc li::marker {
  color: var(--accent);
}
.plan-doc code {
  padding: 1px 4px;
  border-radius: 3px;
  background: var(--neutral-100);
  font-family: ui-monospace, 'SF Mono', Menlo, monospace;
  font-size: 12px;
}
.plan-doc pre {
  margin: 0 0 14px;
  padding: 12px 14px;
  overflow-x: auto;
  border-radius: var(--radius);
  background: var(--neutral-100);
  line-height: 1.55;
}
.plan-doc pre code {
  padding: 0;
  background: none;
  font-size: 12px;
}
.plan-doc blockquote {
  margin: 0 0 12px;
  padding: 4px 14px;
  border-left: 3px solid var(--accent);
  color: var(--muted);
}
.plan-doc a {
  color: var(--accent-600);
}
/* Geniş tablo kendi kutusunda kayar — sayfa gövdesi asla yatay kaymaz. */
.plan-table {
  margin: 0 0 16px;
  overflow-x: auto;
}
.plan-doc table {
  border-collapse: collapse;
  font-size: 12.5px;
  line-height: 1.5;
}
.plan-doc th,
.plan-doc td {
  padding: 7px 10px;
  border: 1px solid var(--divider);
  text-align: left;
  vertical-align: top;
  min-width: 120px;
}
.plan-doc th {
  font-family: var(--heading);
  font-size: 11.5px;
  letter-spacing: 0.02em;
  color: var(--strong);
  background: var(--neutral-100);
}

/* ── Mobil ─────────────────────────────────────────────────────────────── */
@media (max-width: 860px) {
  .hero {
    grid-template-columns: 32px minmax(0, 1fr);
    padding: 22px 20px;
  }
  /* Olgunluk kutusu numaranın hizasına değil, gövdenin altına geçsin. */
  .hero-maturity {
    grid-column: 2;
    text-align: left;
    margin-top: 18px;
    min-width: 0;
  }
  .hero-maturity .maturity-scale {
    justify-content: flex-start;
  }
  .stack-head,
  .stack-group li,
  .signals li {
    grid-template-columns: minmax(0, 1fr);
  }
  .stack-group > ul > li > code {
    grid-column: 1;
  }
  /* Sunucu satırındaki servis listesi de tek sütuna iner: ad, altında ne yaptığı. */
  .servers .host-runs li {
    grid-template-columns: minmax(0, 1fr);
  }

  .shell {
    grid-template-columns: minmax(0, 1fr);
  }
  /* ── Gezinme: üst bar + soldan açılan çekmece ──────────────────────────
     2026-08-07'ye kadar kenar çubuğu burada YATAY BİR ŞERİDE dönüyordu ve o
     şerit yetmiyordu: 390px'de marka, tema düğmesi ve ÇIKIŞ yer aldıktan sonra
     `.nav`a 66px kalıyordu — içeriği 2138px olan bir kaydırma kutusu. Üç grup
     ve on üç madde teknik olarak oradaydı, pratikte ulaşılamıyordu; görünen tek
     şey kırpılmış bir "PROJELE|" başlığıydı.

     Çekmecenin içeriği masaüstündeki kenar çubuğunun AYNISI — ayrı bir mobil
     menü yazılmadı (iki menü ayrışır; kabuğun tek yer olmasının sebebi bu).
     Şerit için yazılmış bütün kurallar (yatay `.nav`, `display: contents` ile
     düzleşen gruplar, etikete dönüşen grup başlığı, gizlenen alt bilgi) da bu
     yüzden silindi: çekmecede dikey liste zaten doğru olan. */
  :root {
    --topbar-h: 62px; /* 8 + 44 + 8 + 2px kenar — bkz. yukarıdaki token notu */
  }
  .topbar {
    display: flex;
    align-items: center;
    gap: 12px;
    position: sticky;
    top: 0;
    z-index: 40;
    padding: 8px 12px;
    background: var(--surface);
    border-bottom: 2px solid var(--divider);
  }
  .topbar-menu {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    min-height: 44px;
    padding: 0 14px 0 10px;
    border: 2px solid var(--divider);
    border-radius: var(--radius);
    background: var(--bg);
    color: var(--text);
    font: inherit;
    font-size: 13px;
    font-weight: 600;
    cursor: pointer;
  }
  .topbar-brand {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    min-width: 0;
  }
  .topbar-brand img {
    width: 26px;
    height: auto;
    display: block;
    /* Kenar çubuğundaki amblemle aynı işlem — bkz. `.brand img`. */
    filter: brightness(0) invert(var(--emblem-invert));
    opacity: 0.92;
  }
  .topbar-brand b {
    font-family: var(--heading);
    font-size: 13px;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }

  .sidebar {
    position: fixed;
    inset: 0 auto 0 0;
    z-index: 90;
    width: min(84vw, 304px);
    height: 100dvh;
    overflow-y: auto;
    overscroll-behavior: contain;
    padding: 18px 0 28px;
    gap: 22px;
    border-right: 2px solid var(--divider);
    transform: translateX(-100%);
    transition: transform 0.18s ease;
  }
  html[data-mobilnav='open'] .sidebar {
    transform: none;
  }
  /* Çekmece açıkken arkadaki sayfa kaymasın. */
  html[data-mobilnav='open'] body {
    overflow: hidden;
  }
  .nav-scrim {
    display: none;
  }
  html[data-mobilnav='open'] .nav-scrim {
    display: block;
    position: fixed;
    inset: 0;
    z-index: 80;
    background: light-dark(rgba(27, 26, 31, 0.42), rgba(0, 0, 0, 0.6));
  }
  /* Marka satırındaki düğme telefonda "çekmeceyi kapat" (kabuk.js bağlıyor);
     masaüstündeki "gezinmeyi gizle" ile aynı işi görüyor, ayrı bir düğme
     eklemek gerekmedi. Sol üstteki geri-açma düğmesi ise burada gereksiz:
     çekmeceyi üst bar açıyor. */
  .nav-opener {
    display: none !important;
  }
  .cols {
    grid-template-columns: minmax(0, 1fr);
  }
  .preview {
    position: static;
  }
  /* Dar ekranda logo kalıyor — satırı tanıtan şey o. Açıklama ve bağlantılar
     hâlâ ad sütununda, yani üçüncüde. */
  /* Mobilde logo satırın ÜSTÜNE, kendi tam genişliğine geçiyor: 390px'te ad ile
     yan yana sıkıştırılsa ikisi de okunmaz hâle gelirdi. Sıra: logo · numara+ad ·
     açıklama. */
  .row {
    grid-template-columns: 32px minmax(0, 1fr);
    column-gap: 14px;
  }
  /* Satırlar açıkça yerleştiriliyor: logo DOM'da numaradan SONRA geliyor, otomatik
     yerleşim onu ikinci satıra atardı.

     Bu kurallar `.row` İÇİN — seçici bilerek `.row` ile kapsanmış. Niteliksiz
     `.mark-stack` yazıldığında `width: min(168px, 62%)` logoyu kullandığı HER
     yere taşıyor: `urun.css` ve `sunum.css` bu yüzden kendi ölçülerini yeniden
     yazmak zorunda kalmıştı, proje şeridindeki çip de mobilde adı kırpılmış
     hâlde çiziliyordu (2026-09-01). Yeni bir yüzey eklerken kural tek: logo
     ölçüsünü VEREN kural, o logonun yaşadığı bağlamı da söylesin. */
  .row .mark-stack {
    grid-area: 1 / 1 / 2 / -1;
    width: min(168px, 62%);
    margin-bottom: 12px;
    gap: 8px;
  }
  .row .mark {
    height: 38px;
  }
  .row .mark-stack:has(.mark + .mark) .mark {
    height: 32px;
  }
  .row .mark b {
    width: 36px;
    height: 36px;
    font-size: 15px;
  }
  .row-no {
    grid-area: 2 / 1;
  }
  .row-name {
    grid-area: 2 / 2;
  }
  .row-desc {
    grid-area: 3 / 2;
  }
  .row-links {
    grid-area: 4 / 2;
  }
}

/* ── Giriş sayfası ─────────────────────────────────────────────────────── */
/* Kimliksiz görülen tek sayfa; paneldeki hiçbir iskeleti (kenar çubuğu, şerit)
   taşımıyor — kullanıcı henüz "içeride" değil. Kart ortada, sayfa geri kalanı
   boş: tek yapılacak iş varsa dikkat dağıtan bir şey de olmamalı.

   Zeminde iki çok soluk turuncu ışık var. Kartın kendisi --surface, kenarı
   2px: panelin geri kalanıyla aynı dil. */
.login-body {
  min-height: 100vh;
  min-height: 100dvh;
  display: grid;
  background:
    radial-gradient(60ch 40ch at 15% -10%, color-mix(in srgb, var(--accent) 9%, transparent), transparent),
    radial-gradient(50ch 36ch at 95% 105%, color-mix(in srgb, var(--accent) 7%, transparent), transparent);
}
.login {
  width: 100%;
  display: grid;
  grid-template-rows: 1fr auto;
  justify-items: center;
  padding: clamp(20px, 5vh, 64px) 20px 24px;
  gap: 20px;
}
.login-card {
  width: 100%;
  max-width: 396px;
  align-self: center;
  background: var(--surface);
  border: 2px solid var(--divider);
  border-radius: var(--radius);
  padding: clamp(24px, 4vw, 36px);
}
/* Marka kilidi: logonun TAMAMI, altında ince bir satır. Kartın geri kalanı
   (başlık, form) sola dayalı olduğu için bu blok da sola dayalı — ortalamak
   ikinci bir hizalama ekseni açardı. */
.login-brand {
  display: grid;
  justify-items: start;
  gap: 13px;
  padding-bottom: 22px;
  margin-bottom: 26px;
  border-bottom: 2px solid var(--divider);
}
/* Logo OLDUĞU GİBİ duruyor: `filter` yok, `opacity` yok, kırpma yok — panelin
   kenar çubuğundaki amblem beyaza çevrilir, burada logo çevrilmez.
   `height: auto` şart: `width`/`height` attribute'ları sunum ipucu olarak CSS'e
   map edilir, tek boyut verilirse görüntü eziliyor (bkz. tasks/lessons.md). */
.login-brand img {
  width: 100%;
  max-width: 228px;
  height: auto;
  display: block;
}
/* "Yönetim Paneli" — logonun altında, onunla yarışmayan bir alt satır: küçük
   punto, geniş harf aralığı, soluk renk. Metin DOM'da özgün yazımıyla duruyor;
   büyük harfe çeviren CSS ve `lang="tr"` sayesinde İ doğru çıkıyor. */
.login-brand span {
  font-size: 11.5px;
  line-height: 15px;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  font-weight: 600;
  color: var(--muted);
}
.login-card h1 {
  font-size: 30px;
  line-height: 1.1;
  margin-left: -0.03em;
}
.login-lede {
  color: var(--muted);
  font-size: 13.5px;
  line-height: 21px;
  margin: 8px 0 24px;
}
.login-card .field {
  margin-bottom: 18px;
}

/* Hata şeridi: .band ile aynı dil ama sol çizgi yerine tam kenarlık — form
   içinde durduğu için "kutu" olarak okunması gerekiyor. */
.login-alert {
  background: var(--accent-100);
  border: 2px solid color-mix(in srgb, var(--accent) 55%, transparent);
  border-radius: var(--radius);
  color: color-mix(in srgb, var(--accent-800) 70%, var(--text));
  font-size: 13px;
  line-height: 20px;
  padding: 10px 14px;
  margin: 0 0 20px;
}

/* `.hint` kuralı `display: block` veriyor; yazar kuralı, `[hidden]`'ın tarayıcı
   varsayılanını (display: none) EZER. Caps Lock ipucu bu yüzden ilk boyamada
   görünüyordu — gizli kalması gereken her ipucu için tek satır düzeltme. */
.hint[hidden] {
  display: none;
}

/* Şifre alanı + göster/gizle. Düğme alanın İÇİNDE; sağ dolgu düğme kadar
   arttırılıyor ki uzun şifre metnin altına girmesin. */
.pw {
  display: block;
  position: relative;
}
.pw input {
  padding-right: 76px;
}
.pw-toggle {
  position: absolute;
  top: 50%;
  right: 6px;
  transform: translateY(-50%);
  background: none;
  border: 0;
  border-radius: var(--radius);
  padding: 6px 8px;
  font: inherit;
  font-size: 11.5px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  font-weight: 600;
  color: var(--muted);
  cursor: pointer;
}
.pw-toggle:hover {
  color: var(--text);
}
.pw-toggle:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
  color: var(--text);
}

.check {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 2px 0 24px;
  font-size: 13.5px;
  color: var(--muted);
  cursor: pointer;
}
.check input[type='checkbox'] {
  appearance: none;
  flex: 0 0 auto;
  width: 18px;
  height: 18px;
  margin: 0;
  background: var(--bg);
  border: 2px solid var(--neutral-300);
  border-radius: 3px;
  cursor: pointer;
}
.check input[type='checkbox']:checked {
  background: var(--accent);
  border-color: var(--accent);
  /* Onay işareti ayrı bir varlık olmadan: iki çizgi, maske yerine gradyanla. */
  background-image: linear-gradient(
      to bottom right,
      transparent 46%,
      #fff 46%,
      #fff 62%,
      transparent 62%
    ),
    linear-gradient(to bottom left, transparent 62%, #fff 62%, #fff 78%, transparent 78%);
  background-size: 60% 60%, 60% 60%;
  background-position: 22% 58%, 62% 42%;
  background-repeat: no-repeat;
}
.check input[type='checkbox']:focus-visible {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 25%, transparent);
}
.check:hover {
  color: var(--text);
}

.btn-block {
  width: 100%;
  justify-content: center;
  padding: 12px 16px;
  font-size: 14px;
}
.btn:disabled {
  opacity: 0.6;
  cursor: default;
}

.login-foot {
  margin: 24px 0 0;
  padding-top: 20px;
  border-top: 2px solid var(--divider);
  font-size: 12px;
  line-height: 19px;
  color: var(--muted);
}
.login-theme {
  margin: 0;
}

/* ── Kenar çubuğunda oturum ────────────────────────────────────────────── */
.session {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: 2px 10px;
  margin: 0 24px 20px;
  padding-top: 18px;
  border-top: 2px solid var(--divider);
}
.session-user {
  font-weight: 700;
  font-size: 13px;
  line-height: 18px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.session-meta {
  grid-column: 1;
  font-size: 11px;
  line-height: 15px;
  color: var(--muted);
}
.session-out {
  grid-row: 1 / span 2;
  grid-column: 2;
  background: none;
  border: 2px solid var(--divider);
  border-radius: var(--radius);
  padding: 5px 10px;
  font: inherit;
  font-size: 11.5px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  font-weight: 600;
  color: var(--muted);
  cursor: pointer;
}
.session-out:hover {
  color: var(--text);
  border-color: var(--neutral-300);
}
.session-out:focus-visible {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 25%, transparent);
}

/* ── Açık oturumlar tablosu (ayarlar) ──────────────────────────────────── */
.sessions {
  border-top: 2px solid var(--divider);
  margin-bottom: 24px;
  padding: 0;
}
.sessions li {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 2px 16px;
  align-items: center;
  padding: 14px 4px;
  border-bottom: 2px solid var(--divider);
  list-style: none;
}
.sessions .s-head {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  font-size: 14px;
  font-weight: 600;
}
.sessions .s-meta {
  grid-column: 1;
  font-size: 12.5px;
  line-height: 19px;
  color: var(--muted);
}
.sessions .s-meta code {
  font-size: 12px;
}
.tag-current {
  background: var(--accent-100);
  color: var(--accent-800);
}

@media (max-width: 860px) {
  .login-card {
    padding: 24px 20px;
  }
  /* Yalnızca emniyet kemeri: şeritte bir şey beklenmedik biçimde büyürse taşma
     SAYFAYI kaydırmasın (gerçek çözüm aşağıdaki daraltmalar). */
  .shell {
    overflow-x: clip;
  }
  /* Oturum kutusu çekmecenin dibinde, masaüstündeki gibi: şerit dönemindeki
     "tek satıra sıkıştır, açık oturum sayısını gizle" kuralları kalktı
     (2026-08-07 — kenar çubuğu artık şerit değil, bkz. yukarıdaki çekmece
     bloğu). Kalan tek fark: sayfa içindeki oturum LİSTESİ (ayarlar sayfası)
     dar ekranda tek sütuna iniyor. */
  .sessions li {
    grid-template-columns: minmax(0, 1fr);
  }
  .sessions li .btn-mini {
    justify-self: start;
    margin-top: 8px;
  }
}

/* ── Telefon: marka ve oturum kutusu ──────────────────────────────────────
   Burada eskiden "şeritte yer yok" diye bir blok vardı: marka metni ve
   kullanıcı adı gizleniyordu, çünkü kenar çubuğu 390px'lik yatay bir şeritti
   ve her piksel gezinmeden çalınıyordu. 2026-08-07'de çubuk soldan açılan bir
   ÇEKMECEYE dönüştü — orada 300px genişlik var, saklanacak bir şey yok.
   Dar ekranda kalan tek daraltma oturum kutusunun tek sütuna inmesi. */
@media (max-width: 600px) {
  .session {
    grid-template-columns: minmax(0, 1fr);
  }
  .session-out {
    grid-column: 1;
  }
}

/* ── Ayarlar menüsü: kenar çubuğu düğmesi ──────────────────────────────── */
/* `margin-top: auto` BURADA: menü kenar çubuğunun dibine yapışsın. Tema
   anahtarı da aynı numarayı kullanıyordu; ikisi birden auto olsa boşluk
   ikiye bölünür ve menü ortada asılı kalırdı — `:has()` ile tema anahtarının
   auto'su bu sayfalarda sıfırlanıyor (kendi kuralına dokunmadan). */
.nav-settings {
  margin: auto 0 0;
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 11px 24px 11px 22px;
  border: 0;
  border-left: 2px solid transparent;
  background: none;
  color: var(--muted);
  font: inherit;
  font-size: 12px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  font-weight: 600;
  cursor: pointer;
  text-align: left;
}
.sidebar:has(.nav-settings) .theme-toggle {
  margin-top: 12px;
}
.nav-settings:hover {
  color: var(--text);
  background: color-mix(in srgb, var(--text) 4%, transparent);
}
.nav-settings:focus-visible {
  outline: none;
  color: var(--text);
  box-shadow: inset 0 0 0 2px color-mix(in srgb, var(--accent) 45%, transparent);
}
.nav-settings svg {
  flex: 0 0 auto;
  opacity: 0.85;
}
/* Açık/kapalı okunu ▸ / ▾ olarak döndürüyoruz: durum düğmenin kendisinde
   görünsün, kullanıcı sütunun nereden geldiğini anlasın. */
.nav-settings-caret {
  margin-left: auto;
  width: 0;
  height: 0;
  border-left: 4px solid currentColor;
  border-top: 4px solid transparent;
  border-bottom: 4px solid transparent;
  transition: transform 0.15s;
}
.nav-settings.is-open .nav-settings-caret {
  transform: rotate(90deg) translateX(-1px);
}
.nav-settings.is-current {
  color: var(--text);
  border-left-color: var(--accent);
  background: color-mix(in srgb, var(--accent) 10%, transparent);
}

/* ── Sayfa şeridi (hata / bilgi) ───────────────────────────────────────── */
.page-alert {
  border: 2px solid color-mix(in srgb, var(--accent) 55%, transparent);
  background: var(--accent-100);
  color: color-mix(in srgb, var(--accent-800) 70%, var(--text));
  border-radius: var(--radius);
  padding: 11px 15px;
  margin: 0 0 24px;
  font-size: 13.5px;
  line-height: 21px;
}
.page-alert-info {
  border-color: var(--divider);
  background: var(--surface);
  color: var(--text);
}

/* ── Kart kutuları (form / sır) ────────────────────────────────────────── */
.panel-card,
.secret-card {
  border: 2px solid var(--divider);
  border-radius: var(--radius);
  padding: 22px clamp(18px, 3vw, 26px);
  margin-bottom: 28px;
  background: color-mix(in srgb, var(--surface) 55%, var(--bg));
}
.panel-card h2,
.secret-card h2 {
  font-size: 17px;
  line-height: 24px;
  margin-bottom: 4px;
}
/* Şifre kutusu bilinçli olarak vurgulu: bir kez gösterilen bir sır burada. */
.secret-card {
  border-color: var(--accent);
  background: var(--accent-100);
}
.secret-card p {
  margin: 6px 0 16px;
  font-size: 13.5px;
  line-height: 21px;
  color: color-mix(in srgb, var(--accent-800) 70%, var(--text));
}
.secret-card strong {
  color: var(--strong);
}
.secret-row {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}
.secret-row code {
  flex: 1 1 260px;
  background: var(--bg);
  border: 2px solid var(--divider);
  border-radius: var(--radius);
  padding: 10px 12px;
  font-size: 15px;
  letter-spacing: 0.04em;
  overflow-wrap: anywhere;
}

.form-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 0 20px;
}
.field-label {
  display: block;
  font-size: 11.5px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
  font-weight: 600;
  margin: 6px 0 10px;
}

/* ── Kullanıcı listesi ─────────────────────────────────────────────────── */
.user-list {
  border-top: 2px solid var(--divider);
  margin-bottom: 8px;
}
.user-row {
  display: grid;
  gap: 6px;
  padding: 18px 4px;
  border-bottom: 2px solid var(--divider);
}
/* Askıya alınmış hesap listede sönük görünür ama gizlenmez: durum, yokluk değil. */
.user-row.is-suspended .user-head h2 {
  color: var(--muted);
}
.user-head {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}
.user-head h2 {
  font-size: 19px;
  line-height: 24px;
}
.user-meta {
  margin: 0;
  font-size: 12.5px;
  line-height: 19px;
  color: var(--muted);
}
.user-actions {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  margin-top: 4px;
}
.role-select {
  width: auto;
  min-width: 190px;
  padding: 6px 34px 6px 10px;
  font-size: 13px;
  line-height: 20px;
  background-position:
    calc(100% - 16px) calc(50% + 1px),
    calc(100% - 10px) calc(50% + 1px);
}
.tag-suspended {
  background: color-mix(in srgb, var(--accent) 18%, transparent);
  color: var(--accent-800);
}
/* Tehlikeli işlem: onaya girene kadar nötr, "Emin misiniz?" derken kırmızı. */
.btn-danger {
  color: var(--accent-700);
}
.btn-danger:hover {
  border-color: var(--accent);
  color: var(--accent-600);
}
.btn.is-armed {
  background: var(--accent);
  border-color: var(--accent);
  color: #fff;
}
.is-locked {
  opacity: 0.55;
  cursor: not-allowed;
}

/* ── İşlem kaydı ───────────────────────────────────────────────────────── */
.audit {
  list-style: none;
  margin: 0;
  padding: 0;
  border-top: 2px solid var(--divider);
}
.audit li {
  display: grid;
  grid-template-columns: 130px 1fr;
  gap: 2px 14px;
  padding: 10px 4px;
  border-bottom: 2px solid var(--divider);
  font-size: 13px;
  line-height: 20px;
}
.audit-when {
  color: var(--muted);
  font-feature-settings: 'tnum' 1;
}
.audit-what {
  font-weight: 600;
}
.audit-target {
  grid-column: 2;
  color: var(--accent-700);
}
.audit-detail {
  grid-column: 2;
  color: var(--muted);
  font-size: 12.5px;
}

/* ── Rol kartları ──────────────────────────────────────────────────────── */
.role-list {
  display: grid;
  gap: 2px;
  background: var(--divider);
  border: 2px solid var(--divider);
  margin-bottom: 8px;
}
.role-card {
  background: var(--bg);
  padding: 20px clamp(16px, 2vw, 22px);
  display: grid;
  gap: 10px;
}
.role-card.is-editing {
  background: color-mix(in srgb, var(--surface) 55%, var(--bg));
}
.role-head {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}
.role-head h2 {
  font-size: 19px;
  line-height: 24px;
}
.role-head code,
.perm-catalog code {
  font-size: 12.5px;
  color: var(--muted);
}
.role-users {
  margin-left: auto;
  font-size: 12px;
  color: var(--muted);
  white-space: nowrap;
}
.role-desc,
.role-meta {
  margin: 0;
  font-size: 13px;
  line-height: 20px;
  color: var(--muted);
}
.role-actions {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}
.chips {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
}
/* Sunucuda zorlanan izin dolu, yalnızca arayüzü etkileyen izin çizgili:
   kullanıcı hangisinin gerçek sınır olduğunu bir bakışta görsün. */
.chip {
  display: inline-block;
  padding: 3px 9px;
  border-radius: 100px;
  font-size: 11.5px;
  line-height: 18px;
  font-weight: 600;
  background: var(--accent-100);
  color: var(--accent-800);
}
.chip-arayüz,
.chip-arayuz {
  background: transparent;
  border: 1px dashed var(--neutral-300);
  color: var(--muted);
}
.chip-kısmi,
.chip-kismi {
  background: transparent;
  border: 1px solid color-mix(in srgb, var(--accent) 45%, transparent);
  color: var(--accent-800);
}
.chip-none {
  background: var(--neutral-100);
  color: var(--neutral-800);
}

/* ── İzin kutucukları ve katalog ───────────────────────────────────────── */
.perm-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 10px 20px;
  margin-bottom: 8px;
}
.perm-item {
  display: grid;
  grid-template-columns: 18px minmax(0, 1fr);
  gap: 10px;
  align-items: start;
  padding: 10px 12px;
  border: 2px solid var(--divider);
  border-radius: var(--radius);
  cursor: pointer;
}
.perm-item:hover {
  border-color: var(--neutral-300);
}
.perm-item input[type='checkbox'] {
  appearance: none;
  width: 18px;
  height: 18px;
  margin: 2px 0 0;
  background: var(--bg);
  border: 2px solid var(--neutral-300);
  border-radius: 3px;
  cursor: pointer;
}
.perm-item input[type='checkbox']:checked {
  background: var(--accent);
  border-color: var(--accent);
  background-image: linear-gradient(to bottom right, transparent 46%, #fff 46%, #fff 62%, transparent 62%),
    linear-gradient(to bottom left, transparent 62%, #fff 62%, #fff 78%, transparent 78%);
  background-size: 60% 60%, 60% 60%;
  background-position: 22% 58%, 62% 42%;
  background-repeat: no-repeat;
}
.perm-item input[type='checkbox']:focus-visible {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 25%, transparent);
}
.perm-title {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 14px;
  font-weight: 600;
  line-height: 20px;
}
.perm-item code {
  display: block;
  font-size: 12px;
  color: var(--muted);
}
.perm-desc {
  display: block;
  font-size: 12.5px;
  line-height: 19px;
  color: var(--muted);
  margin-top: 3px;
}
.enf {
  font-size: 10.5px;
  line-height: 15px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  font-weight: 700;
  padding: 1px 7px;
  border-radius: 100px;
}
.enf-sunucu {
  background: var(--accent-100);
  color: var(--accent-800);
}
.enf-arayüz,
.enf-arayuz {
  background: var(--neutral-100);
  color: var(--neutral-800);
}
/* "kısmen sunucuda": ikisinin arası — aksan mürekkebi, ama dolgu yerine çerçeve.
   `content.edit` iki iş açıyor ve yalnızca biri sunucuda zorlanıyor. */
.enf-kısmi,
.enf-kismi {
  background: transparent;
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent) 45%, transparent);
  color: var(--accent-800);
}

.perm-catalog {
  margin: 0;
  border-top: 2px solid var(--divider);
}
.perm-catalog dt {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  padding: 14px 4px 0;
  font-size: 14px;
  font-weight: 700;
}
.perm-catalog dd {
  margin: 2px 4px 0;
  padding-bottom: 14px;
  border-bottom: 2px solid var(--divider);
  font-size: 13px;
  line-height: 20px;
  color: var(--muted);
}

@media (max-width: 860px) {
  /* NOT: "Ayarlar" düğmesi ve tema anahtarı için burada bir kural YOK. Onlar
     kenar çubuğunun içinde yaşıyor, kenar çubuğu da 2026-08-07'den beri yatay
     bir şerit değil soldan açılan bir ÇEKMECE — masaüstündeki dikey görünümleri
     orada da doğru. Şerit dönemindeki override'lar (etiketi gizle, alt çizgiye
     çevir, sağa it) silindi: çekmecede yalnızca bir dişli görünüyordu. */
  .audit li {
    grid-template-columns: minmax(0, 1fr);
  }
  .audit-target,
  .audit-detail {
    grid-column: 1;
  }
  .role-users {
    margin-left: 0;
  }
}
