/* ═══════════════════════════════════════════════════════════════════════════
   DERS NOTU v2 — SIFIRDAN YAZILDI, 22 Ağustos 2026
   ═══════════════════════════════════════════════════════════════════════════

   Önceki dosya (notes_v2.css.onceki, 738 satır) bir gecede yama üstüne yama
   büyüdü: 274 kuralın bir kısmı birbirini eziyordu, bir kısmı hiç
   çalışmıyordu. Bu dosya onun düzeltilmiş hâli değil — ölçümden yeniden
   türetildi. Aşağıda hangi ölçümün hangi kararı doğurduğu yazıyor.

   ── Ö1 · SAYFADA TEK BİR FORMÜL RENDER EDİLMİYORDU ────────────────────────
   8.156 formülün hepsi ham LaTeX olarak duruyordu ($m=\lim_{h\to 0}...).
   Sebep: eski dosyada `section.bolum { display: contents }` vardı. contents
   kutu üretmez -> getBoundingClientRect() {h:0} -> build.py'deki
   IntersectionObserver hiç tetiklenmez -> bolumRender() hiç çağrılmaz.
   KARAR: display:contents YOK. section.bolum normal bir grid item. Tek
   satır, üç kazanç: formüller render ediyor, bölüm gerçek bir kutu, JS'in
   ölçümleri anlamlı.

   ── Ö2 · content-visibility GERİ KONULMADI ────────────────────────────────
   Aynı contents satırı `content-visibility:auto`u da no-op yapıyordu, yani
   ölçülen hız kazancı zaten ondan gelmiyordu — KaTeX'in tembel render'ından
   geliyordu, o da duruyor. Geri koymamanın iki sebebi:
     (a) contain:content = paint containment; kutuyu kırpar, figürün kenar
         boşluğuna taşmasını ve viewBox'ı aşan <text>'i keser.
     (b) Ekran dışındaki bölümün düzeni hesaplanmaz -> clientWidth 0 ->
         ÖLÇÜM ARACININ KENDİSİ körleşir; "kaydırma çubuğu yok" demek
         imkânsızlaşır.

   ── Ö3 · KaTeX'İ VURAN SEÇİCİ: `.bolum svg` ───────────────────────────────
   KaTeX kendi CSS'inde `.katex svg { height: inherit }` yazıyor. Eski
   dosyadaki `.bolum svg { height: auto }` ile ikisi de (0,1,1) ve bizimki
   sonra yüklendiği için kazanıyordu: \sqrt, \overbrace, \xrightarrow ve
   uzayan parantezler bozuluyordu.
   KARAR: bu dosyada ÇIPLAK `svg`, `span`, `td`, `*` seçicisi YOK. Şekil
   SVG'si her zaman `figure > svg` ile seçiliyor — renderer SVG'yi hep
   figure'ın DOĞRUDAN çocuğu olarak basıyor (render_v2.py:399, 453),
   KaTeX'inki ise hep bir span yığınının içinde; child combinator ikisini
   yapısal olarak ayırıyor.

   ── Ö4 · PARAGRAFLARIN SOL KENARI 13 AYRI DEĞERDEYDİ ──────────────────────
   Her blok kendi yatay padding'ini taşıyordu, sayfa yamuk duruyordu.
   KARAR: OKUMA SÜTUNUNDA YATAY PADDING YOK, SOL ÇİZGİ YOK. Ayrım boşluk +
   mono etiket + YATAY ince çizgi ile yapılıyor (yatay çizgi hizayı bozmaz).
   Zemin gereken bloklarda padding kadar negatif margin ile telafi ediliyor:
   zemin dışarı taşar, İÇERİDEKİ METİN aynı sol kenarda kalır. Bu desen
   dosyada tek yerde tanımlı (§3) ve iç içe geçmeyecek şekilde bütçelenmiş.

   ── Ö5 · 390px'TE 264 ÖĞEDE KAYDIRMA ÇUBUĞU VARDI ─────────────────────────
   Taşma kaydırmaya çevrilerek "çözülmüştü"; her kutuya ayrı çubuk takmak
   çözüm değil.
   KARAR: tek meşru scroll container `.nt-sar` (çok sütunlu veri tablosu —
   sığdırmak sayıları okunmaz yapar). Kalan taşma kaynakları kaynağında
   kapatıldı: türetme tablosu blok düzenine geçti, `button.s-sik`e
   min-width:0, kapsama/notasyon tablolarına table-layout:fixed, formül
   sığmazsa JS puntosunu düşürüyor. Son emniyet main.govde'de
   `overflow-x: clip` — `hidden` DEĞİL: hidden diğer ekseni auto'ya zorlar
   ve elemanı scroll container yapar, clip yapmaz.

   ── Ö6 · 25 AYRI FONT-SIZE, 99'U GÖVDEDEN KÜÇÜK, SIRALAMA TERSTİ ─────────
   Formül 14px (gövdenin 0,78 katı), asıl anlatım metni #6b6152 ile sayfanın
   en soluk yazısıydı. Matematik notunda formül en küçük yazı olamaz.
   KARAR: 8 kademe (--f-h1 / h2 / h3 / mat / lead / govde / yardim / et), ara değer
   yok. Matematik taşıyan blok asla gövdeden küçük değil. Anlatım metni ana
   mürekkebe döndü; mürekkep 4 kademeden 3'e indi (--soluk kaldırıldı,
   kırılmasın diye --muted'a alias bırakıldı).

   ── Ö7 · 35 ZEMİN KURALI, 12 BORDER-RADIUS, 9 BORDER-LEFT ─────────────────
   Hepsi aynı ağırlıkta olduğu için hiçbiri bir şey ifade etmiyordu:
   "Try it yourself first" ile "Notation" piksel piksel aynıydı — sayfanın
   tek gerçek öğrenme anı bir dipnotla aynı görsel ağırlıktaydı.
   KARAR: sayfada İKİ yüzey var.
     YÜZEY 1  --surface + 1px kenarlık  = "sıra sende" (ön test · kontrol
              noktası · pratik grubu · merdiven)
     YÜZEY 2  --vurgu-zemin             = cevap / geri bildirim
   Başka zemin yok. Üç renk, üç anlam: accent = etkileşim ve YANLIŞ ·
   emerald = DOĞRU · amber = DİKKAT.

   ── Ö8 · 1440'TA BOŞLUKLAR 51 / 370 (7,2 KAT ASİMETRİ) ────────────────────
   Grid viewport'a simetrikti ama solda 320px'lik açık sidebar duruyordu.
   KARAR: sidebar bir sütun olarak sayılıyor. ≥1180px'te — JS'in perdeyi tam
   orada kapattığı, yani sidebar'ın kalıcı sütun olduğu eşik — main.govde
   `padding-left: var(--yan-g)` alıyor ve metin AÇIK ALANA ortalanıyor.
   <1180px'te sidebar metnin üstüne perdeyle geliyor; orada padding yok,
   yani dar ekranda metin bir piksel oynamıyor.

   ── Ö9 · `.kart-tek`, `.k-kopru`, `.nt-oku` TARAYICIDA BOŞ ────────────────
   Renderer md()'nin ürettiği <p>'yi bir <p>'nin içine koyuyor; parser
   dıştaki p'yi kapatıyor, metin sonraki çıplak <p>'ye kaçıyor. Bu bir
   renderer hatası ama CSS kendini korumalı: boş p gizleniyor, kaçan metin
   `:empty + p` ile yakalanıp doğru biçimlendiriliyor. 12 Eyl 2026: kardeş
   bir LİSTE geldiğinde o seçici tutmuyordu (`<ul>` bir `<p>` içinde geçerli
   değil, tarayıcı `<p>`yi listenin ÖNÜNDE kapatıyor ve ardından gelen şey
   paragraf değil liste oluyor) — liste küçük-soluk yerine gövde
   punto/renginde çiziliyordu. `:empty + ul` ve `:empty + ol` eklendi.

   ── DEĞİŞMEYEN SÖZLEŞMELER ────────────────────────────────────────────────
   · Arayüz (topbar, düğme) px; İÇERİK rem — punto düğmesi yalnız metni
     büyütsün. JS html'in font-size'ını 16/17/18/19.5/21 arasında değiştirir.
   · Gece modu ayrı palet değil, aynı değişkenlerin yeniden tanımı.
   · Gece modu · punto (5 kademe) · sözlük popover · AI popover · ilerleme
     çubuğu · açılır yan menü: sınıfları HTML'de sabit, hepsi korundu.
   · Genel eleman kuralları `:where(main.govde)` ile yazılıyor: kapsam verir
     ama specificity eklemez, böylece sınıf kuralları onları ezebiliyor.
   ═══════════════════════════════════════════════════════════════════════════ */


/* ══ 1 · DEĞİŞKENLER ═══════════════════════════════════════════════════════ */

:root {
  /* kâğıt ve yüzey — sayfada sadece iki yüzey var (Ö7) */
  --paper:        #faf6ee;
  --paper-soft:   #f4efe3;              /* yalnız arayüz: kod, düğme hover */
  --surface:      #fffdf8;              /* YÜZEY 1 · "sıra sende" */
  --vurgu-zemin:  rgba(181,58,42,.07);  /* YÜZEY 2 · cevap / geri bildirim */

  /* mürekkep: ÜÇ kademe, dördüncü yok (Ö6) */
  --ink:          #241f16;   /* başlık · FORMÜL · cevap */
  --ink-2:        #3c352a;   /* bütün nesir */
  --muted:        #6b6152;   /* mono etiket · gerekçe satırı */
  --soluk:        #6b6152;   /* geriye dönük alias; yeni kural KULLANMAZ */

  --border:       #e6dfd0;
  --border-strong:#d8cfba;

  /* üç renk, üç anlam */
  --accent:       #B53A2A;   /* etkileşim + YANLIŞ */
  --emerald:      #2c6a4c;   /* DOĞRU */
  --amber:        #A36418;   /* DİKKAT */

  --golge: 0 12px 34px rgba(36,31,22,.16);
  --fig-zemin: transparent;

  --serif:  'Literata', Georgia, 'Times New Roman', serif;
  --baslik: 'Crimson Pro', Georgia, serif;
  --ui:     'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  --mono:   'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, monospace;

  /* TİP ÖLÇEĞİ · 8 kademe, ara değer yok (Ö6). İÇERİK kademeleri bunlar;
     aşağıdaki px değerleri yalnız ARAYÜZ (topbar, popover, yan menü, düğme)
     ve bilerek okur puntosuyla büyümüyor. Hepsi rem: punto düğmesi
     html'in font-size'ını değiştiriyor. --f-et'in tabanı var, en küçük
     kademede bile okunur kalsın. */
  --f-h1:     2.60rem;               /* ~47px */
  --f-h2:     1.88rem;               /* ~34px */
  --f-h3:     1.32rem;               /* ~24px */
  --f-mat:    1.12rem;               /* ~20px · matematik taşıyan satır */
  --f-lead:   1.08rem;               /* ~19px · kanca, tek cümlelik özet, h4 */
  --f-govde:  1rem;                  /*  18px */
  --f-yardim: .84rem;                /* ~15px · açıklama, gerekçe */
  --f-et:     max(12.5px, .72rem);   /* ~13px · SADECE mono etiket */

  /* boşluk ölçeği · rem, metinle birlikte büyür */
  --b1: .4rem;  --b2: .85rem;  --b3: 1.6rem;  --b4: 2.6rem;  --b5: 4rem;

  --yan-g: 320px;   /* yan menü genişliği */
  --ust-y: 46px;    /* üst şerit yüksekliği */
}

html[data-tema="gece"] {
  --paper:        #15130f;
  --paper-soft:   #1c1913;
  --surface:      #201d16;
  --vurgu-zemin:  rgba(232,138,116,.13);

  --ink:          #f3ede1;
  --ink-2:        #ddd5c6;
  --muted:        #a99e8b;
  --soluk:        #a99e8b;

  --border:       #332f26;
  --border-strong:#484133;

  --accent:       #e88a74;
  --emerald:      #7cc79f;
  --amber:        #ddaa66;

  --golge: 0 12px 34px rgba(0,0,0,.55);
  /* Üretilen SVG'ler koyu mürekkeple çizildi; gece modunda kaybolmasınlar
     diye kendi kâğıtlarının üzerinde duruyorlar. */
  --fig-zemin: #f6f2e8;
}


/* ══ 2 · TEMEL ═════════════════════════════════════════════════════════════ */

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

html {
  font-size: 18px;              /* JS 16–21 arasında değiştirir */
  scroll-behavior: smooth;
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink-2);
  font-family: var(--serif);
  font-size: var(--f-govde);
  line-height: 1.72;
  font-optical-sizing: auto;
  text-rendering: optimizeLegibility;
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3, h4 {
  margin: 0;
  font-family: var(--baslik);
  color: var(--ink);
  line-height: 1.16;
  letter-spacing: -.005em;
}
h1 { font-size: var(--f-h1); font-weight: 500; font-style: italic; letter-spacing: -.015em; }
h2 { font-size: var(--f-h2); font-weight: 600; }
h3 { font-size: var(--f-h3); font-weight: 600; }
h4 { font-size: var(--f-lead); font-weight: 600; }

p  { margin: 0 0 .95em; }
/* Girinti `em` DEĞİL `rem`: em yerel puntoya bağlı olduğu için --f-yardim
   taşıyan bloklarda liste 20,4px, gövde puntosunda 24,3px giriyordu —
   ölçüldü, aynı sayfada üç ayrı liste hizası vardı (391 · 395 · 396 px). */
ul, ol { margin: 0 0 .95em; padding-left: 1.35rem; }
li { margin-bottom: .3em; }
a  { color: var(--accent); text-underline-offset: 2px; }
b, strong { color: var(--ink); font-weight: 600; }

code {
  font-family: var(--mono); font-size: .8em;
  background: var(--paper-soft); padding: 1px 5px; border-radius: 3px;
}

/* Kod listesi (CS 115, 11 Eyl). Programlama dersinde GIRINTI anlamlidir:
   blok <pre> ile basilir, satir sonlari ve bosluklar aynen kalir. Uzun satir
   sayfayi yatay kaydirmaz, kendi kutusunda kayar. */
pre.kod {
  font-family: var(--mono); font-size: .82em; line-height: 1.55;
  background: var(--paper-soft); color: var(--ink-2);
  border: 1px solid var(--border); border-left: 3px solid var(--border-strong);
  border-radius: 4px; padding: .7em .9em; margin: 0 0 .95em;
  overflow-x: auto; -webkit-overflow-scrolling: touch;
  white-space: pre; tab-size: 4;
}
pre.kod code {
  background: none; padding: 0; border-radius: 0; font-size: inherit;
}

::selection { background: var(--vurgu-zemin); }
:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 2px; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    transition-duration: .01ms !important;
    animation-duration: .01ms !important;
  }
}


/* ══ 3 · TEK HİZALAMA SİSTEMİ ══════════════════════════════════════════════
   Sayfanın TEK bir sütun sistemi var:

     [tam-start] kenar | [metin-start] okuma sütunu [metin-end] | kenar [tam-end]

   Çizgi adları İngilizce `-start`/`-end`: `grid-column: ad` kısayolu ancak
   çizgiler `ad-start`/`ad-end` diye adlandırılmışsa çalışır; Türkçe
   `-bas`/`-son` eki o eşleşmeyi YAPMAZ (bu hata bugün 104px taşmaya sebep
   oldu). Aşağıda yine de her yerde açık `metin-start / metin-end` yazılı.

   NEDEN SUBGRID DEĞİL: taşırılması gereken şeyler (figür, veri tablosu,
   sığmayan display formül) DOM'da 2–5 seviye derinde. Subgrid ancak
   DOĞRUDAN çocuğa sütun verebilir; derindekiler için yine ikinci bir
   mekanizma gerekirdi ve iki mekanizma = iki hiza. Bu yüzden tek mekanizma
   var: NEGATİF MARGIN ile simetrik taşma. `--kenar` kenar boşluğunun garanti
   ALT SINIRI olduğu için `margin-inline: calc(-1 * var(--kenar))` hiçbir
   genişlikte sayfayı taşırmaz: en dar ekranda tam kenara oturur, geniş
   ekranda okuma sütununun biraz dışına çıkar.

   Taşma bütçesi İÇ İÇE GEÇMEZ: zemin taşıyan blok `--pay` kadar dışarı
   çıkarken kendi içindekiler için kalan bütçeyi (`--tas`) düşürüyor.
   Yoksa 390px'te zemin 16px + formül 16px = 32px taşma olurdu.
   ═══════════════════════════════════════════════════════════════════════════ */

main.govde {
  --olcu:  38rem;                      /* okuma sütunu ~ 68–72 karakter */
  --kenar: clamp(16px, 4vw, 56px);     /* kenar boşluğunun ALT SINIRI */
  --pay:   min(var(--kenar), 18px);    /* zeminli bloğun taşma payı */
  --tas:   var(--kenar);               /* derindeki öğeye kalan taşma bütçesi */

  display: grid;
  grid-template-columns:
    [tam-start]   minmax(var(--kenar), 1fr)
    [metin-start] min(var(--olcu), 100% - var(--kenar) * 2)
    [metin-end]   minmax(var(--kenar), 1fr) [tam-end];
  /* Gride sığmayan bir şey olursa yeni sütun AÇMASIN: ölçüldü, 104 piksellik
     bir implicit sütun açılıyor ve sayfa tam o kadar yana kayıyordu. */
  grid-auto-columns: 0;
  grid-auto-flow: row;

  padding: var(--b3) 0 var(--b5);
  /* SON EMNİYET (Ö5). Kenar boşluğuna taşan figür ve formül clip kenarının
     İÇİNDE kalır; sayfayı taşıran bir şey olursa yatay kaydırma yerine
     sessizce kırpılır. */
  overflow-x: clip;
}

main.govde > * {
  grid-column: metin-start / metin-end;
  min-width: 0;      /* grid item'da min-width:auto = min-content -> taşma */
  margin-top: 0;
}

/* Ö8 · sidebar bir sütun olarak sayılıyor. Eşik 1180px, çünkü JS perdeyi tam
   orada kapatıyor (perde.hidden = ... innerWidth >= 1180). */
@media (min-width: 1180px) {
  main.govde { transition: padding-left .22s cubic-bezier(.4,0,.2,1); }
  body.menu-acik main.govde { padding-left: var(--yan-g); }
}

/* Okuma sütununu AŞAN iki şey — ikisi de aynı mekanizma, aynı bütçe.
   `.katex-display.genis` BİLEREK BU LİSTEDE DEĞİL: notes_bolum.css
   `.kb-ifade` ve `.c-son`a `overflow-x: auto` veriyor, yani onlar birer
   scroll container. Bir scroll container SOL taşmayı erişilemez kılar
   (sola scrollLeft<0 diye bir şey yok). Ölçüldü: formül gutter'a taştığında
   390px'te 16 `.genis`in 9'u, 1440px'te 3'ünün 3'ü baştan 16/56 piksel
   kesiliyordu — `\lim_{x\to a}f` görünmüyor, formül "(x)=∞" diye başlıyordu.
   Sığdırma merdiveninin 2. basamağı bu yüzden §15'te taşma değil KENDİ
   KUTUSUNDA KAYDIRMA olarak uygulanıyor. */
main.govde figure,
main.govde .nt-sar { margin-inline: calc(-1 * var(--tas)); }

/* Zemin taşıyan blok: metin aynı sol kenarda kalsın (Ö4). Bu blok kendi
   içindekilerin taşma bütçesini de düşürüyor, taşmalar toplanmasın. */
main.govde .ontest,
main.govde .kontrol,
main.govde .merdiven,
main.govde .pr-grup {
  /* Bu blokların 1px kenarlığı var; padding'den o 1px düşülüyor, yoksa
     içerideki metin okuma sütunundan 1px sağa kayıyor (ölçüldü: 371 yerine
     372). Dış kenar yine tam --pay kadar dışarıda. */
  margin-inline: calc(-1 * var(--pay));
  padding-inline: calc(var(--pay) - 1px);
  --tas: calc(var(--kenar) - min(var(--kenar), 18px));
}


/* ══ 4 · SAYFA KABUĞU ══════════════════════════════════════════════════════ */

/* OKUMA ILERLEMESI · iz + dolgu.
   Alperen, 12 Eyl: "ben derslerde yukarıda ilerleyen bar görmeyi severim.
   insanlara bu estetiği sunuyor muyuz". Çubuk zaten vardı ama İZİ yoktu:
   sayfanın başında `scaleX(0)` ile tamamen görünmezdi, yani bir ilerleme
   göstergesi olduğu hiç belli olmuyordu. Şimdi kılcal bir iz her zaman
   duruyor ve dolgusu kaydırmayla büyüyor; gösterge kendini tanıtıyor.
   Dolgu artık `::after` ve ölçek bir CSS değişkeninden geliyor (JS
   `--ilr` yazıyor), böylece iz sabit kalıyor. */
.ilerleme {
  position: fixed; inset: 0 0 auto 0; height: 2px; z-index: 40;
  background: var(--border);
}
.ilerleme::after {
  content: ''; display: block; height: 100%;
  background: var(--accent);
  transform: scaleX(var(--ilr, 0)); transform-origin: 0 50%;
  will-change: transform;
}

.ust {
  position: sticky; top: 0; z-index: 30;
  background: var(--paper); border-bottom: 1px solid var(--border);
}
.ust-ic {
  display: flex; align-items: center; gap: 14px;
  min-height: var(--ust-y); padding: 0 16px; font-family: var(--ui);
}
.ust-ic > * { min-width: 0; }
.ust a.logo {
  font-family: var(--baslik); font-style: italic; font-size: 19px;
  color: var(--ink); text-decoration: none; line-height: 1; white-space: nowrap;
}
.ust a.logo b { color: var(--accent); font-style: normal; font-size: 12px;
  vertical-align: super; font-weight: 400; }
.ust nav {
  display: flex; gap: 14px; margin-left: 4px;
  font-family: var(--mono); font-size: 10.5px;
  letter-spacing: .06em; text-transform: uppercase;
}
.ust nav a { color: var(--muted); text-decoration: none; white-space: nowrap; }
.ust nav a:hover { color: var(--accent); }
.ust-arac { margin-left: auto; display: flex; align-items: center; gap: 8px; }

.menu-dugme, .tema-dugme, .boyut button, .ic-kapa {
  font: inherit; cursor: pointer; color: var(--muted);
  background: transparent; border: 1px solid var(--border); border-radius: 7px;
}
.menu-dugme { display: inline-flex; align-items: center; gap: 7px;
  padding: 5px 10px; font-size: 11px; letter-spacing: .04em; }
.menu-dugme:hover, .tema-dugme:hover, .boyut button:hover {
  color: var(--accent); border-color: var(--accent); }
.menu-cizgi { position: relative; width: 14px; height: 9px;
  border-top: 1.5px solid currentColor; border-bottom: 1.5px solid currentColor; }
.menu-cizgi::after { content: ''; position: absolute; left: 0; right: 0;
  top: calc(50% - .75px); border-top: 1.5px solid currentColor; }
body.menu-acik .menu-cizgi { border-color: transparent; }
body.menu-acik .menu-cizgi::after { transform: rotate(45deg); }
body.menu-acik .menu-cizgi::before { content: ''; position: absolute; left: 0; right: 0;
  top: calc(50% - .75px); border-top: 1.5px solid currentColor; transform: rotate(-45deg); }
body.menu-acik .menu-dugme { color: var(--accent); border-color: var(--accent); }

.tema-dugme { width: 28px; height: 26px; font-size: 13px; line-height: 1; padding: 0; }
.boyut { display: flex; gap: 3px; }
.boyut button { width: 28px; height: 26px; padding: 0; font-size: 11.5px;
  font-weight: 600; font-family: var(--ui); }
.boyut button span { font-size: 9px; vertical-align: 1px; }
@media (max-width: 560px) {
  .boyut, .menu-yazi { display: none; }
  .ust nav a:not(:last-child) { display: none; }
}

.icindekiler {
  position: fixed; top: var(--ust-y); left: 0; bottom: 0; width: var(--yan-g);
  z-index: 25;
  overflow-y: auto; overscroll-behavior: contain;
  background: var(--paper); border-right: 1px solid var(--border);
  padding: 14px 12px 40px 18px;
  font-family: var(--ui); font-size: 12.5px; line-height: 1.5;
  transform: translateX(-100%); visibility: hidden;
  transition: transform .22s cubic-bezier(.4,0,.2,1), visibility 0s .22s;
}
body.menu-acik .icindekiler {
  transform: none; visibility: visible;
  transition: transform .22s cubic-bezier(.4,0,.2,1), visibility 0s 0s;
}
/* Dar ekranda metnin ÜSTÜNE geliyor: orada gölge gerekiyor. Geniş ekranda
   kalıcı sütun, orada gölge gürültü olurdu. */
@media (max-width: 1179px) { body.menu-acik .icindekiler { box-shadow: var(--golge); } }

.ic-bas { display: flex; align-items: center; gap: 8px; margin-bottom: 10px; }
.ic-bas > * { min-width: 0; }
.icindekiler h4 {
  flex: 1; font-family: var(--mono); font-size: 10px; font-weight: 400;
  letter-spacing: .1em; text-transform: uppercase; color: var(--muted);
}
.icindekiler h4 a { color: inherit; text-decoration: none; }
.icindekiler h4 a:hover { color: var(--accent); }
.ic-kapa { width: 24px; height: 24px; padding: 0; font-size: 17px;
  line-height: 1; border-color: transparent; }
.icindekiler ul { list-style: none; margin: 0; padding: 0; }
.icindekiler li { margin: 0; }
/* DİKKAT: bunlar başlık değil — class'ı h2/h3 olan <a> etiketleri. */
.icindekiler a {
  display: block; padding: 4px 9px;
  color: var(--ink-2); text-decoration: none;
  border-left: 2px solid transparent;
}
.icindekiler a:hover { color: var(--accent); }
.icindekiler a.h2 { font-weight: 600; margin-top: 10px; color: var(--ink); }
.icindekiler a.h3 { padding-left: 20px; font-size: 12px; color: var(--muted); }
.icindekiler a.aktif { border-left-color: var(--accent); color: var(--accent); }
.ic-diger {
  display: block; margin: 16px 9px 0; padding: 10px 0 0;
  border-top: 1px solid var(--border);
  font-size: 12px; color: var(--muted); text-decoration: none;
}
.ic-diger:hover { color: var(--accent); }

.perde {
  position: fixed; inset: 0; z-index: 24;
  background: rgba(20,17,12,.44); opacity: 0; transition: opacity .22s;
}
body.menu-acik .perde { opacity: 1; }


/* ══ 5 · POPOVER'LAR (sözlük + yapay zekâya sor) ═══════════════════════════ */

.sz-term {
  display: inline; font: inherit; color: inherit; background: none;
  border: 0; padding: 0; margin: 0; text-align: inherit; cursor: help;
  border-bottom: 1px dotted var(--border-strong); text-underline-offset: 2px;
}
.sz-term:hover, .sz-term[aria-expanded="true"] {
  color: var(--accent); border-bottom-color: var(--accent);
}
/* Başlığın İÇİNDEKİ terimin altı çizilmesin: 390px'te üç satıra saran bir
   h2'nin altında üç ayrı, farklı hizada nokta çizgi oluşuyordu — "yamuk"
   görüntüsünün doğrudan kaynağı. Terim etkileşimi gövdede kalıyor. */
h1 .sz-term, h2 .sz-term, h3 .sz-term, h4 .sz-term,
summary .sz-term, .kb-bas .sz-term { border-bottom: 0; }

.sz-pop {
  position: fixed; z-index: 70; max-width: min(330px, calc(100vw - 24px));
  padding: 10px 12px;
  background: var(--surface); border: 1px solid var(--border-strong);
  border-radius: 8px; box-shadow: var(--golge);
  font-family: var(--ui); font-size: 12.5px; line-height: 1.55; color: var(--ink-2);
}
.sz-pop b { display: block; font-size: 13px; color: var(--ink); }
.sz-pop i { font-style: normal; font-size: 11.5px; color: var(--muted); }
.sz-pop p { margin: 5px 0 0; }

/* ── YAPAY ZEKÂYA SOR: TERMİNAL PENCERESİ ─────────────────────────────────
   Alperen, 12 Eyl: "ask an ai kısmını daha retrotik mi ikonik mi dersin bi
   hale getirelim bu haliyle arada kanamasının yanı sıra epey ucuz duruyor.
   havalı olsun."

   İlk hâlin iki gerçek kusuru vardı:
   1. UCUZ: her şey 10-11,5px, hap biçimli, gri, `opacity .7`. Tarayıcı
      eklentisi çipi gibi duruyordu, sayfanın dilinde değil.
   2. KANAMA: düğme blokların ARASINDA duruyordu (`margin: 12px 0 0`) ve
      fareyle üstünden geçerken soluklaşıp parlıyordu; göz onu bir yere ait
      saymıyordu.

   Yeni dil sayfanın kendi yeni dili: §24'te kendi terminalimizi kurduk.
   Düğme bir KOMUT SATIRI çipi (`▸ ask an AI`), açılan kutu bir TERMİNAL
   PENCERESİ — başlık çubuğu, karanlık gövde, yeşil istem. Retro ve ikonik
   olan şey bu: 1980'lerin bilgisayarı, okuma sayfasının içinde küçük bir
   pencere. Soluklaşma kaldırıldı, kenar her zaman duruyor: titremiyor. */

.ai-sor {
  display: inline-flex; align-items: center; gap: .45em;
  margin: var(--b2) 0 0; padding: .32em .7em .32em .55em; cursor: pointer;
  font-family: var(--kod-mono, var(--mono)); font-size: var(--f-et);
  color: var(--muted); background: var(--paper-soft);
  border: 1px solid var(--border); border-radius: 3px;
  transition: color .18s ease, border-color .18s ease, background-color .18s ease;
}
/* KOMUT ISTEMI GLIF DEGIL, KENARLIK UCGENI (§18 `.kz-ok` ile ayni gerekce).
   Burada `content: '\25b8'` duruyordu. U+25B8 urettigimiz yedi fontun
   yalniz JetBrains Mono'sunda var, ama bu cip `--kod-mono` ile ciziliyor ve
   o yigin §24'te isletim sistemine gore degisiyor:
     linux -> 'JetBrains Mono', ...      (bizim fontumuz, glif VAR)
     win   -> Consolas, 'Cascadia Mono', 'Lucida Console', ui-monospace
     mac   -> 'SF Mono', SFMono-Regular, Menlo, Monaco, ui-monospace
   Son ikisinde BIZIM HICBIR FONTUMUZ YOK: glif isletim sisteminin sembol
   fontuna kaliyor (Segoe UI Symbol / Apple Symbols), boyu ve agirligi cipin
   yazisiyla uyusmuyor, tasimayan sistemde tofu. `.zor` zorluk noktalarinin
   ve `.kz-ok` satir imlecinin ayni kusuru.
   Ucgen hicbir fonta bagli degil. Olculdu (Brave, tam genislik ve 360px,
   `.ai-et` acik): cip 111,11 -> 111,08 px, ikonun sol kenari 0,03 px
   oynuyor, ucgenin murekkebi glifinkiyle ayni buyuklukte (ekran
   goruntusuyle karsilastirildi). `padding-right` glifin ilerleme
   genisligini (0,614em) tamamliyor: kenarlik payi cikinca kalan kismi odur.
   Ipucu ampulu bu oneki zaten kaldiriyor (`.ip-ac::before{content:none}`,
   S29) -- o kural degismedi. */
.ai-sor::before {
  content: ''; flex: none; box-sizing: content-box; width: 0; height: 0;
  font-size: .95em; line-height: 1;
  border-style: solid; border-width: .17em 0 .17em .34em;
  padding-right: .274em;
  border-color: transparent transparent transparent var(--accent);
}
.ai-sor:hover { color: var(--ink); border-color: var(--border-strong); }
.ai-sor:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.ai-sor > svg { flex: none; }

/* ── SIMGE ONCE, ETIKET HOVER'DA ──
   Alperen, 12 Eyl: "ask to ai yerine logo koysak hoverlanınca ask to ai
   yazsa mesela. biraz animasyon biraz hareket be abicim."
   Etiket DOM'dan SILINMIYOR, genisligi 0'a iniyor: ekran okuyucu ve arama
   motoru yaziyi goruyor, goz gormuyor. Dokunmatikte hover yok, orada etiket
   acik duruyor.

   ETIKET YALNIZ KENDI CIPININ HOVER'INDA ACILIYOR (12 Eyl, Alperen: "hint'in
   uzerine hoverlayinca ask an AI de hoverlaniyor. daha lokalize olmali bu
   isler"). Eski kural blok bazliydi (`.soru:hover > .ai-sor .ai-et`): sorunun
   HERHANGI bir yerine gelmek "ask an AI" etiketini aciyordu, ipucu ampulu de
   o blogun icinde oldugu icin ampule gelmek iki etiketi birden aciyordu.
   Blok hover'i SILINMIYOR ama isi degisiyor: cip yalniz BELIRGINLESIYOR
   (renk + kenar), yazi ve hareket cipin kendi hover'ina kaliyor. Gerekce:
   13px'lik simgeyi kesfetmek icin bloga gelmek yetsin diye konmustu, o
   kesfedilebilirlik korunuyor; ama YAZI isaret edilen seye ait. */
.ai-sor { gap: 0; padding: .32em .5em; }
.ai-et {
  display: inline-block; max-width: 0; overflow: hidden;
  white-space: nowrap; opacity: 0;
  transition: max-width .26s cubic-bezier(.4, 0, .2, 1),
              opacity .2s ease, margin-left .26s cubic-bezier(.4, 0, .2, 1);
}
.ai-sor:hover .ai-et, .ai-sor:focus-visible .ai-et {
  max-width: 9em; opacity: 1; margin-left: .45em;
}
/* Blok hover'i: yalniz DOGRUDAN cocuk cip (yani "ask an AI") belirginlesiyor.
   `>` zorunlu — descendant secici ampulu de yakalar ve AI cipini hoverlamak
   ampulu de degistirirdi (ayni kanamanin ters yonu). */
.soru:hover > .ai-sor, .ornek:hover > .ai-sor {
  color: var(--ink); border-color: var(--border-strong);
}
.ai-sor > svg {
  transition: transform .34s cubic-bezier(.34, 1.56, .64, 1);
}
.ai-sor:hover > svg, .ai-sor:focus-visible > svg {
  transform: rotate(-16deg) scale(1.14);
}
@media (hover: none) {
  .ai-et { max-width: 9em; opacity: 1; margin-left: .45em; }
}
@media (prefers-reduced-motion: reduce) {
  .ai-et, .ai-sor > svg { transition: none; }
  .ai-sor:hover > svg, .ai-sor:focus-visible > svg { transform: none; }
}

/* ── açılan pencere ── */
.ai-pop {
  position: fixed; z-index: 60; padding: 0; overflow: hidden;
  background: var(--trm-zemin, #1d1f21);
  border: 1px solid color-mix(in srgb, var(--trm-zemin, #1d1f21) 60%, var(--border-strong));
  border-radius: var(--pnc-yuvarti, 6px);
  box-shadow: var(--golge); font-family: var(--kod-mono, var(--mono));
}
/* Başlık çubuğu: terminalin kendi çubuğu, aynı token kümesi (§24). */
.ai-bas {
  display: flex; align-items: center; gap: .7em;
  margin: 0; padding: .42em .7em;
  background: var(--trm-bas, #2a2c2e);
  font-family: var(--kod-mono, var(--mono)); font-size: 10.5px;
  letter-spacing: .06em; text-transform: uppercase;
  color: color-mix(in srgb, var(--trm-ink, #e8e6e3) 78%, transparent);
}
.ai-bas > span { flex: 1; min-width: 0; }
.ai-kapa {
  width: 20px; height: 20px; padding: 0; font-size: 15px; line-height: 1;
  cursor: pointer; border: 0; border-radius: 3px;
  color: color-mix(in srgb, var(--trm-ink, #e8e6e3) 70%, transparent);
  background: transparent;
}
.ai-kapa:hover {
  color: var(--trm-ink, #e8e6e3);
  background: color-mix(in srgb, var(--trm-ink, #e8e6e3) 14%, transparent);
}
.ai-ipuc {
  margin: 0; padding: .6em .75em .1em;
  font-size: 11.5px; line-height: 1.5;
  color: color-mix(in srgb, var(--trm-ink, #e8e6e3) 62%, transparent);
}
/* İstem satırı: metnin bir KOMUT olduğunu söylüyor. */
.ai-ipuc::before {
  content: '$ '; color: var(--trm-istem, #7fd1b9);
}
.ai-metin {
  display: block; width: calc(100% - 1.5em); max-height: 40vh; resize: vertical;
  margin: .55em .75em 0; padding: .55em .6em;
  font-family: var(--kod-mono, var(--mono)); font-size: 11.5px; line-height: 1.6;
  color: var(--trm-ink, #e8e6e3);
  background: color-mix(in srgb, var(--trm-ink, #e8e6e3) 7%, transparent);
  border: 1px solid color-mix(in srgb, var(--trm-ink, #e8e6e3) 20%, transparent);
  border-radius: 3px; caret-color: var(--trm-istem, #7fd1b9);
}
.ai-metin:focus {
  outline: none;
  border-color: var(--trm-istem, #7fd1b9);
}
.ai-btn {
  display: flex; gap: .45em; flex-wrap: wrap;
  margin: 0; padding: .6em .75em .7em;
}
.ai-btn button, .ai-btn a {
  font-family: var(--kod-mono, var(--mono)); font-size: 11.5px;
  padding: .35em .85em; cursor: pointer; text-decoration: none;
  color: color-mix(in srgb, var(--trm-ink, #e8e6e3) 82%, transparent);
  background: color-mix(in srgb, var(--trm-ink, #e8e6e3) 8%, transparent);
  border: 1px solid color-mix(in srgb, var(--trm-ink, #e8e6e3) 22%, transparent);
  border-radius: 3px;
  transition: color .18s ease, border-color .18s ease, background-color .18s ease;
}
.ai-btn a:hover, .ai-btn button:hover {
  color: var(--trm-ink, #e8e6e3);
  border-color: var(--trm-istem, #7fd1b9);
}
/* Birincil eylem: panoya kopyala. Terminalin isteminin renginde. */
.ai-btn .birincil {
  color: #10231d; background: var(--trm-istem, #7fd1b9);
  border-color: var(--trm-istem, #7fd1b9); font-weight: 600;
}
.ai-btn .birincil:hover {
  color: #10231d;
  background: color-mix(in srgb, var(--trm-istem, #7fd1b9) 85%, #fff);
  border-color: color-mix(in srgb, var(--trm-istem, #7fd1b9) 85%, #fff);
}
.ai-btn .birincil.oldu { background: var(--emerald); border-color: var(--emerald); color: #fff; }
.ai-uyari {
  margin: 0; padding: 0 .75em .7em; font-size: 11px; line-height: 1.5;
  color: color-mix(in srgb, var(--amber) 72%, var(--trm-ink, #e8e6e3));
}


/* ══ 6 · GÖVDENİN ORTAK ELEMAN KURALLARI ═══════════════════════════════════
   Hepsi `:where(main.govde)` ile: kapsam verir, specificity eklemez. */

/* Ö9 · boş kalan sarmalayıcıyı gizle. */
:where(main.govde) p:empty { display: none; }
:where(main.govde) p:last-child,
:where(main.govde) ul:last-child,
:where(main.govde) ol:last-child { margin-bottom: 0; }

/* <details> · varsayılan SESSİZ. Yalnız `.ontest` bir "sıra sende" bloğu ve
   öyle görünüyor (Ö7). */
:where(main.govde) details { margin-bottom: var(--b3); }
:where(main.govde) summary {
  cursor: pointer; list-style: none;
  font-family: var(--mono); font-size: var(--f-et);
  letter-spacing: .08em; text-transform: uppercase; color: var(--muted);
}
:where(main.govde) summary::-webkit-details-marker { display: none; }
:where(main.govde) summary::before {
  content: '+'; display: inline-block; width: 1.2em;
  color: var(--border-strong); font-weight: 500;
}
:where(main.govde) details[open] > summary::before { content: '–'; }
:where(main.govde) summary:hover,
:where(main.govde) summary:hover::before { color: var(--accent); }
:where(main.govde) summary p { display: inline; margin: 0; }


/* ══ 7 · SAYFA GÖVDESİ (bölümlerin dışı) ═══════════════════════════════════ */

.geri {
  display: inline-block; margin-bottom: var(--b3);
  font-family: var(--mono); font-size: var(--f-et);
  letter-spacing: .05em; color: var(--muted); text-decoration: none;
}
.geri:hover { color: var(--accent); }

/* h1 iki yerde olabiliyor: dizin sayfasında main'in doğrudan çocuğu,
   bölüm sayfasında `section.bolum > h1.bolum-h1`. İkisi de aynı kurala tabi;
   seçici bilerek `>` DEĞİL. */
main.govde h1 { margin-bottom: var(--b3); }
/* Bölüm başlığı sayfanın tek konusu, o yüzden sayfanın en büyük yazısı.
   Dar ekranda --f-h1 (47px) uzun başlıkları beş satıra düşürüyor; orada
   bir kademe iniyor. Yeni bir punto değeri EKLENMEDİ, mevcut ikisi. */
.bolum-h1 { font-style: normal; font-weight: 600; font-size: var(--f-h2); }
@media (min-width: 768px) { .bolum-h1 { font-size: var(--f-h1); } }

/* Bölüm numarası. Dar ekranda başlığın üstünde mono etiket, ≥1280px'te sol
   boşlukta. Eşik 1100 değil 1280: 1180'de sidebar açıkken kenar boşluğu
   70px kalıyor ve 34px'lik bir numara + aralık oraya sığmıyor; 1280'de
   boşluk ~120px, rahat sığıyor. Metnin hizasına dokunmuyor. */
.h1-no {
  display: block; margin-bottom: .5rem;
  font-family: var(--mono); font-size: var(--f-et); font-style: normal;
  font-weight: 400; letter-spacing: .14em; color: var(--muted);
}
@media (min-width: 1280px) {
  main.govde h1 { position: relative; }
  .h1-no {
    position: absolute; right: 100%; top: .22em; margin: 0 .5em 0 0;
    font-family: var(--baslik); font-size: var(--f-h2); font-weight: 500;
    letter-spacing: 0; color: var(--border-strong); white-space: nowrap;
  }
}

.ozet-serit {
  display: flex; gap: 18px; flex-wrap: wrap; margin-bottom: var(--b3);
  font-family: var(--mono); font-size: var(--f-et);
  letter-spacing: .04em; color: var(--muted);
}
.ozet-serit > * { min-width: 0; }
.ozet-serit b { color: var(--ink); font-weight: 500; }

.yerimi {
  margin-bottom: var(--b2); padding: var(--b2) 0;
  border-top: 1px solid var(--border); border-bottom: 1px solid var(--border);
  font-family: var(--ui); font-size: var(--f-yardim); color: var(--ink-2);
}
.yerimi a { font-weight: 600; }
.yerimi-kapa {
  font: inherit; font-size: 11.5px; margin-left: 8px; padding: 2px 8px; cursor: pointer;
  color: var(--muted); background: transparent;
  border: 1px solid var(--border); border-radius: 999px;
}

/* "Bu notlar üretildi" uyarısı: kutu değil — dikkat rengi + ince çizgi. */
.uyari-kutu {
  margin-bottom: var(--b3); padding: var(--b2) 0;
  border-top: 1px solid var(--border); border-bottom: 1px solid var(--border);
  font-family: var(--ui); font-size: var(--f-yardim); line-height: 1.6;
  color: var(--muted);
}
.uyari-kutu strong { color: var(--amber); }

.onizleme {
  margin-top: var(--b2); padding: var(--b2) 0;
  border-top: 1px solid var(--border);
  font-family: var(--ui); font-size: var(--f-yardim); color: var(--ink-2);
}

.arac-serit { display: flex; gap: 7px; flex-wrap: wrap; }
.arac-serit > * { min-width: 0; }
.arac-serit button {
  font-family: var(--ui); font-size: 11.5px; padding: 5px 12px; cursor: pointer;
  color: var(--muted); background: transparent;
  border: 1px solid var(--border); border-radius: 999px;
}
.arac-serit button:hover { border-color: var(--accent); color: var(--accent); }
/* "quiz me with an AI" bir açıp-kapama değil bir EYLEM: komşularından ayrılsın
   ama şeridi de ele geçirmesin. Alperen'in kuralı gereği istem öğrencinin
   kendi hesabına gidiyor, sunucuda hiçbir şey kaydedilmiyor. */
#ai-bolum { color: var(--accent); border-color: var(--border-strong); }
.arac-serit button[aria-pressed="true"] {
  background: var(--ink); color: var(--paper); border-color: var(--ink);
}

/* ── bölümler arası gezinme (sayfa başına tek bölüm basıldığından beri) ──
   Kutu değil: üstten ince çizgi + mono etiket. Yön bilgisini konum veriyor. */
.bolum-gez {
  display: flex; justify-content: space-between; gap: var(--b3);
  margin-top: var(--b5); padding-top: var(--b2);
  border-top: 1px solid var(--border);
}
.bolum-gez > * { min-width: 0; flex: 0 1 auto; }
.bg-onceki, .bg-sonraki {
  display: block; text-decoration: none; color: var(--ink);
  font-family: var(--baslik); font-size: var(--f-h3); font-weight: 600;
  line-height: 1.2;
}
.bg-sonraki { text-align: right; }
.bg-onceki > span, .bg-sonraki > span {
  display: block; margin-bottom: var(--b1);
  font-family: var(--mono); font-size: var(--f-et); font-weight: 400;
  letter-spacing: .1em; text-transform: uppercase; color: var(--muted);
}
.bg-onceki:hover, .bg-sonraki:hover { color: var(--accent); }
@media (max-width: 620px) { .bolum-gez { flex-direction: column; }
  .bg-sonraki { text-align: left; } }

/* ── notes dizini: bölüm listesi ──
   14 satır, kutu yok; ayıran şey yatay ince çizgi ve mono numara. */
.bk-liste { margin: var(--b3) 0 0; }
.bk {
  display: block; padding: var(--b3) 0; text-decoration: none;
  border-top: 1px solid var(--border);
}
.bk:last-child { border-bottom: 1px solid var(--border); }
.bk-no {
  display: block; margin-bottom: var(--b1);
  font-family: var(--mono); font-size: var(--f-et);
  letter-spacing: .14em; color: var(--muted);
}
.bk-ad {
  display: block; font-family: var(--baslik); font-size: var(--f-h3);
  font-weight: 600; line-height: 1.2; color: var(--ink);
}
.bk-say {
  display: block; margin-top: var(--b1);
  font-family: var(--mono); font-size: var(--f-et); color: var(--muted);
}
.bk:hover .bk-ad, .bk:hover .bk-no { color: var(--accent); }
@media (min-width: 1280px) {
  .bk { position: relative; }
  .bk-no { position: absolute; right: 100%; top: .1em; margin: 0 .9em 0 0;
    font-size: var(--f-govde); letter-spacing: .08em; white-space: nowrap; }
}

/* ── kavram araması ──
   Dizin sayfası on dört bölüm başlığından ibaretti. Sınav sorusu kavramın
   ADINI söylüyor ("normal line", "critical point"), bölüm başlığını değil;
   o adla arayan öğrencinin gidecek yeri yoktu. Kutu boşken bölüm listesi
   olduğu gibi duruyor — bu katman mevcut hiçbir şeyi değiştirmiyor. */
.kv-ara { margin: var(--b3) 0 var(--b2); }
.kv-et {
  display: block; margin-bottom: var(--b1);
  font-family: var(--mono); font-size: var(--f-et);
  letter-spacing: .14em; text-transform: uppercase; color: var(--muted);
}
.kv-in {
  width: 100%; box-sizing: border-box;
  padding: .62em .8em;
  font-family: var(--ui); font-size: var(--f-govde); color: var(--ink);
  background: var(--kagit); border: 1px solid var(--border); border-radius: 3px;
}
.kv-in:focus { outline: none; border-color: var(--accent); }
.kv-in::placeholder { color: var(--muted); opacity: .75; }
.kv-say {
  margin-top: var(--b1);
  font-family: var(--mono); font-size: var(--f-et); color: var(--muted);
}
.kv-bas {
  margin: var(--b2) 0 var(--b1);
  font-family: var(--mono); font-size: var(--f-et);
  letter-spacing: .1em; color: var(--muted);
}
.kv-s {
  display: block; padding: var(--b2) 0; text-decoration: none;
  border-top: 1px solid var(--border);
}
.kv-sonuc .kv-s:last-child { border-bottom: 1px solid var(--border); }
.kv-b {
  font-family: var(--mono); font-size: var(--f-et);
  letter-spacing: .1em; color: var(--muted); margin-right: .7em;
}
.kv-ad {
  font-family: var(--baslik); font-weight: 600; color: var(--ink);
}
.kv-t {
  margin-left: .6em; padding: .08em .45em;
  font-family: var(--mono); font-size: var(--f-et);
  color: var(--muted); border: 1px solid var(--border); border-radius: 2px;
}
.kv-oz {
  display: block; margin-top: .3em;
  font-size: var(--f-yardim); line-height: 1.45; color: var(--muted);
}
.kv-s:hover .kv-ad { color: var(--accent); }
/* `[hidden]` UA kurali (0,0,0) ile `.bk-liste{display:grid}` (0,1,0) yarisinda
   yazar kazaniyor: JS `hidden=true` diyor, liste ekranda duruyordu. Ayni tuzak
   `.konum` icin de yasanmisti; olcum "gizli" der, ekran aksini gosterir. */
.kv-sonuc[hidden], .kv-say[hidden] { display: none; }

.kv-yok {
  padding: var(--b2) 0; font-size: var(--f-yardim); color: var(--muted);
}

.alt-katki {
  margin-top: var(--b5); padding-top: var(--b2);
  border-top: 1px solid var(--border);
  font-family: var(--ui); font-size: var(--f-yardim); color: var(--muted);
}


/* ══ 8 · BÖLÜM ═════════════════════════════════════════════════════════════
   section.bolum NORMAL bir grid item (Ö1): kendi kutusu var, o yüzden
   IntersectionObserver onu görüyor ve formüller render ediliyor. İçi normal
   blok akışı — alt seviyede grid yok, yani min-width tuzağı da yok. */

section.bolum {
  margin-top: 6.8rem;      /* bölüm başlığı yeni bir sayfa açar */
  margin-bottom: 0;
}
main.govde > section.bolum:first-of-type { margin-top: var(--b4); }

/* Bölüm başlığı: ALT ÇİZGİ YOK — o çizgi ders kitabı bölüm başlığının
   kendisiydi. Ayıran şey boşluk ve numara. */
section.bolum > h1, section.bolum > h2 {
  margin: 0 0 var(--b3);
  scroll-margin-top: calc(var(--ust-y) + 16px);
}
/* Bölüm numarası artık h1'de (`span.h1-no`), CSS sayacında değil: sayfa
   başına tek bölüm basıldığı için `counter(bolum)` her sayfada "01"
   gösteriyordu — 07. bölümün sayfasında da "01". Kaynağı HTML olan sayı
   doğru olan. Bkz. §7, `.h1-no`. */

section.bolum h3 {
  margin: var(--b5) 0 var(--b2);
  scroll-margin-top: calc(var(--ust-y) + 16px);
}

/* ── kanca: bölümün açılış cümlesi. Gövdeden BÜYÜK, ana mürekkepte. ── */
.hook { margin-bottom: var(--b4); font-size: var(--f-lead); line-height: 1.66; color: var(--ink); }
.hook-soz { margin-top: var(--b2); font-size: var(--f-yardim); color: var(--muted); }

/* ── mono etiketler: sayfadaki tek "rozet" tipi ── */
.kart-bas, .cram-bas, .kz-bas, .ok-bas, .kn-bas, .md-bas, .so-bas,
.fk-bas, .dn-bas, .pr-bas, .kb-tip, .o-sinav, .fl-no, .s-no, .s-konu, .zor {
  font-family: var(--mono); font-size: var(--f-et); font-weight: 400;
  letter-spacing: .1em; text-transform: uppercase; color: var(--muted);
}
.kart-bas, .cram-bas, .kz-bas, .ok-bas, .kn-bas, .md-bas, .so-bas,
.fk-bas, .dn-bas, .pr-bas { display: block; margin-bottom: var(--b2); }

/* ── "60 saniyede" kartı ── */
.kart { margin-bottom: var(--b4); padding-top: var(--b2);
  border-top: 1px solid var(--border-strong); }
.kart-tek, .kart-tek:empty + p,
.kart-tek:empty + ul, .kart-tek:empty + ol {
  font-size: var(--f-lead); color: var(--ink); margin-bottom: var(--b3);
}

/* Formül satırı: ad üstte küçük, FORMÜL altında büyük ve tam genişlikte,
   ne işe yaradığı en altta. İki sütun kalktı — 460px'e sıkışan formül
   ortasından kırılıyordu. */
.kart-form { margin-bottom: var(--b3); }
.kf, .fk { padding: var(--b2) 0; border-top: 1px solid var(--border); }
.kf-ad, .fk-ad {
  margin-bottom: var(--b1);
  font-family: var(--mono); font-size: var(--f-et);
  letter-spacing: .06em; color: var(--muted);
}
.kf-tex, .fk-tex { margin-bottom: var(--b1); font-size: var(--f-mat); color: var(--ink); }
.kf-ne, .fk-kos { font-size: var(--f-yardim); color: var(--muted); }

.kart-hata { margin-bottom: var(--b2); font-size: var(--f-yardim); }
.kart-hata > b {
  display: block; margin-bottom: var(--b1);
  font-family: var(--mono); font-size: var(--f-et); font-weight: 400;
  letter-spacing: .1em; text-transform: uppercase; color: var(--accent);
}
.kart-hata ol { margin: 0; }
.kart-sinav { font-size: var(--f-yardim); color: var(--muted); }

/* ── okuma bütçeleri ── */
.cram { margin-bottom: var(--b4); }
.cy { padding: var(--b2) 0; border-top: 1px solid var(--border); }
.cy-ad {
  margin-bottom: var(--b1);
  font-family: var(--mono); font-size: var(--f-et);
  letter-spacing: .06em; text-transform: uppercase; color: var(--accent);
}
.cy-kaz { font-size: var(--f-yardim); }
.cy-blok { margin-top: var(--b1); font-family: var(--mono);
  font-size: var(--f-et); color: var(--muted); }

/* ── kazanımlar ── */
.kazanim { margin-bottom: var(--b4); font-size: var(--f-yardim); }
.kazanim ol { margin: 0; }
.kazanim li { margin-bottom: var(--b1); }

/* ── önkoşul / kabuller / sonraki bölüm — üçü de aynı sınıf.
   468 satır içi formül taşıyor, o yüzden gövde puntosunda. ── */
.onkosul { margin-bottom: var(--b4); }
.ok { padding: var(--b2) 0; border-top: 1px solid var(--border); }
.ok > b { display: block; margin-bottom: var(--b1); color: var(--ink); }
.ok-nic { display: block; margin-top: var(--b1);
  font-size: var(--f-yardim); color: var(--muted); }
.ok-nic p { margin: 0; }

/* ── sessiz <details> blokları ── */
.kapsama, .notasyon, .defter, .sozluk {
  padding-top: var(--b2); border-top: 1px solid var(--border);
}

/* ── YÜZEY 1 · SIRA SENDE ──
   Sayfada zeminli iki şeyden biri. Ön test artık Notation'la aynı
   görünmüyor: kendi zemini, kendi kenarlığı, accent başlığı var. */
.ontest, .kontrol, .merdiven, .pr-grup {
  background: var(--surface);
  border: 1px solid var(--border-strong);
  border-radius: 4px;
  padding-block: var(--b3);
}
.ontest > summary, .kontrol > .kn-bas, .merdiven > .md-bas, .pr-grup > .pr-bas {
  color: var(--accent);
}
.ontest > summary {
  font-family: var(--ui); font-size: var(--f-yardim);
  letter-spacing: .01em; text-transform: none;
}

/* ── notasyon tablosu ──
   ARTIK SARMALAYICISI VAR (`.nt-kap`) ve tablo kendi kabinda kayiyor.
   OLCULDU 13 Eyl, 768px (phys-102/14): `table-layout: fixed` dort sutunu
   esit boluyordu, notasyon hucresi 155 px kaliyor ve icindeki kirilamaz
   formul (`white-space: nowrap`; mobil sarma kurali 760 px USTUNDE kapali)
   hucreyi 59 px, tabloyu 43 px asiyordu. Asan kisim kirpilmiyordu ama komsu
   sutunun metninin UZERINE biniyordu ve kaydirilacak bir kap yoktu.
   `table-layout: auto` + `min-width: 100%`: sutunlar iceriginin genisligini
   aliyor (formul hucresi ihtiyaci kadar yer buluyor), tablo yine kabini
   dolduruyor, GERCEKTEN sigmadiginda kap kayiyor — sayfa govdesi degil.
   <=700px'te tablo zaten blok duzenine geciyor, orada `table-layout`
   etkisiz; yani bu degisiklik yalniz tablet/masaustunu ilgilendiriyor.
   İZLENCE KAPSAMASI ARTIK TABLO DEĞİL: başlık + paragraf + filigran oldu,
   kuralları §31'de (`.kpsm`). Buradaki `.cv*` ve `.dmg*` kuralları o yüzden
   kaldırıldı — basılmayan markup'ın CSS'i dosyayı yanlış anlatıyor. */
.nt-kap {
  overflow-x: auto; overflow-y: hidden;
  overscroll-behavior-x: contain; -webkit-overflow-scrolling: touch;
}
.nt2 {
  table-layout: auto; width: auto; min-width: 100%; border-collapse: collapse;
  margin-top: var(--b2); font-size: var(--f-yardim);
}
/* Kagitta kaydirma yok: kesilen sutun basilmaz. */
@media print { .nt-kap { overflow: visible; } }
.nt2 td, .nt2 th {
  padding: var(--b1) var(--b2) var(--b1) 0;
  border-bottom: 1px solid var(--border);
  vertical-align: top; text-align: left;
}
.nt2 th {
  font-family: var(--mono); font-size: var(--f-et); font-weight: 400;
  letter-spacing: .08em; text-transform: uppercase; color: var(--muted);
}
.nt-sem { color: var(--ink); }
.nt-dik { color: var(--muted); }
/* Kırılamayan kısa jetonlar dar ekranda kutularını aşıyordu. KaTeX bundan
   etkilenmiyor: §14'teki `.katex, .katex *` koruması !important. */
.nt-sem, .s-konu, .zor { overflow-wrap: anywhere; }

/* Dar ekranda notasyon blok düzenine geçiyor: sembol üstte, anlamı altında.
   Sabit düzenli 3–4 sütun 390px'te okunmuyor. */
@media (max-width: 700px) {
  .nt2, .nt2 tbody, .nt2 tr, .nt2 td { display: block; width: auto; }
  .nt2 thead { position: absolute; width: 1px; height: 1px; overflow: hidden;
    clip-path: inset(50%); white-space: nowrap; }
  .nt2 tr { padding: var(--b2) 0; border-bottom: 1px solid var(--border); }
  .nt2 td { padding: 0; border: 0; }
  .nt-sem { margin-bottom: var(--b1); font-size: var(--f-mat); }
  .nt-dik { margin-top: var(--b1); }
}


/* ══ 9 · KAVRAM AKIŞI ══════════════════════════════════════════════════════
   `.anlatim` DÜZ bir kap: kavram wrapper'ı YOK, kavram sınırını yalnız h3
   çiziyor. Bu yüzden burada `.kavram` seçicisi de yok — eski dosyada vardı
   ve hiçbir şeyi seçmiyordu. */

.anlatim { margin-bottom: var(--b4); }
.anlatim > p { color: var(--ink-2); }     /* asıl anlatım metni ANA mürekkepte */

/* köprü cümlesi (Ö9: kendisi boş, metin sonraki p'ye kaçıyor) */
.k-kopru, .k-kopru:empty + p,
.k-kopru:empty + ul, .k-kopru:empty + ol { color: var(--muted); font-style: italic; }

/* ── neden gerekti: yapabildiğimiz / yapamadığımız ──
   İki sütun ALT ALTA. 684px'lik okuma sütununda iki sütun her birine ~330px
   bırakıyor, içinde 200 satır içi formül var; formül parçalanıp dikey bir
   karakter sütununa dönüyordu. */
.mf { margin: var(--b4) 0; }
.mf-ikili { display: grid; grid-template-columns: minmax(0,1fr); gap: var(--b3); }
.mf-ikili > * { min-width: 0; }
.mf-ikili b {
  display: block; margin-bottom: var(--b1);
  font-family: var(--mono); font-size: var(--f-et); font-weight: 400;
  letter-spacing: .08em; text-transform: uppercase; color: var(--muted);
}
.mf-ikili ul { margin: 0; }
.mf-deneme { margin-top: var(--b3); padding-top: var(--b2);
  border-top: 1px solid var(--border); }
.mf-neden { margin-top: var(--b2); color: var(--ink-2); }
.mf-neden b { color: var(--accent); }

/* ── TEOREM / KURAL: sahnedeki en büyük nesne ──
   Kutu yok, zemin yok, yuvarlak köşe yok. Ayıran şey kalın üst çizgi, mono
   rozet ve DISPLAY FORMÜLÜN KENDİSİ. Üretim zaten `\boxed{...}` kullanıyor:
   ifadeyi KaTeX kendi çerçeveliyor, üstüne CSS kutusu koymak çerçeve içinde
   çerçeve demek. */
.kutu { margin: var(--b5) 0; padding-top: var(--b2); border-top: 2px solid var(--ink); }
.kb-bas {
  display: flex; align-items: baseline; gap: var(--b2); flex-wrap: wrap;
  margin-bottom: var(--b2);
  font-family: var(--baslik); font-size: var(--f-h3); font-weight: 600;
  color: var(--ink); line-height: 1.2;
}
.kb-bas > * { min-width: 0; }
.kb-tip { color: var(--accent); }
.kb-kosul { margin-bottom: var(--b2); color: var(--muted); }
.kb-kosul > b {
  display: block; margin-bottom: var(--b1);
  font-family: var(--mono); font-size: var(--f-et); font-weight: 400;
  letter-spacing: .08em; text-transform: uppercase; color: var(--muted);
}
.kb-kosul ul { margin: 0; }
.kb-ifade { margin: var(--b3) 0; }
/* Formülün düz cümleyle okunuşu: formül tek başına sessiz. */
.kb-sozel { margin-top: var(--b2); color: var(--ink-2); }
.kb-ispat { margin-top: var(--b3); }

/* ── şekil ── */
figure { margin-block: var(--b5); }
.k-fig, .widget { text-align: center; color: var(--ink-2); }
/* ÇIPLAK `svg` DEĞİL (Ö3): child combinator KaTeX'i yapısal olarak dışarıda
   bırakıyor. viewBox'ı biraz aşan <text> de KESİLMESİN — ölçüldü, 16 etiket
   çerçevenin dışına taşıyordu ve tam da açıklamayı taşıyan satırlardı. */
figure > svg {
  display: block; width: auto; max-width: 100%; height: auto;
  margin: 0 auto; overflow: visible; background: var(--fig-zemin);
}
figcaption {
  margin-top: var(--b2); text-align: center;
  font-family: var(--ui); font-size: var(--f-yardim); line-height: 1.55;
  color: var(--muted);
}

/* ── karşı örnek: "buna benziyor ama değil" — DİKKAT rengi ── */
.karsi { margin: var(--b4) 0; }
.karsi > b {
  display: block; margin-bottom: var(--b1);
  font-family: var(--mono); font-size: var(--f-et); font-weight: 400;
  letter-spacing: .08em; text-transform: uppercase; color: var(--amber);
}
.karsi-neden { margin-top: var(--b2); color: var(--muted); }

/* ── veri tablosu: DOSYADAKİ TEK MEŞRU SCROLL CONTAINER ──
   Çok sütunlu sayı tablosu 390px'e sığmaz ve sığdırmak sayıları okunmaz
   yapar. Burada kaydıran şey SAYFA değil, tablonun kendisi; kenardaki maske
   kaydırılabildiğini söylüyor. Renderer 25/25 `.nt`yi sarıyor (doğrulandı,
   tasarım notundaki "6/25" ölçümü yanlıştı). */
.nt-sar {
  margin-block: var(--b4);
  overflow-x: auto; overscroll-behavior-x: contain;
  -webkit-mask-image: linear-gradient(to right, #000 94%, transparent);
  mask-image: linear-gradient(to right, #000 94%, transparent);
}
.nt-sar::-webkit-scrollbar { height: 4px; }
.nt-sar::-webkit-scrollbar-thumb { background: var(--border-strong); border-radius: 2px; }
table.nt {
  width: max-content; min-width: 100%;
  border-collapse: collapse; font-size: var(--f-yardim);
}
table.nt th, table.nt td {
  padding: var(--b1) var(--b3) var(--b1) 0;
  border-bottom: 1px solid var(--border);
  text-align: left; white-space: nowrap;
}
table.nt th {
  font-family: var(--mono); font-size: var(--f-et); font-weight: 400;
  letter-spacing: .08em; text-transform: uppercase; color: var(--muted);
}
.nt-oku, .nt-oku:empty + p,
.nt-oku:empty + ul, .nt-oku:empty + ol {
  margin: calc(-1 * var(--b2)) 0 var(--b4);
  font-size: var(--f-yardim); color: var(--muted);
}


/* ══ 10 · ÇÖZÜMLÜ ÖRNEK + TÜRETME ══════════════════════════════════════════ */

.ornek { margin: var(--b5) 0; }
.ornek > h4 {
  display: flex; align-items: baseline; gap: var(--b2); flex-wrap: wrap;
  margin-bottom: var(--b2);
}
.ornek > h4 > * { min-width: 0; }
.o-sinav { color: var(--accent); }

/* ── ÇÖZÜM KAPAĞI: SAYFANIN EN ÖNEMLİ DÜĞMESİ ──
   Alperen, 12 Eyl: "solutionlar neden direkt açık ve fontu kötü".
   İkisi aynı kusurun iki yüzü. Kutu `open` basılıyordu (bir bölümde 371
   `<details>`in 181'i açık; ölçüldü) ve kapağı §6'daki SESSİZ summary
   kuralına düşüyordu: mono, 13px, büyük harf, geniş harf aralığı. Yani
   "çözümü gör" kararının düğmesi, sayfanın en küçük ve en soğuk yazısıydı.
   Şimdi arayüz yüzünde, okur puntosunda, kendi çerçevesi olan bir denetim.
   Adımlar (`o-adim`) sessiz kalıyor: onlar çözümün İÇİ, kapağı değil. */
.o-coz { margin: var(--b3) 0 0; }
.o-coz > summary {
  display: inline-flex; align-items: center; gap: .5em;
  padding: .42em .95em;
  font-family: var(--ui); font-size: var(--f-yardim); font-weight: 500;
  letter-spacing: 0; text-transform: none; color: var(--accent);
  background: transparent;
  border: 1px solid var(--border-strong); border-radius: 5px;
  transition: color .18s ease, border-color .18s ease, background-color .18s ease;
}
/* IMLEC GLIF DEGIL, KENARLIKLA CIZILMIS UCGEN.
   12 Eyl 2026, Alperen: "solution kisminda arkada b8 mi yaziyor bir sey
   yaziyor ust uste". Tofu degildi, KACMIS BIR ESCAPE'ti: burada
   `content: '\25b8'` (U+25B8) yazilmak istenmis, ama dizgi bir Python
   kaynagindan gecerken `\25` OKTAL kacis sayilmis ve chr(0o25) = U+0015
   (NAK) bayti dosyaya yazilmis. Yani CSS'te duran sey `'<U+0015>b8'`ti:
   ekranda gorunmeyen bir kontrol karakteri + harfi harfine "b8". Ustelik
   ust kural (`:where(main.govde) summary::before`) `width: 1.2em` veriyor,
   iki karakter o kutuyu asiyor ve `[open]` halindeki `rotate(90deg)` yaziyi
   "Solution"un ustune deviriyordu.
   Escape'i DOGRU yazmak da cozum degil: U+25B8 arayuz fontu Inter'in ne
   subset'inde ne kaynak dosyasinda var (fontTools ile olculdu; yedi fontun
   yalniz JetBrains Mono'sunda var). Glif basmak sistem yedegine dusmek,
   kotu halde kutu cizmek demek. Ucgen artik hicbir fonta bagli degil;
   `width/height` ust kuraldan gelen `1.2em`i EZIYOR. */
.o-coz > summary::before {
  content: ''; flex: none; display: block; box-sizing: content-box;
  width: 0; height: 0;
  border-left: .44em solid currentColor;
  border-top: .28em solid transparent;
  border-bottom: .28em solid transparent;
  transition: transform .18s ease;
}
/* ACIK HALDE `content`i BU KURAL GERI ALIR.
   Yukaridaki `content: ''` yalniz KAPALI hali kurtariyordu: §6'daki
   `:where(main.govde) details[open] > summary::before { content: '–' }`
   kurali daha ozgul (0,1,3 > 0,1,2) oldugu icin kapak acilinca ucgenin
   uzerine bir en dash basiliyordu (olculdu: glif_test "content=\"–\"").
   Bu kural (0,2,2) ikisini de yener; ucgen hicbir halde metin basmaz. */
.o-coz[open] > summary::before { content: ''; transform: rotate(90deg); }
.o-coz > summary:hover {
  border-color: var(--accent); background: var(--paper-soft);
}
.o-coz > summary:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.o-coz[open] > summary { margin-bottom: var(--b2); }

.o-adim { margin: var(--b3) 0; }
.o-adim > summary { color: var(--ink-2); letter-spacing: .06em; }

/* Çözümün SEÇİM gerekçesi: neden bu yol, hangi alternatif neden daha pahalı. */
.c-secim { margin-bottom: var(--b3); font-size: var(--f-yardim); color: var(--muted); }

/* ── TÜRETME: tablo değil, ANLATI ──
   Eski hâli iki sütunlu bir tabloydu: solda matematik 13,5px, sağda gerekçe.
   390px'te 326px kutuda 535px yer kaplıyordu ve matematik sayfanın en küçük
   yazısıydı. Artık her adım tam genişlikte — matematik kendi satırında
   --f-mat ile, gerekçesi hemen altında küçük ve soluk. Dikey yer iki katına
   çıkıyor; istenen şey bu, türetme bir tablo değil. */
.c-tablo, .c-tablo tbody, .c-tablo tr, .c-tablo td {
  display: block; width: auto; padding: 0; border: 0;
}
.c-tablo { margin: var(--b2) 0; }
.c-tablo thead {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap;
}
.c-tablo tbody { counter-reset: adim; }
.c-tablo tbody > tr { counter-increment: adim; padding: var(--b2) 0; }
.c-tablo tbody > tr + tr { border-top: 1px solid var(--border); }
.c-mat { font-size: var(--f-mat); color: var(--ink); }
.c-ned { margin-top: var(--b1); font-size: var(--f-yardim); color: var(--muted); }
.c-ned p { margin: 0; }
/* Adım numarası sol boşlukta — sadece boşluğun kesin yettiği genişlikte.
   Metnin hizasına dokunmuyor, tek hizalama korunuyor. */
@media (min-width: 1280px) {
  .c-tablo .c-mat { position: relative; }
  .c-tablo .c-mat::before {
    content: counter(adim);
    position: absolute; right: 100%; top: .45em; margin-right: 1.1em;
    font-family: var(--mono); font-size: var(--f-et); color: var(--border-strong);
  }
}

/* ── YÜZEY 2 · CEVAP ──
   Zemin var ama YATAY PADDING YOK: metin okuma sütununun sol kenarında
   kalıyor, zemin tam sütun boyunca uzanıyor. Böylece iç içe taşma bütçesi
   harcanmıyor (bkz. §3). */
.c-son {
  margin-top: var(--b2); padding-block: var(--b2);
  background: var(--vurgu-zemin); border-radius: 4px; color: var(--ink);
}
.c-son > b, .c-dogrula > b, .c-not > b {
  font-family: var(--mono); font-size: var(--f-et); font-weight: 400;
  letter-spacing: .1em; text-transform: uppercase; color: var(--emerald);
}
.c-dogrula, .c-not { margin-top: var(--b2); font-size: var(--f-yardim); color: var(--muted); }


/* ══ 11 · HATA · YANLIŞ / DOĞRU ════════════════════════════════════════════ */

.hata { margin: var(--b4) 0; }
.hata > b {
  display: block; margin-bottom: var(--b1);
  font-family: var(--ui); font-size: var(--f-govde); font-weight: 600;
  color: var(--accent);
}
.h-neden { margin-bottom: var(--b2); font-size: var(--f-yardim); color: var(--muted); }

/* Yanlış/doğru çifti TEK SÜTUN: iki sütun her birine ~315px bırakıyordu,
   kesirli bir limit ifadesi oraya sığmıyor ve KaTeX dikey bir karakter
   sütununa dönüyordu. Alt alta — önce yanlış olan, hemen altında doğrusu. */
.h-ikili { display: grid; grid-template-columns: minmax(0,1fr); gap: var(--b3); }
.h-ikili > * { min-width: 0; }
.h-yanlis, .h-dogru { font-size: var(--f-mat); color: var(--ink); }
/* SEÇİCİ KaTeX'İ YAKALAMASIN: bu kural bir zamanlar `.h-yanlis span` idi ve
   formülün HER parçasını ayrı satıra düşürüyordu (ölçüldü: 642px kutuda
   603px'lik formül 120px yüksekliğe sardı). Etiketin kendi sınıfı var. */
.h-et {
  display: block; margin-bottom: var(--b1);
  font-family: var(--mono); font-size: var(--f-et); font-weight: 400;
  letter-spacing: .1em; text-transform: uppercase;
}
.h-yanlis > .h-et { color: var(--accent); }
.h-dogru  > .h-et { color: var(--emerald); }


/* ══ 12 · SORU · ŞIK · İPUCU · ÇÖZÜM ═══════════════════════════════════════ */

.kontrol { margin: var(--b5) 0; }
/* ── SOL RAY: "soruda mıyım, anlatımda mıyım" ──
   Alperen, 12 Eyl: "soruda mıyım der anlatımında mıyım görünmüyor".
   Doğruydu: `.soru`nun hiçbir görsel kabı yoktu, yalnız boşluk ve iki soru
   arasında ince bir çizgi vardı. Uzun bir nesir akışında blok sınırı
   görünmüyordu.

   Kutu YOK (Ö7: sayfada iki yüzey var, üçüncüsü açılmıyor). Bunun yerine
   kenar boşluğuna 2px'lik bir ray: metin AYNI sol kenarda kalıyor (§3
   hizalama sistemi bozulmuyor), ray `--pay` bütçesinde duruyor — zeminli
   bloğun zaten kullandığı taşma payı, yeni bir mekanizma değil.

   İKİ RAY İKİ ANLAM: soru vurgu renginde, çünkü orada SEN yapıyorsun
   (Ö7'de accent = etkileşim). Çözümlü örnek nötr çünkü orada sana
   gösteriliyor. */
.soru, .ornek { position: relative; }
.soru::before, .ornek::before {
  content: ''; position: absolute;
  left: calc(-1 * var(--pay, 16px)); top: .15em; bottom: .15em; width: 2px;
  border-radius: 1px;
}
.soru::before { background: color-mix(in srgb, var(--accent) 34%, transparent); }
.ornek::before { background: var(--border-strong); }
/* Dar ekranda pay 16px; ray hâlâ sütunun içinde kalıyor. 30rem altında
   raylar birbirine çok yakın düşmesin diye ince tutuluyor. */
@media (max-width: 30rem) {
  .soru::before, .ornek::before { left: calc(-1 * var(--pay, 12px)); width: 2px; }
}
@media print { .soru::before, .ornek::before { display: none; } }

.soru { margin-bottom: var(--b4); }
.soru:last-child { margin-bottom: 0; }
.pr-grup .soru + .soru, .ontest .soru + .soru {
  padding-top: var(--b4); border-top: 1px solid var(--border);
}

.s-ust { display: flex; align-items: baseline; gap: var(--b2); flex-wrap: wrap;
  margin-bottom: var(--b2); }
.s-ust > * { min-width: 0; }
.s-no { color: var(--accent); }
/* ZORLUK NOKTALARI GLIF DEGIL, CSS DAIRESI.
   Eskiden `●●○○○` basiliyordu. `●` (U+25CF) mono fontun subset'inde VAR ama
   `○` (U+25CB) JetBrains Mono'nun ne subset'inde ne kaynak dosyasinda var
   (fontTools ile olculdu) -- yani ayni bes noktalik dizide dolu noktalar
   JetBrains'ten, bos noktalar sistem yedeginden geliyordu: iki ayri font,
   iki ayri govde. Iki nokta artik ayni kutudan cikiyor. */
.zor { margin-left: auto; letter-spacing: 0; }
.zor-n {
  display: inline-block; vertical-align: middle;
  width: .52em; height: .52em; border-radius: 50%;
  border: 1px solid currentColor;
}
.zor-n + .zor-n { margin-left: .24em; }
.zor-dolu { background: currentColor; }

.s-baglam { margin-bottom: var(--b2); }
.s-verilen, .s-istenen { margin-bottom: var(--b2); }
.s-verilen > b, .s-istenen > b {
  display: block; margin-bottom: var(--b1);
  font-family: var(--mono); font-size: var(--f-et); font-weight: 400;
  letter-spacing: .1em; text-transform: uppercase; color: var(--muted);
}
.s-verilen ul, .s-istenen ol { margin: 0; }

.s-sikler { display: grid; gap: var(--b1); margin: var(--b3) 0; }
.s-sikler > * { min-width: 0; }
/* Ölçüldü: 390px'te `button.s-sik` 388px genişlik istiyor ve 420px'te
   bitiyordu — buton bir grid item ve min-width:auto = min-content.
   min-width:0 + overflow-wrap taşmayı kapatıyor; formül `.katex` koruması
   sayesinde bundan etkilenmiyor (§14). */
.s-sik {
  font: inherit; font-size: var(--f-govde); text-align: left;
  padding: var(--b2); cursor: pointer;
  color: inherit; background: transparent;
  border: 1px solid var(--border); border-radius: 4px;
  min-width: 0; max-width: 100%; overflow-wrap: anywhere;
}
.s-sik p { margin: 0; }
.s-sik:hover:enabled { border-color: var(--accent); }
.s-sik.dogru { border-color: var(--emerald); color: var(--ink); }
.s-sik.yanlis { border-color: var(--accent); opacity: .6; }
.s-geri {
  margin: var(--b2) 0; padding-block: var(--b2);
  background: var(--vurgu-zemin); border-radius: 4px;
  font-size: var(--f-yardim); color: var(--ink-2);
}

.s-ipuclari { display: grid; gap: 0; margin: var(--b3) 0; }
.s-ipuclari > * { min-width: 0; }
.s-ipucu { margin: 0; padding: var(--b2) 0; border-top: 1px solid var(--border);
  font-size: var(--f-yardim); }
.s-cozum { margin: var(--b3) 0 0; }
.s-cozum > summary { color: var(--accent); }


/* ══ 13 · YÖNTEM · KARŞITLIK · MERDİVEN · PRATİK ═══════════════════════════ */

.yontem { margin: var(--b5) 0; padding-top: var(--b2);
  border-top: 1px solid var(--border-strong); }
.y-bas { margin-bottom: var(--b1); font-family: var(--baslik);
  font-size: var(--f-h3); font-weight: 600; color: var(--ink); line-height: 1.2; }
.y-ne { margin-bottom: var(--b2); font-size: var(--f-yardim); color: var(--muted); }
.yontem ol { margin: 0; }
.yontem li { margin-bottom: var(--b2); }
.y-tuzak { margin-top: var(--b3); padding-top: var(--b2);
  border-top: 1px solid var(--border); font-size: var(--f-yardim); color: var(--muted); }
.y-tuzak > b {
  display: block; margin-bottom: var(--b1);
  font-family: var(--mono); font-size: var(--f-et); font-weight: 400;
  letter-spacing: .08em; text-transform: uppercase; color: var(--amber);
}
.y-tuzak ul { margin: 0; }

/* Karşıtlık çifti: iki tam çözümlü örnek YAN YANA DEĞİL. 684px'lik sütunda
   yan yana koymak her birine 335px bırakıyor ve ikisi de matematik dolu.
   Alt alta + ayıran cümle, karşılaştırmayı daha iyi kuruyor. */
.karsit { margin: var(--b5) 0; }
.kt-ikili { display: grid; grid-template-columns: minmax(0,1fr); gap: var(--b4); }
.kt-ikili > * { min-width: 0; }
.kt-cumle { margin-top: var(--b3); padding-top: var(--b2);
  border-top: 1px solid var(--border); color: var(--ink); }
.kt-kural { margin-top: var(--b2); font-size: var(--f-yardim); color: var(--muted); }
.kt-kural > b {
  font-family: var(--mono); font-size: var(--f-et); font-weight: 400;
  letter-spacing: .08em; text-transform: uppercase; color: var(--muted);
}

.merdiven { margin: var(--b5) 0; }
.fl-iskelet { margin-bottom: var(--b3); font-size: var(--f-yardim); }
.fl-iskelet > b {
  display: block; margin-bottom: var(--b1);
  font-family: var(--mono); font-size: var(--f-et); font-weight: 400;
  letter-spacing: .08em; text-transform: uppercase; color: var(--muted);
}
.fl-b { margin-top: var(--b4); padding-top: var(--b2); border-top: 1px solid var(--border); }
.fl-no { display: block; margin-bottom: var(--b2); color: var(--accent); }
.fl-ned { display: inline-block; margin: 0 0 0 var(--b2); font-size: var(--f-et); }
.fl-sahte { font-size: var(--f-govde); }

.sinav-ornek { margin: var(--b5) 0; }
.pratik { margin-top: var(--b5); }
.pratik > h3 { margin-top: 0; }
.pr-grup { margin-bottom: var(--b4); }
.pr-bas { display: flex; align-items: baseline; gap: var(--b2); }
.pr-bas > * { min-width: 0; }
.pr-bas > span { margin-left: auto; }


/* ══ 14 · BÖLÜM SONU ═══════════════════════════════════════════════════════ */

.fkart { margin: var(--b5) 0; padding-top: var(--b2);
  border-top: 1px solid var(--border-strong); }
.denetim { margin: var(--b5) 0; padding-top: var(--b2);
  border-top: 1px solid var(--border-strong); }
.dn-hatirla, .dn-hatirla:empty + p,
.dn-hatirla:empty + ul, .dn-hatirla:empty + ol { font-size: var(--f-govde); color: var(--ink-2); }
.dn-liste { margin: var(--b2) 0 0; font-size: var(--f-yardim); }
.dn-liste li { margin-bottom: var(--b2); }
.sa-yon { display: block; margin-top: var(--b1); color: var(--muted); }

.sz-liste { display: grid; gap: 0; margin-top: var(--b2); }
.sz-liste > * { min-width: 0; }
.sz { padding: var(--b2) 0; border-top: 1px solid var(--border);
  font-size: var(--f-yardim); }
.sz > b { display: flex; gap: var(--b2); align-items: baseline; flex-wrap: wrap;
  margin-bottom: var(--b1); color: var(--ink); }
.sz > b > * { min-width: 0; }
.sz > b i { font-style: normal; font-weight: 400; color: var(--muted);
  font-family: var(--mono); font-size: var(--f-et); }
.sz > span { display: block; color: var(--muted); }

.kaynak-l { margin-top: var(--b5); font-size: var(--f-yardim); color: var(--muted); }
.kaynak-l > b {
  display: block; margin-bottom: var(--b1);
  font-family: var(--mono); font-size: var(--f-et); font-weight: 400;
  letter-spacing: .08em; text-transform: uppercase;
}
.kaynak-l ul { margin: 0; }
.kaynak-l li { margin-bottom: .3em; line-height: 1.6; }
.kaynak-l a { color: var(--ink-2); border-bottom: 1px solid var(--border-strong); }
.kaynak-l a:hover { color: var(--accent); border-color: var(--accent); }
/* Kaynagin TURU adindan once: "video" mu "eski sinav" mi, bunu bilmek
   basliga bakmaktan hizli. 12 Eyl: phys-101'in bolumlerine 88 kaynak
   eklendi (39 ders videosu, 15 sinav cozumu, lab kilavuzu, ucretsiz kitap
   bolumleri) ve karisik bir listede tur etiketi olmadan goz kayboluyor. */
.kl-tur {
  display: inline-block; min-width: 6.4em; margin-right: .5em;
  font-family: var(--mono); font-size: 10.5px; letter-spacing: .05em;
  text-transform: uppercase; color: var(--muted);
}
@media (max-width: 30rem) { .kl-tur { min-width: 0; } }

/* "sadece problem göster" — anlatımı gizle, alıştırma kalsın */
body.sadece-problem .anlatim,
body.sadece-problem .kutu,
body.sadece-problem .mf,
body.sadece-problem .hook,
body.sadece-problem .onkosul,
body.sadece-problem .yontem { display: none; }


/* ══ 15 · KaTeX DOKUNULMAZ ═════════════════════════════════════════════════
   Bu dosyada ÇIPLAK `span`, `svg`, `td`, `*` seçicisi yok; formül onlarca iç
   içe <span>'dir. Aşağıdaki kurallar formülü, yukarıdaki taşma önlemlerinin
   yan etkisinden korur. Formül bir kelime değil: sarması ANLAMI bozar.
   Sığmıyorsa (1) kenar boşluklarına taşar (.genis), (2) hâlâ sığmıyorsa JS
   puntosunu düşürür (build.py · sigdirBolum). Asla kırılmaz, asla kaydırılmaz. */

.katex, .katex * {
  overflow-wrap: normal !important;
  word-break: keep-all !important;
  word-wrap: normal !important;
  hyphens: none !important;
}
/* ÖLÇÜLDÜ 22 Ağu: KaTeX'in erişilebilirlik katmanı `.katex-mathml`
   `position: absolute` ve KaTeX'in kendi CSS'inde `.katex` konumlandırılmış
   DEĞİL — yani o katmanın kapsayan bloğu initial containing block oluyor ve
   main.govde'nin `overflow: clip`inden KAÇIYOR. Sonuç: 800px'te sayfa 326px
   yana kayıyordu; hiçbir görünür öge taşmıyordu, kaçan şey görünmez MathML
   katmanıydı. `.katex`e `position: relative` vermek kapsayan bloğu formülün
   içine alır — ölçü, biçim, satır kırımı değişmez, ofset verilmiyor.
   Ölçüm: yatay kayma 326 -> 0.
   `.katex-mathml { display: none }` de 0 yapıyor AMA o katman ekran
   okuyucunun formülü okuduğu yer; silinmez. */
.katex { position: relative; }
/* SATIR İÇİ formül sarmaz — sarması anlamı bozar. */
.katex { white-space: nowrap; }

/* DISPLAY formül KIRILABİLİR. KaTeX display modda üst düzey ilişki ve ikili
   işleç işaretlerinde (=, +, −, <, …) satır kırmayı kendi destekler; tek
   şartı kapsayıcının `white-space: normal` olması.
   Alperen 22 Ağu: "satır olmuyorsa satırı güzel bir şekilde kır yana
   sürüklenmesin". Kırmak kaydırmaktan iyi: kaydırılan formülün yarısı ekran
   dışında kalıyor ve orada olduğu bile belli olmuyor. */
.katex-display > .katex { white-space: normal; }
.katex-display > .katex > .katex-html { display: block; }
.katex-display > .katex > .katex-html > .base { margin: 0 auto; }

/* MOBİLDE UZUN HESAP ZİNCİRİ SATIRINI KIRABİLİR, `.mat-uzun`.
   ÖLÇÜLDÜ 11 Eyl (56 sayfa, 63.334 satır içi formül): 360px'te 290'ı,
   390px'te 199'u okuma sütununu aşıyordu ve zincirde `overflow-x: auto`
   YOKTU, yani kesilen yere kaydırarak da ulaşılamıyordu, içerik kayıptı.
   phys-101/14'te `v = \omega\sqrt{A^2-x^2} = ... = 0.566` ekranda
   `= 20.0\sqrt{0.00160-0.00080` diye bitiyordu: hesabın SONUCU yok.
   `main.govde`nin `overflow-x: clip`i (§3) yerinde kalıyor, gerekçesi orada;
   onu kaldırmak sayfayı yana kaydırırdı.

   Neden kaydırma değil KIRMA: üç aday canlıya CSS enjekte edilerek aynı
   sayfada (phys-101/14, 360px, 962 satır içi formül) ölçüldü.
     · bütün satır içine `inline-block + overflow-x:auto`: kırpılma 7→0 ama
       183 formülde gizli DİKEY kırpılma doğdu (`overflow-x:auto` öteki
       ekseni zorunlu `hidden` yapıyor) ve sayfa 3.689px uzadı.
     · bütün satır içine `white-space: normal`: kırpılma 7→0, dikey 0, ama
       112 KISA formül de sardı (`F = -kx` → "F =" / "-kx"). §15'in ilk
       kuralı tam bunu yasaklıyor.
     · yalnız uzun olanlar (bu kural): kırpılma 7→0, dikey 0, yalnız 18
       formül sardı, hepsi çoklu `=` taşıyan hesap zinciri, ve sayfa boyu
       256.569→256.568 px, yani değişmedi.
   Alperen'in display formül için verdiği karar burada da geçerli: "satır
   olmuyorsa satırı güzel bir şekilde kır yana sürüklenmesin".

   `.mat-uzun` sunucuda basılıyor (render_v2.py · uzun_mat_isaretle); ölçüt
   LaTeX kaynağından tahmin edilen glif sayısı ≥ 15. Sınıf bir İZİN, emir
   değil: işaretli formül satıra sığıyorsa tarayıcı sarmaz. 760px üstünde bu
   kural hiç uygulanmıyor, masaüstü ve tablet birebir aynı kalıyor.

   KALAN (bilinen, ölçülmüş): KaTeX kendi CSS'inde `.katex .base`i
   `display:inline-block; white-space:nowrap` yapıyor. Satır kırımı yalnız
   BASE'ler ARASINDA olur, base'in içinde olmaz; KaTeX base'i de üst düzey
   ikili/bağıntı işaretlerinde ayırır. Yani üst düzeyinde `=`, `+`, `-` gibi
   bir işaret TAŞIMAYAN uzun bir formül tek base'tir ve hiçbir şekilde
   kırılamaz, `\max\{\text{...},\text{...}\}` ya da virgülle ayrılmış
   ölçüm listesi (`12.31,\ 12.30,\ ...`) gibi. 360px'te 63.334 formülün
   5'i bu durumda (en kötüsü 125px). `overflow-wrap: anywhere` denendi,
   ÖLÇÜLDÜ: base inline-block olduğu için hiçbir şey değiştirmiyor. Çözüm
   CSS'te değil, o ifadelerin display formül olarak yazılmasında.

   İKİNCİ AÇIK (ölçüldü, bilerek kapatılmadı): buradaki kapı VIEWPORT
   genişliği, oysa asıl ölçüt KAPSAYICININ genişliği. Notasyon tablosunun
   hücresi 768px'te 155px kalıyor; oradaki işaretli formülün en geniş base'i
   92px, yani SIĞARDI, ama viewport 768 olduğu için kural uygulanmıyor ve
   `td` 59px taşıyor (phys-102/14 ve phys-102/01). Kapatmanın bilinen yolu
   `main.govde td .mat-uzun .katex { white-space: normal }`; yapılmadı çünkü
   bu iş MOBİLLE sınırlıydı ve o kural tablet/masaüstü yerleşimini
   değiştirir. tests/notes_test.py bunu bütçeli olarak izliyor. */
@media (max-width: 760px) {
  main.govde .mat-uzun .katex { white-space: normal; }
}

/* mtable (cases, matris, aligned) KENDİ İÇ DÜZENİDİR: satırları ve sütunları
   KaTeX yerleştirir. Buraya `white-space: normal` vermek hücreleri sardırıp
   ÜST ÜSTE BİNDİRİYORDU — \begin{cases} örneğindeki bozukluk buydu. */
.katex .mtable, .katex .mtable * { white-space: nowrap; }

/* Taşan display formül KIRPILMAZ: `overflow:hidden` bir zamanlar buradaydı
   ve formül kartında 455, çözümlerde 416 piksel sessizce kesiliyordu.
   font-size VERİLMİYOR — KaTeX zaten 1.21em ile ölçekliyor, üstüne bir kat
   daha koymak JS'in sığdırma merdivenini gereksiz yere tetikler. */
.katex-display { overflow: visible; margin: var(--b3) 0; padding: 0; text-align: left; }
.katex-display > .katex { display: inline-block; transform-origin: left center; }

/* SIĞDIRMA MERDİVENİNİN SON BASAMAĞI — `.nt-sar`ın yanındaki İKİNCİ ve SON
   kaydırma istisnası.
   JS `.genis`i yalnız okuma sütununa sığmayan display formüle ekliyor
   (build.py · sigdirBolum). O formülün puntosu 0,62em'e kadar düşüyor;
   bundan sonra hâlâ sığmıyorsa geriye iki seçenek kalıyor: matematiği
   sessizce kesmek, ya da O KUTUYU kaydırılabilir yapmak. ÖLÇÜLDÜ (390px,
   bütün çözümler açık): kesme 165 piksele çıkıyor — bir teorem ifadesinin
   dörtte biri, okuyucunun HİÇ ulaşamayacağı yerde. Kesmek daha kötü.
   Sığan formülde scrollWidth == clientWidth olduğu için çubuk çıkmıyor:
   390px'te 16 `.genis`in yalnız 2'si kayıyor, 768px ve üstünde 0.
   overflow-y bilerek `clip` DEĞİL `visible` bırakılamıyor (auto/visible
   birlikte olmuyor); `hidden` yerine `auto` seçildi ki uzun kesirler dikeyde
   de kırpılmasın — ölçüldü, dikey taşma 0. */
/* `overflow-x: auto` diğer ekseni de auto'ya çeviriyor (CSS'te auto+visible
   olmuyor). KaTeX'in kesir/kök yapıları satır kutusunun 2–7 piksel dışına
   taşıyor, o da 36 piksellik bir kutuya DİKEY kaydırma çubuğu takıyordu.
   Dikey payı padding ile soğuruyoruz: kırpma yok, çubuk yok. Ölçüldü. */
.katex-display.genis {
  overflow-x: auto; overscroll-behavior-x: contain;
  padding-block: .5em;
}
.katex-display.genis::-webkit-scrollbar { height: 3px; }
.katex-display.genis::-webkit-scrollbar-thumb {
  background: var(--border-strong); border-radius: 2px;
}


/* ══ 16 · YAZDIRMA ═════════════════════════════════════════════════════════ */

@media print {
  .ust, .icindekiler, .perde, .ilerleme, .arac-serit,
  .ai-sor, .ai-pop, .sz-pop, .yerimi, .geri { display: none !important; }
  body { background: #fff; color: #000; }
  main.govde { padding: 0; overflow: visible; }
  section.bolum { margin-top: 3rem; }
  section.bolum > h2, section.bolum h3 { break-after: avoid; }
  .kutu, .ornek, .soru, figure, .c-tablo tbody > tr { break-inside: avoid; }
}

/* ══ 17 · ÇIKTI TAHMİNİ: ÖĞRENCİ YAZAR, SAYFA KONTROL EDER ════════════════
   ÖLÇÜLDÜ 12 Eyl: CS 115 §01+§02'de 61 soru var; renderer yalnız `choices`
   taşıyan 17'sine kontrol veriyordu. Oysa dersin gerçek vizesinde
   "Question 2 (30 points) What is the output when the following programs are
   executed?" yazıyor — yani 30 puan doğrudan bu beceride. Sayfada bu tipte
   16 soru duruyordu ve 1'inde anında geri bildirim vardı.
   Cevabı TEK cit bloğu olan 35 soru birebir karşılaştırılabilir; bu bölüm
   onların arayüzü. Karşılaştırma istemcide, sunucuda kayıt yok.

   JS YOKKEN: `.sy-kontrol` `hidden` basılır ve öyle kalır, textarea yine
   yazılabilir (kâğıda yazmak gibi), çözüm zaten aşağıdaki <details>'te.
   Yani katman düşse ders kaybı olmuyor, yalnız geri bildirim kaybı oluyor. */

.s-yaz { margin: var(--b3) 0; }
.sy-et {
  display: block; font-family: var(--ui); font-size: var(--f-yardim);
  color: var(--ink-2); margin-bottom: var(--b1);
}
.sy-et span { color: var(--muted); }
/* Girdi KOD gibi görünür: öğrenci boşluk sayıyor, mono olmazsa hizayı
   göremez ve "iki boşluk mu üç mü" sorusu ekranda kaybolur. */
.sy-girdi {
  display: block; width: 100%; box-sizing: border-box;
  font-family: var(--mono); font-size: .82em; line-height: 1.55;
  color: var(--ink); background: var(--surface);
  border: 1px solid var(--border); border-left: 3px solid var(--border-strong);
  border-radius: 4px; padding: .7em .9em;
  white-space: pre; overflow-x: auto; tab-size: 4; resize: vertical;
}
.sy-girdi:focus { border-color: var(--accent); }
.s-yaz[data-bitti] .sy-girdi { border-left-color: var(--emerald); }
.s-yaz[data-yanlis] .sy-girdi { border-left-color: var(--accent); }

/* SPYDER KONSOLU ÇERÇEVESİ. Alperen 12 Eyl: "kod çıktıları ve egzersizler
   spyder görünümlü olabilir". Öğrencinin çıktıyı gördüğü yer Spyder'ın
   IPython konsolu; alıştırma da o çerçeveye oturuyor. Sekme çubuğu
   adımlayıcıyla AYNI sınıf (`.kz-tab`, §18): sayfada tek bir IDE dili var,
   ikinci bir görsel sözlük uydurulmuyor. Doğru/yanlış işareti hem sol
   çubukta hem çerçevede; çubuk her zaman 3px (şeffaf), yoksa cevap
   verilince metin yana kayıyor. */
.sy-kon {
  margin: var(--b1) 0 var(--b2);
  border: 1px solid var(--border); border-radius: 4px;
  background: var(--paper-soft); overflow: hidden;
}
.sy-istem {
  /* Sol dolgu textarea'nin 3px'lik şeffaf işaret çubuğunu telafi ediyor:
     mono bir konsolda istem satırı ile altındaki çıktı AYNI kolonda
     başlamazsa göz hizayı yanlış okur. */
  padding: .45em .8em 0 calc(.8em + 3px);
  font-family: var(--mono); font-size: .78em; color: var(--ink-2);
  white-space: pre; overflow-x: auto;
}
.sy-istem span { color: var(--emerald); }
.sy-kon .sy-girdi {
  border: 0; border-left: 3px solid transparent; border-radius: 0;
  background: transparent; padding: .25em .8em .7em;
}
.sy-kon .sy-girdi:focus {
  outline: 2px solid var(--accent); outline-offset: -2px;
}
.s-yaz[data-bitti] .sy-kon { border-color: var(--emerald); }
.s-yaz[data-yanlis] .sy-kon { border-color: var(--accent); }

.sy-alt {
  display: flex; align-items: center; gap: var(--b2);
  margin-top: var(--b1); flex-wrap: wrap;
}
.sy-kontrol {
  font: inherit; font-family: var(--ui); font-size: var(--f-yardim);
  padding: .45em 1em; cursor: pointer;
  color: var(--paper); background: var(--accent);
  border: 1px solid var(--accent); border-radius: 4px;
}
.sy-kontrol:hover:enabled { opacity: .88; }
.sy-kontrol:disabled { cursor: default; opacity: .5; }
.sy-say { font-family: var(--mono); font-size: var(--f-et); color: var(--muted); }

.sy-geri {
  margin: var(--b2) 0 0; padding: var(--b2);
  background: var(--vurgu-zemin); border-radius: 4px;
  font-family: var(--ui); font-size: var(--f-yardim); color: var(--ink-2);
}
.sy-geri b { color: var(--ink); }
.s-yaz[data-bitti] .sy-geri { background: rgba(44,106,76,.09); }
/* Ayrılan satır MONO ve tam görünür: "üçüncü satırda ayrıldın" demek
   yetmiyor, öğrenci kendi yazdığıyla beklenenin hizasını görmeli. */
.sy-fark {
  display: block; font-family: var(--mono); font-size: .82em;
  white-space: pre; overflow-x: auto; margin-top: var(--b1);
  color: var(--ink);
}
.sy-fark i { color: var(--muted); font-style: normal; }

/* NEDEN — cevap verildikten sonra açılır. Metin gövde tonunda, geri bildirim
   tonunda DEĞİL: bu bir uyarı değil, sorunun asıl dersi. ÖLÇÜLDÜ 12 Eyl:
   cs-115 §02'nin 13 drill sorusunun 13'ünde bu açıklama üretimde zaten
   yazılmıştı ve hiç basılmıyordu, çünkü eski süzgeç blok sonrası metni
   "cevap sadece çıktı değil" sanıp soruyu tümden reddediyordu. */
.sy-neden {
  margin-top: var(--b2); padding-top: var(--b2);
  border-top: 1px solid var(--border);
  font-size: var(--f-govde); color: var(--ink-2);
}
.sy-neden p:first-child { margin-top: 0; }
.sy-neden p:last-child { margin-bottom: 0; }

@media print {
  .sy-kontrol, .sy-say { display: none !important; }
  .sy-girdi { min-height: 4em; }
  /* Kâğıtta açıklama görünür: yazdıran öğrenci cevabı zaten kendi yazacak. */
  .sy-neden { display: block !important; }
}


/* ══ 18 · KOD ADIMLAYICI · SPYDER PANOLARI ═════════════════════════════════
   Alperen, 11 Eyl: "cs dersini azıcık duolingo ya da 3 minutes prown
   (3Blue1Brown) gibi yapamaz mıyız". Bir programlama dersinde gösterilecek
   şey çalışmanın kendisi: hangi satır koşuyor, hangi ad hangi değere bağlı,
   konsola o ana kadar ne düşmüş.

   12 Eyl, iki cümle bu yerleşimi belirledi: "kod çıktıları ve egzersizler
   spyder görünümlü olabilir" ve "genelde ders çalışırken pc den
   çalışıyorlar". Öğrencinin haftada saatlerce önünde durduğu pencere Spyder
   ve o pencerenin üç panosu var — solda editör, sağda üstte Variable
   Explorer, sağda altta IPython konsolu. Adımlayıcı artık aynı üç panoyu
   aynı yerleşimle gösteriyor: burada öğrenilen şey NEREYE BAKILACAĞI da
   oluyor. ≥56rem'de iki sütun (PC), altında üst üste — dar ekran eksik
   değil, SIKIŞIK.

   PALET DEĞİŞMEDİ. Spyder'ın kendi varsayılan teması da açık renkli, yani
   IDE hissiyatı için gece paleti gerekmiyor; bu bölümde tek bir yeni renk
   yok, hepsi mevcut token. Tek bilinçli gerilim: IPython isteminin
   (`In [1]:`) rengi `--emerald`. Ö7'de emerald "DOĞRU" demek, ama bu istem
   konsolun tek tanınır imzası ve bir doğruluk göstergesinin yanında hiç
   durmuyor (doğru/yanlış geri bildirimi `.sy-*` ve `.s-geri`de, başka
   panoda). Karar bilerek verildi, kaza değil.

   VERİ GERÇEK: izler `scripts/notes/kod.py izle` ile kod gerçekten
   koşturularak çıkarıldı. Variable Explorer'ın dört sütunundan üçü — tip ve
   boyut dahil — o koşumda `type()` ve `len()` ile ÖLÇÜLDÜ. ÖLÇÜLDÜ 12 Eyl:
   cs-115'in 8 bölümünde 374 kod bloğu adımlayıcıya değdi.

   JS YOKSA: hiçbir şey görünmez, `<pre>` olduğu gibi kod listesi kalır.
   Açma düğmesi de panolar da JS tarafından doğuruyor; kutu kapanınca `<pre>`
   geri geliyor, yani JS'siz durumla birebir aynı. */

.kz-ac {
  display: block; margin: -.55em 0 1.1em;
  font-family: var(--ui); font-size: var(--f-yardim);
  padding: .4em .9em; cursor: pointer;
  color: var(--accent); background: transparent;
  border: 1px solid var(--border-strong); border-radius: 4px;
}
.kz-ac:hover { border-color: var(--accent); background: var(--paper-soft); }

.kz {
  margin: -.55em 0 1.2em; padding: var(--b2);
  border: 1px solid var(--border); border-radius: 4px;
  background: var(--surface);
}
.kz:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* ── araç çubuğu ── */
.kz-ust { display: flex; align-items: center; gap: var(--b1); flex-wrap: wrap; }
.kz-d {
  font: inherit; font-size: var(--f-govde); line-height: 1;
  width: 2.1em; height: 2.1em; cursor: pointer;
  color: var(--ink-2); background: var(--paper-soft);
  border: 1px solid var(--border-strong); border-radius: 4px;
}
.kz-d:hover:enabled { border-color: var(--accent); color: var(--accent); }
.kz-d:disabled { opacity: .35; cursor: default; }
.kz-say {
  font-family: var(--mono); font-size: var(--f-et); color: var(--muted);
  margin-left: var(--b1);
}
/* "guess first" — Duolingo halkasını ZORUNLU kılan düğme: açıkken değişen
   değer `?` gelir, öğrenci önce söyler. */
.kz-tahmin {
  margin-left: auto;
  font-family: var(--mono); font-size: var(--f-et);
  padding: .35em .7em; cursor: pointer;
  color: var(--muted); background: transparent;
  border: 1px dashed var(--border-strong); border-radius: 4px;
}
.kz-tahmin[aria-pressed="true"] {
  color: var(--accent); border-style: solid; border-color: var(--accent);
}

.kz-kaydir { width: 100%; margin: var(--b2) 0 var(--b1); accent-color: var(--accent); }

/* ── panoların yerleşimi ── */
.kz-panolar {
  display: grid; grid-template-columns: minmax(0, 1fr);
  gap: var(--b2); margin-top: var(--b1);
}
.kz-sag { display: grid; gap: var(--b2); align-content: start; min-width: 0; }
/* PC eşiği. 56rem çünkü okuma sütunu 38rem + iki kenar boşluğu; bunun
   altında iki pano yan yana 190px'e düşüyor ve Variable Explorer'ın dört
   sütunu okunmaz oluyor (ölçüldü). */
@media (min-width: 56rem) {
  .kz-panolar { grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr); }
  /* Geniş ekranda kutu kenar boşluğuna taşıyor — figürün ve veri tablosunun
     zaten kullandığı bütçe (§3), yeni bir mekanizma değil. */
  .kz { margin-inline: calc(-1 * var(--tas)); }
}

.kz-pano {
  display: flex; flex-direction: column;
  border: 1px solid var(--border); border-radius: 4px;
  background: var(--paper-soft); min-width: 0; overflow: hidden;
}
/* Editör panosu yüksekliği doldursun: kod kısayken kaydırma çubuğu panonun
   ORTASINDA kalıyor ve altında ölü bir alan duruyordu. */
.kz-sol .kz-ed, .kz-pano .kz-kon { flex: 1 1 auto; }
/* Spyder'ın sekme çubuğu. */
.kz-tab {
  display: flex; align-items: baseline; gap: var(--b1);
  padding: .32em .6em; border-bottom: 1px solid var(--border);
  background: var(--surface);
  font-family: var(--mono); font-size: var(--f-et); color: var(--muted);
}
.kz-tab-ad { color: var(--ink-2); }
/* Hangi çerçevenin yerelleri gösteriliyor: fonksiyona girince Variable
   Explorer'daki adlar YENİ bir kümedir, bunu yazmayan pano yanıltıyor. */
.kz-cer { margin-left: auto; color: var(--accent); }
.kz-cer:empty { display: none; }

/* ── EDİTÖR PANOSU ── */
.kz-ed {
  position: relative;              /* JS satırı kendi kabında kaydırıyor */
  max-height: 26em; overflow: auto;
  padding: .35em 0;
  font-family: var(--mono); font-size: .8em; line-height: 1.55;
}
.kz-sat {
  display: grid; grid-template-columns: 1.1em 2.3em minmax(0, 1fr);
  align-items: baseline; min-height: 1.55em;
  /* Uzun satır sarılmaz (girinti anlamlıdır); pano kendi içinde kayar ve
     vurgulanan satırın zemini kaydırma genişliğince uzar. */
  width: max-content; min-width: 100%;
}
/* Oluk KOPYALANMIYOR: öğrenci kodu kopyaladığında araya satır numarası
   girmesi Spyder'da olmayan bir şey. */
.kz-ok, .kz-no { user-select: none; -webkit-user-select: none; }
/* SATIR IMLECI: GLIF DEGIL KENARLIK UCGENI.
   `▸` (U+25B8) uretilen yedi fontun altisinda YOK (fontTools ile olculdu) ve
   `--kod-mono` yigini Windows/macOS gorunumlerinde bizim JetBrains'imizi hic
   icermiyor — glif sistem fontuna kaliyor, tasimayan sistemde tofu cikiyor ve
   bazi fontlar tofunun icine '25B8' yazip ekranda okunur hale getiriyor.
   Kenarlik ucgeni hicbir fonta bagli degil, her DPI'da net. */
.kz-ok {
  display: grid; place-items: center; opacity: 0;
}
.kz-ok::before {
  content: ''; width: 0; height: 0;
  border-style: solid; border-width: .3em 0 .3em .42em;
  border-color: transparent transparent transparent var(--accent);
}
.kz-no {
  text-align: right; padding-right: .55em;
  color: var(--muted); opacity: .75;
}
/* `code` genel kuralı zemin + dolgu + .8em veriyor; burada kod bir tablo
   hücresi gibi hizalanmalı, o yüzden hepsi sıfırlanıyor. */
.kz-kd {
  white-space: pre; background: none; padding: 0; border-radius: 0;
  font-size: 1em; color: var(--ink);
}
/* İnce kaydırma çubuğu: dosyanın kendi konvansiyonu (`.nt-sar`, §11). */
.kz-ed::-webkit-scrollbar, .kz-kon::-webkit-scrollbar { height: 4px; width: 4px; }
.kz-ed::-webkit-scrollbar-thumb, .kz-kon::-webkit-scrollbar-thumb {
  background: var(--border-strong); border-radius: 2px;
}
.kz-simdi { background: var(--vurgu-zemin); }
.kz-simdi .kz-ok { opacity: 1; }
.kz-simdi .kz-no { color: var(--accent); opacity: 1; }

/* ── VARIABLE EXPLORER ── */
.kz-vt {
  width: 100%; border-collapse: collapse; table-layout: fixed;
  font-family: var(--mono); font-size: .78em;
}
.kz-vt th {
  text-align: left; font-weight: 500; color: var(--muted);
  font-size: var(--f-et); padding: .3em .5em;
  background: var(--surface); border-bottom: 1px solid var(--border);
}
/* Dört sütun sabit paylı: içerik sütun genişliğini oynatmasın, adım
   attıkça tablo zıplamasın. Değer sütunu kalanı alır ve SARILIR — repr
   120 karakterde kesiliyor, yani en kötü hâli biliniyor. */
.kz-vt th:nth-child(1) { width: 33%; }
.kz-vt th:nth-child(2) { width: 17%; }
.kz-vt th:nth-child(3) { width: 11%; }
.kz-vt td {
  padding: .28em .5em; vertical-align: top;
  border-bottom: 1px solid var(--border);
  color: var(--ink-2); overflow-wrap: anywhere;
}
.kz-vt tr:last-child td { border-bottom: 0; }
.kz-v-ad { color: var(--ink); font-weight: 600; }
.kz-v-tip, .kz-v-boy { color: var(--muted); }
.kz-v-boy { text-align: right; }
.kz-v-dg { color: var(--ink); }
/* O adımda DEĞİŞEN satır: gözün gideceği yer tek olsun. Zemin YÜZEY 2,
   yani "cevap" yüzeyi (Ö7) — değişen değer, "bu satır ne yapacak"
   sorusunun cevabının kendisi. */
tr.kz-yeni td { background: var(--vurgu-zemin); }
.kz-bos { color: var(--muted); font-size: var(--f-et); }

/* ── IPYTHON KONSOLU ── */
.kz-kon {
  margin: 0; padding: .5em .65em; min-height: 3.4em;
  max-height: 14em; overflow: auto;
  font-family: var(--mono); font-size: .8em; line-height: 1.5;
  /* Biçimli çıktı (`'{:>8}'.format`) dersin konusu; sarmak hizayı bozar,
     o yüzden konsol da editör gibi kendi kutusunda kayıyor. */
  white-space: pre; color: var(--ink); background: transparent;
}
.kz-istem { color: var(--emerald); }
.kz-kmt { color: var(--ink-2); }
.kz-hata { color: var(--accent); }

.kz-not {
  margin-top: var(--b2); font-family: var(--ui); font-size: var(--f-yardim);
  color: var(--amber);
}

/* Yazdırırken adımlayıcı yok: kâğıtta tek bir adım göstermek yanıltıcı. */
@media print {
  .kz, .kz-ac { display: none !important; }
}

/* ══ 19 · WIDGET'IN UÇ DURUMLARI ═══════════════════════════════════════════
   ÖLÇÜLDÜ 12 Eyl: şemada tanımlı (`edge_cases`, sema.md:228) ve corpus'taki
   20 widget'ın neredeyse hepsinde dolu olan bu alan HİÇ BASILMIYORDU —
   `grep edge_cases render_v2.py build.py` sıfır satır dönüyordu. Yani yazarın
   elle yazdığı "bu parametre ucuna giderse ne olur ve neden" yorumu %100
   çöpe gidiyordu. Bir parametrenin uç değerinde ne olduğunu bilmek o
   parametreyi anlamanın kendisidir. */
.wg-uc { margin-top: var(--b2); text-align: left; }
.wg-uc-bas {
  font-family: var(--mono); font-size: var(--f-et);
  letter-spacing: .04em; text-transform: uppercase; color: var(--muted);
  margin-bottom: 6px;
}
.wg-uc dl { margin: 0; }
.wg-uc dt {
  font-family: var(--ui); font-size: var(--f-yardim); color: var(--ink);
  margin-top: var(--b1);
}
.wg-uc dt span {
  font-family: var(--mono); font-size: var(--f-et); color: var(--accent);
  background: var(--vurgu-zemin); padding: 1px 5px; border-radius: 3px;
}
.wg-uc dd {
  margin: 2px 0 0; font-size: var(--f-yardim); color: var(--ink-2);
}
.wg-uc dd p { margin: 0; }

/* ══ 20 · İLK YAPILABİLİR ŞEY ══════════════════════════════════════════════
   ÖLÇÜLDÜ 12 Eyl (360px, math-101/01): ilk cevaplanabilir şeye 8.161 px =
   12,8 ekran; gerçek alıştırma 143.578 px'te. Duolingo'da bu mesafe sıfır.
   Sayfa kısaltılmadı, SIRA değişti: ön testin ilk sorusu artık başlıktan
   hemen sonra. Kutu vurgulu değil SAKİN: sayfanın ilk şeyi bir uyarı gibi
   görünmemeli, bir davet gibi görünmeli. */
.baslat {
  margin: var(--b3) 0 var(--b4); padding: var(--b2) var(--b2) var(--b1);
  border: 1px solid var(--border-strong); border-radius: 8px;
  background: var(--surface);
}
.bs-bas {
  font-family: var(--mono); font-size: var(--f-et);
  letter-spacing: .04em; text-transform: uppercase; color: var(--accent);
}
.bs-not {
  margin: 4px 0 var(--b2); font-size: var(--f-yardim); color: var(--muted);
}
.baslat .soru { margin: 0; border: 0; padding: 0; }
/* Sınav moduna çalışan biri ön testi görmek istemiyor: modun mantığı
   "doğrudan notu getiren şeye git". */
body.mod-sinav .baslat, body.sadece-problem .baslat { display: none; }

/* ══ 21 · PLANI SIRAYA KOY ═════════════════════════════════════════════════
   Alperen, 12 Eyl: "sırayla kodda ne yapması gerektiğini kodun mantığını
   interaktif şekilde anlatabilir misin".

   İki liste sayfada zaten vardı ve ikisi de düz basılıyordu: yöntemin
   adımları (`method_boxes[].steps[].label`) ve her problemin paylaştığı
   iskelet (`faded_ladder.shared_skeleton`). Öğrenci önce cevabı okuyor,
   sonra "anladım" diyordu. Sıra değişti: liste önce KARIŞIK düğmeler olarak
   geliyor, doğru sırayı kuran öğrenciye asıl liste açılıyor.

   YENİ YÜZEY YOK (Ö7). Bu blok `.merdiven`in İÇİNDE de duruyor ve merdiven
   zaten YÜZEY 1; içine ikinci bir `--surface` koymak görünmez bir kutu
   demekti. Ayrım, dosyanın kendi deseniyle: boşluk + mono etiket + yatay
   ince çizgi. Düğmeler `.s-sik`in birebir aynısı — aynı işi yapan öğeye
   ikinci bir düğme dili uydurulmadı. Emerald yalnız İŞ BİTİNCE giriyor,
   çünkü doğruluk ancak o an biliniyor.

   SÜRÜKLE-BIRAK YOK: dokunmatikte sürükleme sayfa kaydırmasıyla yarışır,
   klavyeyle hiç yapılamaz. Yerleştirme dokunarak; düğme olduğu için klavye
   ve ekran okuyucu bedavaya çalışıyor. */
.pl {
  margin: var(--b2) 0 var(--b3); padding-top: var(--b2);
  border-top: 1px solid var(--border);
}
.pl-bas {
  font-family: var(--mono); font-size: var(--f-et);
  letter-spacing: .06em; text-transform: uppercase; color: var(--accent);
}
.pl-ip {
  margin: 4px 0 var(--b2);
  font-size: var(--f-yardim); color: var(--muted);
}
.pl-plan { margin: 0 0 var(--b2); padding-left: 1.6rem; }
.pl-plan li { margin-bottom: var(--b1); }
.pl-plan li::marker { font-family: var(--mono); color: var(--muted); }
.pl-bos {
  list-style: none; margin-left: -1.6rem;
  font-family: var(--mono); font-size: var(--f-et); color: var(--muted);
}
/* Havuz ile plan GÖRSEL OLARAK ayrışmalı: ölçüldü, ikisi de aynı kutu
   olduğunda tek fark baştaki numara kalıyor ve "hangileri yerleşti"
   bir bakışta okunmuyor. Kesikli kenar dosyanın kendi dilinde
   "henüz değil" demek (`.kz-tahmin`, `.pl-kucuk` aynı deseni kullanıyor). */
.pl-et {
  font-family: var(--mono); font-size: var(--f-et); color: var(--muted);
  margin-bottom: 4px;
}
.pl-havuz { display: grid; gap: var(--b1); margin-bottom: var(--b2); }
.pl-havuz .pl-oge { border-style: dashed; }
.pl-plan .pl-oge { border-style: solid; }
.pl-oge {
  display: block; width: 100%;
  font: inherit; font-size: var(--f-yardim); text-align: left;
  padding: var(--b1) var(--b2); cursor: pointer;
  color: inherit; background: transparent;
  border: 1px solid var(--border); border-radius: 4px;
  min-width: 0; overflow-wrap: anywhere;
}
.pl-oge:hover:enabled { border-color: var(--accent); }
.pl-oge:disabled { cursor: default; }
/* Emerald YALNIZCA öğrenci kendisi bulduğunda (Ö7: emerald = DOĞRU).
   "show the order" ile açıldığında `data-bitti="goster"` oluyor ve yeşil
   gelmiyor: pes etmek çözmekle aynı görünmez. */
.pl[data-bitti="1"] .pl-secili { border-color: var(--emerald); color: var(--ink); }
.pl-geri {
  margin: var(--b2) 0; padding: var(--b2);
  background: var(--vurgu-zemin); border-radius: 4px;
  font-size: var(--f-yardim); color: var(--ink-2);
}
.pl-geri b { color: var(--emerald); }
.pl-alt { display: flex; gap: var(--b2); flex-wrap: wrap; }
.pl-kucuk {
  font-family: var(--mono); font-size: var(--f-et);
  padding: .3em .6em; cursor: pointer;
  color: var(--muted); background: transparent;
  border: 1px dashed var(--border-strong); border-radius: 4px;
}
.pl-kucuk:hover { color: var(--accent); border-color: var(--accent); }

/* Kâğıtta bulmaca yok: liste JS'siz hâliyle, olduğu gibi basılır. */
@media print { .pl { display: none !important; } }

/* ══ 22 · EKRAN GÖRÜNTÜLERİ ════════════════════════════════════════════════
   Alperen, 12 Eylül: "artık ansiklopedilerden sıkıldık. bize gözümüze de
   hitap edecek bir materyal lazım" · "spyder kurulumu gösteren ekran
   görüntülerini de koyabilirsin. yani bir öğrenci başka bir şeye ihtiyaç
   durmasın ve sıkılmasın asıl amaç".

   Bunlar sayfanın bir parçası değil, BİR UYGULAMANIN FOTOĞRAFI. O yüzden
   çerçeveli ve altyazılı: okuyucu neyin site, neyin ekran görüntüsü olduğunu
   ayırt etmeli. Görüntüler gerçek — Spyder sanal bir X ekranında fabrika
   ayarlarıyla koşturuldu ve pencere olduğu gibi çekildi; altyazı hangi sürüm
   ve hangi işletim sistemi olduğunu yazıyor.

   Figür zaten §3'te kenar boşluğuna taşma bütçesine sahip (`main.govde
   figure`), yani ekran görüntüsü okuma sütunundan geniş çıkıyor. Koyu temalı
   bir ekran görüntüsü açık kâğıdın üstünde duracak; bu bilinçli, çünkü
   Spyder'ın kendi varsayılanı koyu. */
.ekranlar { margin: var(--b4) 0; }
.ek-bas {
  font-family: var(--mono); font-size: var(--f-et);
  letter-spacing: .06em; text-transform: uppercase; color: var(--accent);
}
.ek-not {
  margin: 4px 0 var(--b3);
  font-size: var(--f-yardim); color: var(--muted);
}
figure.ekran { margin-block: var(--b3); }
figure.ekran img {
  display: block; width: 100%; height: auto;
  border: 1px solid var(--border-strong); border-radius: 4px;
  background: var(--paper-soft);
}
figure.ekran figcaption {
  margin-top: var(--b1); padding-inline: var(--tas);
  font-size: var(--f-yardim); color: var(--ink-2); text-align: left;
}
figure.ekran figcaption b { display: block; color: var(--ink); }
figure.ekran figcaption p { margin: 0; }
.ek-kunye {
  display: block; margin-top: 4px;
  font-family: var(--mono); font-size: var(--f-et); color: var(--muted);
}
.ek-kur { margin-top: var(--b3); padding-top: var(--b2);
  border-top: 1px solid var(--border); }
.ek-kur-bas {
  font-family: var(--mono); font-size: var(--f-et);
  letter-spacing: .06em; text-transform: uppercase; color: var(--muted);
  margin-bottom: var(--b1);
}
.ek-kur ol { margin: 0; font-size: var(--f-yardim); }
.ek-kur li { margin-bottom: var(--b1); }
.ek-kur li p { margin: 0; }

/* Her bölümde tam gezinti yok: ötekilerde KAPALI bir kutu içinde tek kare. */
.ekran-kisa { margin: var(--b3) 0; }
.ekran-kisa > summary {
  font-family: var(--mono); font-size: var(--f-et);
  letter-spacing: .04em; color: var(--accent); cursor: pointer;
}
.ekran-kisa figure.ekran { margin-top: var(--b2); }

/* Kâğıtta ekran görüntüsü basılmaz: mürekkep yer, öğretmez. */
@media print { .ekranlar, .ekran-kisa { display: none !important; } }

/* ══ 23 · KARELİ WIDGET ════════════════════════════════════════════════════
   ÖLÇÜLDÜ 12 Eyl: corpus'ta 19 widget var, `data-widget` adlarının hiçbiri
   için build.py'de JS YOKTU — yani şema interaktif bir şey istiyor, model
   üretiyor, sayfa yalnızca yedek SVG'yi basıyordu. 19'unun 19'u kıpırdamıyordu.
   Alperen 12 Eyl: "artık ansiklopedilerden sıkıldık, bize gözümüze de hitap
   edecek bir materyal lazım". Sebebi buydu.

   Tarayıcıda matematik yapılmıyor: yazar sıralı KARELER veriyor, JS yalnızca
   kareyi değiştiriyor. Her kare elle yazılmış, denetlenebilir bir figür.
   JS yokken sayfada yine anlamlı bir figür duruyor.

   Denetim düğmeleri adımlayıcının BİREBİR aynısı (aynı ölçü, aynı renk):
   sayfada iki ayrı gezinme dili olmasın. */
.wg-ust {
  display: flex; align-items: center; gap: var(--b1);
  flex-wrap: wrap; margin-bottom: var(--b1);
}
.wg-d {
  font: inherit; font-size: var(--f-govde); line-height: 1;
  width: 2.1em; height: 2.1em; cursor: pointer;
  color: var(--ink-2); background: var(--paper-soft);
  border: 1px solid var(--border-strong); border-radius: 4px;
}
.wg-d:hover:enabled { border-color: var(--accent); color: var(--accent); }
.wg-d:disabled { opacity: .35; cursor: default; }
.wg-et {
  font-family: var(--mono); font-size: var(--f-et); color: var(--muted);
  margin-left: var(--b1); text-align: left;
}
.wg-kaydir {
  width: 100%; margin: 0 0 var(--b2); accent-color: var(--accent);
}
.wg-sahne > svg { display: block; width: auto; max-width: 100%; height: auto;
  margin-inline: auto; }
figure.widget[data-wg]:focus-visible {
  outline: 2px solid var(--accent); outline-offset: 3px;
}

/* Kâğıtta tek kare basılır (yedek SVG), gezinme düğmeleri basılmaz. */
@media print { .wg-ust, .wg-kaydir { display: none !important; } }

/* ══ 24 · SPYDER AÇIK · ÜÇ İŞLETİM SİSTEMİ ════════════════════════════════
   Alperen, 12 Eyl, üç mesajda sırayla:
     "linux windows ve mac os teması koyarsan insanlar basar yukarıdan"
     "ekran görüntüsü değil de terminali kendimiz oluşturabilir miyiz...
      png değil bizim temamız olur... içinden kopyalanabilir olur"
     "kodlar yorum satırlarıyla birlikte sanki terminal havası vermeliydi...
      print deyince renk değişiyordu... sanki python çalıştırıyor gibi
      yapamaz mıyız... sanki spyder'ı açmışız gibi yap yani"

   ── RENKLER UYDURULMADI, ÖLÇÜLDÜ ────────────────────────────────────────
   kaplıkaya'da kurulu Spyder 5.5.1'in kendi ayar sözlüğü okundu
   (`spyder.config.appearance.APPEARANCE`). Seçili şema `spyder/dark`, yani
   öğrenci Spyder'ı ilk açtığında KARANLIK temayı görüyor. Ölçülen değerler:
     background #19232D · normal #ffffff · keyword #c670e0 · builtin #fab16c
     comment #999999 · string #b0e686 (italik) · number #faed5c
     definition #57d6e4 (kalın) · instance #ee6772 (italik)
     currentline #3a424a · sideareas #222b35
   Aşağıdaki her hex bu listeden. Tek eklediğim şey, kâğıt sayfanın üstünde
   bu bloğun kendi gölgesi ve kenarı.

   ── ÜÇ SİSTEM ARASINDA NE DEĞİŞİR, NE DEĞİŞMEZ ──────────────────────────
   DEĞİŞMEZ: Spyder'ın kendi içi. Spyder üç sistemde de aynı görünür;
   editörü Windows'ta mor, macOS'ta mavi yapmak UYDURMA olurdu.
   DEĞİŞİR ve hepsi gerçek:
     · pencere çerçevesi (başlık çubuğu, düğmeler, köşe yarıçapı)
     · dosya yolu: C:\Users\student\ · /Users/student/ · /home/student/
     · satır sonu: Windows CRLF, ötekiler LF
     · mono yüz: Consolas · SF Mono · JetBrains/DejaVu
     · IPython açılış satırındaki derleyici etiketi: MSC v.1916 · Clang · GCC
   Sonuncusu Python'un `sys.version`'ından gelen gerçek bir fark.

   ── HEPSİ HTML VE CSS ───────────────────────────────────────────────────
   Tek PNG yok. Metin seçilebilir, kopyalanabilir, punto düğmesiyle büyür,
   ekran okuyucu okur, indirilecek bayt yok. Boyama SUNUCUDA yapılıyor
   (`render_v2.py:py_boya`, Python'un kendi `tokenize`'ı), yani JS kapalıyken
   de renkli.

   ── Ö7 İLE GERİLİM, BİLEREK ─────────────────────────────────────────────
   Sayfada iki yüzey var. Bu blok üçüncü bir yüzey değil, sayfanın GÖSTERDİĞİ
   bir AYGIT. Bir fotoğrafın içindeki renkler sayfanın paletine sayılmıyorsa,
   kendi elimizle çizdiğimiz Spyder penceresinin renkleri de sayılmaz. Karar
   bilinçli; ölçütü de belli: bu palet `.kz` ve `.sy-kon` dışına SIZMIYOR. */

:root {
  --kod-mono: var(--mono);
  --pnc-yuvarti: 4px;

  /* Spyder Dark — ölçülen değerler */
  --sp-zemin:  #19232d;
  --sp-ink:    #ffffff;
  --sp-oluk:   #222b35;   /* satır numarası oluğu (sideareas) */
  --sp-satir:  #3a424a;   /* koşan satır (currentline) */
  --sp-kw:     #c670e0;
  --sp-bi:     #fab16c;
  --sp-cm:     #999999;
  --sp-st:     #b0e686;
  --sp-nm:     #faed5c;
  --sp-df:     #57d6e4;
  --sp-in:     #ee6772;
  --sp-kenar:  #2b3642;   /* panolar arası ayrım (zeminden bir kademe açık) */

  /* eski `--trm-*` adlari, `.ai-pop` ve yazma kutusu bunlari okuyor */
  --trm-zemin: var(--sp-zemin);
  --trm-bas:   var(--sp-oluk);
  --trm-ink:   var(--sp-ink);
  --trm-istem: var(--sp-st);
  --trm-kmt:   var(--sp-cm);
  --trm-hata:  var(--sp-in);

  --yol-onek: '';
  --satir-sonu: 'LF';
  --derleyici: 'GCC';
}

.kz-kd, .kz-kon, .kz-vt, .kz-tab, .sy-girdi, .sy-istem, .kz-ed, .kz-durum {
  font-family: var(--kod-mono);
}

/* ── SPYDER PENCERESİ ────────────────────────────────────────────────────── */
.kz {
  background: var(--sp-zemin);
  border-color: var(--sp-kenar);
  border-radius: var(--pnc-yuvarti);
}
.kz-pano, .sy-kon {
  background: var(--sp-zemin); border-color: var(--sp-kenar);
  border-radius: calc(var(--pnc-yuvarti) - 2px);
}
.kz-tab {
  background: var(--sp-oluk); color: var(--sp-ink);
  border-bottom-color: var(--sp-kenar);
}
.kz-tab-ad { color: var(--sp-ink); }
.kz-cer { color: var(--sp-bi); }
/* Pencere düğmeleri VARSAYILAN GİZLİ; üç görünümün her biri kendi bloğunda
   kendi düğmesini açıyor: Windows 46x32 üç dikdörtgen, macOS 12px trafik
   lambası, GNOME tek 24px yuvarlak kapat. Üçü de SVG, hiçbiri font glifine
   dayanmıyor.
   12 EYLÜL'DE BURADA YANLIŞ BİR ŞEY YAZIYORDU: bu yorum macOS lambasının ve
   GNOME düğmesinin YAPILDIĞINI söylüyordu, oysa CSS'te yoktu ve ekran
   görüntüsünde iki görünümde de başlık çubuğu ÇIPLAK çıkıyordu. Yorum bir
   iddiadır, ölçülmeden yazılmaz. */
.pnc-cap { display: none; margin-left: auto; align-items: center; }
/* Olculer ve renkler OS bloklarinda: ucunun pencere dugmesi ayni sey degil.
   Windows'ta 46x32 dikdortgen, macOS'ta 12px daire, GNOME'da 24px tek daire.
   Tabanda yalniz ortak olan duruyor. */
.pnc-b { display: grid; place-items: center; color: inherit; }
.pnc-g-mac { display: none; }

/* Dosya yolu sekmede, adın önünde: soluk, adı bastırmıyor. */
.kz-sol .kz-tab-ad::before, .sy-kon .kz-tab-ad::before {
  content: var(--yol-onek); color: var(--sp-cm); font-weight: 400;
}

/* araç çubuğu düğmeleri bu zeminde okunur kalsın */
.kz-ust { color: var(--sp-ink); }
.kz-d {
  color: var(--sp-ink); background: var(--sp-oluk);
  border-color: var(--sp-kenar);
}
.kz-d:hover:enabled { color: var(--sp-df); border-color: var(--sp-df); }
.kz-say { color: var(--sp-cm); }
.kz-tahmin { color: var(--sp-cm); border-color: var(--sp-kenar); }
.kz-tahmin[aria-pressed="true"] { color: var(--sp-nm); border-color: var(--sp-nm); }
.kz-kaydir { accent-color: var(--sp-df); }
.kz-not { color: var(--sp-bi); }

/* ── EDİTÖR ──────────────────────────────────────────────────────────────── */
.kz-ed { color: var(--sp-ink); }
.kz-kd { color: var(--sp-ink); background: none; }
.kz-no {
  color: var(--sp-cm); opacity: .8;
  background: var(--sp-oluk);
}
.kz-ok::before { border-left-color: var(--sp-bi); }
/* Koşan satır: Spyder'ın kendi `currentline` rengi. */
.kz-simdi { background: var(--sp-satir); }
.kz-simdi .kz-no { color: var(--sp-ink); opacity: 1; background: var(--sp-satir); }
.kz-ed::-webkit-scrollbar-thumb, .kz-kon::-webkit-scrollbar-thumb,
.kz-vt-sar::-webkit-scrollbar-thumb { background: #44505e; }

/* TOKEN RENKLERİ — `py_boya` bu sınıfları basıyor */
.t-kw { color: var(--sp-kw); }
.t-bi { color: var(--sp-bi); }
.t-cm { color: var(--sp-cm); }
.t-st { color: var(--sp-st); font-style: italic; }
.t-nm { color: var(--sp-nm); }
.t-df { color: var(--sp-df); font-weight: 600; }
.t-in { color: var(--sp-in); font-style: italic; }

/* Gövde içindeki `<pre class="kod">` de aynı pencere: JS kapalıyken görülen
   şey de Spyder'ın editörü olsun, iki ayrı kod görünümü olmasın. */
pre.kod {
  background: var(--sp-zemin); color: var(--sp-ink);
  border: 1px solid var(--sp-kenar); border-radius: var(--pnc-yuvarti);
}
pre.kod code { color: var(--sp-ink); background: none; }

/* ── DURUM ÇUBUĞU ───────────────────────────────────────────────────────── */
.kz-durum {
  display: flex; gap: 1.4em; flex: none;
  padding: .28em .6em; border-top: 1px solid var(--sp-kenar);
  background: var(--sp-oluk);
  font-size: 10.5px; letter-spacing: .04em; color: var(--sp-cm);
  user-select: none; -webkit-user-select: none;
}
.kz-durum::before { content: 'UTF-8'; }
/* `\00b7` kacisindan SONRAKI bosluk kacisin SONLANDIRICISI sayiliyor ve
   ekranda yutuluyordu ("LF ·Python"). Bosluk da kacisla yaziliyor. */
.kz-durum::after  { content: var(--satir-sonu) ' \00b7\0020Python 3.11'; }

/* ── VARIABLE EXPLORER ──────────────────────────────────────────────────── */
.kz-vt th {
  color: var(--sp-cm); background: var(--sp-oluk);
  border-bottom-color: var(--sp-kenar);
}
.kz-vt td { color: var(--sp-ink); border-bottom-color: var(--sp-kenar); }
.kz-v-ad { color: var(--sp-df); }
.kz-v-tip { color: var(--sp-kw); }
.kz-v-boy { color: var(--sp-cm); }
.kz-v-dg { color: var(--sp-ink); }
tr.kz-yeni td { background: var(--sp-satir); }
.kz-bos { color: var(--sp-cm); }

/* ── IPYTHON KONSOLU ────────────────────────────────────────────────────── */
.kz-kons .kz-kon { color: var(--sp-ink); background: transparent; }
.kz-kons .kz-istem { color: var(--sp-st); }
.kz-kons .kz-kmt { color: var(--sp-cm); }
.kz-kons .kz-hata { color: var(--sp-in); }
/* AÇILIŞ SATIRI. Spyder'ın konsolu boş açılmıyor; IPython kendini tanıtıyor.
   Derleyici etiketi işletim sistemine göre GERÇEKTEN değişiyor: Windows'ta
   MSC, macOS'ta Clang, Linux'ta GCC (Python'un `sys.version`'ından). */
/* `attr()` yalniz ELEMANIN KENDI ozniteligini okur; `data-os` <html>'de
   duruyor, o yuzden isletim sistemi adi buraya `attr()` ile GELMEZ. Fark
   zaten derleyici etiketinde ve o gercek bir fark. */
/* Banner KISA. Uzun hali ("-- An enhanced Interactive Python.") panoyu
   asiyor ve sagdan kirpilmis gorunuyordu; kirpik bir acilis satiri
   "yarim kalmis" hissi veriyor. Iki satir yeter, ikisi de gercek. */
.kz-kons .kz-kon::before {
  content: 'Python 3.11.5 [' var(--derleyici) ']\A IPython 8.15.0\A\A';
  color: var(--sp-cm); white-space: pre;
}
.sy-kon .sy-istem { color: var(--sp-st); }
.sy-kon .sy-girdi {
  color: var(--sp-ink); background: #121a22;
  border-color: var(--sp-kenar); caret-color: var(--sp-st);
}
.sy-kon .sy-girdi::placeholder { color: var(--sp-cm); }
.sy-kon .sy-girdi:focus { border-color: var(--sp-st); }

/* ── LINUX · GNOME ──────────────────────────────────────────────────────── */
html[data-os="linux"] {
  --kod-mono: 'JetBrains Mono', 'DejaVu Sans Mono', 'Ubuntu Mono',
              ui-monospace, monospace;
  --pnc-yuvarti: 10px;
  --yol-onek: '/home/student/';
  --satir-sonu: 'LF';
  --derleyici: 'GCC 11.2.0';
}
html[data-os="linux"] .kz-tab {
  padding: .4em .4em .4em .75em; font-weight: 500; align-items: center;
}
/* GNOME BASLIK CUBUGU: TEK dugme.
   Adwaita'da kucult/buyut varsayilan olarak GIZLI; basligin sagindaki tek
   yuvarlak kapat dugmesi kalir. Windows'un uclusunu buraya tasimak yanlis
   olurdu — ucunu ayirt eden sey tam olarak bu. Kapat glifi `×` DEGIL SVG:
   uretilen font subset'inde box-drawing/simge kod noktalari yok (fontTools
   ile olculdu), SVG hem her DPI'da net hem tofu riski sifir. */
html[data-os="linux"] .pnc-cap { display: flex; }
html[data-os="linux"] .pnc-kucult, html[data-os="linux"] .pnc-buyut {
  display: none;
}
html[data-os="linux"] .pnc-x {
  width: 24px; height: 24px; border-radius: 50%;
  background: rgba(255, 255, 255, .1); opacity: .82;
  transition: background-color .14s ease, opacity .14s ease;
}
html[data-os="linux"] .pnc-x:hover {
  background: rgba(255, 255, 255, .18); opacity: 1;
}
html[data-os="linux"] .pnc-g-win { width: 9px; height: 9px; }

/* ── WINDOWS ────────────────────────────────────────────────────────────── */
html[data-os="win"] {
  --kod-mono: Consolas, 'Cascadia Mono', 'Lucida Console',
              ui-monospace, monospace;
  --pnc-yuvarti: 8px;
  --yol-onek: 'C:\\Users\\student\\';
  --satir-sonu: 'CRLF';
  --derleyici: 'MSC v.1916 64 bit';
}
html[data-os="win"] .kz-d, html[data-os="win"] .sy-girdi { border-radius: 2px; }
/* WINDOWS 11 PENCERE DUGMELERI — ölçülen değerlerle.
   Kaynak: microsoft/windows-dev-docs `titlebar-design.md` (başlık çubuğu
   32px, başlık 12px, simgesiz sol boşluk 16px) ve microsoft/terminal
   `MinMaxCloseControl.xaml` (düğme kutusu 46x32, glif 10x10). Kapat
   düğmesinin hover rengi #C42B1C, glifi beyaz.
   Glifler UNICODE DEĞİL inline SVG: `─` ve `☐` bizim font subset'inde YOK
   ve kaynak fontta da olmadığı için eklenemiyor (fontTools ile ölçüldü),
   Android'de de tofu veriyor. Gerekçe build.py'de `pencereDugmeleri`.
   BIZDE YANLIS OLAN BIR SEY DAHA DUZELTILDI: etkin sekmenin altındaki 2px
   çizgiyi Windows chrome'unda yok; o Qt'nin kendi sekme çizgisi, pencere
   çubuğunun değil. Kaldırıldı. */
html[data-os="win"] .pnc-cap { display: flex; align-self: stretch; }
html[data-os="win"] .pnc-b {
  width: 46px; height: 32px; opacity: .62;
  transition: background-color .12s ease, opacity .12s ease;
}
html[data-os="win"] .pnc-b:hover {
  background: rgba(255, 255, 255, .09); opacity: 1;
}
html[data-os="win"] .pnc-x:hover { background: #C42B1C; color: #fff; opacity: 1; }
html[data-os="win"] .kz-tab { padding: 0 0 0 16px; min-height: 32px; }
html[data-os="win"] .kz-tab-ad { font-size: 12px; align-self: center; }
html[data-os="win"] .kz-cer { align-self: center; padding-right: .5em; }
html[data-os="win"] .kz-pano, html[data-os="win"] .sy-kon {
  border-radius: 8px 8px 2px 2px;
}

/* ── macOS ──────────────────────────────────────────────────────────────── */
html[data-os="mac"] {
  --kod-mono: 'SF Mono', 'SFMono-Regular', Menlo, Monaco,
              ui-monospace, monospace;
  --pnc-yuvarti: 11px;
  --yol-onek: '/Users/student/';
  --satir-sonu: 'LF';
  --derleyici: 'Clang 14.0.6';
}
/* macOS TRAFIK LAMBASI.
   Renkler Big Sur sonrasi olculen degerler: kapat #ff5f57, kucult #febc2e,
   tam ekran #28c840; cap 12px, aralik 8px, sol kenardan 10px.
   SIRA DOM'DAN FARKLI: DOM kucult/buyut/kapat basiyor (Windows sirasi),
   macOS'ta sira kapat/kucult/tam-ekran. `order` ile cevriliyor, JS'te iki
   ayri agac tutmaya gerek yok.
   BASLIK TAM GENISLIKTE ORTALI kaliyor: lambalar mutlak konumda DEGIL, iki
   yana esit `padding` verilerek yer aciliyor. Mutlak konum verilirse dar
   ekranda yol adi lambalarin ALTINA kayiyordu (olculdu). Bu yol hem ortali
   kaliyor hem carpismiyor.
   GLIFLER SADECE HOVER'DA: gercek macOS de boyle yapiyor; duran halde uc
   sade renk noktasi. */
html[data-os="mac"] .kz-tab {
  position: relative; justify-content: center; align-items: center;
  padding: .45em 58px;
}
html[data-os="mac"] .kz-tab-ad {
  text-align: center; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
html[data-os="mac"] .pnc-cap {
  display: flex; gap: 8px; margin: 0;
  position: absolute; left: 10px; top: 50%; transform: translateY(-50%);
}
html[data-os="mac"] .pnc-b {
  width: 12px; height: 12px; border-radius: 50%;
  color: rgba(0, 0, 0, .62);
}
html[data-os="mac"] .pnc-x      { order: 1; background: #ff5f57; }
html[data-os="mac"] .pnc-kucult { order: 2; background: #febc2e; }
html[data-os="mac"] .pnc-buyut  { order: 3; background: #28c840; }
html[data-os="mac"] .pnc-g-win { display: none; }
html[data-os="mac"] .pnc-g-mac {
  display: block; width: 7px; height: 7px;
  opacity: 0; transition: opacity .13s ease;
}
html[data-os="mac"] .kz-tab:hover .pnc-g-mac,
html[data-os="mac"] .pnc-cap:focus-within .pnc-g-mac { opacity: 1; }
@media (prefers-reduced-motion: reduce) {
  html[data-os="mac"] .pnc-g-mac { transition: none; }
}

/* ── ÜST ŞERİTTEKİ SEÇİCİ ────────────────────────────────────────────────
   JS DOĞURUYOR ve yalnız sayfada kod panosu varsa: matematik bölümünde
   editör görünümü ayarı gereksiz bir düğmedir (Ö9). İşaretler yazıyla değil
   GEOMETRİYLE anlatıyor, dar ekranda etiket yazısına yer yok. */
.os-sec { display: flex; align-items: center; gap: 2px; }
.os-sec button {
  display: inline-flex; align-items: center; gap: .42em;
  font-family: var(--ui); font-size: 11px; line-height: 1;
  padding: 5px 7px; cursor: pointer;
  color: var(--muted); background: transparent;
  border: 1px solid transparent; border-radius: 5px;
  transition: color .18s ease, border-color .18s ease, background-color .18s ease;
}
.os-sec button:hover { color: var(--ink-2); background: var(--paper-soft); }
.os-sec button[aria-pressed="true"] {
  color: var(--accent); border-color: var(--border-strong);
  background: var(--paper-soft);
}
.os-im { display: inline-block; flex: none; color: currentColor; }
.os-im-linux {
  width: 11px; height: 9px; border: 1px solid currentColor;
  border-radius: 2px 2px 1px 1px;
  background: linear-gradient(to bottom, currentColor 2.5px, transparent 2.5px);
}
/* `box-shadow` ELEMANIN GENISLIGINE SAYILMIYOR: isaret 3px genis
   gorunuyor ama golgesi 10px daha saga uzuyor ve etiket yazisi golgenin
   uzerine biniyordu (olculdu, ekran goruntusunde "•••macOS" diye
   bitisik cikti). Sag bosluk golgenin ERISTIGI yere gore veriliyor. */
.os-im-win {
  width: 4px; height: 4px; background: currentColor; margin-right: 12px;
  box-shadow: 6px 0 0 currentColor, 0 6px 0 currentColor, 6px 6px 0 currentColor;
  transform: translateY(-2px);
}
.os-im-mac {
  width: 3px; height: 3px; border-radius: 50%; background: currentColor;
  margin-right: 15px;
  box-shadow: 5px 0 0 currentColor, 10px 0 0 currentColor;
}
.os-ad { display: none; }
@media (min-width: 58rem) { .os-ad { display: inline; } }

/* Kâğıtta karanlık blok mürekkep yakar ve hiçbir şey anlatmaz. */
@media print {
  .os-sec, .kz-durum { display: none; }
  .kz, .kz-pano, .sy-kon, pre.kod { background: #fff; border-color: #ccc; }
  .kz-kd, .kz-kon, .kz-tab-ad, .kz-vt td, pre.kod code { color: #000; }
  .t-kw, .t-bi, .t-cm, .t-st, .t-nm, .t-df, .t-in { color: #000; }
  .kz-kons .kz-kon::before { content: none; }
}

/* ══ 25 · DERSİN KENDİ KAYNAKLARI + KAPSAM ═════════════════════════════════
   Alperen, 12 Eyl: "bazı derslerin bazen öğretmen sayfaları bazen de kendi
   webde sayfaları oluyor. bu sayfalardan yardım alabilirsin sanki" ve aynı
   gün: "şube bazlı farklı müfredat işlenen eng hum dersi gibi dersler
   var... küçük küme için genelleme yapma yani".

   İki blok, aynı cümlenin iki yarısı: "işte dersin resmî sayfaları" ve "ama
   senin şubende şu değişir". Bölüm kartlarının ALTINDA duruyorlar, çünkü
   öğrencinin aradığı ilk şey bölüm listesi.

   KART DEĞİL LİSTE (Ö4/Ö7): on beş bağı karta koymak ekranı doldurur ve
   hiçbiri öne çıkmaz. Tür solda sabit genişlikte mono etiket, ad ortada bağ,
   gerekçe altında yardım puntosunda. Yeni bir yüzey ya da yeni bir renk
   YOK — çelişki kutusu zaten var olan DİKKAT rengini kullanıyor.

   KAPSAM VARSAYILAN KAPALI: "gereksiz şeyler için açık olmaması gibi şeyler
   önemli". Bir uyarı değil bir kayıt; soran öğrenci açıyor. */

.kynk-blok { margin: var(--b4) 0 var(--b3); }
.kynk-h2 {
  font-family: var(--baslik); font-size: var(--f-h3); color: var(--ink);
  margin: 0 0 var(--b1); font-weight: 600;
}
.kynk-say {
  font-family: var(--mono); font-size: var(--f-et); color: var(--muted);
  font-weight: 400; margin-left: .5em;
}
.kynk-alt {
  margin: 0 0 var(--b2); font-size: var(--f-yardim); color: var(--muted);
  line-height: 1.62; max-width: 62ch;
}
.kynk-liste {
  list-style: none; margin: 0; padding: 0;
  border-top: 1px solid var(--border);
}
.kynk-og {
  display: grid; grid-template-columns: 5.6em minmax(0, 1fr);
  gap: 1px var(--b2); align-items: baseline;
  padding: .7em 2px; border-bottom: 1px solid var(--border);
}
.kynk-tur {
  grid-row: 1 / span 2; padding-top: .18em;
  font-family: var(--mono); font-size: 10.5px; letter-spacing: .07em;
  text-transform: uppercase; color: var(--muted);
}
.kynk-ad {
  font-size: var(--f-govde); color: var(--ink); text-decoration: none;
  border-bottom: 1px solid var(--border-strong);
  transition: color .18s ease, border-color .18s ease;
}
.kynk-ad:hover { color: var(--accent); border-color: var(--accent); }
.kynk-not {
  grid-column: 2; font-size: var(--f-yardim); color: var(--muted);
  line-height: 1.58;
}
/* Dar ekranda iki sütun 100px'e düşüyor ve tür etiketi sarıyor: orada üst
   üste bin, etiket kendi satırında kalsın. */
@media (max-width: 30rem) {
  .kynk-og { grid-template-columns: minmax(0, 1fr); }
  .kynk-tur { grid-row: auto; padding-top: 0; }
  .kynk-not { grid-column: 1; }
}
.kynk-yok {
  margin: var(--b2) 0 0; padding: .6em .85em;
  font-size: var(--f-yardim); color: var(--ink-2); line-height: 1.62;
  background: var(--paper-soft); border-radius: 4px;
}
.kynk-proje {
  margin: var(--b3) 0 0; padding: var(--b2);
  background: var(--surface); border: 1px solid var(--border);
  border-radius: 5px;
}
.kynk-proje-bas {
  font-weight: 600; font-size: var(--f-lead); color: var(--ink);
  margin-bottom: var(--b1);
}
.kynk-proje ul { margin: 0 0 var(--b1); padding-left: 1.15em; }
.kynk-proje li {
  font-size: var(--f-yardim); color: var(--ink-2); line-height: 1.68;
  margin-bottom: .18em;
}
.kynk-proje-not {
  margin: 0 0 var(--b1); font-size: var(--f-yardim); color: var(--muted);
  line-height: 1.62;
}
.kynk-proje-bag { font-size: var(--f-yardim); color: var(--accent); }

/* ── kapsam ── */
.kapsam {
  margin: var(--b3) 0 var(--b4);
  border-top: 1px solid var(--border); border-bottom: 1px solid var(--border);
}
.kapsam > summary {
  cursor: pointer; padding: .7em 2px; list-style: none;
  font-family: var(--ui); font-size: var(--f-yardim); color: var(--muted);
  transition: color .18s ease;
}
.kapsam > summary::-webkit-details-marker { display: none; }
.kapsam > summary::before {
  content: '+'; display: inline-block; width: 1.1em;
  font-family: var(--mono); color: var(--muted);
}
.kapsam[open] > summary::before { content: '\2212'; }
.kapsam > summary:hover { color: var(--ink); }
.kps-ic { padding: 0 2px var(--b2) calc(1.1em + 2px); max-width: 66ch; }
.kps-sat {
  margin: 0 0 var(--b2); font-size: var(--f-yardim); color: var(--ink-2);
  line-height: 1.7;
}
.kps-et {
  display: block; margin-bottom: .1em;
  font-family: var(--mono); font-size: 10.5px; letter-spacing: .07em;
  text-transform: uppercase; color: var(--muted);
}
.kps-olcum {
  margin: 0 0 var(--b2); font-size: var(--f-yardim); color: var(--ink-2);
  line-height: 1.7;
}
.kps-olcum b { font-variant-numeric: tabular-nums; color: var(--ink); }
/* İki resmî kaynak aynı şeyi farklı söylüyorsa İKİSİ de yazılır. Birini
   seçip ötekini gizlemek okura "tek cevap var" demek olurdu. */
.kps-cel {
  margin: var(--b2) 0; padding: .6em .85em;
  background: var(--paper-soft); border-left: 2px solid var(--amber);
  border-radius: 0 4px 4px 0;
}
.kps-cel-ne {
  font-weight: 600; font-size: var(--f-yardim); color: var(--ink);
  margin-bottom: .3em;
}
.kps-cel-a, .kps-cel-b {
  position: relative; padding-left: 1em;
  font-size: var(--f-yardim); color: var(--ink-2); line-height: 1.62;
}
.kps-cel-a::before, .kps-cel-b::before {
  content: '\2022'; position: absolute; left: 0; color: var(--amber);
}
.kps-cel-k {
  margin-top: .35em; font-size: var(--f-yardim); color: var(--amber);
  line-height: 1.62;
}

@media print { .kapsam { display: none; } }

/* ── proje fikirleri (§25'in devamı) ──
   Alperen, 12 Eyl: "insanlara proje tavsiyeleri verdin mi... bana proje bul
   gibi bir şey var mı mesela". Kutu KAPALI: resmî kural önce okunur, öneri
   sonra gelir. Her fikir dört satır taşıyor ve dördüncüsü asıl mesele:
   "başarılı sonuç neye benzer". O satır olmadan öneri, öğrenciye "veri
   topladım, şimdi ne yapacağım" sorusunu bırakıyor. */
.pf-kutu { margin: var(--b2) 0 0; border-top: 1px solid var(--border); }
.pf-kutu > summary {
  cursor: pointer; padding: .55em 0 .5em; list-style: none;
  font-family: var(--ui); font-size: var(--f-yardim); color: var(--accent);
}
.pf-kutu > summary::-webkit-details-marker { display: none; }
.pf-kutu > summary::before {
  content: '+'; display: inline-block; width: 1.1em;
  font-family: var(--mono); color: var(--muted);
}
.pf-kutu[open] > summary::before { content: '\2212'; }
.pf-uyari, .pf-arac {
  margin: 0 0 .55em; padding-left: 1.1em; max-width: 64ch;
  font-size: var(--f-yardim); color: var(--muted); line-height: 1.62;
}
.pf-liste { list-style: none; margin: 0; padding: 0 0 .3em 1.1em; }
.pf { padding: .7em 0; border-top: 1px solid var(--border); }
.pf-ad {
  font-weight: 600; font-size: var(--f-govde); color: var(--ink);
  margin-bottom: .3em;
}
.pf-sat {
  display: grid; grid-template-columns: 11.5em minmax(0, 1fr); gap: 1px var(--b2);
  font-size: var(--f-yardim); color: var(--ink-2); line-height: 1.62;
  margin-bottom: .18em;
}
.pf-et {
  padding-top: .18em;
  font-family: var(--mono); font-size: 10.5px; letter-spacing: .05em;
  text-transform: uppercase; color: var(--muted);
}
@media (max-width: 34rem) {
  .pf-sat { grid-template-columns: minmax(0, 1fr); }
  .pf-et { padding-top: 0; }
}

/* ══ 26 · SINAV ÖRÜNTÜSÜ ═══════════════════════════════════════════════════
   Alperen, 12 Eyl: "istatistikler sundun mu öneriler var mı".

   Öğrencinin sınavdan önce sorduğu somut soru: bu konu HANGİ sınavda çıkar
   ve ne sıklıkta. Cevap Bilkent'in kendi sınav arşivinde duruyordu ama
   kimse saymamıştı. Ölçüldü: MATH 101 için 104 sınav / 611 soru kalemi
   (1989-2025), MATH 102 için 106 sınav / 599 kalem (1988-2026).

   VARSAYILAN KAPALI ve sayı özetin İÇİNDE: kapağı okuyan zaten "74 soru,
   33/36 yılda" bilgisini alıyor, açan dağılımı görüyor.

   GÜVEN AÇIKÇA YAZILI. Sınıflandırma %100 değil (elle okunan 60 soruluk
   bağımsız örnekte %83) ve bazı bölümün soruları arşivde adlandırılmıyor.
   Orada sayı "en az bu kadar" demektir ve kutu bunu söylüyor. Bir sayıyı
   kesinmiş gibi basmak öğrenciyi yanlış konuya çalıştırır. Zayıf güven
   DİKKAT renginde, güçlü olan sessiz: uyarı gördüğünde bir şey demek. */

.oru { margin: var(--b2) 0 0; border-top: 1px solid var(--border); }
.oru > summary {
  cursor: pointer; padding: .5em 0; list-style: none;
  font-family: var(--ui); font-size: var(--f-yardim); color: var(--muted);
  transition: color .18s ease;
}
.oru > summary::-webkit-details-marker { display: none; }
.oru > summary::before {
  content: '+'; display: inline-block; width: 1.1em;
  font-family: var(--mono); color: var(--muted);
}
.oru[open] > summary::before { content: '\2212'; }
.oru > summary:hover { color: var(--ink); }
.oru > summary b { color: var(--ink); font-variant-numeric: tabular-nums; }
.oru-ic { padding: 0 0 var(--b2) calc(1.1em); max-width: 62ch; }
.oru-sat {
  display: grid; grid-template-columns: 11em minmax(0, 1fr); gap: 2px var(--b2);
  margin: 0 0 .3em; font-size: var(--f-yardim); color: var(--ink-2);
  line-height: 1.6;
}
.oru-sat b { color: var(--ink); font-variant-numeric: tabular-nums; }
.oru-et {
  font-family: var(--mono); font-size: 10.5px; letter-spacing: .05em;
  text-transform: uppercase; color: var(--muted); padding-top: .18em;
}
.oru-guven {
  margin: var(--b1) 0 0; font-size: var(--f-yardim); line-height: 1.6;
  color: var(--muted);
}
.oru-zayif {
  color: var(--amber); padding-left: .7em;
  border-left: 2px solid var(--amber);
}
.oru-kaynak {
  margin: var(--b1) 0 0; font-size: var(--f-et); color: var(--muted);
  line-height: 1.6;
}
.oru-kaynak b { color: var(--ink-2); font-variant-numeric: tabular-nums; }
@media (max-width: 34rem) {
  .oru-sat { grid-template-columns: minmax(0, 1fr); }
  .oru-et { padding-top: 0; }
}
@media print { .oru { display: none; } }

/* ══ 27 · DOĞRU MU YANLIŞ MI: GÖZLE GÖRÜNEN GERİ BİLDİRİM ═════════════════
   Alperen, 12 Eyl: "doğruysa tik gelebilir ekran sallanabilir. yanlışsa
   yanlış olan kısımlar incelenebilir. altları kırmızı olabilir falan.
   eğitici olması çok önemli burada."

   İKİ KARAR, ikisi de bilinçli:
   1. SALLANMA YANLIŞA BAĞLI, doğruya değil. Sallanma evrensel olarak
      "olmadı" demek; doğru cevapta sallamak ödülü cezaya benzetir. Doğru
      cevapta yukarı doğru kısa bir sıçrama ve çizilen bir tik var.
   2. KIRMIZI ALTI ÇİZGİ AYRILMA NOKTASINDAN SONRASINI işaretliyor, doğru
      cevabı YAZMIYOR. Öğrenci "buraya kadar doğruydu" diyebiliyor ve
      satırına geri dönüyor. Doğru cevabı basmak o öğrenmeyi bitirir.

   Boşluklar `·` ile görünür kılınıyor (JS `gorunur`), çünkü "iki boşluk mu
   üç mü" ekranda sayılamazsa geri bildirim işe yaramaz. */

.sy-tik {
  vertical-align: -2px; margin-right: .4em; color: var(--emerald);
}
@media (prefers-reduced-motion: no-preference) {
  .sy-tik path {
    stroke-dasharray: 24; stroke-dashoffset: 24;
    animation: sy-tik-ciz .42s .06s ease-out forwards;
  }
}
@keyframes sy-tik-ciz { to { stroke-dashoffset: 0; } }

/* Ayrılma noktasından sonrası: dalgalı kırmızı altı çizgi + soluk zemin. */
.sy-kotu {
  text-decoration: underline wavy var(--sp-in, #ee6772);
  text-decoration-thickness: 1.5px; text-underline-offset: 3px;
  background: color-mix(in srgb, var(--sp-in, #ee6772) 16%, transparent);
  border-radius: 2px;
}
/* Satır doğru başlıyor ama ERKEN bitiyor: eksik olan yeri bir imle göster. */
.sy-eksik {
  display: inline-block; width: .62em; height: 1.05em;
  vertical-align: -.2em; margin-left: 1px; border-radius: 2px;
  background: color-mix(in srgb, var(--sp-in, #ee6772) 30%, transparent);
  border-bottom: 2px solid var(--sp-in, #ee6772);
}
@media (prefers-reduced-motion: no-preference) {
  .sy-eksik { animation: sy-imlec 1.1s steps(2, jump-none) infinite; }
}
@keyframes sy-imlec { 0%, 100% { opacity: 1; } 50% { opacity: .35; } }

@media (prefers-reduced-motion: no-preference) {
  .sy-oyna-ok  { animation: sy-sicra .38s cubic-bezier(.34, 1.4, .64, 1); }
  .sy-oyna-yok { animation: sy-salla .34s ease-out; }
}
@keyframes sy-sicra {
  0%   { transform: translateY(0); }
  45%  { transform: translateY(-4px); }
  100% { transform: translateY(0); }
}
@keyframes sy-salla {
  0%, 100% { transform: translateX(0); }
  20% { transform: translateX(-5px); }
  40% { transform: translateX(5px); }
  60% { transform: translateX(-3px); }
  80% { transform: translateX(3px); }
}
/* Kutunun kenarı da cevabı söylüyor: yeşil doğru, kırmızı değil. */
.s-yaz[data-bitti="1"] .sy-kon { border-color: var(--emerald); }
.s-yaz[data-yanlis="1"] .sy-kon { border-color: var(--sp-in, #ee6772); }

/* ── GERİ BİLDİRİM TERMİNALİN İÇİNDE ──
   Alperen, 12 Eyl: "run it step by step kısmı terminalin devamı gibi olursa
   daha güzel olur" ve "yanlışlar falan olunca terminalde bana nasıl sorular
   soruyorsan oralarda da aynı fikirleri kullanabilirsin."
   Geri bildirim artık konsolun İÇİNDE, kendi `In [n]:` istemiyle. Öğrencinin
   ekranda gördüğü son şey bir yargı değil bir SORU: soru konsol yorumu
   biçiminde (`#`), yani terminalin kendi dilinde. */
.sy-kon .sy-geri {
  margin: 0; padding: .5em .8em .7em calc(.8em + 3px);
  font-family: var(--kod-mono, var(--mono)); font-size: .82em; line-height: 1.6;
  color: var(--sp-ink, #fff); background: transparent;
  border: 0; border-top: 1px solid var(--sp-kenar, #2b3642);
}
.sy-kon .sy-geri b { color: var(--sp-nm, #faed5c); font-weight: 600; }
.sy-istem2 { color: var(--sp-st, #b0e686); }
/* Soru kendi satirinda, yorum renginde: cevap degil, yön. */
.sy-soru {
  display: block; margin-top: .55em;
  color: var(--sp-cm, #999); font-style: normal;
}
/* Öğrencinin kendi satırı, ayrılma noktası işaretli. */
.sy-kon .sy-fark {
  display: block; margin-top: .5em; white-space: pre-wrap;
  color: var(--sp-ink, #fff);
}
.sy-kon .sy-fark i { color: var(--sp-cm, #999); font-style: normal; }

/* ══ 28 · ODAK SESİ ════════════════════════════════════════════════════════
   Alperen, 12 Eyl: "insanlar ders çalışırken müzik falan dinliyorlar. çal ya
   da oynat ya da play falan tuşu olsa... daha sade bir görünüm olabilir."

   Panel macOS panelinin sakin hâli: yumuşak köşe, tek gölge, kâğıt yüzeyi.
   Yeni renk yok. Çalarken düğmedeki üç çubuk hareket ediyor, durunca
   hareket duruyor ve çubuklar bir üçgene (play) dönüşmüyor: gösterge
   DURUMU söylüyor, eylemi değil, çünkü düğmenin işi hem açmak hem kapatmak.

   GÜRÜLTÜ TARAYICIDA ÜRETİLİYOR (build.py `Ses`): dış istek yok, dosya yok,
   telif yok, indirilen bayt yok. Gerekçe orada yazılı. Panelin "music"
   bölümü ve çalar şeridi §33'te — bu bölüm gürültü tarafının kabuğu. */

.ses-sar { position: relative; display: flex; align-items: center; }
.ses-d {
  display: inline-flex; align-items: center; gap: .4em;
  padding: 5px 7px; cursor: pointer;
  font-family: var(--ui); font-size: 11px; line-height: 1;
  color: var(--muted); background: transparent;
  border: 1px solid transparent; border-radius: 5px;
  transition: color .18s ease, border-color .18s ease, background-color .18s ease;
}
.ses-d:hover { color: var(--ink-2); background: var(--paper-soft); }
.ses-sar[data-calan="1"] .ses-d {
  color: var(--emerald); border-color: var(--border-strong);
  background: var(--paper-soft);
}
/* Üç çubuk: durunca sabit ve kısa, çalarken kendi ritminde. */
.ses-im { display: inline-flex; align-items: flex-end; gap: 2px; height: 11px; }
.ses-im i {
  display: block; width: 2px; height: 4px; border-radius: 1px;
  background: currentColor;
}
.ses-sar[data-calan="1"] .ses-im i { height: 11px; transform-origin: 50% 100%; }
@media (prefers-reduced-motion: no-preference) {
  .ses-sar[data-calan="1"] .ses-im i:nth-child(1) { animation: ses-cub 1.1s ease-in-out infinite; }
  .ses-sar[data-calan="1"] .ses-im i:nth-child(2) { animation: ses-cub 1.1s ease-in-out .18s infinite; }
  .ses-sar[data-calan="1"] .ses-im i:nth-child(3) { animation: ses-cub 1.1s ease-in-out .36s infinite; }
}
@keyframes ses-cub {
  0%, 100% { transform: scaleY(.32); }
  50%      { transform: scaleY(1); }
}
/* Etiket yalnız geniş ekranda: üst şeritte yer dar. */
.ses-et { display: none; }
@media (min-width: 64rem) { .ses-et { display: inline; } }

.ses-pop {
  position: absolute; top: calc(100% + 8px); right: 0; z-index: 62;
  width: 15.5rem; padding: 10px;
  background: var(--surface); border: 1px solid var(--border-strong);
  border-radius: 11px; box-shadow: var(--golge);
  font-family: var(--ui);
}
.ses-pop[hidden] { display: none; }
.ses-bas {
  font-family: var(--mono); font-size: 10px; letter-spacing: .08em;
  text-transform: uppercase; color: var(--muted); margin-bottom: 7px;
}
.ses-sec {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: .6em; width: 100%; padding: .42em .55em; margin-bottom: 2px;
  cursor: pointer; text-align: left;
  font-family: var(--ui); font-size: 13px; color: var(--ink-2);
  background: transparent; border: 1px solid transparent; border-radius: 6px;
  transition: color .16s ease, background-color .16s ease, border-color .16s ease;
}
.ses-sec:hover { background: var(--paper-soft); color: var(--ink); }
.ses-sec i { font-style: normal; font-size: 11px; color: var(--muted); }
.ses-sec[aria-pressed="true"] {
  color: var(--emerald); border-color: var(--border-strong);
  background: var(--paper-soft);
}
.ses-duz {
  display: flex; align-items: center; gap: .6em;
  margin: 8px 0 0; font-size: 11px; color: var(--muted);
}
.ses-duz input { flex: 1; min-width: 0; accent-color: var(--emerald); }
.ses-not {
  margin: 9px 0 0; font-size: 11px; line-height: 1.5; color: var(--muted);
}
@media print { .ses-sar { display: none; } }


/* ══ 31 · KAPSAM: BAŞLIK, PARAGRAF, FİLİGRAN ═══════════════════════════════
   Alperen, 12 Eyl 2026, üç mesaj: (1) "syllabus coverage kısmı mesela verimsiz
   bir kelime var ve yanında upuzun paragraflar var aynı hacimde. daha mantıklı
   yapılabilir oralar." (2) "'covered' demişsin mesela, onu ... damgalı bir
   şekilde yapabilirsin. ya da filigran gibi geçebilirsin." (3) "başlık,
   paragraf ve hafif coverage filigranı ile."

   ÖLÇÜLDÜ (276 kapsam satırı): blok bir TABLOYDU. Durum hücresi 7,5em'lik kendi
   sütununu tutuyor, jeton ayrıca %26 alıyordu; konu satırları ise 1–124 kelime.
   Yani tek kelimelik bir karar, 124 kelimelik bir konuyla aynı yerleşim
   ağırlığındaydı. Tablo kalktı: BAŞLIK üstte (izlence jetonu), PARAGRAF altında,
   durum arkada FİLİGRAN. Durumun artık kendi kolonu yok — sütun payı sorunu
   ortadan kalktı, bölüştürülmedi.

   Konu satırı çoğu zaman nesir değil virgülle dizilmiş bir alt konu dizisiydi;
   renderer onu artık noktalı bir diziye (`.kp-lst`) çeviriyor. D15 "hiçbir nesir
   bloğu 60 kelimeyi aşmadan bir şeye çarpmalı" diyor ve çarptığı şey bu dizi.
   Tek kelime atılmadı: kısaltma değil, doğru kap.

   FİLİGRAN SÜSTÜR, BİLGİ DEĞİL. Üç sınırı var:
   · `pointer-events:none` + `user-select:none` — metni seçerken araya girmez,
     tıklamayı yutmaz.
   · `aria-hidden` (render_v2.py) — ekran okuyucu filigranı okumaz; durumun metin
     karşılığı başlığın içindeki `.kp-sr`da durur, yani süsü gizlemek bilgiyi
     gizlemiyor.
   · KONTRAST ÖLÇÜLDÜ (Brave, 1280px, filigranın en yoğun noktasının altındaki
     gövde metni, 215×33 px kesişim): kâğıt 4,95:1 · gece 5,40:1 — WCAG AA
     gövde eşiği 4.5:1'in üstünde. Ölçüm `tests/kapsam_test.py`de duruyor:
     metin gizlenip zemin ekran görüntüsünden okunuyor, yani "hafif görünüyor"
     değil, ölçülen kontrast. 13 Eyl: ölçümün kendisi ARIZALIYDI —
     `html{scroll-behavior:smooth}` kaydırmayı animasyonlu yaptığı için
     dikdörtgenler kaydırma ÖNCESİ okunuyor, kesişim bulunamıyor ve iddia bir
     `if` içinde sessizce hiç koşmuyordu. Artık ölçüm boyunca kaydırma
     ışınlanıyor (inline `scroll-behavior:auto`), durduğu ardışık iki okumayla
     doğrulanıyor ve ölçüm düşerse iddia KIRMIZI yanıyor. Araç iki yönlü
     sınandı: `--kp-op` .25'te 3,87:1 · .85'te 1,27:1, ikisinde de alarm.
     Opaklık tek yerde (`--kp-op`); büyütmek istersen testi tekrar koştur.

   DAR EKRANDA BİNMEZ (≤700px): filigran akışa girer (`position:static`), kendi
   satırında küçük bir damga olur. 360px'te yatay taşma sıfır (ölçüldü).

   KÂĞIT: döndürme, çerçeve ve zemin düşer, tek küçük mono kelime kalır —
   filigran mürekkep yakmaz ama durum kâğıtta da okunur.

   Damga/filigran hissi GEOMETRİYLE kuruldu, yeni font YOK: Caveat (el yazısı)
   not sayfalarına yüklenmiyor (ölçüldü: basılan sayfada "caveat" 0 kez geçiyor)
   ve yalnız bu blok için font indirmek FCP'ye dokunurdu. Döndürme + çift çerçeve
   + büyük harf + harf aralığı, sayfanın kendi başlık yüzüyle. Yeni renk de yok:
   emerald/amber/muted zaten palette. */
.kpsm { --kp-op: .085; margin-top: var(--b2); }
html[data-tema="gece"] .kpsm { --kp-op: .14; }

.kp {
  position: relative;
  padding: var(--b2) 0;
  /* Filigran bloğun dışına taşmaz: taşan bir süs 360px'te yatay kaydırma
     doğuruyor ve sayfanın "sadece aşağı scroll" kuralını bozuyor. */
  overflow: hidden;
}
.kp + .kp { border-top: 1px solid var(--border); }

/* Metin filigranın ÜSTÜNDE: konumlanmış bir kardeş, akıştaki içeriğin üstüne
   boyanır. Bu yüzden z-index iki tarafta da yazılı, varsayılana bırakılmadı. */
.kp-bas, .kp-gov, .kp-lst, .kp-not { position: relative; z-index: 1; }

.kp-bas {
  margin: 0 0 var(--b1);
  font-family: var(--baslik); font-size: 1.02rem; font-weight: 600;
  line-height: 1.35; color: var(--ink);
  overflow-wrap: anywhere;
}
.kp-gov { font-size: var(--f-yardim); color: var(--ink-2); }
.kp-gov p { margin: 0; }

/* Alt konu dizisi: satır satır liste 18 öğede kendi duvarını kuruyordu,
   noktalı akış aynı bilgiyi ~beş satırda veriyor. `display:inline` metin gibi
   sarıyor, yani hiçbir öğe kutusunu aşamıyor. */
.kp-lst {
  margin: 0; padding: 0; list-style: none;
  font-size: var(--f-yardim); color: var(--ink-2); line-height: 1.7;
}
.kp-lst > li { display: inline; }
.kp-lst > li + li::before { content: ' · '; color: var(--muted); }

.kp-not {
  margin-top: var(--b1);
  font-size: var(--f-yardim); color: var(--muted); line-height: 1.62;
}
.kp-not p { margin: 0; }
.kp-not p + p { margin-top: var(--b1); }
/* "deferred" bir karar değil ADRES: notu bir okla başlıyor. Ok ilk paragrafın
   İÇİNDE: `.kp-not::before` blok bir `<p>`nin önüne düşüp kendi satırına
   çıkıyordu. */
.kp-yon .kp-not > p:first-child::before {
  content: '\2192\00a0'; color: var(--muted);
}

/* Durumun metin karşılığı: gözden gizli, ekran okuyucuda başlığın parçası. */
.kp-sr {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap;
}

.kp-fg {
  position: absolute; top: 50%; right: -.12em; z-index: 0;
  transform: translateY(-50%) rotate(-4deg); transform-origin: 100% 50%;
  pointer-events: none; -webkit-user-select: none; user-select: none;
  padding: .06em .3em .09em;
  font-family: var(--baslik); font-size: clamp(1.3rem, 4.6vw, 2.15rem);
  font-weight: 600; letter-spacing: .1em; text-transform: uppercase;
  line-height: 1.1; white-space: nowrap;
  color: var(--muted);
  border: 2px solid currentColor; border-radius: 3px;
  box-shadow: 0 0 0 2px currentColor;   /* çift çerçeve = damga geometrisi */
  opacity: var(--kp-op);
}
.kp-var .kp-fg { color: var(--emerald); }
.kp-yok .kp-fg { color: var(--amber); }
.kp-dis .kp-fg { opacity: calc(var(--kp-op) * .8); }

@media (max-width: 700px) {
  /* Filigran akışa giriyor: dar ekranda metnin üstüne binmesi okumayı
     zorlaştırır, kendi satırında küçük bir damga olarak durur. */
  .kp-fg {
    position: static; display: block; width: max-content; max-width: 100%;
    margin: 0 0 var(--b1);
    transform: rotate(-2.2deg); transform-origin: 0 50%;
    font-size: .95rem; letter-spacing: .08em;
    border-width: 1px; box-shadow: 0 0 0 1px currentColor;
    opacity: .55;
  }
  .kp-dis .kp-fg { opacity: .45; }
}

@media print {
  .kp { overflow: visible; break-inside: avoid; }
  .kp-fg {
    position: static; display: block; width: auto;
    margin: 0 0 .15em; padding: 0;
    transform: none; opacity: 1; color: inherit;
    border: 0; box-shadow: none;
    font-family: var(--mono); font-size: 9pt; letter-spacing: .06em;
  }
}


/* ══ 30 · TERMİNALİN DEVAMI ════════════════════════════════════════════════
   Alperen, 12 Eyl: "check my answer ve run it step by step hala altında
   küçücük olarak duruyor. terminal dediğim daha kuvvetli olabilir, o koyu
   panelin altından sanki geçmiş gibi yapabiliriz."

   ── ÖNCEKİ HÂL ÖLÇÜLDÜ (tests/terminal_test.py, 1280px, Linux görünümü) ──
   check my answer      : `.sy-kon`un DIŞINDA · kabın altıyla arasında
                          15,3 px kâğıt zemin · 15,12 px Inter · 157×42 px
   run it step by step  : `pre.kod`un altında 5,7 px kâğıt zemin ·
                          15,12 px Inter · 225×33 px (44 px'in altında)
   İkisi de sayfanın açık zemininde duran küçük bağlantılardı; koyu panel
   biter, altında kâğıt görünür, düğme oraya düşerdi. "Kuvvetsiz" görünmesi
   bir üslup meselesi değil, o 5-15 px'lik açık şeritti.

   ── ŞİMDİ: AYNI KAP ────────────────────────────────────────────────────
   Yeni bir görsel dil yok, §24'ün yüzeyi AŞAĞI UZATILDI:
     · `.sy-alt` artık `.sy-kon`un ÇOCUĞU (render_v2._yaz_kutusu). Konsolun
       dibinde, tepesindeki `.kz-tab` sekme çubuğunun karşılığı bir çubuk:
       zemin `--sp-oluk`, üstünde `--sp-kenar` çizgisi. Arada açık zemin
       KALMIYOR, çünkü fiziksel olarak aynı kabın içinde.
     · `.kz-ac` `pre.kod`a yapıştı (`kod-sapli`): panonun alt yuvartısı ve
       alt boşluğu şeride devredildi, ikisi tek pencere oldu.
   Punto `--f-yardim` (15,1 px) → `--f-govde` (18 px) ve yüz `--ui` → panonun
   kendi `--kod-mono`su: düğme artık sayfanın değil terminalin diliyle
   konuşuyor. Dokunma alanı `min-height: 44px` ile tabanlandı.

   ── PALETİN SINIRI: §24'ÜN ÖLÇÜTÜ KORUNDU ──────────────────────────────
   §24 "bu palet `.kz` ve `.sy-kon` dışına sızmıyor" diyor; ölçüt AYGIT,
   sayfa yüzeyi değil — §24'ün kendisi `pre.kod`u, §5 de `.ai-pop`u aynı
   token'larla boyuyor. `.kz-ac` o aygıtın eylem şeridi: `pre.kod`un alt
   kenarına kaynamış, ondan bağımsız hiçbir yerde görünmüyor. Sayfanın
   okuma yüzeyine bir piksel koyu renk geçmiyor; test bunu iddia olarak
   ölçüyor ("koyu palet aygıtın dışına sızmıyor"). YENİ RENK YOK: aşağıdaki
   her değer §24'te ölçülmüş `--sp-*` kümesinden.

   ── ÜÇ İŞLETİM SİSTEMİ ─────────────────────────────────────────────────
   Alt yuvartı `--pnc-yuvarti` üzerinden geliyor (Linux 10px · Windows 8px ·
   macOS 11px) ve mono yüz `--kod-mono`dan, yani şerit üç görünümde de
   panosuyla aynı kalıba oturuyor; elle yazılmış tek bir yarıçap yok.

   ── ANİMASYON ──────────────────────────────────────────────────────────
   Tek hareket hover'daki zemin geçişi. `prefers-reduced-motion: reduce`
   altında §2'deki genel kural bütün geçişleri .01ms'e indiriyor (ölçüldü:
   hesaplanan `transition-duration` 1e-05s), bu yüzden burada ikinci bir
   media sorgusu yazılmıyor — iki yerde duran bir kural er ya da geç
   ayrışır. */

/* ── 1 · "check my answer" · KONSOLUN DİP ÇUBUĞU ─────────────────────────
   Şerit ve düğme HTML'de `hidden` basılıyor (kontrol JS'te), JS açıyor.
   `display: flex` sınıf seçicisiyle geldiği için UA'nın
   `[hidden] { display: none }` kuralını YENİYOR; JS kapalıyken terminalin
   altında boş bir koyu bant kalmasın diye ikisi de burada geri kapatılıyor.
   Ölü yem yok: JS yoksa şerit hiç görünmüyor, çözüm zaten aşağıdaki
   <details>'te. */
.sy-kon .sy-alt {
  display: flex; align-items: stretch; flex-wrap: wrap; gap: 0;
  margin: 0; padding: 0;
  background: var(--sp-oluk);
  border-top: 1px solid var(--sp-kenar);
}
.sy-kon .sy-alt[hidden], .sy-kon .sy-kontrol[hidden] { display: none; }

.sy-kon .sy-kontrol {
  display: inline-flex; align-items: center; gap: .6em;
  flex: 1 1 14em; min-width: 0; min-height: 44px;
  /* Sol dolgu `.sy-istem` ile AYNI hesap: textarea'nın 3px'lik şeffaf
     işaret çubuğu telafi ediliyor, yoksa şerit konsolun kolonundan kayar. */
  padding: .5em .9em .5em calc(.9em + 3px);
  text-align: left; white-space: normal; cursor: pointer;
  font-family: var(--kod-mono, var(--mono));
  font-size: var(--f-govde); line-height: 1.35;
  color: var(--sp-ink); background: transparent;
  border: 0; border-radius: 0;
  transition: background-color .18s ease, color .18s ease;
}
/* YEŞİL ÇALIŞTIR ÜÇGENİ — Spyder'ın kendi Run düğmesi de bu.
   GLİF DEĞİL, kenarlıkla çizilen üçgen: `▶` bizim font subset'inde yok
   (§24'te `─` ve `☐` ile aynı tuzak, fontTools ile ölçülmüştü) ve
   Android'de tofu veriyor. Renk `--sp-st`, yani konsolun istem yeşili. */
.sy-kon .sy-kontrol::before, .kz-ac::before {
  content: ''; flex: none; width: 0; height: 0;
  border: 5px solid transparent;
  border-right-width: 0; border-left-width: 8px;
  border-left-color: var(--sp-st);
}
.sy-kon .sy-kontrol:hover:enabled { background: var(--sp-satir); }
.sy-kon .sy-kontrol:focus-visible {
  background: var(--sp-satir);
  outline: 2px solid var(--sp-st); outline-offset: -2px;
}
/* Doğru cevaptan sonra düğme kapanıyor: üçgen de sönüyor, yoksa
   "hâlâ basılabilir" der. */
.sy-kon .sy-kontrol:disabled { cursor: default; color: var(--sp-cm); }
.sy-kon .sy-kontrol:disabled::before { border-left-color: var(--sp-cm); }

.sy-kon .sy-say {
  align-self: center; flex: none; padding: 0 .9em;
  font-family: var(--kod-mono, var(--mono)); font-size: var(--f-et);
  color: var(--sp-cm);
}

/* ── 2 · "run it step by step" · KOD LİSTESİNİN DİP ÇUBUĞU ───────────────
   `pre.kod` ile şerit tek pencere: panonun alt kenarı şeridin üst kenarı
   oluyor (tek 1px `--sp-kenar` çizgisi), alt yuvartı da şeride geçiyor. */
.kz-ac {
  display: flex; align-items: center; flex-wrap: wrap; gap: .6em;
  width: 100%; min-height: 44px; margin: 0 0 1.1em;
  padding: .5em .9em; text-align: left; white-space: normal;
  font-family: var(--kod-mono, var(--mono));
  font-size: var(--f-govde); line-height: 1.35;
  color: var(--sp-ink); background: var(--sp-oluk);
  border: 1px solid var(--sp-kenar); border-top: 0;
  border-radius: 0 0 var(--pnc-yuvarti) var(--pnc-yuvarti);
  transition: background-color .18s ease;
}
.kz-ac:hover { background: var(--sp-satir); border-color: var(--sp-kenar); }
.kz-ac:focus-visible {
  background: var(--sp-satir);
  outline: 2px solid var(--sp-st); outline-offset: -2px;
}
/* Etiket esner, adım sayısı esnemez: 360px'te sayı alt satıra iner ve
   etiket kırılmaz. */
.kz-ac-et { flex: 1 1 auto; min-width: 0; }
.kz-ac-say { flex: none; font-size: var(--f-et); color: var(--sp-cm); }
.kz-ac-say[hidden] { display: none; }

/* Sınıf JS'te konuyor (düğme de JS'te doğuyor): JS yoksa `pre` kendi
   yuvartısı ve kendi alt boşluğuyla kalıyor, yani hiçbir şey değişmemiş
   gibi. */
pre.kod.kod-sapli {
  margin-bottom: 0;
  border-bottom-left-radius: 0; border-bottom-right-radius: 0;
}
/* 13 Eyl 2026: BU KURALIN ANAHTARI DEĞİŞTİ, ölçülerek.
   Eski hâli `pre.kod.kod-sapli[hidden] + .kz-ac` idi: hem `pre`nin gizli
   olmasına hem de düğmenin `pre`ye KOMŞU olmasına dayanıyordu. §35'ten sonra
   ikisi de yanlış — kutu açıkken `pre` artık gizlenmiyor ve düğmenin komşusu
   `pre` değil, `<pre>`i saran editör panosu (`.kz-yerinde`). Kural sessizce
   düşüyordu; `terminal_test` yakaladı.
   Yeni anahtar düğmenin KENDİ durumu (`data-acik`, JS zaten yazıyor).
   Açıkken şerit artık bir BAŞLIK değil DİKİŞ: üstünde editör panosu, altında
   adımlayıcı kutusu var, yani iki yandan da kaynıyor ve yuvartı taşımıyor. */
.kz-ac[data-acik="1"] {
  border-top: 1px solid var(--sp-kenar); border-bottom: 0;
  border-radius: 0;
  margin-bottom: 0;
}
/* Sarma dip yuvartısını dikişe devrediyor: üçü tek gövde okunuyor. */
.kz-yerinde {
  border-bottom-left-radius: 0; border-bottom-right-radius: 0;
}
.kz-ac[data-acik="1"] + .kz {
  margin-top: 0;
  border-top-left-radius: 0; border-top-right-radius: 0;
}
/* Açıkken gösterge kare (dur), üçgen (çalıştır) değil: düğmenin işi o an
   kapatmak. §28'deki karar ile aynı çizgi — gösterge DURUMU söylüyor. */
.kz-ac[data-acik="1"]::before {
  width: 9px; height: 9px; border: 0; border-radius: 1px;
  background: var(--sp-cm);
}

/* Kâğıtta şerit yok: `.kz-ac` §18'de zaten gizli, `.sy-alt` da burada
   gizlenip panonun yuvartısı ve alt boşluğu geri veriliyor. */
@media print {
  .sy-kon .sy-alt { display: none !important; }
  pre.kod.kod-sapli {
    margin-bottom: .95em;
    border-bottom-left-radius: var(--pnc-yuvarti);
    border-bottom-right-radius: var(--pnc-yuvarti);
  }
}

/* ══ 33 · MÜZİK ÇALAR ══════════════════════════════════════════════════════
   Alperen, 12 Eyl: "bir de çirkin müzik koyacağımıza hiç koymayız daha iyi.
   lofinin telifsiz müzikleri varsa al onları. ders çalışma müziği lazım
   bize, hareketli falan değil."

   §28'in kabuğunu PAYLAŞIYOR: aynı düğme, aynı panel, aynı `.ses-sec` satır
   biçimi. İkinci bir çalar kurmak iki ayrı ses düzeyi, iki ayrı durdurma
   düğmesi ve üst şeritte iki ayrı ikon demekti. Burada yalnızca müziğin
   fazladan ihtiyacı olan şey var: bölüm başlığı arası, taşıma şeridi
   (önceki/sonraki/döngü), çalan parçanın adı ve künye.

   YENİ RENK YOK: hepsi --muted / --ink-2 / --emerald / --paper-soft /
   --border-strong. Punto §28'in puntoları.

   360px: panel `max-width` ile ekrana sığıyor, parça adı taşmıyor kısalıyor
   (`min-width:0` + ellipsis). Yatay kaydırma doğmuyor. */

/* Panel dar ekranda ekranı taşmasın: §28'deki 15.5rem genişlik korunuyor,
   yalnızca üst sınır ekleniyor. */
.ses-pop { max-width: calc(100vw - 24px); }

/* İki bölüm arası: yeni bir çizgi değil, yalnızca nefes. */
.ses-bas-2 { margin-top: 11px; }

/* ── Taşıma şeridi ─────────────────────────────────────────────────────── */
.ses-tasi {
  display: flex; align-items: center; gap: 4px;
  margin-top: 6px; padding-top: 7px;
  border-top: 1px solid var(--border);
}
.ses-yon, .ses-dongu {
  flex: none; cursor: pointer;
  font-family: var(--ui); line-height: 1;
  color: var(--muted); background: transparent;
  border: 1px solid transparent; border-radius: 5px;
  transition: color .16s ease, background-color .16s ease, border-color .16s ease;
}
.ses-yon {
  /* Dokunma hedefi: 26px, parmakla basılabilecek en küçük makul ölçü. */
  width: 26px; height: 26px; padding: 0;
  font-size: 16px; font-weight: 600;
}
.ses-dongu {
  padding: 0 7px; height: 26px;
  font-family: var(--mono); font-size: 9.5px;
  letter-spacing: .07em; text-transform: uppercase;
}
.ses-yon:hover, .ses-dongu:hover { background: var(--paper-soft); color: var(--ink-2); }
.ses-dongu[aria-pressed="true"] {
  color: var(--emerald); border-color: var(--border-strong);
  background: var(--paper-soft);
}
/* Çalan parçanın adı. Şeridin esneyen parçası: uzun ad düğmeleri ezmiyor,
   kendisi kısalıyor. */
.ses-simdi {
  flex: 1; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-family: var(--ui); font-size: 11.5px; color: var(--ink-2);
  text-align: center;
}

/* ── Künye ─────────────────────────────────────────────────────────────────
   CC-BY parçalar için GÖRÜNÜR olması lisansın şartı. Küçük ama okunur,
   `<details>` içinde saklı değil; bağlantılar da altı çizili kalıyor ki
   tıklanabilir olduğu belli olsun. */
.ses-kunye {
  margin: 9px 0 0; padding-top: 8px;
  border-top: 1px solid var(--border);
  font-size: 10.5px; line-height: 1.55; color: var(--muted);
}
.ses-kunye a { color: var(--muted); text-decoration: underline; }
.ses-kunye a:hover { color: var(--ink-2); }

/* Müzik satırı da gürültü satırı gibi susuyor. §28 `.ses-sar`ı zaten
   gizliyor; bu yalnızca çalar bir gün şeridin dışına taşırsa diye. */
@media print { .ses-tasi, .ses-kunye { display: none; } }


/* ══ 32 · SORU BİR BÜTÜN · AÇILAN KUTUNUN İÇ BOŞLUĞU ══════════════════════
   Alperen, 12 Eylül 2026, iki ayrı cümle:
     "soru veriliyor, aralarına konan bilgilerle soruyu unutabiliyorum. daha
      kompakt yapılı olabilir, iç içe geçirmeden."
     "basınca alta açılan tabloların sağ sol marginleri falan çok sıkışık
      hissettiriyor."
   Yanına sayfadan yapıştırdığı örnek sorunun nasıl dağıldığını gösteriyordu:
   "the days are to be numbered 1 to 7" / "Find" / "A day list of the right
   length, and the call that uses it." — üç parça, ortadaki tek kelime.

   ÖLÇÜLDÜ 12 Eyl (cs-115 §02, 1280px ve 360px):
   · Bağlam ile "ne isteniyor" arasına `Given` bloğu giriyordu: arada 1 blok,
     1280px'te 189 px, 360px'te 313 px. Tek kelimelik "Find" etiketi ayrıca
     `display:block` ile kendi satırını tutuyor, altında 7 px bırakıyordu.
   · Sorunun bitişine kadar (çözüm KAPALIYKEN) 1280px'te 622 px, 360px'te
     773 px içerik vardı; çözüm açılınca adım tablosu bunu katlıyor. Yani
     "sorulan ne"yi kaybetmek için özel bir dikkatsizlik gerekmiyordu.
   · 294 `<details>`in 127'si İÇ İÇEYDİ; 117'si çözüm kutusunun içindeki
     `o-adim` kutusuydu ve hepsi `open` basılıyordu — açılıp kapanan bir şey
     değil sadece bir başlıktı. Renderer artık onları düz başlık basıyor.
   · Açılan HER `<details>`in ilk bloğu `padding: 2px 11px 10px` + 1px
     kenarlık alıyordu (notes_bolum.css `details[open] > summary + *`). Sonuç:
     metin okuma sütununun 12 px İÇİNDE başlıyor (§3'ün tek hizası kırılıyor)
     ve 11 px sayfanın hiçbir ölçeğinde yok (`--b1` 7 · `--b2` 15 · `--pay`
     16–18). Tablo hücresi kutunun iç kenarına 0 px'de oturuyordu.

   YENİ RENK YOK, YENİ PUNTO YOK, ÜÇÜNCÜ YÜZEY YOK: hepsi §1'in jetonları ve
   §3'ün bütçesi.
   ═══════════════════════════════════════════════════════════════════════════ */

/* Yapışkan yığın ÖLÇÜLDÜ: `header.ust` sticky top 0 / 47 px, `.konum` sticky
   top 46 px / 31 px yüksek (`white-space: nowrap` olduğu için yüksekliği
   sabit). Soru şeridi bu ikisinin ALTINA oturuyor. */
main.govde { --konum-y: 31px; }

/* ── SORU KOMPAKT: İÇİ SIKI, DIŞI GENİŞ ──
   Bağlam · istenen · verilen tek bir birim gibi duruyor: aralarındaki boşluk
   --b2'den --b1'e iniyor. Sonraki blok (şıklar, yazı kutusu, ipuçları, çözüm)
   zaten --b3 üst boşluğuyla geliyor ve komşu marjlar birleşiyor, yani birimin
   içi 7 px, dışı 29 px — sınır böylece GÖRÜLÜYOR, kutu çizmeye gerek yok. */
.soru > .s-baglam, .soru > .s-istenen, .soru > .s-verilen,
.ornek > .s-istenen, .ornek > .s-verilen { margin-bottom: var(--b1); }

/* Tek öğeli Given/Find SATIR İÇİ. `<p>` kabuğu renderer'da soyuluyor
   (`_tek_p`), burada yalnız etiket satır içine alınıyor: tek kelimelik bir
   etiket kendi paragrafını tutmuyor. Tip aynı — mono, --f-et, büyük harf. */
.s-istenen.s-tek > b, .s-verilen.s-tek > b {
  display: inline; margin: 0 .55em 0 0;
}
/* ETİKET YALNIZ İLK `<b>`. `parca()` öğenin başındaki şık işaretini
   `**(a)**` diye üretiyor, yani satır içi blokta İKİNCİ bir `<b>` var ve
   §12'nin `.s-istenen > b` kuralı onu da mono/büyük harf/soluk yapıyordu —
   "(a)" ekrana "(A)" diye, etiket puntosunda çıkıyordu. */
.s-istenen.s-tek > b ~ b, .s-verilen.s-tek > b ~ b {
  display: inline; margin: 0;
  font-family: inherit; font-size: inherit; font-weight: 700;
  letter-spacing: normal; text-transform: none; color: inherit;
}

/* ── "SORULAN BUYDU": İSTENEN SATIR ÇÖZÜM BOYUNCA EKRANDA ──
   Üst şeritlerle ÇAKIŞMIYOR: 46 + 31 = 77 px'in altına yapışıyor ve z'si
   `.konum`ın (22) altında, yani bir gün değerler kayarsa konum şeridi üstte
   kalır. Yükseklik ölçüldü (49 örnek): 1280px'te p95 133 px, 360px'te p95
   195 px / en fazla 226 px = 800 px ekranın %28'i. `max-height` yine de bir
   tavan koyuyor; taşarsa metin KENDİ kutusunda kayıyor, kaybolmuyor.
   Kısa ekranda (yatay telefon) hiç açılmıyor. */
@media (min-height: 34rem) {
  .soru > .s-istenen, .ornek > .s-istenen {
    position: sticky; top: calc(var(--ust-y) + var(--konum-y)); z-index: 6;
    max-height: 38vh; overflow: auto;
    padding-block: var(--b1);
    /* Zemin kabın zemini — üçüncü yüzey açılmıyor (Ö7). Alttan geçen metni
       kapatması için kenar boşluğuna taşıyor, padding metni §3'ün sol
       kenarında TUTUYOR. Solda 4 px pay: `.soru::before` rayı açıkta kalsın.
       Sağda --pay-1, zeminli kabın (`.ontest` vd.) kendi payı da o. */
    background: var(--paper);
    margin-inline: calc(4px - var(--pay)) calc(1px - var(--pay));
    padding-inline: calc(var(--pay) - 4px) calc(var(--pay) - 1px);
    --tas: 0px;
  }
  /* Zeminli kapların içinde şeridin zemini de o kabın zemini. */
  .baslat .s-istenen, .ontest .s-istenen, .kontrol .s-istenen,
  .merdiven .s-istenen, .pr-grup .s-istenen { background: var(--surface); }
}
@media print {
  .soru > .s-istenen, .ornek > .s-istenen {
    position: static; max-height: none; overflow: visible;
  }
}

/* ── ALT HEDEF BAŞLIĞI: ARTIK BİR `<summary>` DEĞİL ──
   Eski hâli `<details class="o-adim" open><summary>`di: açılıp kapanmayan,
   sadece açık duran 117 kutu. Tip jetonları eskisiyle aynı. */
.o-adim > .o-adim-bas {
  margin: 0 0 var(--b1); padding-block: 4px;
  font-family: var(--mono); font-size: var(--f-et); font-weight: 400;
  letter-spacing: .06em; text-transform: uppercase; color: var(--ink-2);
}

/* ── AÇILAN KUTUNUN İÇ BOŞLUĞU ──
   `:where()` KULLANILMIYOR ve bu bilinçli: hedef kural notes_bolum.css'te,
   yani bu dosyadan SONRA okunuyor. Eşit özgüllükte yazılan bir kural sırayı
   kaybederdi. Buradaki seçici (0,2,3) ile oradaki (0,1,2)yi özgüllükle
   geçiyor, dosya sırasına güvenmiyor. */
main.govde details[open] > summary + * {
  /* 11 px yerine sayfanın kendi payı — `.ontest`in kullandığı değerin aynısı
     (§3: `calc(var(--pay) - 1px)`), yani 1280px'te 17 px, 360px'te 15 px. */
  padding-inline: calc(var(--pay) - 1px);
  /* Kutu bir zemin taşıyor: içindekilere kalan taşma bütçesi düşüyor,
     taşmalar üst üste binmesin (§3'ün aynı hesabı). */
  --tas: calc(var(--kenar) - min(var(--kenar), 18px));
}

/* Çözüm ve ipucu: KUTU YOK. Çözüm sorunun DEVAMI, ayrı bir kap değil; metni
   sorunun metniyle aynı sol kenarda duruyor (§3). Kapağın kendisi zaten bir
   düğme (§10) — gövdeye ikinci bir çerçeve çizmek hem 12 px kayma hem de
   yalnız İLK bloğu saran, sonrakileri dışarıda bırakan bir kutu demekti. */
main.govde .s-cozum[open] > summary + *,
main.govde .o-coz[open] > summary + *,
main.govde .s-ipucu[open] > summary + * {
  border: 0; border-radius: 0; padding: 0;
  margin-top: var(--b2);
  --tas: var(--kenar);
}
/* Altında devam eden kutu olmadığı için kapağın alt kenarlığı geri geliyor:
   notes_bolum.css açık `summary`nin altını şeffaflaştırıyor, o kural gövdesi
   kutulu olan `<details>`ler için. Değerler kapalı hâlin değerleri. */
main.govde .s-cozum[open] > summary,
main.govde .s-ipucu[open] > summary {
  border-bottom-color: var(--border); border-radius: 7px;
}
main.govde .o-coz[open] > summary {
  border-bottom-color: var(--border-strong); border-radius: 5px;
}


/* ══ 29 · İPUCU ════════════════════════════════════════════════════════════
   Alperen, 12 Eyl 2026: "hintler alt alta ama tek hint şeysi olsa, o da işte
   ampül simgesi gibi olsa, hoverlayınca hint yazsa, bastıkça daha çok hint
   olsa, sağa sola kaydırmalı falan daha estetik durur."

   Dört ipucu dört ayrı `<details>` kapağıydı: soru ile çözüm arasında alt alta
   dört kutu. Şimdi TEK denetim var — bir ampul — ve ipuçları onun altındaki
   yatay bir rayda duruyor; her basış bir kart daha açıyor.

   DÖRT KARAR:
   1. AMPUL İNLİNE SVG (render_v2.py `_ampul_svg`). Ampul emojisi (U+1F4A1)
      hiçbir kaynak fontumuzda YOK; kapsam listesine kod noktası yazmak da
      onu üretilen woff2'ye sokmuyor — ekranda tofu çıkıyor (§24'te `─` ve
      `☐` ile aynı tuzak). Şekil bu yüzden çizgi: cam, duy, ışınlar.
   2. ETİKET §5'İN DİLİ. "ask an AI" düğmesi zaten "simge önce, yazı
      hover'da" yapıyor. Aynı kap (`.ai-sor`) ve aynı etiket sınıfı
      (`.ai-et`) kullanılıyor: geçiş, odak halkası, dokunmatikte etiketin
      açık kalması ve `prefers-reduced-motion` §5'ten BEDAVA geliyor, ikinci
      bir çip dili açılmıyor. Burada yalnız iki şey değişiyor — `▸` öneki
      kapanıyor (yerinde ampul var) ve hover'da dönme yerine büyüme var
      (dönen bir ampul sallanıyor gibi duruyor). Etiket ve büyüme AMPULÜN
      KENDİ hover'ına bağlı, bloğun hover'ına değil: aynı soruda iki çip var
      ve blok bazlı bir kural ikisini birden yakıyordu (§5'te ölçüldü).
   3. KUTU YOK. Kart ne zemin ne çerçeve taşıyor: zeminli bir kap metni
      okuma sütunundan içeri iter (§3 · Ö4) ve sayfaya üçüncü bir yüzey açar
      (Ö7). Kaydırılabildiğini rayın kendisi söylüyor — şeritteki sayaç
      (2/4), ‹ › düğmeleri ve her kartın kendi "Hint 2/4" başlığı.
   4. SAYAÇ SOL SÜTUNDA DEĞİL ŞERİTTE: "kaçıncı ipucundayım" bilgisi
      denetimin yanında duruyor, yani gözün zaten olduğu yerde.

   JS'SİZ HÂL BİR KAYIP DEĞİL: sunucu hiçbir karta `hidden` basmıyor, dört
   ipucu §12'nin düz listesi olarak duruyor. Bu bölümün ray kuralları
   `[data-js]`e bağlı ve o özniteliği JS yazıyor; gizli basılan tek şey
   denetim şeridi, çünkü JS yoksa basılacak bir düğme de yok. İpucu ÖĞRETİM
   İÇERİĞİ: kademeli açılma bir ilerleme, bir kapı değil.
   ═══════════════════════════════════════════════════════════════════════════ */

/* Kartın kendi başlığı. Tip jetonları §13'ün mono etiketiyle aynı. */
.ip-no {
  display: block; margin-bottom: var(--b1);
  font-family: var(--mono); font-size: var(--f-et); font-weight: 400;
  letter-spacing: .08em; text-transform: uppercase; color: var(--muted);
}

/* Canlı bölge: yalnız ekran okuyucu için. Gözle görülen karşılığı şeritteki
   sayaç, o yüzden burada ikinci bir satır çizilmiyor. */
.ip-durum {
  position: absolute; width: 1px; height: 1px; margin: 0; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap;
}

/* ── denetim şeridi ───────────────────────────────────────────────────────── */
.ip-serit { display: flex; align-items: center; gap: .3em; margin: var(--b2) 0 0; }
.ip-serit[hidden] { display: none; }
.ip-ac { margin: 0; }
.ip-ac::before { content: none; }
/* Buyume AMPULUN KENDI hover'ina bagli. Eskiden `.soru:hover .ip-ac > svg` de
   vardi: "ask an AI" cipini (ya da sorunun herhangi bir yerini) hoverlamak
   ampulu de oynatiyordu. Alperen 12 Eyl: "daha lokalize olmali bu isler". */
.ip-ac:hover > svg, .ip-ac:focus-visible > svg { transform: scale(1.12); }
.ip-say {
  flex: none; margin-left: .45em;
  font-family: var(--mono); font-size: var(--f-et); color: var(--muted);
}
.ip-say:empty { display: none; }
/* AMPUL YANIYOR: ilk ipucu açılınca ışınlar geliyor. Yeni renk değil, yalnız
   görünürlük — kapalıyken ışınlar `opacity: 0`. */
.ip-ampul .ip-isin { opacity: 0; transition: opacity .22s ease; }
.ip-ac[aria-expanded="true"] .ip-isin { opacity: 1; }
.ip-ac[aria-expanded="true"] { color: var(--ink); border-color: var(--border-strong); }

/* ‹ › · §28'in yön düğmeleriyle aynı ölçü ve aynı jetonlar. İkinci bir ipucu
   açılana kadar `hidden`: tek kart varken kaydıracak bir şey yok. */
.ip-yon {
  flex: none; width: 26px; height: 26px; padding: 0; cursor: pointer;
  font-family: var(--mono); font-size: 15px; line-height: 1;
  color: var(--muted); background: transparent;
  border: 1px solid var(--border); border-radius: 3px;
}
.ip-yon:hover { color: var(--ink-2); background: var(--paper-soft); }
.ip-yon:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.ip-yon[hidden] { display: none; }
.ip-yon:disabled { opacity: .4; cursor: default; }

/* ── ray ──────────────────────────────────────────────────────────────────
   Kaydırma İÇ KAPTA: kartlar rayın tam genişliği (`flex: 0 0 100%`), yani
   ray 360px'te bile okuma sütunundan taşmıyor ve sayfa gövdesi yana
   kaymıyor. `main.govde`nin `overflow-x: clip`i son emniyet, bu kural onu
   gerektirmiyor. */
.s-ipuclari[data-js] .ip-ray {
  display: flex; gap: var(--b3);
  margin-top: var(--b2); padding-top: var(--b2);
  border-top: 1px solid var(--border);
  overflow-x: auto; overflow-y: hidden;
  overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory; scroll-behavior: smooth;
  scrollbar-width: none;
}
.s-ipuclari[data-js] .ip-ray::-webkit-scrollbar { height: 0; }
.s-ipuclari[data-js] .ip-kart {
  flex: 0 0 100%; min-width: 0;
  margin: 0; padding: 0; border-top: 0;   /* §12'nin ayıracı rayda bir kez */
  scroll-snap-align: start;
}
/* Yeni açılan kart SAĞDAN geliyor: hareket "bir tane daha var" diyor. */
@keyframes ip-gel {
  from { opacity: 0; transform: translateX(12px); }
  to   { opacity: 1; transform: none; }
}
.s-ipuclari[data-js] .ip-kart.ip-yeni {
  animation: ip-gel .26s cubic-bezier(.4, 0, .2, 1) both;
}

/* Hareket kapalıysa KAYDIRMA da animasyon da yok — ama içerik yine değişiyor:
   kart açılıyor, ray o karta anında atlıyor. */
@media (prefers-reduced-motion: reduce) {
  .s-ipuclari[data-js] .ip-ray { scroll-behavior: auto; }
  .s-ipuclari[data-js] .ip-kart.ip-yeni { animation: none; }
  .ip-ampul .ip-isin { transition: none; }
  .ip-ac:hover > svg, .ip-ac:focus-visible > svg { transform: none; }
}

/* Kâğıtta ne şerit ne ray var: dört ipucu alt alta basılıyor. `hidden`
   kartlar da geri geliyor, yoksa çıktı öğrencinin o an açtığı kadarını
   taşırdı. */
@media print {
  .ip-serit { display: none; }
  .s-ipuclari[data-js] .ip-ray {
    display: block; overflow: visible; border-top: 0; padding-top: 0;
  }
  .s-ipuclari .ip-kart[hidden] { display: block; }
  .s-ipuclari[data-js] .ip-kart {
    padding: var(--b2) 0; border-top: 1px solid var(--border);
  }
}

/* ══ 34 · SORU DAMGASI · ŞIK GERİ BİLDİRİMİ · KAYDIRMA İMİ · EL YAZISI ═════
   Alperen, 13 Eyl (canlı sayfaya bakarak):
     · "soruların bloğunun sol üst köşesine hep rastgele olacak şekilde bizim
        logonun kırmızısını yapar mısın, o bizim marka kimliğimiz olur yani.
        ve soru soruluyor diye hissettirir. bazen 45 derece döner bazen yatay
        olur falan elle çizilmiş hissiyatı olursa soruları daha iyi ayırmış
        oluruz."
     · "mesela şıkkı seçtim ya. duolingodaki gibi doğru olan yeşil diğerleri
        kırmızı falan olsun hafif sallansın."
     · "bloklar içindeki metinleri yana kaydırarak görmemeliyim... pythonda
        sonsuza kadar yana mı kaydırılıyor mesela. eğer zorunluysa anlaşılması
        için koy."
     · "bazı yerlerde el yazısı gibi yazabilirsin not düşülen yerleri. sürekli
        aynı yazı fontu yorabiliyor."
     · "boşluklar bazen çok fazla oluyor hele hint butonunun arasındaki boşluk.
        hint butonu satır kaplamadığı için saçma boşluk çıkartıyor."
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── 34.1 · SORU DAMGASI ──────────────────────────────────────────────────
   ŞEKİL UYDURULMADI. Altı kollu yıldız `scripts/ikon_uret.py`nin ta kendisi
   (`KOL=6, DIS=0.41, KALINLIK=0.150`, yuvarlak uç) — favicon, OG kartı ve
   sayfa içi im de aynı tek kaynaktan çiziliyor ve `marka_test` o birliği
   ölçüyor. Buraya elle bir yıldız çizmek markanın DÖRDÜNCÜ şekli olurdu;
   `tests/damga_test.py` bu data-URI'nin `ikon_uret.yollar(24)` ile bayt bayt
   aynı kaldığını ölçüyor, yani im sessizce kayamaz.

   RENK `mask-image` İLE, `background-image` ile değil: maskede boya
   `background-color`dan okunur, yani damga `--accent`i takip ediyor ve gece
   modunda da doğru (#B53A2A -> #e88a74). Rengi data-URI'nin içine gömmek
   gece modunu kaybettirirdi.

   AÇI RASTGELE DEĞİL, SIRAYLA — ve `:nth-of-type` İLE DEĞİL. İlk deneme
   `:nth-of-type(5n+k)` idi; gerçek tarayıcıda ölçünce beş sorunun dördü aynı
   açıda çıktı, çünkü `.soru` blokları tek bir ebeveynin kardeşleri değil
   (her biri kendi kabında), yani hepsi "1. öge" sayılıyor. Açı artık
   sunucudan geliyor: `render_v2.py` her soruya `data-damga="0..4"` basıyor
   (bölüm içi sıra mod 5). Deterministik: sayfa yenilenince damga yer
   değiştirmiyor — zıplayan bir damga elle basılmış değil, bozuk görünür —
   ve JS kapalıyken de duruyor.
   Açılar küçük (-13°..+16°): asterisk altı katlı simetrik olduğu için 60°
   dönüşü zaten kendine eşit, o yüzden "45 derece" yerine küçük sapmalar
   elle basılmış hissini veriyor.

   YER: `.s-ust`in ilk flex ögesi, yani soru numarasının solu = sol üst köşe.
   Mutlak konumlama BİLEREK yok: `--pay` bütçesine taşan bir damga 360px'te
   `main.govde`nin `overflow-x: clip`ine girip kırpılırdı (§3). Akışın içinde
   durunca hem kırpılmıyor hem satır yüksekliğini değiştirmiyor. */
.soru > .s-ust::before {
  content: ''; flex: none; order: -1;
  width: .82em; height: .82em; align-self: center;
  background-color: var(--accent);
  -webkit-mask-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><g stroke='%23000' stroke-width='3.6' stroke-linecap='round' fill='none'><path d='M12.00 12.00L12.00 2.16'/><path d='M12.00 12.00L3.48 7.08'/><path d='M12.00 12.00L3.48 16.92'/><path d='M12.00 12.00L12.00 21.84'/><path d='M12.00 12.00L20.52 16.92'/><path d='M12.00 12.00L20.52 7.08'/></g></svg>");
  mask-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><g stroke='%23000' stroke-width='3.6' stroke-linecap='round' fill='none'><path d='M12.00 12.00L12.00 2.16'/><path d='M12.00 12.00L3.48 7.08'/><path d='M12.00 12.00L3.48 16.92'/><path d='M12.00 12.00L12.00 21.84'/><path d='M12.00 12.00L20.52 16.92'/><path d='M12.00 12.00L20.52 7.08'/></g></svg>");
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
  -webkit-mask-size: contain; mask-size: contain;
  opacity: .92;
}
/* Beş açı, elle basılmış izlenimi. Açıyı sunucu veriyor (`data-damga`),
   çünkü `.soru`lar ortak bir ebeveynde kardeş değil — ölçüldü. */
.soru[data-damga="0"] > .s-ust::before { transform: rotate(-13deg); }
.soru[data-damga="1"] > .s-ust::before { transform: rotate(9deg); }
.soru[data-damga="2"] > .s-ust::before { transform: rotate(-4deg); }
.soru[data-damga="3"] > .s-ust::before { transform: rotate(16deg); }
.soru[data-damga="4"] > .s-ust::before { transform: rotate(-8deg); }
/* Kâğıtta damga yok: mürekkep harcıyor, ayırt etmeye de gerek kalmıyor. */
@media print { .soru > .s-ust::before { display: none; } }

/* ── 34.2 · ŞIK GERİ BİLDİRİMİ ────────────────────────────────────────────
   Alperen, 13 Eyl: "mesela şıkkı seçtim ya. duolingodaki gibi doğru olan
   yeşil diğerleri kırmızı falan olsun hafif sallansın."

   DÜZELTME (bu bölümün ilk sürümü YANLIŞ yazılmıştı): not sayfasındaki
   `.s-sik` davranışı "cevaplanınca hepsi renklenir" DEĞİL. `build.py`'deki
   işleyici, yanlış şıkta yalnız TIKLANANI kırmızıya boyayıp kilitliyor ve
   deneme SÜRÜYOR; doğru şık seçilince kutu bitiyor ve doğru olan yeşile
   dönüyor. Gerekçesi kodun yanında yazılı: "doğru cevabı hemen vermek
   denemeyi bitiriyor." ("Hepsi renklenir" davranışı sayfadaki ÖTEKİ çoktan
   seçmeliye ait — `.msc`, kendi CSS'i var.)
   Bu yüzden "diğerleri kırmızı olsun" isteği AYNEN uygulanmadı: uygulanırsa
   tekrar deneme biter, yani ölçülmüş bir öğretim kararı sessizce bozulur.
   İstenen HİS sallanmayla geliyor; renk ise tıklanan şıkta.

   TİK VE ÇARPI GLİF DEĞİL, ÇİZİM: `✓` (U+2713) ve `✗` (U+2717) kaynak
   fontlarımızın hiçbirinde yok — §24'te `─`, `☐`, `▸` ile aynı tuzak, ekranda
   tofu çıkardı. İkisi de maskeli SVG.

   SALLANMA YALNIZ YANLIŞTA ve KISA: §27 bunun gerekçesini yazıyor (sallanma
   evrensel olarak "olmadı" demek; doğru cevapta sallamak ödülü cezaya
   benzetir). `.s-sik`te yalnız tıklanan şık `.yanlis` aldığı için sallanma
   tam o şıkta kalıyor — dört şıkkın üçü birden sallanmıyor. */
.s-sik.dogru {
  border-color: var(--emerald); color: var(--ink);
  background: color-mix(in srgb, var(--emerald) 12%, transparent);
}
.s-sik.yanlis {
  border-color: color-mix(in srgb, var(--accent) 55%, transparent);
  background: color-mix(in srgb, var(--accent) 7%, transparent);
  opacity: .72;
}
/* İm sağda, metnin akışını bozmadan. */
.s-sik.dogru::after, .s-sik.yanlis::after {
  content: ''; flex: none; margin-left: auto;
  width: .9em; height: .9em;
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
  -webkit-mask-size: contain; mask-size: contain;
}
.s-sik.dogru::after {
  background-color: var(--emerald);
  -webkit-mask-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M4 13l5.5 5.5L20 6' fill='none' stroke='%23000' stroke-width='2.6' stroke-linecap='round' stroke-linejoin='round'/></svg>");
  mask-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M4 13l5.5 5.5L20 6' fill='none' stroke='%23000' stroke-width='2.6' stroke-linecap='round' stroke-linejoin='round'/></svg>");
}
.s-sik.yanlis::after {
  background-color: var(--accent);
  -webkit-mask-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M6 6l12 12M18 6L6 18' fill='none' stroke='%23000' stroke-width='2.6' stroke-linecap='round'/></svg>");
  mask-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M6 6l12 12M18 6L6 18' fill='none' stroke='%23000' stroke-width='2.6' stroke-linecap='round'/></svg>");
}
/* Şık düğmesi zaten grid/flex değilse im sağa yatmaz; kabı esnek yap. */
.s-sik { display: flex; align-items: center; gap: var(--b2); }
@media (prefers-reduced-motion: no-preference) {
  /* Doğru şık YUKARI sıçrıyor (§27'nin `sy-sicra` diliyle aynı). */
  .s-sik.dogru { animation: sik-sicra .34s cubic-bezier(.34, 1.4, .64, 1); }
  /* Yanlış şık SALLANIYOR — Alperen'in istediği "hafif sallansın". §27'nin
     `sy-salla`sıyla aynı eğri ve aynı süre; yeni bir hareket dili açılmıyor,
     genlik biraz daha küçük çünkü sallanan şey tek bir düğme. */
  .s-sik.yanlis { animation: sik-salla .32s ease-out; }
}
@keyframes sik-sicra {
  0%   { transform: translateY(0); }
  45%  { transform: translateY(-3px); }
  100% { transform: translateY(0); }
}
@keyframes sik-salla {
  0%, 100% { transform: translateX(0); }
  22% { transform: translateX(-4px); }
  45% { transform: translateX(4px); }
  70% { transform: translateX(-2px); }
}

/* ── 34.3 · İPUCU ŞERİDİ: BOŞ SATIR HARCAMAZ ──────────────────────────────
   Şerit (`.ip-serit`) ampul + sayaç + ‹ › taşıyor; üçü toplam ~7em yer
   tutuyor ama blok düzeni olduğu için TAM SATIR harcıyordu. Alperen: "hint
   butonu satır kaplamadığı için saçma boşluk çıkartıyor."
   ÖLÇÜLDÜ (13 Eyl, gerçek tarayıcı): `display: inline-flex` BURADA ÇALIŞMAZ.
   `.s-ipuclari` bir grid kabı (§29) ve `.ip-serit` onun grid ögesi; CSS grid
   ögelerinin display'ini blokluyor, yani `inline-flex` hesaplanan değerde
   `flex`e dönüyor. Şeridi gerçekten satırdan çıkarmak için onu `.s-ust`e
   (soru başlığı satırına, zorluk noktalarının yanına) TAŞIMAK gerekiyor;
   o taşıma JS'i de ilgilendiriyor (`build.py` şeridi `kap.querySelector`
   ile arıyor) ve ayrı bir adımda yapılıyor.
   Burada CSS'in yapabileceği kadarı: üst boşluk `--b2`den `--b1`e iniyor ve
   şerit satırın tamamına yayılmıyor (`justify-self: start`), yani sağda
   uzanan boş şerit gitti. */
.ip-serit { justify-self: start; margin-top: var(--b1); }

/* ── 34.4 · KAYDIRMA İMİ ──────────────────────────────────────────────────
   Alperen: "bloklar içindeki metinleri yana kaydırarak görmemeliyim...
   zorunluysa anlaşılması için koy."
   Kod satırını SARMAK bir seçenek değil: Python'da girinti anlam taşıyor,
   sarılan satır yanlış girinti okutur. O yüzden kaydırma kalıyor ama artık
   GÖRÜNÜYOR: sağ kenarda, yalnız gerçekten taşma varken beliren bir solma.
   `background-attachment: local` hilesi: solma yalnız içerik kaydırılabilir
   olduğunda çiziliyor, kısa satırda kendiliğinden kayboluyor — JS ölçümü
   gerekmiyor. */
.kz, .nt2, .kb-ifade, .c-son {
  background-image: linear-gradient(to left,
      color-mix(in srgb, var(--paper) 92%, transparent), transparent 2.2em);
  background-repeat: no-repeat;
  background-position: right center;
  background-size: 2.2em 100%;
  background-attachment: local;
}
@media print {
  .kz, .nt2, .kb-ifade, .c-son { background-image: none; }
}

/* ── 34.5 · EL YAZISI HİSSİ: NOT DÜŞÜLEN YERLER ───────────────────────────
   Alperen: "bazı yerlerde el yazısı gibi yazabilirsin not düşülen yerleri.
   sürekli aynı yazı fontu yorabiliyor."
   YENİ FONT İNDİRİLMİYOR. El yazısı fontu eklemek sayfaya bir woff2 daha
   yüklerdi ve Alperen'in aynı mesajdaki ikinci şikâyeti tam bu ("sitelerin
   yüklenmesi epey vakit alıyor"). Zaten gömülü olan Crimson Pro'nun
   İTALİĞİ kullanılıyor: kenara düşülmüş bir not için doğru his, sıfır bayt.
   Nesir gövdesi (`--serif`, Literata) değişmiyor — ayrım ancak gövde aynı
   kalırsa okunur. */
.nt-oku, .dn-hatirla, .kp-not p {
  font-family: var(--baslik); font-style: italic;
  font-size: calc(var(--f-govde) * 1.02);
}

/* ══ 35 · KOD YERİNDE KALIR · ADIMLAYICI ALTINDA DEVAM EDER ════════════════
   Alperen, 13 Eyl (canlı sayfaya bakarak):
     · "run step by step dediğinde altta çıkacağına ALANIN ÜZERİNE yazdığı
        için neyi run ettiğini anlayamıyorum."
     · "zaten yukarıda kod var, sırayla oynarsın. çıktı kısmını bilerek boş
        bırakırsın, gerekirse ek satır eklersin, ama daha iyi durur böylelikle."
     · "python console gibi hissiyat vermiyor... olabildiğince gerçekçi tut."
     · "alt alta olmasında sorun yok ama yan yana o kadar hoş olmuyor."
     · "scroll edildiğinde sağa sola hareket eden bloklar görüyorum."

   NE DEĞİŞTİ: eski sürüm ham `<pre>`i GİZLİYOR (`pre.hidden = true`) ve aynı
   kodu ayrı bir editör panosunda (`.kz-ed`) yeniden çiziyordu. Kodun yerinde
   başka bir şeye dönüşmesi tam da "üzerine yazdı" hissini veriyordu. Artık
   satırlar orijinal `<pre>`in İÇİNDE işaretleniyor (`.kz-l`), `<pre>` bir
   editör panosuna sarılıyor (sekme + pencere düğmeleri + durum çubuğu) ve
   kutuya yalnız denetim + Variable explorer + konsol giriyor.

   SATIR NUMARASI CSS SAYACI: DOM'da metin olarak yok, yani öğrenci kodu
   kopyalayınca numaralar karışmıyor. Eski sürümde numara gerçek bir düğümdü
   ve `user-select: none` ile korunuyordu; sayaç o korumayı gereksiz kılıyor
   (tarayıcılar `::before` içeriğini kopyalamıyor).
   ═══════════════════════════════════════════════════════════════════════════ */

/* Satırlı `<pre>`: sayaç kökü ve oluk payı. */
pre.kod.kz-canli { counter-reset: kzl; position: relative; }
pre.kod.kz-canli > code { display: block; }
.kz-canli .kz-l {
  counter-increment: kzl;
  display: block; position: relative;
  padding-left: 3.2em;               /* oluk: numara + imleç */
  min-height: 1.55em;
}
/* Numara. `tabular-nums` yok: mono yüzde zaten eşit genişlikte. */
.kz-canli .kz-l::before {
  content: counter(kzl);
  position: absolute; left: 0; width: 2.3em;
  text-align: right; color: var(--muted); opacity: .75;
}
/* KOŞAN SATIR. Zemin satırın tamamına yayılsın diye `display: block` +
   negatif kenar yok: `<pre>` kendi içinde kaydığı için `width: max-content`
   hilesine gerek kalmıyor, zemin görünen genişliği dolduruyor. */
.kz-canli .kz-l.kz-simdi { background: var(--vurgu-zemin); }
.kz-canli .kz-l.kz-simdi::before { color: var(--accent); opacity: 1; }
/* İmleç üçgeni: §18'in aynısı, glif değil kenarlık. */
.kz-canli .kz-l.kz-simdi::after {
  content: ''; position: absolute; left: 2.5em; top: .5em;
  width: 0; height: 0; border-style: solid;
  border-width: .3em 0 .3em .42em;
  border-color: transparent transparent transparent var(--accent);
}

/* Sarılmış editör panosu: `<pre>` panonun içinde, kendi yuvartısı gitmiş. */
.kz-yerinde { margin: var(--b3) 0 0; }
.kz-yerinde > pre.kod {
  margin: 0; border: 0; border-radius: 0; max-height: 26em; overflow: auto;
}
/* Panonun içindeki `<pre>` dip çubuğuna yapışmıyor artık: durum çubuğu
   araya giriyor, yuvartıyı pano taşıyor. */
.kz-yerinde > pre.kod.kod-sapli { border-radius: 0; }

/* PANOLAR ALT ALTA. §24'teki 56rem iki-sütun eşiği kalktı: Alperen "yan yana
   o kadar hoş olmuyor" dedi ve iki sütunda Variable Explorer'ın dört sütunu
   zaten sıkışıyordu (eski ölçüm, aynı dosyada yazılı). */
.kz-panolar { grid-template-columns: minmax(0, 1fr) !important; }

/* KONSOL BOŞ ALAN AYIRIYOR.
   Alperen: "çıktı kısmını bilerek boş bırakırsın, gerekirse ek satır
   eklersin." Sebebi düzen kararlılığı: çıktı adım adım geldikçe konsol
   büyüyor ve altındaki her şey aşağı kayıyordu — "scroll edildiğinde sağa
   sola hareket eden bloklar" şikâyetinin kardeşi. Yükseklik baştan ayrılınca
   adım atmak sayfayı oynatmıyor. 8.5em ≈ 7 satır: `%run` istemi + tipik
   çıktı + bir sonraki istem sığıyor. */
.kz-kons .kz-kon { min-height: 8.5em; }

/* ══ 36 · KOD BLOĞUNA KOPYALA DÜĞMESİ ══════════════════════════════════════
   Alperen, 13 Eyl: "kodlu olan yerlerin sağ üstüne kopyalama işareti
   koyarsan iyi olur. sonra 'code copied to clipboard' falan yazarsa iyi
   olur. direkt kopyalaya da bilir çünkü."

   DÜĞME `<pre>`İN DIŞINDA (JS onu bir `.kod-sar`a alıyor). İçine konsa
   düğmenin metni KOPYALANAN METNE karışırdı — bu depoda belgelenmiş bir hata
   sınıfı; satır numaraları da tam bu yüzden CSS sayacına taşındı (§35).

   İKON GLİF DEĞİL MASKE: `⧉`/`✓` gibi kod noktaları kaynak fontlarımızda yok
   (§24'ün tuzağı), kod yüzeyi de `--kod-mono` ile çiziliyor. İki şekil de
   maskeli SVG, yani her fontta aynı.

   ETİKET HOVER'DA, İKON HER ZAMAN: §5'in dili ("simge önce, yazı hover'da").
   Dokunmatikte hover yok, o yüzden `@media (hover: none)` altında etiket
   kalıcı — dokunan kullanıcı ne olduğunu okuyabiliyor.
   ═══════════════════════════════════════════════════════════════════════════ */

/* DUGME KODUN USTUNE BINMIYOR.
   Ilk surum `<pre>`in sag ust kosesine mutlak oturuyordu; `glif_test`
   olctu ve yakaladi: `pre.kod` x `button.kod-kopya` = 61x23px cakisma.
   Bindirme tiklamayi yutar ve uzun bir kod satirini kapatir (bu depoda
   belgelenmis bir hata sinifi). Cozum: sarmalayici USTTE bir bant
   ayiriyor, dugme o bantta duruyor — hala "sag ust kose", ama kodun
   dikdortgeninin DISINDA. */
.kod-sar { position: relative; padding-top: 1.75em; }
.kod-kopya {
  position: absolute; top: 0; right: .15em; z-index: 2;
  display: inline-flex; align-items: center; gap: .35em;
  padding: .3em .45em; cursor: pointer;
  /* SAYFA PALETI, AYGIT PALETI DEGIL.
     Ilk surum `--sp-*` (Spyder) degiskenlerini kullaniyordu; `terminal_test`
     olctu ve yakaladi: "koyu palet aygitin disina sizmiyor" — §24'un kurali.
     Dugme artik `<pre>`in DISINDA, kagit zeminde duruyor (yukaridaki bant),
     yani dogru palet sayfanin kendisi. */
  font-family: var(--mono); font-size: 12.5px; line-height: 1;
  color: var(--muted); background: var(--paper-soft);
  border: 1px solid var(--border); border-radius: 3px;
  opacity: 0; transition: opacity .16s ease, color .16s ease;
}
/* İkon: iki üst üste dikdörtgen = kopya. */
.kod-kopya::before {
  content: ''; flex: none; width: 13px; height: 13px;
  background-color: currentColor;
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
  -webkit-mask-size: contain; mask-size: contain;
  -webkit-mask-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><rect x='9' y='9' width='11' height='11' rx='2' fill='none' stroke='%23000' stroke-width='2'/><path d='M5 15V5a2 2 0 0 1 2-2h8' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round'/></svg>");
  mask-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><rect x='9' y='9' width='11' height='11' rx='2' fill='none' stroke='%23000' stroke-width='2'/><path d='M5 15V5a2 2 0 0 1 2-2h8' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round'/></svg>");
}
/* Etiket hover'da açılıyor: kapalıyken sıfır genişlik, kod satırını kapatmıyor. */
.kk-et {
  max-width: 0; overflow: hidden; white-space: nowrap;
  opacity: 0; transition: max-width .2s ease, opacity .16s ease;
}
.kod-sar:hover .kod-kopya, .kod-kopya:focus-visible { opacity: 1; }
.kod-kopya:hover, .kod-kopya:focus-visible {
  color: var(--ink); border-color: var(--border-strong);
}
.kod-kopya:hover .kk-et, .kod-kopya:focus-visible .kk-et {
  max-width: 15em; opacity: 1;
}
/* ONAY: ikon tike dönüyor, etiket açık kalıyor, renk yeşil. */
.kod-kopya.oldu {
  opacity: 1; color: var(--emerald);
  border-color: color-mix(in srgb, var(--emerald) 60%, transparent);
}
.kod-kopya.oldu .kk-et { max-width: 15em; opacity: 1; }
.kod-kopya.oldu::before {
  -webkit-mask-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M4 13l5.5 5.5L20 6' fill='none' stroke='%23000' stroke-width='2.6' stroke-linecap='round' stroke-linejoin='round'/></svg>");
  mask-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M4 13l5.5 5.5L20 6' fill='none' stroke='%23000' stroke-width='2.6' stroke-linecap='round' stroke-linejoin='round'/></svg>");
}
/* Dokunmatikte hover yok: düğme ve etiketi görünür kalıyor. */
@media (hover: none) {
  .kod-kopya { opacity: .85; }
  .kk-et { max-width: 15em; opacity: 1; }
}
@media print { .kod-kopya { display: none; } }

/* Sayı ile birimi bölünmez (build.py `oru` özeti). Alperen 13 Eyl: özet
   satırı sarılırken kırılma `74` ile `questions` arasına düşüyordu ve sayı
   kendi satırında yalnız kalıyordu ("şu kısım yamuk biraz").
   YALNIZ 30rem ÜSTÜNDE. Ölçüldü 13 Eyl (`notes_test`): koşulsuz `nowrap`
   360px'te künye özetini 101px taşırıyordu — dar ekranda satırın kırılacak
   başka yeri yok. Orada zaten her şey sarıldığı için "yamuk" sorunu da
   ortaya çıkmıyor. */
@media (min-width: 30rem) {
  .oru > summary .oru-cift { white-space: nowrap; }
}
/* Kopyalanamadıysa bunu SÖYLÜYOR: sessiz başarısızlık öğrenciye yanlış
   bilgi verir (13 Eyl'de headless'ta ölçüldü — `navigator.clipboard`
   reddedilince eski sürüm hiçbir şey göstermiyordu). */
.kod-kopya.olmadi {
  opacity: 1; color: var(--accent);
  border-color: color-mix(in srgb, var(--accent) 60%, transparent);
}
.kod-kopya.olmadi .kk-et { max-width: 22em; opacity: 1; }

/* ══ 37 · İPUCU ŞERİDİ SORU BAŞLIĞINDA ═════════════════════════════════════
   Alperen, 13 Eyl: "boşluklar bazen çok fazla oluyor hele hint butonunun
   arasındaki boşluk. hint butonu satır kaplamadığı için saçma boşluk
   çıkartıyor. daha iyi konumu var mı ya da ux'i falan."

   ÖLÇÜLDÜ (gerçek tarayıcı): şerit 66px yer tutuyordu ama blok düzeni
   olduğu için 651px'lik satırın TAMAMINI harcıyordu — satırın %90'ı boş.
   §34.3'te CSS ile çözmeyi denedim ve olmadı: `.s-ipuclari` bir grid kabı,
   grid ögesinin `display`i bloklanıyor (`inline-flex` → `flex`). Şerit artık
   JS tarafından SORU BAŞLIĞI satırına taşınıyor (`build.py`, `ipucuKur`):
   zorluk noktalarının hemen soluna, gözün zaten olduğu yere. Yeni satır
   açılmıyor, `.s-ipuclari` yalnız rayı taşıyor.

   ‹ › ARTIK GİZLENMİYOR, DEVRE DIŞI KALIYOR: "hintler arasında geçiş
   yapılabilmeli" dedi; geçiş zaten vardı ama iki ipucu açılana kadar
   `hidden` basılıyordu, yani bir ipucu açan öğrenci geçişin var olduğunu
   hiç görmüyordu. Tek ipuçlu soruda (n<2) hâlâ gizli — orada gösterilecek
   bir şey yok.
   ═══════════════════════════════════════════════════════════════════════════ */

/* Başlık satırındaki şerit: kendi yerini kadar, sağa yatık, satır yüksekliğini
   büyütmeyecek kadar sıkı. `.s-ust` baseline hizalı olduğu için şeridin
   kendisi `center` hizalanıyor — ampul harflerin ortasına oturuyor. */
.s-ust > .ip-serit-ust {
  margin: 0 0 0 auto;            /* zorluk noktalarından ÖNCE, sağa yatık */
  align-self: center;
  gap: .25em;
}
/* Noktalar şeritten sonra geldiği için kendi `margin-left:auto`su artık
   gerekmiyor; iki öge arasında sabit bir boşluk kalıyor. */
.s-ust > .ip-serit-ust + .zor { margin-left: .55em; }

/* Ray, şerit taşındıktan sonra tek başına kalıyor: üstündeki çizgi artık
   şeridi değil rayı sınırlıyor, o yüzden üst boşluk küçülüyor. */
.s-ipuclari[data-js] .ip-ray { margin-top: var(--b1); }

/* 360px: başlık satırı sarılabilir (`.s-ust` zaten `flex-wrap: wrap`).
   Şerit alt satıra düşerse `margin-left: auto` onu sağa iter ve yine boş
   bir satır doğar; dar ekranda sola yatıyor ve noktalarla aynı satırda
   kalıyor. */
@media (max-width: 30rem) {
  .s-ust > .ip-serit-ust { margin-left: .4em; }
}

/* ══ 38 · YAZMA ALANLARI: ÜRETMEK, OKUMAK DEĞİL ════════════════════════════
   14 Eyl 2026. İki yer öğrenciden yazmasını İSTİYOR ama yazacak yer
   vermiyordu:
     · `rung2_self_explain` metni birebir "write, in the empty column, why
       each line is allowed" diyor; sayfada boş sütun yoktu, model gerekçe
       bir tık ötedeydi.
     · `free_recall_prompt` "write down everything you can" diyor; yazacak
       alan yoktu.
   Kanıt: Bisra 2018 self-explanation prompt g=0,55 (64 rapor, ~6000
   katılımcı) ama ölçtüğü şey açıklamanın ÜRETİLMESİ. Retrieval practice
   Dunlosky'nin iki "yüksek fayda"sından biri. Bjork'un bulgusu tam burada
   ısırıyor: yer yoksa öğrenci kolay olanı seçip hazır cevabı açıyor.

   HİÇBİR YERE KAYDEDİLMİYOR — ne sunucuya ne cihaza. Alperen'in yazma
   tezgâhı için koyduğu kuralın aynısı: "altta kopyala butonu olur. biz
   kaydetmeyiz." Bu bir sınır, gizlenmiyor: sayfa yenilenirse yazılan gider,
   o yüzden kopyala düğmesi var.

   GÖRÜNÜM: alan sayfanın kendi kâğıdında, çerçevesi ince; §3'ün okuma
   sütununu bozmuyor. `rows="1"` + `field-sizing` ile tek satır başlıyor,
   yazdıkça büyüyor (destekleyen tarayıcıda); desteklemeyen tarayıcıda tek
   satır kalıyor ve kendi içinde kayıyor, kayıp yok.
   ═══════════════════════════════════════════════════════════════════════════ */

.fl-yaz { display: block; margin: var(--b1) 0 var(--b1); }
.fl-yaz-et {
  display: block; margin-bottom: 2px;
  font-family: var(--mono); font-size: var(--f-et);
  letter-spacing: .06em; text-transform: uppercase; color: var(--muted);
}
.fl-gir, .dn-gir {
  display: block; width: 100%; box-sizing: border-box;
  padding: .4em .55em; resize: vertical;
  font-family: var(--serif); font-size: var(--f-govde); line-height: 1.5;
  color: var(--ink); background: var(--paper);
  border: 1px solid var(--border); border-radius: 3px;
  field-sizing: content;            /* destekleyen tarayicida yazdikca buyur */
}
.fl-gir { min-height: 2.1em; }
.dn-gir { min-height: 5em; }
.fl-gir:focus, .dn-gir:focus {
  outline: 2px solid var(--accent); outline-offset: 1px;
  border-color: var(--border-strong);
}
/* Yazılan bir şey varsa kenar rengi değişiyor: "burada işim var" izi. */
.fl-gir:not(:placeholder-shown), .dn-gir:not(:placeholder-shown) {
  border-color: var(--border-strong); background: var(--paper-soft);
}

.dn-yaz { position: relative; margin: var(--b2) 0; }
.yaz-kopya {
  position: absolute; right: .35em; bottom: .45em;
  padding: .25em .5em; cursor: pointer;
  font-family: var(--mono); font-size: 12px; line-height: 1;
  color: var(--muted); background: var(--paper-soft);
  border: 1px solid var(--border); border-radius: 3px;
}
.yaz-kopya:hover, .yaz-kopya:focus-visible {
  color: var(--ink); border-color: var(--border-strong);
}
.yaz-kopya.oldu { color: var(--emerald); border-color: var(--emerald); }
.yaz-kopya.olmadi { color: var(--accent); border-color: var(--accent); }

/* Kâğıtta yazma alanı BOŞ KUTU olarak basılıyor: yazdıran öğrenci elle
   doldurabilsin. Delgado 2018'in kâğıt avantajı (g=-0,21) tam bu kesişimde
   (bilgilendirici metin + sınav öncesi zaman baskısı). */
@media print {
  .fl-gir, .dn-gir {
    min-height: 3.2em; background: transparent;
    border: 1px solid #bbb; field-sizing: fixed;
  }
  .yaz-kopya { display: none; }
}

/* ══ 39 · FORMÜL KARTLARI → ANKI ═══════════════════════════════════════════
   Aralıklı tekrar (distributed practice) Dunlosky 2013'ün yalnız iki "yüksek
   fayda" işaretinden biri; sitede bunu tetikleyen hiçbir şey yoktu (ölçüldü:
   `.tsv`/`.ics`/Anki dışa aktarma = 0). Kendi zamanlayıcımızı yazmak yerine
   öğrencinin zaten kullandığı araca veri veriyoruz: hesap yok, sunucuda
   öğrenci verisi tutulmuyor, günler süren bir takvimi taşıyacak yerimiz de
   yok. Düğme formül kartı başlığının yanında, çünkü indirdiği şey tam o.
   ═══════════════════════════════════════════════════════════════════════════ */

.fk-bas { display: flex; align-items: baseline; gap: var(--b2); }
.fk-anki {
  margin-left: auto; padding: .28em .55em; cursor: pointer;
  font-family: var(--mono); font-size: 12px; line-height: 1;
  color: var(--muted); background: var(--paper-soft);
  border: 1px solid var(--border); border-radius: 3px;
}
.fk-anki:hover, .fk-anki:focus-visible {
  color: var(--ink); border-color: var(--border-strong);
}
.fk-anki.oldu { color: var(--emerald); border-color: var(--emerald); }
.fk-anki.olmadi { color: var(--accent); border-color: var(--accent); }
@media print { .fk-anki { display: none; } }

/* ═══════════════════════════════════════════════════════════════════════
   BÖLÜM SAYFALARI — dizin kartları, bölüm gezinmesi, başlık numarası
   22 Ağustos 2026

   Alperen: "bölümleri komple yüklemek yerine parçalara ayırman gerekebilir
   sanki. onun da optimizasyonunu yapman lazım."

   Ölçüldü: on dört bölüm tek sayfada 3,26 MB (gzip 789 KB), 57.269 DOM
   elemanı. Formüllerin tembel render'ı ilk ekranı kurtarıyordu ama indirilen
   bayt duruyordu; mobil veride bunun karşılığı yok.

   İkinci kazanç arama tarafında: tek sayfa Google'da tek sonuç. On dört ayrı
   sayfa on dört ayrı sonuç demek, ve "math 101 limit" arayan öğrenci doğrudan
   §01'e düşüyor — 3 MB'lik bir sayfanın ortasına değil.

   Bu dosya ana CSS'ten AYRI tutuluyor: ana dosya aynı gün sıfırdan yeniden
   yazıldı, iki iş aynı dosyada çakışmasın diye.
   ═══════════════════════════════════════════════════════════════════════ */

/* ── dizin: bölüm kartları ────────────────────────────────────────────── */
.bk-liste {
  display: grid;
  gap: 2px;
  margin: 8px 0 0;
}
/* `display: grid` (0,1,0) tarayicinin `[hidden] { display: none }` kuralini
   (0,0,0) eziyor: JS `hidden = true` diyor, liste ekranda kaliyor. Ayni tuzak
   `.konum` icin de yasandi. Oznitelik dogru, ekran yanlis. */
.bk-liste[hidden] { display: none; }
.bk {
  display: grid;
  /* Alanlar ACIK yerlestiriliyor. Otomatik yerlesim birakildiginda numara,
     baslik ve sayi satiri ayni hucreye dusuyor, baslik kelime kelime kirilip
     sayilar uzerine biniyordu. */
  grid-template-columns: 2.6rem minmax(0, 1fr);
  grid-template-areas: "no ad" "no say";
  gap: 2px 14px;
  align-items: start;
  padding: 15px 0;
  color: inherit;
  text-decoration: none;
  border-bottom: 1px solid var(--border, #e6dfd0);
}
.bk:first-child { border-top: 1px solid var(--border, #e6dfd0); }
.bk:hover .bk-ad { color: var(--accent, #B53A2A); }
.bk-no {
  grid-area: no;
  font-family: 'JetBrains Mono', monospace;
  font-size: 13px;
  color: var(--soluk, #8b8172);
  padding-top: 2px;
}
.bk:hover .bk-no { color: var(--accent, #B53A2A); }
.bk-ad {
  grid-area: ad;
  font-family: 'Crimson Pro', Georgia, serif;
  font-size: 1.16rem;
  font-weight: 600;
  line-height: 1.3;
  color: var(--ink, #241f16);
}
.bk-say {
  grid-area: say;
  font-family: 'Inter', sans-serif;
  font-size: 11.5px;
  color: var(--muted, #6b6152);
}

/* ── bölüm başlığındaki numara ────────────────────────────────────────── */
/* Numara okuma sütununun DIŞINA taşar: metnin sol kenarı bozulmasın diye.
   Dar ekranda yer yok, o zaman başlığın üstüne geçer. */
h1 .h1-no {
  font-family: 'JetBrains Mono', monospace;
  font-size: .42em;
  font-style: normal;
  font-weight: 400;
  color: var(--soluk, #8b8172);
  letter-spacing: .06em;
}
@media (min-width: 900px) {
  h1 .h1-no {
    position: absolute;
    transform: translateX(calc(-100% - 0.9rem));
  }
  main.govde > h1 { position: relative; }
}
@media (max-width: 899px) {
  h1 .h1-no { display: block; margin-bottom: 4px; }
}

/* ── bölüm sonu gezinmesi ─────────────────────────────────────────────── */
.bolum-gez {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 12px;
  margin: 56px 0 0;
  padding-top: 18px;
  border-top: 1px solid var(--border, #e6dfd0);
}
.bolum-gez a {
  display: block;
  padding: 12px 0;
  font-family: 'Crimson Pro', Georgia, serif;
  font-size: 1.02rem;
  font-weight: 600;
  line-height: 1.35;
  color: var(--ink, #241f16);
  text-decoration: none;
}
.bolum-gez a:hover { color: var(--accent, #B53A2A); }
.bolum-gez span {
  display: block;
  margin-bottom: 3px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  font-weight: 400;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--soluk, #8b8172);
}
.bg-sonraki { text-align: right; }
@media (max-width: 620px) {
  .bolum-gez { grid-template-columns: minmax(0, 1fr); gap: 0; }
  .bg-sonraki { text-align: left; border-top: 1px solid var(--border, #e6dfd0); }
}

/* İçindekiler başlığındaki ders kodu artık dizine götürüyor. */
.icindekiler h4 a { color: inherit; text-decoration: none; }
.icindekiler h4 a:hover { color: var(--accent, #B53A2A); }


/* ── UZUN FORMÜLÜN SON ÇARESİ ─────────────────────────────────────────────
   Ölçüldü 390px'te: yanlış/doğru kutusunda 358px'lik alana 918px'lik bir
   formül düşüyor. Bunu sığdırmak %39 ölçek demek — okunmaz. Kırmak da
   olmuyor: formül bir kelime değil, sarması anlamı bozuyor.

   Kalan tek dürüst davranış: FORMÜLÜN KENDİ KUTUSU kaysın. Kayan şey sayfa
   değil, o kutu; kenardaki maske kaydırılabildiğini söylüyor. Bu üç blokla
   sınırlı — bir gece önce 264 öğede kaydırma vardı, o başka bir şeydi.

   Kalıcı çözüm üretim tarafında: 120 karakteri aşan satır içi formül
   \begin{aligned} ile kırılmalı. denetim.py artık bunu sayıyor. */
.fk-tex, .h-yanlis, .h-dogru, .kf-tex, .c-mat,
.kb-ifade, .s-ipucu > p, .kt-a, .kt-b, .mf-a, .mf-b, .c-son, .cv-not {
  overflow-x: auto;
  /* `overflow-x: auto` CSS geregi diger ekseni de auto'ya ceker. KaTeX'in
     kesir ve kok yapilari satir kutusunun 2-7 piksel disina tastigi icin
     bu kutulara DIKEY kaydirma cubugu takiliyordu — olculdu, 255 ogede;
     36 piksellik bir hucrede 15 piksellik cubuk. Dikey pay o tasmayi
     sogurunca cubuk gerekmez oluyor, yatay kaydirma kaliyor. */
  padding-block: .38em;
  /* Dikey ekseni ACIKCA kapat. `overflow-x: auto; overflow-y: hidden` gecerli
     bir kombinasyon (yalniz biri `visible` olursa oteki auto'ya cevrilir).
     Tablo hucresinde padding tek basina yetmedi — olculdu, td.c-mat'ta 153
     dikey cubuk kaldi. Pay tasmayi sogurdugu icin hidden bir sey kesmiyor. */
  overflow-y: hidden;
  overscroll-behavior-x: contain;
  -webkit-mask-image: linear-gradient(to right, #000 95%, transparent);
  mask-image: linear-gradient(to right, #000 95%, transparent);
}
.fk-tex::-webkit-scrollbar, .h-yanlis::-webkit-scrollbar,
.h-dogru::-webkit-scrollbar, .kf-tex::-webkit-scrollbar,
.c-mat::-webkit-scrollbar, .kb-ifade::-webkit-scrollbar,
.s-ipucu > p::-webkit-scrollbar { height: 3px; }
.fk-tex::-webkit-scrollbar-thumb, .h-yanlis::-webkit-scrollbar-thumb,
.h-dogru::-webkit-scrollbar-thumb, .kf-tex::-webkit-scrollbar-thumb,
.c-mat::-webkit-scrollbar-thumb, .kb-ifade::-webkit-scrollbar-thumb,
.s-ipucu > p::-webkit-scrollbar-thumb { background: var(--border-strong, #d8cfba);
  border-radius: 2px; }


/* Sigmayan satir ici formul display moda cevrildi (JS): artik KaTeX'in
   kendi satir kirma noktalari devrede. Blok gibi davranir ama cevresindeki
   metinden kopmasin diye dikey payi kucuk. */
.blok-cevrim { display: block; margin: .35em 0; text-align: left; }
.blok-cevrim > .katex { white-space: normal; }
.blok-cevrim .mtable, .blok-cevrim .mtable * { white-space: nowrap; }


/* ═══════════════════════════════════════════════════════════════════════
   NEREDEYİM · NE ZAMAN ÇALIŞACAĞIM · NİYE BURADAYIM
   22 Ağustos 2026 · ikinci tur

   Alperen: "hangi bölümde olduğumdan hangi konuyu çalışmam gerektiğinden
   tam emin olamıyorum" ve "sınava yönelik mi çalışıyor, yoksa sadece konu mu".

   Üç ayrı eksik, üç ayrı çözüm:
     1. KONUM  — künye + dönem şeridi + kaydırınca beliren yapışkan şerit
     2. TAKVİM — hafta numarası, kitap bölümü, dönemin neresi
     3. NİYET  — çalışma modu; aynı sayfa öğrenmek ile sınava hazırlanmak
                 için aynı sırada okunmuyor
   ═══════════════════════════════════════════════════════════════════════ */

/* ── künye: haftası, kitabı, süresi ───────────────────────────────────── */
.kunye { margin: 0 0 var(--b3); }
.ky-ust {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px 14px;
  font-family: var(--ui); font-size: 12.5px; color: var(--muted);
}
.ky-hf {
  font-family: var(--mono); font-size: var(--f-et);
  letter-spacing: .05em; text-transform: uppercase;
  color: var(--accent); font-weight: 500;
}
.ky-kt { color: var(--ink-2); }
.ky-dk { color: var(--muted); }
.ky-dk::before { content: '~'; }
.ky-alt { margin-top: 10px; }
.ky-sinav b { color: var(--accent); }

/* ── dönem şeridi: on dört bölümlük mini harita ───────────────────────── */
/* Menü 1180px altında kapalı; telefonda "kaçıncı bölümdeyim"in başka
   kaynağı yoktu. Kutucuklar 14 tane, 390px'e sığsın diye esnek. */
.donem-serit {
  display: flex; gap: 3px; margin: 12px 0 0;
  padding-bottom: 2px;
}
.donem-serit .ds {
  flex: 1 1 0; min-width: 0;
  display: flex; align-items: center; justify-content: center;
  height: 22px; border-radius: 3px;
  background: var(--paper-soft);
  font-family: var(--mono); font-size: 10px; color: var(--muted);
  text-decoration: none;
  transition: background .12s, color .12s;
}
.donem-serit .ds:hover { background: var(--border); color: var(--ink); }
.donem-serit .ds.aktif {
  background: var(--accent); color: var(--paper); font-weight: 500;
}
/* DÖNEMİN BU HAFTASI. `aktif` ile karıştırılmamalı: `aktif` OKUDUĞUN
   bölüm, `ds-simdi` TAKVİMDEKİ hafta. İkisi genelde farklı yerde ve ikisini
   aynı işaretle göstermek "yanlış bölümdeyim" hissi verir.
   Alperen, 12 Eylül: "bu haftadayız yazar mesela. canlı site olduğunu
   hissettirir." İşaret altta küçük bir nokta: kutucuğun zeminini almıyor,
   yani okunan bölümün vurgusunu bastırmıyor. Hafta İSTEMCİDE hesaplanıyor,
   build anında gömülmüyor. */
.donem-serit { padding-bottom: 6px; }
.donem-serit .ds { position: relative; }
.donem-serit .ds-simdi::after {
  content: ''; position: absolute; left: 50%; bottom: -5px;
  width: 4px; height: 4px; margin-left: -2px; border-radius: 50%;
  background: var(--emerald);
}
.donem-serit .ds-simdi:not(.aktif) {
  color: var(--ink); background: var(--border);
}
@media (prefers-reduced-motion: no-preference) {
  .donem-serit .ds-simdi::after { animation: ds-nabiz 2.8s ease-in-out infinite; }
}
@keyframes ds-nabiz {
  0%, 100% { opacity: .55; }
  50%      { opacity: 1; }
}

/* ── yapışkan konum şeridi ────────────────────────────────────────────── */
/* `hidden` ile `display: flex` ayni ozgullukte (0,1,0); tarayicinin
   `[hidden]{display:none}` kurali UA sayfasindan geldigi icin BURADAKI
   `display: flex` kazaniyor ve serit sayfanin tepesinde de goruluyordu.
   JS `hidden`i dogru kuruyordu — olcum "gizli: true" diyor, ekran aksini
   gosteriyordu. Ozniteligi acikca bagla. */
.konum[hidden] { display: none; }
.konum {
  position: sticky; top: var(--ust-y); z-index: 22;
  display: flex; align-items: center; gap: 8px;
  padding: 7px 16px;
  background: var(--paper); border-bottom: 1px solid var(--border);
  font-family: var(--ui); font-size: 12px; line-height: 1.3;
  /* Bir satır, taşarsa kesilir: iki satıra çıkıp metni aşağı itmesin. */
  white-space: nowrap; overflow: hidden;
}
/* VURGU TERS ÇEVRİLDİ.
   Alperen, 12 Eyl: "yukarıda hangi konuda olduğumuzun başlığı olabilir aşağı
   kaydırdıkça kayar... bu sayede neredeyim sorusuna cevap vermiş oluruz.
   bazen kayboluyorum çünkü."

   Şerit vardı ve çalışıyordu, ama vurgu yanlış yerdeydi: BÖLÜM adı koyu ve
   kalın, üstelik %45 genişlikte ve üç noktayla kesiliyordu ("The Basic
   elements of Python, Branching, Strings, Input, Iteration (Chapte…");
   KAVRAM adı ise soluk ve artan yerde duruyordu. Oysa "neredeyim"in cevabı
   kavram: bölüm sadece bağlam. Ağırlıklar yer değiştirdi ve yer kavrama
   verildi. */
.konum .kn-bol {
  color: var(--muted); font-weight: 400; text-decoration: none;
  flex: 0 1 auto; max-width: 30%; overflow: hidden; text-overflow: ellipsis;
}
.konum .kn-bol:hover { color: var(--accent); }
.konum .kn-kav {
  color: var(--ink); font-weight: 500; min-width: 0; flex: 1 1 auto;
  overflow: hidden; text-overflow: ellipsis;
}
.konum .kn-kav:not(:empty)::before {
  content: '›'; margin-right: 8px; color: var(--border-strong);
  font-weight: 400;
}
@media (max-width: 560px) {
  /* Dar ekranda bölüm adı yalnız NUMARAYA düşüyor: iki üç harflik bir
     kırpıntı ("The Bas…") hiçbir şey söylemiyor, numara söylüyor. */
  .konum .kn-bol { max-width: 4.2em; }
}
/* Menü açıkken şerit de kaysın: menü `position: fixed` ve 320 piksel yer
   kaplıyor, şerit tam genişlikte kaldığı için sol ucu menünün ALTINDA
   kalıyordu ("Derivatives…" yerine "…ules" görünüyordu). */
@media (min-width: 1180px) {
  .konum { transition: padding-left .22s cubic-bezier(.4,0,.2,1); }
  body.menu-acik .konum { padding-left: calc(var(--yan-g) + 16px); }
}

/* ── "bu hafta" (dizin sayfası) ───────────────────────────────────────── */
.bu-hafta {
  margin: 0 0 14px; padding: 11px 14px;
  border-left: 2px solid var(--accent);
  background: var(--vurgu-zemin);
  font-family: var(--ui); font-size: 13.5px; line-height: 1.5;
  color: var(--ink-2);
}
.bu-hafta b { color: var(--ink); font-weight: 600; }
.bu-hafta a { color: var(--accent); }

/* ── dizin kartında hafta ─────────────────────────────────────────────── */
.bk { grid-template-areas: "no ad" "no hf" "no say"; }
.bk-hf {
  grid-area: hf;
  font-family: var(--mono); font-size: 10.5px;
  letter-spacing: .04em; color: var(--muted);
}
.bk-simdi { background: var(--vurgu-zemin); }
.bk-simdi .bk-no { color: var(--accent); }
.bk-simdi .bk-hf { color: var(--accent); }

/* ── içindekiler: numara + hafta ──────────────────────────────────────── */
.icindekiler a.h2 {
  display: grid;
  grid-template-columns: 1.7rem minmax(0, 1fr) auto;
  gap: 0 8px; align-items: baseline;
}
.icindekiler a.h2 .tc-no {
  font-family: var(--mono); font-size: 10px; font-weight: 400;
  color: var(--muted);
}
.icindekiler a.h2 .tc-hf {
  font-family: var(--mono); font-size: 9.5px; color: var(--muted);
  letter-spacing: .03em;
}
.icindekiler a.h2.aktif .tc-no,
.icindekiler a.h2.aktif .tc-hf { color: var(--accent); }

/* ── çalışma modu ─────────────────────────────────────────────────────── */
.mod-serit {
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px;
  margin: 0 0 12px;
}
.mod-soru-et {
  font-family: var(--mono); font-size: var(--f-et);
  letter-spacing: .04em; text-transform: uppercase; color: var(--muted);
}
.mod-sec { display: flex; gap: 0; flex-wrap: wrap; }
.mod-sec button {
  font-family: var(--ui); font-size: 12px; cursor: pointer;
  padding: 6px 12px; color: var(--muted);
  background: transparent; border: 1px solid var(--border);
  margin-left: -1px;
}
.mod-sec button:first-child { margin-left: 0; border-radius: 7px 0 0 7px; }
.mod-sec button:last-child { border-radius: 0 7px 7px 0; }
.mod-sec button:hover { color: var(--accent); }
.mod-sec button[aria-pressed="true"] {
  background: var(--ink); border-color: var(--ink); color: var(--paper);
  position: relative; z-index: 1;
}

/* Sınav modu: hikâye, motive eden başarısızlık ve ispat gider; formül,
   hata, sınav sorusu kalır. Kavram anlatımı KALIR — sınava çalışan da
   neden öyle olduğunu sormak zorunda kalıyor. */
body.mod-sinav .hook,
body.mod-sinav .mf,
body.mod-sinav .kb-ispat,
body.mod-sinav .kapsama,
body.mod-sinav .kaynak-l,
body.mod-sinav .k-kopru { display: none; }

.sinav-rota {
  margin: 0 0 var(--b3); padding: 12px 14px;
  border: 1px solid var(--border); border-radius: 8px;
  background: var(--surface);
}
.sr-bas {
  display: block; margin-bottom: 8px;
  font-family: var(--mono); font-size: var(--f-et);
  letter-spacing: .04em; text-transform: uppercase; color: var(--muted);
}
.sr-bag { display: flex; flex-wrap: wrap; gap: 6px 8px; }
.sr-bag a {
  font-family: var(--ui); font-size: 12.5px;
  padding: 5px 10px; border-radius: 6px;
  background: var(--paper-soft); color: var(--ink-2); text-decoration: none;
}
.sr-bag a:hover { background: var(--accent); color: var(--paper); }
/* Modun NE YAPTIGINI soyleyen satir. 12 Eyl: sinav modu sayfanin %0,8'ini
   kaldiriyordu ve bunu kimse goremiyordu, cunku mod etkisini hic yazmiyordu.
   Artik kac cozumun kapandigini ve kac problemin denenmeyi bekledigini
   yaziyor; sayi sifirsa satir hic basilmiyor, yani yanlis guven vermiyor. */
.sr-not {
  display: block; margin-top: 8px;
  font-family: var(--mono); font-size: var(--f-et); color: var(--muted);
}

@media print { .konum, .donem-serit, .mod-serit, .sinav-rota { display: none !important; } }


/* ── kavram başlığı numarası ──────────────────────────────────────────── */
/* "3.2" — bölüm 3'ün ikinci kavramı. Okuma sütununun dışında durur ki
   metnin sol kenarı tek kalsın; dar ekranda başlığın önüne geçer. */
h3 .k-no {
  font-family: var(--mono); font-size: .55em; font-weight: 400;
  color: var(--muted); letter-spacing: .04em;
}
@media (min-width: 900px) {
  .anlatim h3 { position: relative; }
  .anlatim h3 .k-no {
    position: absolute; transform: translateX(calc(-100% - 0.8rem));
    top: .35em;
  }
}
@media (max-width: 899px) {
  h3 .k-no { display: block; margin-bottom: 2px; }
}

/* ── cevap bloğu ──────────────────────────────────────────────────────── */
/* Alperen: "answer kısmı falan çok sade yani ne olduğu belli değil".
   Önceki hâli yalnızca zemini hafifçe renklendiriyordu; çözümün SONUCU
   ile ara adımlar aynı ağırlıktaydı. Sol kenarda kalın yeşil çizgi, kendi
   payı ve bir tık büyük formül: göz çözümün sonunu arıyorsa buluyor. */
.c-son {
  margin-top: var(--b3);
  padding: var(--b2) var(--b2) var(--b2) calc(var(--b2) + 5px);
  background: rgba(44, 106, 76, .07);
  border-left: 3px solid var(--emerald);
  border-radius: 0 5px 5px 0;
}
.c-son > b { display: block; margin-bottom: 3px; }
.c-son .katex-display { margin: 0; }
.c-son .katex { font-size: 1.06em; }
html[data-tema="gece"] .c-son { background: rgba(88, 170, 130, .1); }


/* ── tek başına duran formül artık DISPLAY ───────────────────────────────
   Ölçüldü 22 Ağu, 390px, §14 tüm çözümler açık: 108 kutuda yatay kaydırma.
   65'i çözüm tablosunun matematik hücresi, 27'si yanlış/doğru kutusu,
   13'ü formül kartı. Hepsi satır içi (`blok=False`) basılıyordu ve KaTeX
   satır kırmayı YALNIZ display modda destekler — yani o formüller
   kırılamıyor, küçültülünce okunmaz oluyor, geriye kaydırma kalıyordu.

   Display'e çevrildiler. Display'in kendi dikey payı burada fazla: bunlar
   zaten kendi kutusunda, çevresinde başlık ve gerekçe var. */
.c-mat > .katex-display,
.fk-tex > .katex-display,
.kf-tex > .katex-display,
.h-yanlis > .katex-display,
.h-dogru > .katex-display { margin: 0; text-align: left; }
.c-mat > .katex-display > .katex,
.fk-tex > .katex-display > .katex,
.kf-tex > .katex-display > .katex,
.h-yanlis > .katex-display > .katex,
.h-dogru > .katex-display > .katex { text-align: left; }
/* Kırılan satırların hepsi sola dayansın: KaTeX display'i ortalar, kırılmış
   bir zincirde ortalanmış satırlar merdiven gibi görünüyor. */
.c-mat .katex-html > .base,
.fk-tex .katex-html > .base,
.kf-tex .katex-html > .base,
.h-yanlis .katex-html > .base,
.h-dogru .katex-html > .base { margin: 0; }

/* Künyedeki hafta, DÖNEMİN neresinde olduğumuza göre etiketleniyor:
   "this week" · "3 weeks ago" · "next week". İstemcide hesaplanıyor;
   build anında gömülse sayfa bir hafta sonra yanlış söylerdi. */
.ky-hf.simdi { color: var(--accent); }
.ky-ne {
  font-family: var(--ui); font-size: 11.5px; color: var(--muted);
  padding: 1px 7px; border-radius: 9px; background: var(--paper-soft);
}
.ky-hf.simdi + .ky-ne { background: var(--vurgu-zemin); color: var(--accent); }


/* ═══════════════════════════════════════════════════════════════════════
   BÖLÜM HARİTASI + KAVRAMIN ÖZÜ
   23 Ağustos 2026

   Alperen: "kapsam için azaltma, sadece özetle tarzı bir şey olursa
   bölümlerde isteyen kısa bakar" ve "bölümlerde odakları nerede olması
   gerektiğini ben bile karıştırıyorum".

   Bölüm KISALTILMADI. Üstüne, kavramların tamamını tek ekranda gösteren
   bir katman kondu. Her satırda kavramın adı değil NE İŞE YARADIĞI duruyor
   — başlık zaten adı söylüyordu, eksik olan buydu. Ağırlık satırın tonunu
   belirliyor: çekirdek koyu, ek okuma soluk. Ölçüldü: bölüm başına 5-7
   kavram, 3'ü çekirdek.
   ═══════════════════════════════════════════════════════════════════════ */

.harita {
  margin: 0 0 var(--b4);
  padding: var(--b2) 0 0;
  border-top: 1px solid var(--border);
}
.ha-bas {
  margin-bottom: var(--b2);
  font-family: var(--mono); font-size: var(--f-et);
  letter-spacing: .06em; text-transform: uppercase; color: var(--muted);
}
.ha-cek { color: var(--accent); }
.ha-liste { list-style: none; margin: 0; padding: 0; }
.ha {
  display: grid;
  grid-template-columns: 2.6rem minmax(0, 1fr);
  gap: 1px 12px;
  padding: 9px 0;
}
.ha + .ha { border-top: 1px solid var(--border); }
.ha > a {
  display: contents;             /* numara ve ad kendi ızgara hücrelerinde */
  color: inherit; text-decoration: none;
}
.ha-no {
  grid-column: 1; grid-row: 1 / span 2;
  font-family: var(--mono); font-size: 11px; color: var(--muted);
  padding-top: .25em;
}
.ha-ad {
  grid-column: 2;
  font-family: var(--baslik); font-size: 1.06rem; font-weight: 600;
  line-height: 1.3; color: var(--ink);
}
.ha:hover .ha-ad { color: var(--accent); }
.ha-oz {
  grid-column: 2;
  font-size: var(--f-yardim); line-height: 1.5; color: var(--muted);
}
/* Ağırlık = ton. Rozet değil: yedi satırın üçüne rozet takmak gürültü,
   koyuluk farkı aynı bilgiyi sessizce veriyor. */
.ha-core .ha-ad { color: var(--ink); }
.ha-core .ha-no { color: var(--accent); }
.ha-extra .ha-ad { color: var(--muted); font-weight: 500; }
.ha-extra .ha-oz { color: var(--border-strong); }

/* Kavramın özü, başlığın altında. */
.k-oz {
  margin: calc(var(--b1) * -1) 0 var(--b3);
  font-size: var(--f-yardim); line-height: 1.55; color: var(--muted);
}
.anlatim h3.k-core .k-no { color: var(--accent); }

/* Sınav modunda ek okuma kavramları haritada da geri planda kalsın. */
body.mod-sinav .ha-extra { opacity: .5; }
body.mod-soru .harita { display: none; }

@media print { .harita { break-inside: avoid; } }

/* Kâğıt sayısı: bu kavram kaç eski sınavda çıktı. Ağırlık etiketi de bundan
   türüyor (0 → extra, 1-2 → standard, 3+ → core). Sayının kendisi "önemli"
   demekten güçlü: öğrenci kendi kararını veriyor. */
.ha-ks {
  display: inline-block; margin-left: 7px;
  font-family: var(--mono); font-size: 10.5px;
  color: var(--muted); white-space: nowrap;
}
.ha-ks b { color: var(--accent); font-weight: 500; }
.ha-ks0 { color: var(--border-strong); }


/* ═══════════════════════════════════════════════════════════════════════
   AÇILABİLİRLİK VE ADIM AKIŞI · 23 Ağustos
   Alperen: "bazı yerlerde açılabilir şey olduğunu hissetmedim, sanki yazı
   gibi ama. aşağı ok ya da farklı bir şey faydalı olabilir." ve "işlemler
   lojik sırayla değil aniden beliriyor."

   Ölçüldü: bir bölümde 327 katlanabilir blok var; `summary::before` içeriği
   "+" ama rengi --border-strong, yani paletin en soluk grisi. Üstelik
   `summary` ile açılamayan blok başlıkları (RECALL FIRST, CHECKPOINT) aynı
   mono/uppercase/muted stilini paylaşıyor. Ekran görüntüsünde
   "+ SYLLABUS COVERAGE" ile "RECALL FIRST" ayırt edilemiyor.

   İkinci ölçüm: çözüm adımlarının numarası `@media (min-width: 1280px)`
   içindeydi, yani telefonda adımlar numarasız akıyordu.
   ═══════════════════════════════════════════════════════════════════════ */

/* ── açılabilir olan, açılabilir GÖRÜNSÜN ─────────────────────────────── */
:where(main.govde) summary {
  display: flex; align-items: baseline; gap: 9px;
  padding: 7px 11px;
  border: 1px solid var(--border);
  border-radius: 7px;
  background: var(--paper-soft);
  transition: border-color .13s, background .13s;
  list-style: none;
}
/* Üçgen: yön DURUMU söylüyor, sağa bakan kapalı, aşağı bakan açık. */
:where(main.govde) summary::before {
  content: ''; flex: 0 0 auto; align-self: center;
  width: 0; height: 0; margin-right: 1px;
  border-left: 5px solid currentColor;
  border-top: 4.5px solid transparent;
  border-bottom: 4.5px solid transparent;
  color: var(--muted);
  transition: transform .16s cubic-bezier(.4,0,.2,1);
}
/* ACIK HALDE UCGENIN USTUNE BIR `–` BASILIYORDU.
   Olculdu 12 Eyl gecesi (tarayicida, computed `content`): `notes_v2.css`'in
   ESKI `+`/`–` tasariminda kalan
   `:where(main.govde) details[open] > summary::before { content: '–' }`
   kurali AYNI ozgullukte ama bundle sirasinda ONCE geliyor (notes_v2 +
   notes_bolum) ve `content`i sonradan kimse geri almiyordu. Ucgenin 0x0
   kutusundan tasan en dash, donen ucgenin uzerine biniyordu: "ust uste"
   sikayetinin gorunen ikinci yarisi. Ucgen tasarimi METIN BASMAZ. */
:where(main.govde) details[open] > summary::before { content: ''; transform: rotate(90deg); }
:where(main.govde) summary:hover {
  border-color: var(--accent-soft, var(--border-strong));
  background: var(--surface);
}
:where(main.govde) summary:hover, :where(main.govde) summary:hover::before {
  color: var(--accent);
}
:where(main.govde) details[open] > summary {
  border-bottom-left-radius: 0; border-bottom-right-radius: 0;
  border-bottom-color: transparent; background: var(--surface);
}
/* Açık gövde, başlığıyla aynı kutunun devamı gibi dursun. */
:where(main.govde) details[open] > summary + * {
  border: 1px solid var(--border); border-top: 0;
  border-radius: 0 0 7px 7px;
  padding: 2px 11px 10px;
  margin-top: 0;
}

/* Çözüm adımı kutuları sayfada 124 tane; hepsine kutu çizmek gürültü olur.
   Onlar zaten açık geliyor ve kendi akış çizgileri var. */
:where(main.govde) details.o-adim > summary {
  border: 0; background: transparent; padding: 4px 0;
}
:where(main.govde) details.o-adim[open] > summary { background: transparent; }
:where(main.govde) details.o-adim[open] > summary + * {
  border: 0; padding: 0; border-radius: 0;
}
:where(main.govde) details.fl-ned > summary {
  border: 0; background: transparent; padding: 3px 0;
}
:where(main.govde) details.fl-ned[open] > summary + * { border: 0; padding: 0; }

/* ── adımların sırası HER ekranda görünsün ────────────────────────────── */
/* Numara 1280px'in altında da var; orada sola taşacak yer yok, o yüzden
   satırın başında duruyor ve adımları dikey bir çizgi bağlıyor. */
.c-tablo tbody > tr { position: relative; }
@media (max-width: 1279px) {
  .c-tablo tbody { padding-left: 26px; display: block; }
  .c-tablo tbody > tr { padding-left: 0; }
  .c-tablo tbody > tr::before {
    content: counter(adim);
    position: absolute; left: -26px; top: calc(var(--b2) + .15em);
    width: 18px; text-align: right;
    font-family: var(--mono); font-size: 10.5px;
    color: var(--muted);
  }
  /* Adımları birbirine bağlayan çizgi: akışın sürdüğünü gösteriyor. */
  .c-tablo tbody > tr:not(:last-child)::after {
    content: ''; position: absolute; left: -18px; top: calc(var(--b2) + 1.5em);
    bottom: -.4em; width: 1px; background: var(--border);
  }
  .c-tablo tbody > tr + tr { border-top: 0; }
}


/* ═══════════════════════════════════════════════════════════════════════
   İŞARETLEME VE NOT · 23 Ağustos
   Alperen: "istedikleri yeri işaretleme ve notlar kısmında eklemeyi de
   yapabilmeliyiz."

   Depo tarayıcıda (localStorage), sunucuya hiçbir şey gitmiyor. İşaret
   çapa + karakter ofseti olarak saklanıyor; sayfa yeniden üretilip metin
   değişirse işaret sessizce düşüyor — yanlış yere yapışmaktansa doğrusu bu.
   ═══════════════════════════════════════════════════════════════════════ */

/* ── seçim aracı ──────────────────────────────────────────────────────── */
.sec-arac {
  position: fixed; z-index: 75;
  display: flex; gap: 1px; padding: 3px;
  background: var(--ink); border-radius: 9px;
  box-shadow: var(--golge);
}
.sec-arac[hidden] { display: none; }
.sec-arac button {
  display: inline-flex; align-items: center; gap: 6px;
  font: inherit; font-family: var(--ui); font-size: 12px;
  padding: 6px 11px; cursor: pointer;
  color: var(--paper); background: transparent;
  border: 0; border-radius: 6px; white-space: nowrap;
}
.sec-arac button:hover { background: rgba(255,255,255,.14); }
.sa-ik {
  width: 11px; height: 11px; border-radius: 2px;
  background: var(--amber); opacity: .9;
}
.sa-ik.sa-not { background: transparent; border: 1.5px solid var(--paper); }

/* ── not yazma kutusu ─────────────────────────────────────────────────── */
.not-yaz {
  position: fixed; z-index: 76; left: 50%; bottom: 22px;
  transform: translateX(-50%);
  width: min(430px, calc(100vw - 28px));
  padding: 12px; border-radius: 11px;
  background: var(--surface); border: 1px solid var(--border-strong);
  box-shadow: var(--golge);
}
.not-yaz[hidden] { display: none; }
.not-yaz textarea {
  width: 100%; resize: vertical; box-sizing: border-box;
  font-family: var(--ui); font-size: 13.5px; line-height: 1.5;
  color: var(--ink-2); background: var(--paper);
  border: 1px solid var(--border); border-radius: 7px; padding: 9px 10px;
}
.ny-btn { display: flex; gap: 7px; margin-top: 9px; }
.ny-btn button {
  font: inherit; font-family: var(--ui); font-size: 12.5px; cursor: pointer;
  padding: 6px 14px; border-radius: 7px;
  border: 1px solid var(--border); background: transparent; color: var(--muted);
}
.ny-btn .birincil { background: var(--ink); border-color: var(--ink); color: var(--paper); }
.ny-btn button:hover { border-color: var(--accent); color: var(--accent); }
.ny-btn .birincil:hover { background: var(--accent); border-color: var(--accent); color: var(--paper); }

/* ── işaretin kendisi ─────────────────────────────────────────────────── */
mark.im {
  background: rgba(163, 100, 24, .17);
  color: inherit; padding: .05em 0; border-radius: 2px;
}
mark.im-not { border-bottom: 2px solid var(--amber); }
mark.im-vurgu { background: rgba(163, 100, 24, .42); transition: background .3s; }
html[data-tema="gece"] mark.im { background: rgba(214, 158, 74, .22); }

/* ── işaret sayacı ve panel ───────────────────────────────────────────── */
.notlarim-ac {
  position: fixed; right: 16px; bottom: 18px; z-index: 60;
  width: 38px; height: 38px; border-radius: 50%; cursor: pointer;
  background: var(--surface); border: 1px solid var(--border-strong);
  box-shadow: var(--golge); color: var(--ink);
  font-family: var(--mono); font-size: 12px;
}
.notlarim-ac[hidden] { display: none; }
.notlarim-ac:hover { border-color: var(--accent); color: var(--accent); }
.notlarim {
  position: fixed; right: 0; top: var(--ust-y); bottom: 0; z-index: 61;
  width: min(330px, 92vw); overflow-y: auto; overscroll-behavior: contain;
  background: var(--paper); border-left: 1px solid var(--border);
  padding: 12px 14px 30px;
}
.notlarim[hidden] { display: none; }
.nt-bas {
  display: flex; align-items: center; justify-content: space-between;
  margin-bottom: 10px;
  font-family: var(--mono); font-size: var(--f-et);
  letter-spacing: .05em; text-transform: uppercase; color: var(--muted);
}
.nt-kapa {
  font: inherit; font-size: 17px; line-height: 1; cursor: pointer;
  background: transparent; border: 0; color: var(--muted); padding: 0 3px;
}
.nt-kapa:hover { color: var(--accent); }
.nt-bos { font-family: var(--ui); font-size: 12.5px; color: var(--muted); line-height: 1.55; }
.nt-oge { padding: 11px 0; border-bottom: 1px solid var(--border); }
.nt-oge blockquote {
  margin: 0; padding-left: 9px; border-left: 2px solid var(--amber);
  font-family: var(--serif); font-size: 13px; line-height: 1.5; color: var(--ink-2);
}
.nt-not {
  margin: 7px 0 0; font-family: var(--ui); font-size: 12.5px;
  line-height: 1.5; color: var(--ink);
}
.nt-ara { display: flex; gap: 12px; margin-top: 7px; }
.nt-ara button {
  font: inherit; font-family: var(--mono); font-size: 10.5px; cursor: pointer;
  background: transparent; border: 0; padding: 0; color: var(--muted);
  letter-spacing: .04em;
}
.nt-ara button:hover { color: var(--accent); }

@media print { .sec-arac, .not-yaz, .notlarim, .notlarim-ac { display: none !important; } }
