/*
 * Boşluk uyumlama katmanı.
 *
 * KAPSAM: yalnızca dikey ritim. Tipografi, renk, fotoğraf ve bölüm hiyerarşisi
 * DEĞİŞTİRİLMEZ. Onaylı CSS dosyaları (style.css, blog.css, experience.css,
 * design-system.css) referanstan değiştirilmeden alındığı için düzeltmeler
 * burada toplanır.
 *
 * YÖNTEM: değerler uydurulmaz; design-system.css'teki --space-* belirteçleri
 * kullanılır. Negatif margin, !important, sabit yükseklik veya boş HTML
 * elemanı KULLANILMAZ.
 *
 * GEREKÇE: 26 sayfa 1440 / 768 / 390 px'te tarandı (olcek.mjs). Ölçüm, aynı
 * işlevdeki bileşenlerde farklı boşluklar olduğunu gösterdi; aşağıdaki
 * kurallar yalnızca o tutarsızlıkları kapatır. Onaylı tasarımın bilinçli
 * ritmi (ör. yazı gövdesindeki 42/46 px bölüm araları) KORUNUR.
 */

/* ── 1 · Ana sayfa ofis grubu ───────────────────────────────────────────
 * Ölçüldü (önce): etiket→başlık 16 · başlık→açıklama 24 · açıklama→adres 20
 * · adres→buton 0 (buton adrese yapışıktı).
 * Kök neden: `.office p + .button` kuralı butonun paragrafın KARDEŞİ olmasını
 * bekliyor; buton `<p>` içine sarılınca kural eşleşmiyordu. İşaretleme
 * düzeltildi (bkz. templates/bolum-ofis.php), kalan iki değer ölçeğe oturur.   */
/* Özgüllük notu: onaylı `.office .lead + p` kuralı (0,2,1) 20 px veriyor;
   aşağıdaki seçici (0,3,0) ondan güçlüdür. !important kullanılmaz,
   yalnızca margin ezilir — punto ve renk onaylı kuraldan gelmeye devam eder. */
.office .office-grid .office-address { margin-top: var(--space-3); }
.office .office-grid .office-address + .button { margin-top: var(--space-4); }

/* ── 2 · Numaralı satır bileşenleri ─────────────────────────────────────
 * `.principle-rows` (ofis ilkeleri), `.business-rows` (işletme gündemi) ve
 * `.policy-grid` (yayın ilkeleri) aynı işi görür: etiket + başlık + metin.
 * Ölçüldü: etiket→başlık 12 / 16 / 25 px, başlık→metin 12 / 16 px.
 * Üçü de ortak ritme bağlanır.                                                  */
.principle-rows article > span,
.business-rows article > span,
.policy-grid article > span { display: block; margin-bottom: var(--space-2); }

.principle-rows article h3,
.business-rows article h3,
.policy-grid article h3 { margin: 0 0 var(--space-2); }

.principle-rows article p,
.business-rows article p,
.policy-grid article p { margin: 0; }

/* ── 3 · Kaynak şeridi ──────────────────────────────────────────────────
 * Ölçüldü: başlık→metin 22 px; aynı kalıbın diğer örnekleri 24 px.            */
.resource-banner h2 + p { margin-top: var(--space-3); }

/* ── 4 · Bölüm girişindeki açıklama sütunu ──────────────────────────────
 * Ölçüldü: "İşletmenizin gündemi" girişinde açıklama paragrafı 127 px
 * genişliğe çöküyor ve satır başına 1–3 kelime düşüyordu.
 *
 * Kök neden: `.section-intro` bir flex satırıdır ve `justify-content:
 * space-between` kullanır. Paragrafa esneme verilmediği için genişliği
 * min-content'e iniyor; onaylı `.section-intro > .lead { max-width: 460px }`
 * kuralı ise yalnızca ÜST SINIR koyar, genişlik vermez.
 *
 * Düzeltme, o kuralın niyetini işler hâle getirir: paragraf 460 px'e kadar
 * büyür. Sabit yükseklik, kırpma veya punto küçültme kullanılmaz.                */
.section-intro > .lead { flex: 1 1 460px; }

/* `.office-scope` içinde giriş ZATEN dar bir ızgara sütunundadır (ölçüldü:
 * 507 px). Başlık ile açıklamayı orada yan yana koymak paragrafı 127 px'e
 * düşürüyordu. Bu bağlamda giriş dikey akar; başlık ve açıklama tam
 * genişliği kullanır.                                                            */
.office-scope .section-intro { flex-direction: column; gap: var(--space-3); }
.office-scope .section-intro > .lead { flex: 0 1 auto; max-width: 52ch; }

/* ── 5 · Sticky ofsetleri ve çapa payları: TEK KAYNAK ───────────────────
 * Ölçüldü: masaüstünde header 104 px, `.area-switcher` ise 80 px'te
 * duruyordu → şeridin 24 px'i başlığın altında kalıyor, "Alan değiştir"
 * düğmesinin ilk 13 px'i örtülüyordu.
 *
 * Kök neden: `body:has(.site-header.is-scrolled) .area-switcher { top:80px }`
 * kuralı, kaydırılınca header'ın 80 px'e ineceğini varsayıyor. Oysa
 * experience.css masaüstünde kaydırılmış header'ı da 104 px tutuyor;
 * yalnızca ≤899 px'te 80 px'e iniyor.
 *
 * ÇAPA PAYI tek yerde: `html { scroll-padding-top }`. Buna ek olarak
 * ögeye `scroll-margin-top` vermek TOPLANIR — onaylı dosyalardaki
 * 120/128/180 px'lik değerler kök dolgusuyla toplanıp çapaları gereğinden
 * çok aşağı indiriyordu (ölçüldü: bölüm 298 px'e düşüyordu). Bu yüzden
 * öge bazlı paylar sıfırlanır; yalnızca üstünde SABİT ŞERİT olan bölümler
 * şerit yüksekliği kadar ek pay alır.
 */
:root {
  --header-h: 104px;          /* ≥900px: tepe ve kaydırılmış hâl aynı */
  --serit-h: 66px;            /* .area-switcher yüksekliği */
  --sticky-pay: var(--space-2);
  --capa-pay: var(--space-3);
}
@media (max-width: 899px) {
  :root { --header-h: 80px; }
}

html { scroll-padding-top: calc(var(--header-h) + var(--capa-pay)); }

/* Sticky şeritler */
.area-switcher,
body:has(.site-header.is-scrolled) .area-switcher { top: var(--header-h); }

/* Sticky yan sütunlar: header + bir nefes payı */
.resources-visual,
.directory-visual,
.process-visual,
.legal-layout aside,
.article-toc { top: calc(var(--header-h) + var(--sticky-pay)); }

/* Öge bazlı paylar sıfırlanır; kök dolgusu zaten yeterli. */
.article-body > section,
.legal-copy > section,
.faq h2[id],
.area-detail .faq h2[id],
.area-detail .article-body > section { scroll-margin-top: 0; }

/* Üstünde sabit şerit olan bölümler yalnızca şerit kadar ek pay alır. */
.area-switcher ~ section[id],
.area-switcher ~ * section[id],
.area-switcher ~ section .faq h2[id] { scroll-margin-top: var(--serit-h); }

/* ── 6 · Kısa ekranda mobil menü ────────────────────────────────────────
 * Ölçüldü (844×390 yatay telefon): açılan menü 481 px yüksekliğinde,
 * alt kenarı 560 px'te. 390 px'lik görünür alanda "Kaynaklar" (425) ve
 * "İletişim" (489) ekran dışında kalıyor ve menünün kendi kaydırması yok.
 * Yatay taşma testi bunu yakalayamaz; dikey erişilebilirlik sorunudur.
 *
 * Çözüm: menü, header'ın altında kalan kullanılabilir yüksekliğe sınırlanır
 * ve gerektiğinde KENDİ İÇİNDE kaydırılır. Sabit yükseklik verilmez;
 * içerik kısaysa menü de kısa kalır.
 */
@media (max-width: 899px) {
  .site-header nav {
    max-height: calc(100svh - var(--header-h));
    overflow-y: auto;
    overscroll-behavior: contain;
    -webkit-overflow-scrolling: touch;
    padding-bottom: max(24px, env(safe-area-inset-bottom, 0px));
  }
  /* Dokunma hedefi: tüm menü bağlantıları en az 44 px */
  .site-header nav > a { min-height: 44px; display: flex; align-items: center; }
}

/* ── 7 · Aktif menü sayfası görünür olsun (T14) ─────────────────────────
 * `aria-current="page"` basılıyordu ama görsel karşılığı yoktu: bulunduğunuz
 * sayfa menüde diğerleriyle aynı görünüyordu.
 */
/**
 * D01 — Aktif kural CTA'yı da kapsıyordu.
 *
 * `.site-header nav > a[aria-current="page"]` seçicisi iletişim CTA'sını
 * (`a.button`) da yakalıyordu: yazı `--blue`, zemin de `--blue` → kontrast
 * **1,00:1** (ÖLÇÜLDÜ, /iletisim/ 1920 ve 1440). Ayrıca blok seviyesindeki
 * `::after` flex boşluğu üretip CTA genişliğini 140px'ten 169px'e
 * çıkarıyordu.
 *
 * `aria-current` KALDIRILMADI — doğru işaretleme. Kural `:not(.button)`
 * ile sınırlandı; CTA kendi renk çiftini açıkça tanımlar.
 */
.site-header nav > a:not(.button)[aria-current="page"] {
  color: var(--blue);
  font-weight: 700;
}
/* Mevcut alt çizgi `::after` olarak zaten var ve scaleX(0) ile duruyor;
 * aktif sayfada ikinci bir çizgi üretmek yerine aynı çizgi açılır. */
.site-header nav > a:not(.button)[aria-current="page"]::after {
  transform: scaleX(1);
}
@media (max-width: 899px) {
  /* Mobil menüde alt çizgi yerine sol şerit daha okunur */
  .site-header nav > a:not(.button)[aria-current="page"]::after { transform: scaleX(0); }
  .site-header nav > a:not(.button)[aria-current="page"] {
    border-left: 3px solid var(--blue);
    padding-left: 12px;
    margin-left: -15px;
  }
}

/**
 * Header CTA'sının renk çifti AÇIKÇA tanımlı: aktif sayfa olsun olmasın
 * aynı okunur durum. İkon `currentColor` kullanır, odak halkası korunur.
 */
.site-header nav > a.button,
.site-header nav > a.button[aria-current="page"] {
  color: #fff;
  background: var(--blue);
  border-color: var(--blue);
}
.site-header nav > a.button:hover,
.site-header nav > a.button:focus-visible,
.site-header nav > a.button[aria-current="page"]:hover,
.site-header nav > a.button[aria-current="page"]:focus-visible {
  color: #fff;
  background: var(--night);
  border-color: var(--night);
}
.site-header nav > a.button svg,
.site-header nav > a.button svg * { stroke: currentColor; }

/* ── 8 · Kart tıklanabilirliği (T12) ────────────────────────────────────
 * Hizmet kartının tamamı hover/active hareketi alıyordu ama yalnızca alttaki
 * bağlantı tıklanabilirdi; başlık ve ok hedef değildi. Kart bağlantısı tüm
 * yüzeyi kaplar (başlık ve ok dâhil), metin seçilebilir kalır.
 */
.service-card { position: relative; }
.service-card .card-link::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
}
.service-card .card-link:focus-visible::after {
  outline: 2px solid var(--blue);
  outline-offset: 4px;
}

/* ── 9 · Kart bağlantısının erişilebilir adı (V05) ──────────────────────
 * ÖLÇÜLDÜ: altı çalışma alanı kartının bağlantısı da "Detayları inceleyin"
 * adını taşıyordu. Ekran okuyucu bağlantı listesinde altısı ayırt edilemez.
 * Görünen metin değişmez; alan adı yalnız erişilebilirlik ağacına eklenir.
 */
.gorsel-gizli {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* ── 10 · Yazı girişi (V07 provası) ─────────────────────────────────────
 * ÖLÇÜLDÜ: eski sırada ana metne ulaşmak 1440'ta ekranın %123'ü, 390'da
 * %133'ü kadar kaydırma istiyordu; arada 425px'lik kapak vardı.
 * Yeni sırada kısa özet kapaktan önce gelir ve kapak alçalır.
 */
/* Giriş: masaüstünde özet ve fotoğraf YAN YANA, mobilde sıralı.
 *
 * Önceki provada kapak `max-height:27vh` + `object-fit:cover` ile
 * alçaltılıyordu; bu 16:9 fotoğrafı panoramik KESİYORDU. Artık giriş,
 * fotoğrafı yanına alarak kısalır — oran hiç bozulmaz.
 */
.article-intro-duo {
  display: grid;
  gap: var(--space-4);
  margin-top: var(--space-3);
  margin-bottom: var(--space-4);
  align-items: start;
}
.article-intro-duo .article-summary { margin: 0; }
.article-cover-oran { margin: 0; }
.article-cover-oran img { width: 100%; height: auto; }

@media (min-width: 900px) {
  .article-intro-duo { grid-template-columns: minmax(0, 1fr) minmax(0, 1.05fr); align-items: center; }
  /* Özet önce okunsun diye solda kalır; fotoğraf sağda oranıyla durur. */
}

/* V08 · yazı başlığı: "dev punto" yerine okunur bir ölçek.
 * ÖLÇÜLDÜ: h1 143px yer kaplıyordu; metnin kendisi değil ölçeği küçülür. */
/* D03 · yazı H1 istisnası, PROVA KAPSAMI DIŞINDAKİ yazılarda KORUNUR.
 *
 * İstisna tamamen kaldırılırsa prova dışındaki sekiz yazının görünümü de
 * değişir. Yayılım kabul edilene kadar eski hâlleri duruyor; prova
 * yazısında `design-system.css`'teki tek `--rol-h1` tokenı geçerli. */
body:not(.t-prova) .page-heading:has(+ .article-intro-duo) h1 { font-size: clamp(28px, 3.1vw, 42px); }

/* ── 11 · Mesaj önceliği (V08, yalnız prova bölümlerinde) ───────────────
 * ÖLÇÜLDÜ (ana sayfa, 1440): dekoratif slogan ile somut etiket aynı
 * ağırlıkta geliyordu — H2'lerin dördü de 48px. Anlatım sahnesinde slogan
 * 47,5px, onu açıklayan metin 14px: oran 3,4×.
 *
 * Metin DEĞİŞMEZ; yalnız ölçek ayrışır. Slogan bir kademe iner, açıklama
 * bir kademe çıkar. Hero ve diğer bölümler korunur.
 */
.story h2 { font-size: clamp(34px, 3.4vw, 48px); }
.motion-ready .story h2 { font-size: clamp(34px, 3.4vw, 48px); }
.story-step p { font-size: 16px; }
.story-step h3 { font-size: clamp(20px, 1.7vw, 24px); }

/* ── 12 · Sahne sığmıyorsa doğal akış (V04) ─────────────────────────────
 * `max-height` büyütmek kırpma SINIRINI kaldırmaz, yalnız öteler. Uzun
 * metin veya %200 yakınlaştırmada sahne sticky kalırsa içeriğin bir kısmı
 * erişilemez olur. app.js gerçek yüksekliği ölçer; sığmıyorsa bu sınıf
 * sahneyi normal akışa döndürür.
 */
.story.story-akis { height: auto; }
.story.story-akis .story-sticky { position: static; height: auto; }
.story.story-akis .story-inner { height: auto; }
.story.story-akis .story-step { opacity: 1; transform: none; }
.story.story-akis .story-step p { max-height: none; opacity: 1; margin-top: 12px; }
.story.story-akis .story-progress,
.story.story-akis .story-counter { display: none; }

/* Ölçüm anı: içeriğin DOĞAL yüksekliği.
 * `.story-inner` normalde `height:100%` olduğu için scrollHeight her zaman
 * ekran boyuna eşit çıkıyordu — kabı ölçüyordu, içeriği değil (ÖLÇÜLDÜ:
 * taban hep 900). Ölçüm sırasında yükseklik serbest bırakılır ve bütün
 * adımlar kapatılır; üstüne en uzun paragraf eklenir. */
.story.story-olcum-kapali .story-sticky,
.story.story-olcum-kapali .story-inner { height: auto; }
.story.story-olcum-kapali .story-step p { max-height: 0; margin-top: 0; }

@media (min-width: 900px) and (min-height: 680px) and (prefers-reduced-motion: no-preference) {
  .motion-ready .story-inner { padding-top: 80px; padding-bottom: 24px; }
  .motion-ready .story-image { max-height: 44vh; }
  .motion-ready .story-visual-yigin .story-kare,
  .motion-ready .story-visual-yigin picture { max-height: 44vh; }
}

@media (min-width: 900px) and (min-height: 680px) and (max-height: 859px) and (prefers-reduced-motion: no-preference) {
  .motion-ready .story-inner { padding-top: 72px; padding-bottom: 24px; }
  .motion-ready .story-image { max-height: 42vh; }
  .motion-ready .story-visual-yigin .story-kare,
  .motion-ready .story-visual-yigin picture { max-height: 42vh; }
}

#services-title,
#story-title,
#office-title,
#knowledge-title { font-size: clamp(34px, 3.4vw, 48px); line-height: 1.15; letter-spacing: -.035em; }
.services .section-intro { display: block; max-width: 760px; }

#cmplz-manage-consent > button.cmplz-manage-consent { display: none !important; }

/* ── 13 · İletişim formu alanlarında iOS yakınlaştırma eşiği (T16) ──────
 * iOS Safari, odaklanılan form alanının punto değeri 16px'in ALTINDAYSA
 * sayfayı kendiliğinden yakınlaştırır ve odak bırakılınca eski ölçeğe
 * dönmez. Dört görünür alan 15px'ti (ÖLÇÜLDÜ): ziyaretci-ad,
 * ziyaretci-eposta, gorusme-konusu, ziyaretci-mesaj.
 *
 * Yalnız alan METNİ 16px'e çıkar. Etiketler (12px), butonlar ve genel
 * tipografi DEĞİŞMEZ. Kullanıcı yakınlaştırması engellenmez — viewport'a
 * `maximum-scale` veya `user-scalable=no` EKLENMEZ; bu erişilebilirliği
 * bozar ve sorunun çözümü değildir.
 *
 * Not: Bu kaynak bulgusudur. Gerçek iPhone/Safari doğrulaması T16 kapsamında
 * AYRI yapılacaktır; bu değişiklik T16'yı kapatmaz.
 */
.form-fields input,
.form-fields select,
.form-fields textarea { font-size: 16px; }

/* ── 14 · Arama kutularında iOS yakınlaştırma eşiği (T16) ───────────────
 * Aynı 16px eşiği düzenlenebilir iki arama alanı için de geçerlidir:
 * bilgi merkezinin yerinde filtresi (#blog-query) ve site araması
 * (#site-arama). İkisi de 14px'ti (ÖLÇÜLDÜ).
 *
 * Yalnız bu iki alanın METNİ büyür. Etiket, buton, sonuç sayacı ve genel
 * tipografi değişmez; viewport'a dokunulmaz.
 */
#blog-query,
#site-arama { font-size: 16px; }

/* ── 15 · Anlatım: adım başına görsel (V3) ──────────────────────────────
 * Üç adım üç ayrı kavram anlatıyor; her birinin kendi görseli olabilir.
 * Görsel yoksa bölümün ortak görseli kullanılır ve bu blok hiç basılmaz.
 *
 * Masaüstü sahnesinde kareler üst üste yığılır ve opaklıkları KAYDIRMA
 * İLERLEMESİNDEN hesaplanır (zamana bağlı geçiş yok; ileri/geri scrub'da
 * aynı ilerleme aynı görüntüyü verir).
 *
 * Mobilde ve azaltılmış harekette yığın gizlenir; her adım kendi
 * görselini doğal akışta gösterir.
 */
/* VARSAYILAN: yığın GİZLİ.
 * Önceki hâlde yığın varsayılan olarak görünürdü; `.motion-ready` ve
 * `story-akis` sınıfları JS ile SONRADAN geldiği için tarayıcı o ana kadar
 * her iki kümeyi de indiriyordu (ÖLÇÜLDÜ: 1280@2x → 6 dosya).
 * Artık yığın yalnız sahne gerçekten etkinken açılır. */
.story-visual-yigin { position: relative; display: none; }
.story-visual-yigin .story-kare { grid-area: 1 / 1; }
.story-adim-gorsel { margin: 16px 0 0; }
/**
 * ORAN KORUNUR. `object-fit: fill` bir güvence değildir: kutu oranı
 * kaynaktan farklıysa görseli ESNETİR. Panelden ileride 4:3 olmayan bir
 * görsel seçilebileceği için davranış açıkça yazılır — `height:auto` ile
 * doğal oran, `contain` ile de kırpma/esnetme yok.
 */
.story-adim-gorsel img {
  width: 100%;
  height: auto;
  object-fit: contain;
  border-radius: 14px;
}
/* Ortak sahne görseli (adım görseli yoksa kullanılır) de esnemesin. */
.story-visual > picture > .story-image,
.story-visual-yigin .story-image { height: auto; object-fit: contain; }

@media (min-width: 900px) and (min-height: 680px) and (prefers-reduced-motion: no-preference) {
  .motion-ready .story:not(.story-akis) .story-visual-yigin { display: grid; }
  .motion-ready .story-visual-yigin .story-kare { opacity: 0; will-change: opacity; }
  .motion-ready .story-visual-yigin .story-kare.is-active { opacity: 1; }
  /* Sahnede adım içi kopya gizlenir — görsel üstteki yığından gelir. */
  .motion-ready .story:not(.story-akis) .story-adim-gorsel { display: none; }
}

/* Doğal akışta (mobil, azaltılmış hareket, sığmayan sahne) yığın gizli. */
/* Doğal akışta ve mobilde zaten gizli (varsayılan). */
.story.story-akis .story-visual-yigin { display: none !important; }

/* ── 16 · Harita paneli: izin öncesi konum kartı ────────────────────────
 * İzin verilmeden önce harita YERİNE adresin kendisi gösterilir. Kullanılan
 * tek grafik, temada gömülü SVG konum imidir: harita görüntüsü taklit
 * edilmez, sokak/rota/koordinat çizilmez ve sağlayıcıya istek gitmez.
 *
 * `.map-placeholder` flex sütundur (design-system.css); kart ve karar
 * bloğu onun iki öğesi olarak akar.
 */
.map-placeholder { align-items: stretch; }

/* Geniş ekranda kart ve karar bloğu yan yana: tek sütunda kart ekran
 * genişliğine yayılıp şerit gibi görünüyordu (1440'ta 1214px ölçüldü). */
@media (min-width: 900px) {
  .map-placeholder { flex-direction: row; align-items: center; gap: var(--space-4); }
  .map-placeholder > .konum-karti { flex: 0 1 380px; } /* içerik yüksekliği: stretch boş alan bırakıyordu */
  .map-placeholder > .map-karar { flex: 1 1 0; }
  .map-placeholder > .map-onizleme { flex: 0 1 380px; }
}

.konum-karti {
  display: flex; gap: var(--space-2); align-items: flex-start;
  width: 100%; box-sizing: border-box;
  padding: var(--space-3);
  background: #fff;
  border: 1px solid var(--line);
  border-radius: 16px;
}
.konum-im {
  flex: 0 0 auto;
  display: inline-flex; align-items: center; justify-content: center;
  width: 42px; height: 42px; border-radius: 12px;
  background: var(--ice); color: var(--blue);
}
.konum-govde { min-width: 0; }
.konum-govde .eyebrow { margin: 0 0 6px; }
.konum-govde .text-link { margin-top: var(--space-2); }

.map-adres { font-style: normal; margin: 0; color: var(--ink); }
.map-adres p { margin: 0 0 4px; }
.map-adres p:last-child { margin-bottom: 0; }

/* Karar bloğu: başlık, açıklama ve düğmeler. */
.map-karar { display: flex; flex-direction: column; align-items: flex-start; gap: var(--space-2); }
.map-karar h3 { margin: 0; }
.map-karar p { margin: 0; }

/* Panele gerçek fotoğraf yüklenirse kartın üstünde durur. */
.map-onizleme { margin: 0; width: 100%; }
.map-onizleme img { width: 100%; height: auto; border-radius: 14px; display: block; }

@media (max-width: 599px) {
  .konum-karti { padding: var(--space-2); }
  .konum-im { width: 38px; height: 38px; }
}
