/* ============================================================================
   Contact.css — YALNIZ /iletisim
   Şablon: Pages/Site/Contact.html · Davranış: Js/Site/Contact.js

   Features / Categories / Growth / Sleep / Pricing / Faq'in kurduğu desen:
   sayfaya özel kurallar sayfaya özel dosyada yaşar, Site.css'e bir satır bile
   eklenmez. Bu dosya Site.css'in §18 ("İletişim"), §18c ("Etkinlik Öner") ve
   `.aside-*` bloklarının yerini aldı — üçü de HER SAYFAYA iniyordu ama yalnız
   burada geçiyordu. Oraya `.cx-*` kuralı GERİ EKLENMEZ.

   TASARIM FİKRİ — SAYFADA TEK YÜZEY VAR: FORM PANELİ.
   İlk sürümde sol kolon üç özdeş yuvarlak kutunun istifiydi (e-posta · SSS ·
   ekip) ve sağdaki panelle aynı ağırlıkta okunuyordu: sayfa "hangisi asıl
   yüzey?" diye soruyordu, cevabı da yoktu. Bugün sol kolon KUTUSUZ — iki
   kılcal bağlantı satırı ve tek sıcak imza notu. Ağırlık tek bir yerde
   toplanınca hiyerarşi renkten ya da puntodan değil, YÜZEY SAYISINDAN geliyor.
   (Aynı gerekçe hero'daki "dolu blok sayısı" kuralında da geçiyor.)

   TASARIM SİSTEMİNDEN NE ÖDÜNÇ ALINDI: token'ların tamamı, `.eyebrow`,
   `.container`, `.btn`/`.btn-primary`, `fadeUp` ve
   `orbFloat` keyframe'leri, `.hero`nun "tam bir ekran" tekniği ve ajax takas
   kabı (`.af-swap` / `.af-result`, Site.css §33). Yeni font yok, yeni
   kütüphane yok, yeni görsel varlık yok, yeni renk ailesi yok.

   İÇİNDEKİLER
     1) Sahne: tam bir ekran + atmosfer
     2) Sol kolon: kopya, kılcal bağlantı satırları, maskotlu imza
     3) Sağ kolon: panel + amaç seçicisi (tablist)
     4) Form alanları + alan altı hata
     5) Sonuç mesajları (ajax + sunucu render'ı)
     6) Sıralı giriş
     7) Responsive
     8) prefers-reduced-motion
============================================================================ */

/* ----------------------------------------------------------------------------
   1) Sahne

   SAHNE TAM BİR EKRANDIR — ana sayfanın hero'sundaki teknik (`Site.css` §5),
   aynı üç gerekçeyle:
   - `100svh`, `vh` DEĞİL: mobilde adres çubuğu açıkken `100vh` viewport'tan
     büyüktür ve sahne ekrana sığmaz.
   - `align-content: safe center`, düz `center` DEĞİL (yedek olarak önce
     yazılır): içerik ekrandan uzun olduğunda düz `center` negatif boşluğu iki
     yana taşırıp sahnenin TEPESİNİ navbar'ın altında bırakır — kaydırarak da
     ulaşılamayan bir alan. `safe` o durumda `start`a döner.
   - Sabit dolgulu hâlinde sahne ekranın üst yarısına yapışıyor ve altında bir
     ekran boyu ölü bant kalıyordu (1440×900'de ölçüldü: içerik ~800px'te
     bitiyor, bölüm 1435px sürüyordu).

   ÜST DOLGUYA `--nav-h` DAHİLDİR. Navbar `position: fixed`, yani sayfa
   akışında hiç yer kaplamıyor ve bölüm `top: 0`dan başlıyor
   (Kategoriler/Gelişim/Uyku/Fiyatlandırma hero'larındaki aynı tuzak).
---------------------------------------------------------------------------- */
.cx {
  position: relative; overflow: hidden;
  display: grid;
  align-content: center;
  align-content: safe center;
  min-height: 100svh;
  padding: calc(var(--nav-h) + clamp(24px, 3.4vw, 48px)) 0 clamp(40px, 5vw, 72px);
}
.cx-bg { position: absolute; inset: 0; pointer-events: none; }

/* Renk yıkamaları — çok düşük alfa, çok geniş yarıçap. Bilgi taşımazlar,
   DERİNLİK taşırlar: onlarsız sayfa düz bir krem dikdörtgen.
   İkisi de KENARLARDA durur ve metnin altına girmez (`gx-blob` kuralı);
   girseydi gövde metninin AA payını sessizce yerdi. */
.cx-wash {
  position: absolute; border-radius: 50%;
  filter: blur(30px);
}
.cx-wash--1 {
  width: min(46vw, 620px); aspect-ratio: 1;
  top: -18%; right: -12%;
  background: radial-gradient(circle, color-mix(in oklch, var(--blue) 34%, transparent), transparent 66%);
  opacity: .5;
}
.cx-wash--2 {
  width: min(38vw, 500px); aspect-ratio: 1;
  bottom: -22%; left: -14%;
  background: radial-gradient(circle, color-mix(in oklch, var(--violet) 26%, transparent), transparent 66%);
  opacity: .38;
}
[data-theme="dark"] .cx-wash--1 { opacity: .34; }
[data-theme="dark"] .cx-wash--2 { opacity: .28; }

/* Kopya solda, form sağda. Form kolonu bilerek GENİŞ: baş rol formun — sayfaya
   gelen ziyaretçi zaten yazmak için geliyor, sol kolon onu doğru kanala
   yönlendiriyor. `minmax(0, …)` şart: `min-width: auto` olan bir ızgara öğesi
   uzun bir e-posta adresiyle satırı taşırır. */
.cx-in {
  position: relative; z-index: 1;
  display: grid;
  grid-template-columns: minmax(0, .88fr) minmax(0, 1.12fr);
  /* SATIR ARALIĞI SIFIR, sütun aralığı eskisi gibi: sol kolonun iki satırı
     arasındaki boşluğu maskotun taşma payını da kapsayan `.cx-team`in kendi
     `margin-top`u verir (aşağıda). `gap` kısayolu yazılırsa o boşluk iki kez
     eklenir ve maskot kartın üstünde havada asılı kalır. */
  column-gap: clamp(30px, 4.4vw, 64px);
  row-gap: 0;
  /* ARTAN BOŞLUK İKİNCİ SATIRA GİDER. Sağdaki panel iki satırı birden kaplıyor
     ve sol kolondan uzun; satırlar tanımlanmazsa ızgara o farkı kapsanan iki
     satıra EŞİT böler, yani birinci satır (tanıtım) şişer ve güven notu
     masaüstünde 29px aşağı kayar. `auto 1fr` farkın tamamını ikinci satıra
     verir; kart `align-items: start` ile satırın tepesinde kalır. */
  grid-template-rows: auto 1fr;
  align-items: start;
}

/* ---- 2b) SOL KOLON İKİ SATIR, sağdaki panel ikisini birden kaplar ----------
   Güven notu DOM'da formun ARKASINDA duruyor (gerekçe Contact.html'de: mobilde
   tek kolona inince sıra DOM'dan gelir ve o kart formu 217px aşağı itiyordu).
   Masaüstündeki yeri buradan, AÇIK IZGARA KOORDİNATIYLA geri veriliyor — bu
   `order` DEĞİL: `order` görsel sırayı odak sırasından ayırır, ızgara
   koordinatı ise yalnız kutunun nereye yerleşeceğini söyler ve taşınan blokta
   odaklanabilir hiçbir öğe yok. Koordinatlar yazılmazsa otomatik yerleşim
   `.cx-team`i panelin ALTINA, ikinci satırın ilk boş hücresine atar. */
.cx-intro { grid-column: 1; grid-row: 1; }
.cx-team  { grid-column: 1; grid-row: 2; }
.cx-panel { grid-column: 2; grid-row: 1 / span 2; }

/* ----------------------------------------------------------------------------
   2) Sol kolon

   BAŞLIĞIN PUNTOSU ELLE YAZILIR. Taban `h1` kuralı yalnız aile/ağırlık/satır
   verir, ÖLÇÜ vermez; yazılmazsa tarayıcının 2em varsayılanı geçerli olur ve
   başlık masaüstünde 34px'te kalır — iki kolonlu bir sahnede kopya baş roldür,
   küçük başlık sağdaki paneli yalnız bırakır. Tavan `.page-hero`nun ÜSTÜNDE:
   sayfanın tek başlığı bu ve sahnenin ağırlık merkezi o.
---------------------------------------------------------------------------- */
/* Kopya bir tık aşağıda başlar: başlığın optik merkezi sağdaki sekme şeridiyle
   hizalanır. İki kolonun tepeden birebir hizalandığı hâli "iki sütun" gibi
   okunuyordu, sahne gibi değil. */
.cx-intro { padding-top: clamp(0px, 2.2vw, 30px); }
.cx-intro h1 {
  margin: 12px 0 16px;
  font-size: clamp(2.15rem, 4.9vw, 3.35rem);
  line-height: 1.06; letter-spacing: -.025em; text-wrap: balance;
}
.cx-lead {
  margin: 0 0 clamp(26px, 3.4vw, 40px);
  font-size: var(--fs-2xl); color: var(--tx2);
  max-width: 32em;
}

/* ---- Doğrudan kanallar: KILCAL SATIRLAR ----
   Kutu yok. Satırın TAMAMI bağlantı; ayrımı `1px solid var(--border)` kılcal
   çizgi verir (renkli aksan şeridi YASAK). Etiket küçük ve aksiyon renginde,
   DEĞER büyük ve başlık ailesinde: e-posta adresi sayfadaki tek "veri" ve
   burada bir tasarım öğesi olarak duruyor. */
/* ALT BOŞLUK YOK, ve bu bilinçli. Kanal listesi artık sol kolonun SON öğesi
   (güven notu `.cx-in`e taşındı, §2b). Buraya bir alt marj yazılırsa aşağıdaki
   iki komşunun boşluğuna EKLENİR — kardeş marjları birleşirken ızgara
   öğelerininki birleşmez — ve masaüstünde güven notu 56px aşağı kayar. Bir kez
   oldu; yalnız ölçümde görüldü, ekran görüntüsünde "biraz boşluk" gibi duruyor.
   Aradaki mesafeyi kimin verdiği tek yerde yazılı: masaüstünde `.cx-team`in
   maskot payını kapsayan `margin-top`u, mobilde `.cx-panel`inki (§7). */
.cx-ways { list-style: none; margin: 0; padding: 0; }
.cx-ways li { border-top: 1px solid var(--border); }
.cx-ways li:last-child { border-bottom: 1px solid var(--border); }

.cx-way {
  position: relative;
  display: grid; grid-template-columns: minmax(0, 1fr) auto;
  align-items: center; gap: 2px 16px;
  min-height: 46px;             /* WCAG 2.5.8 — ölçü min-height ile, dolguyla DEĞİL */
  padding: clamp(14px, 1.6vw, 20px) 0;
  color: var(--tx1);
  transition: padding-left var(--t-sm) ease;
}
/* Hover'da satır sağa kayar ve altında ince bir ilerleme çizgisi doğar.
   Çizgi DEKORASYON DEĞİL, geri bildirim: yalnız etkileşimde var, nötr değil
   aksiyon renginde ve `transform: scaleX` ile büyüdüğü için düzeni hiç
   değiştirmiyor. */
.cx-way::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: -1px; height: 1px;
  background: var(--btn-tx);
  transform: scaleX(0); transform-origin: left;
  transition: transform var(--t) cubic-bezier(.22,.61,.36,1);
}
.cx-way:hover { padding-left: 10px; }
.cx-way:hover::after, .cx-way:focus-visible::after { transform: scaleX(1); }

.cx-way-k {
  display: flex; align-items: center; gap: 8px;
  font-family: var(--font-head); font-size: var(--fs-sm); font-weight: 800;
  letter-spacing: .04em; color: var(--btn-tx);
}
.cx-way-k i { font-size: 1.02em; opacity: .82; }
/* Uzun e-posta adresi dar kolonda satırı taşırmasın. */
.cx-way-v {
  font-family: var(--font-head); font-weight: 700;
  font-size: clamp(1.06rem, 1.5vw, 1.3rem);
  color: var(--tx1); overflow-wrap: anywhere;
}
.cx-way-v--sm {
  font-family: var(--font-body); font-weight: 600;
  font-size: var(--fs); color: var(--tx2); max-width: 30em;
}
/* `grid-column` AÇIKÇA YAZILIR. Yalnız `grid-row` verildiğinde otomatik
   yerleşim satırı sabit olan öğeyi ÖNCE ve o satırın İLK boş kolonuna koyar:
   ok birinci kolona düşüyor, etiket ile değer de sağa itiliyordu (Gelişim
   kartlarındaki chevron'un birebir aynı tuzağı). */
.cx-way-go {
  grid-column: 2; grid-row: 1 / span 2; align-self: center;
  color: var(--tx3);
  transition: transform var(--t-sm) ease, color var(--t-sm) ease;
}
.cx-way:hover .cx-way-go { color: var(--btn-tx); transform: translateX(4px); }

/* ---- Maskotlu imza ----
   Sol kolonun TEK yüzeyi, ve hak ediyor: sayfanın insan anı burası. Üstündeki
   iki satır bilgi verir, bu blok "karşında biri var" der — o yüzden ton da
   sıcak (mavi tint), ötekiler nötr.

   MASKOT SERBEST DURUR — sitedeki diğer ikisiyle (`.steps-mascot`,
   `.trust-explain-kido`) aynı dil: zemin/kenarlık kutusu yok, derinliği yalnız
   `drop-shadow` verir, kartın ÜST kenarından taşarak bakar. İki tuzak:
   - Kabında `overflow: hidden` OLAMAZ; eklenirse maskot `orbFloat` ile
     süzülürken kesilir.
   - Üst boşluk `top`un mutlak değerini + süzülme payını (11px) KAPSAMAK
     zorunda, yoksa maskot bir üstteki öğenin köşesine biner. İlk sürümde tam
     olarak bu oldu ve yalnız ekran görüntüsünde görüldü. */
.cx-team {
  position: relative;
  margin-top: clamp(74px, 7.5vw, 92px);
  padding: 30px 26px 24px;
  border: 1px solid var(--border);
  border-radius: var(--r-xl);
  /* Tint sRGB'de değil OKLCH'de karılır: sRGB'de açık uçta mavi chroma'sını
     kaybedip griye kaçar ve kutu "soluk/klinik" okunur (`.cta-box`taki aynı
     ölçüm). Oran bir TAVAN — %12'de gövde metni (`--tx2`) zemine karşı 4.68:1,
     yani AA sınırının hemen üstünde. */
  background: color-mix(in oklch, var(--blue) 12%, var(--card-solid));
  box-shadow: var(--shadow), var(--edge);
}
/* KOYU TEMADA NÖTR KART YÜZEYİ (kullanıcı kararı, 2026-08-26). Blok bir dönem
   kapanış kutusunun tavanını (%20 OKLCH mavi tint + `--cta-surface`) paylaşıyordu;
   gerekçe "sayfanın tek sıcak yüzeyi kardeşi olduğu .cta-box'tan ayrışmasın"dı.
   Gece zemininde bedeli görünür: mor-mavi bir kutu, sayfanın nötr lacivert kart
   ailesinin (`--card`) yanında **başka bir yerden gelmiş** okunuyordu — üstelik
   /iletisim `ctaBand` çağırmıyor, yani ayrışmayacağı kardeş bu sayfada YOK.
   AÇIK TEMA DEĞİŞMEDİ: orada tint kutuyu krem zeminden ayıran şeyin kendisi ve
   %12 ölçülmüş tavan (gövde metni 4.68:1). */
[data-theme="dark"] .cx-team { background: var(--card); }
.cx-team-kido {
  position: absolute; z-index: 2;
  top: -68px; right: 20px;
  width: 92px; height: 92px;
  display: grid; place-items: center;
  pointer-events: none;
  animation: orbFloat 5.5s ease-in-out infinite;
}
.cx-team-kido img {
  width: 100%; height: 100%; object-fit: contain;
  filter: drop-shadow(0 7px 12px rgba(36, 55, 105, .24));
}
.cx-team b {
  display: block; margin-bottom: 6px;
  font-family: var(--font-head); font-size: var(--fs-2xl); color: var(--tx1);
  text-wrap: balance;
}
.cx-team p { margin: 0; font-size: var(--fs); color: var(--tx2); }

/* ----------------------------------------------------------------------------
   3) Sağ kolon: form paneli + amaç seçicisi

   SAYFANIN TEK GERÇEK YÜZEYİ. Düz dolgu yerine ince bir geçiş taşır
   ("yukarıdan aydınlatılmış" kenar, `--edge`in devamı) ve altında rengini
   yıkamalardan alan bir hale var — panel sayfanın üstünde DURUYOR, üstüne
   çizilmiş değil. Düz `--card` hâlinde krem zeminde "boyanmış bir dikdörtgen"
   okunuyordu (özellik turu panelindeki aynı gerekçe).
---------------------------------------------------------------------------- */
.cx-panel {
  position: relative;
  padding: clamp(22px, 2.8vw, 34px);
  border: 1px solid var(--border);
  border-radius: var(--r-xl);
  background: linear-gradient(168deg,
              var(--card-solid) 0%,
              color-mix(in oklch, var(--blue) 5%, var(--card-solid)) 100%);
  box-shadow:
    var(--shadow-lg),
    var(--edge),
    0 44px 90px -56px color-mix(in srgb, var(--blue) 70%, transparent);
}
[data-theme="dark"] .cx-panel {
  background: linear-gradient(168deg,
              var(--card-solid) 0%,
              color-mix(in oklch, var(--blue) 15%, var(--card-solid)) 100%);
}

/* Etiket bir FORM ETİKETİDİR, ikinci bir başlık değil: `--fs-xl` kalın hâli
   soldaki h1 ile yarışıyor ve panel "kendi sayfası" gibi başlıyordu. */
.cx-purpose { margin-bottom: clamp(16px, 2vw, 22px); }
.cx-purpose-l {
  display: block; margin-bottom: 9px;
  font-family: var(--font-head); font-weight: 800;
  font-size: var(--fs-sm); letter-spacing: .05em;
  color: var(--tx3);
}

/* SEÇİCİ JS'E BAĞLIDIR, o yüzden `.cxjs` olmadan HİÇ ÇİZİLMEZ: tıklanınca
   hiçbir şey yapmayan bir sekme sahte butondur (Uyku sayfasındaki ölü oynat
   üçgeninin aynı kuralı). JS yokken iki form da açık okunur ve ayrımı
   `.cx-pane-h` başlıkları taşır. */
.cx-tabs { display: none; }
.cxjs .cx-tabs {
  display: grid; grid-template-columns: 1fr 1fr;   /* İKİ EŞİT GENİŞLİKTE BUTON */
  gap: 5px; padding: 5px;
  border-radius: calc(var(--r) + 4px);
  /* Şerit OYUK okunur, seçili sekme onun üstünde YÜZER: seçimi anlatan şey
     renk değil YÜKSEKLİK farkı. */
  background: color-mix(in srgb, var(--blue) 9%, transparent);
  box-shadow: inset 0 1px 3px rgba(20, 35, 80, .07);
}
[data-theme="dark"] .cxjs .cx-tabs { box-shadow: inset 0 1px 3px rgba(0, 0, 0, .35); }
.cx-tab {
  display: flex; align-items: center; justify-content: center; gap: 8px;
  min-width: 0;                 /* uzun etiket ızgarayı taşırmasın */
  min-height: 46px;             /* WCAG 2.5.8 */
  padding: 8px 10px;
  border: 0; border-radius: var(--r);
  background: transparent; cursor: pointer;
  font-family: var(--font-head); font-size: var(--fs); font-weight: 800;
  line-height: 1.25; text-align: center;
  color: color-mix(in srgb, var(--btn-tx) 78%, var(--tx1));
  transition: background var(--t-sm) ease, color var(--t-sm) ease,
              box-shadow var(--t-sm) ease, transform var(--t-sm) ease;
}
.cx-tab i { font-size: .96em; }
.cx-tab:hover:not([aria-selected="true"]) { color: var(--btn-tx); }
/* `aria-selected` TEK DURUM KAYNAĞI: görünüm ondan türer, ayrı bir `is-active`
   sınıfı yok — iki kaynak sessizce ayrışır (Gelişim'in `gx-tab` kararı). */
.cx-tab[aria-selected="true"] {
  background: var(--card-solid); color: var(--btn-tx);
  box-shadow: 0 6px 16px -8px rgba(10, 24, 55, .55), var(--edge);
  transform: translateY(-1px);
}
/* KOYU TEMADA MÜREKKEP DE ÇEVRİLİR. Açık temada seçilinin rengi `--btn-tx`
   (koyu mavi) ve beyaz zeminde en ağır okunan o; gece zemininde aynı token
   komşusundan DAHA SÖNÜK kalır, yani hiyerarşi tersine döner. Zemin farkı tek
   başına yetmiyor — ikisi de aynı lacivert ailesinden. */
[data-theme="dark"] .cx-tab[aria-selected="true"] {
  background: color-mix(in srgb, var(--blue) 30%, var(--card-solid));
  color: var(--tx1);
}

/* PANEL GİZLEME `.cxjs` ÖN EKLİ, ve bu bir tercih değil şart: gizleme
   şablondaki bir `hidden` özniteliğiyle yazılsaydı JS kapalı ziyaretçide
   ikinci form KALICI olarak kapalı kalırdı — sekmesi de çizilmediği için
   açılabilecek hiçbir yol olmadan. (Tam olarak bir kez oldu; JS'i kapalı
   tarayıcıda yakalandı.) `.cxjs` sınıfını gövdeden ÖNCE senkron çalışan bir
   satır yazdığı için JS varken de "önce ikisi birden görünüp sonra biri
   kapanan" bir zıplama olmaz.

   Durum tek çağrıdan gelir (Contact.js `select()`): sekmede `aria-selected`,
   panelde `is-open`. */
.cx-pane { display: grid; }
.cxjs .cx-pane { display: none; }
.cxjs .cx-pane.is-open { display: grid; animation: fadeUp .4s cubic-bezier(.22,.61,.36,1) both; }

/* JS varken sekme aynı metni zaten taşıyor; ikisini birden göstermek etiketi
   panelde iki kez okutur. Panelin erişilebilir adı her iki durumda da
   sekmeden gelir (`aria-labelledby`). */
.cxjs .cx-pane-h { display: none; }
.cx-pane-h { margin: 0 0 6px; font-size: var(--fs-2xl); }
.cx-pane-lead { margin: 0 0 20px; font-size: var(--fs); color: var(--tx2); }
/* JS yokken iki panel alt alta okunur; aralarına görünür bir ayrım gerekir. */
.cx-pane + .cx-pane { margin-top: 26px; padding-top: 26px; border-top: 1px solid var(--border); }
.cxjs .cx-pane + .cx-pane { margin-top: 0; padding-top: 0; border-top: 0; }

/* ----------------------------------------------------------------------------
   4) Form alanları
---------------------------------------------------------------------------- */
.cx-field { margin-bottom: 16px; }
.cx-field label {
  display: block; margin-bottom: 7px;
  font-family: var(--font-head); font-weight: 700; font-size: var(--fs);
  color: var(--tx1);
}
.cx-opt { font-weight: 600; color: var(--tx3); }

/* Alan OYUK okunur (zemin `--bg`, yani sayfanın kremi), panel ise yüzey:
   sitedeki bütün form alanlarının kuralı. Ters çevirmek — beyaz alan, beyaz
   panel — alanların kenarlığını tek ayırt edici hâline getirir. */
.cx-field input, .cx-field textarea {
  width: 100%;
  min-height: 46px;             /* WCAG 2.5.8 — dolguyla değil, ölçüyle */
  padding: 12px 16px;
  font-family: var(--font-body); font-size: var(--fs-lg);
  color: var(--tx1);
  background: var(--bg);
  border: 1.5px solid var(--border-strong);
  border-radius: var(--r-sm);
  transition: border-color var(--t-sm) ease, box-shadow var(--t-sm) ease, background var(--t-sm) ease;
}
.cx-field input::placeholder, .cx-field textarea::placeholder { color: var(--tx3); }
.cx-field input:hover, .cx-field textarea:hover { border-color: color-mix(in srgb, var(--blue) 40%, var(--border-strong)); }
.cx-field input:focus-visible, .cx-field textarea:focus-visible {
  outline: none;                /* halka `box-shadow` ile — global outline'dan daha görünür */
  border-color: var(--blue);
  box-shadow: var(--ring);
  background: var(--card-solid);
}
.cx-field textarea { resize: vertical; min-height: 132px; }

/* ---- Alan altı hata ----
   YALNIZCA RENK KULLANILMAZ: kenarlık kırmızıya döner AMA mesajı taşıyan şey
   ikon + cümledir. Kırmızıyı ayırt edemeyen (ya da yüksek kontrast modundaki)
   ziyaretçi de neyin yanlış olduğunu okur. */
.cx-field input[aria-invalid="true"], .cx-field textarea[aria-invalid="true"] {
  border-color: #D64545;
}
.cx-field input[aria-invalid="true"]:focus-visible,
.cx-field textarea[aria-invalid="true"]:focus-visible {
  border-color: #D64545;
  box-shadow: 0 0 0 4px rgba(214, 69, 69, .18);
}
.cx-err {
  display: flex; align-items: flex-start; gap: 7px;
  margin: 7px 0 0;
  font-size: var(--fs-sm); font-weight: 700; line-height: 1.45;
  color: #B32B2B;
}
.cx-err i { margin-top: .12em; }
/* `[hidden]`i GERİ VEREN kural — bkz. §3'teki aynı not. `display: flex` yazar
   sayfasından geldiği için tarayıcının `[hidden] { display: none }`
   varsayılanını EZER: kural olmadan altı alanın altında birden, daha hiçbir
   şey yazılmadan, boş birer kırmızı uyarı ikonu durur. Tam olarak bir kez
   oldu ve gözle yakalandı. */
.cx-err[hidden] { display: none; }
[data-theme="dark"] .cx-err { color: #FFB4B4; }
[data-theme="dark"] .cx-field input[aria-invalid="true"],
[data-theme="dark"] .cx-field textarea[aria-invalid="true"] { border-color: #FF8A8A; }

.cx-btn { width: fit-content; min-height: 48px; margin-top: 6px; }
.cx-privacy {
  display: flex; align-items: flex-start; gap: 7px;
  margin: 14px 0 0; font-size: var(--fs-sm); color: var(--tx3);
}

/* ----------------------------------------------------------------------------
   5) Sonuç mesajları

   Aynı iki sınıf İKİ YERDE birden kullanılır: sunucu render'ında formun
   üstünde (JS yoksa tek yol), ajax'ta ise alanların TAM YERİNDE
   (`data-ok-class` / `data-err-class` → Site.js). Metinleri `data-msg-*`
   özniteliklerinden gelir, yani kopya SiteContent'te kalır.
---------------------------------------------------------------------------- */
.cx-msg {
  display: flex; align-items: flex-start; gap: 10px;
  padding: 15px 18px;
  border-radius: var(--r);
  font-weight: 700; font-size: var(--fs-lg); line-height: 1.45;
  color: var(--tx1);
}
/* `[hidden]`i GERİ VEREN kural, ve burada ŞART: Site.js sonucu 5 sn sonra
   `result.hidden = true` ile kapatıp alanları geri getiriyor. `display: flex`
   o varsayılanı ezdiği için kural olmadan mesaj EKRANDA KALIR ve formun
   üstünde asılı durur — hiçbir şey hata vermez. */
.cx-msg[hidden] { display: none; }
/* Sunucu render'ında mesaj formun ÜSTÜNDE durur ve altında boşluk ister;
   ajax'ta takas kabının tek çocuğu (`.af-result { margin: 0 }`, Site.css §33). */
form > .cx-msg { margin-bottom: 18px; }
/* İkon `content` ile: durum yalnız RENKTEN okunmaz. FA 5 glyph'i — sınıf
   yazamayacağımız yerde (JS mesajı düz metin yazar) kural budur. */
.cx-msg::before {
  font-family: "Font Awesome 5 Free"; font-weight: 900;
  font-size: 1.05em; line-height: 1.35; flex: 0 0 auto;
}
.cx-msg--ok  { background: rgba(35,195,140,.12);  border: 1.5px solid rgba(35,195,140,.42); }
.cx-msg--ok::before  { content: "\f058"; color: #0FA06E; }   /* fa-check-circle */
.cx-msg--err { background: rgba(214,69,69,.12);   border: 1.5px solid rgba(214,69,69,.42); }
.cx-msg--err::before { content: "\f06a"; color: #D64545; }   /* fa-exclamation-circle */
[data-theme="dark"] .cx-msg--ok::before  { color: #4ADE80; }
[data-theme="dark"] .cx-msg--err::before { color: #FF8A8A; }

/* ----------------------------------------------------------------------------
   6) Sıralı giriş

   TEK, İYİ KURGULANMIŞ SAYFA AÇILIŞI — dağınık mikro etkileşimlerden daha
   çok iş görür. Sahne yukarıdan aşağı kurulur (etiket → başlık → cümle →
   kanallar → imza), panel ise onlarla birlikte ama biraz gecikmeli gelir:
   ziyaretçi önce nerede olduğunu okur, sonra formu görür.

   `.reveal` KULLANILMAZ: o kaydırmayla tetikleniyor ve bu sahne zaten ilk
   ekranda — `.is-visible` gelene kadar sayfanın tamamı boş kalırdı.
   Hero'nun kendi çözümü de bu (`fadeUp … both`).
---------------------------------------------------------------------------- */
/* `.cx-team` BURADA AYRICA SAYILIR: artık `.cx-intro`nun çocuğu değil, `.cx-in`
   ızgarasının kendi öğesi (bkz. §2b). Eski `.cx-intro > .cx-team` seçicisi
   taşımadan sonra hiçbir şey seçmiyordu — kart animasyonsuz, yani `both`
   dolgusuz kalıyordu; bu sessiz kırılır, çünkü animasyonsuz öğe DE görünür. */
.cx-intro > *, .cx-ways li, .cx-panel, .cx-team {
  animation: fadeUp .66s cubic-bezier(.22,.61,.36,1) both;
}
.cx-intro > .eyebrow { animation-delay: .02s; }
.cx-intro > h1       { animation-delay: .09s; }
.cx-intro > .cx-lead { animation-delay: .16s; }
.cx-intro > .cx-ways { animation: none; }     /* çocukları tek tek geliyor */
.cx-ways li:nth-child(1) { animation-delay: .23s; }
.cx-ways li:nth-child(2) { animation-delay: .30s; }
.cx-team             { animation-delay: .38s; }
.cx-panel            { animation-delay: .12s; }

/* ----------------------------------------------------------------------------
   7) Responsive

   Eşik 900px: iki kolon altında sağdaki panel ~380px'e iniyor ve iki sekme
   etiketi üç satıra düşüyor. Tek kolonda sıra DOM'dan gelir, `order` ile
   çevrilmez: çevrilirse klavye/ekran okuyucu sırası ile görsel sıra ayrışır.
   DOM sırası TANITIM → FORM → GÜVEN NOTU, yani mobilde görülen sıra da bu.
---------------------------------------------------------------------------- */
@media (max-width: 900px) {
  /* Tek kolonda sahne zaten ekrandan uzun; `min-height` yalnız üstte ölü
     boşluk açardı. */
  .cx { min-height: 0; }
  /* Tek kolonda ızgara koordinatları düşer: üç blok da DOM sırasıyla akar. */
  .cx-in { grid-template-columns: 1fr; grid-template-rows: none; }
  .cx-intro, .cx-team, .cx-panel { grid-column: 1; grid-row: auto; }
  /* Satır aralığı `row-gap` ile değil, panelin kendi üst boşluğuyla verilir:
     `.cx-team`in altındaki 74px'lik maskot payı `row-gap`la toplanınca kart
     sayfanın dibinde gereksizce uzağa düşüyordu. */
  .cx-panel { margin-top: clamp(46px, 6vw, 62px); }
  .cx-intro { padding-top: 0; }
  .cx-lead { max-width: none; }
  /* TANITIM KOPYASI TEK KOLONDA ORTALANIR (2026-09-10). Ayni cokuste `/uyku`
     (`.sx-hero-copy`) ve `/gelisim` (`.gx-hero-copy`) kopyayi ortaliyor; bu
     sayfa olculdugunde (390px) site genelinde TEK istisnaydi — burada
     `text-align: start`, o ikisinde `center`.
     KANAL SATIRLARI HARIC: `.cx-way` bir izgara satiri (`1fr auto`, sag rayda
     chevron) ve `::after` ilerleme cizgisi soldan buyuyor — ortalanirsa ikisi
     birden bozulur, bu yuzden liste sola geri cevrilir (`/ozellikler`in
     "baslik ortali, govde/liste sola" kapsam kuralinin aynisi). */
  .cx-intro { text-align: center; }
  .cx-intro h1, .cx-lead { margin-inline: auto; }
  .cx-ways { text-align: left; }
  .cx-wash--1 { top: -8%; right: -30%; }
  .cx-wash--2 { bottom: -6%; left: -34%; }
}

@media (max-width: 560px) {
  .cx-panel { padding: 18px 16px 22px; border-radius: var(--r-lg); }
  /* Dar ekranda ikon + iki satırlık etiket sekmeyi şişiriyor; etiket kalır,
     ikon düşer — bilgi taşıyan metindir. */
  .cx-tab i { display: none; }
  .cx-tab { font-size: var(--fs-sm); }
  /* Buton tam genişlik: tek kolonda "fit-content" bir gönder butonu satırın
     solunda yetim kalıyor. */
  .cx-btn { width: 100%; }
  /* Parmakla dokunulan bir satırda "sağa kayma" hover'ı yok; kalıcı bir
     dolgu kayması bırakırdı. */
  .cx-way:hover { padding-left: 0; }
}

/* ----------------------------------------------------------------------------
   8) Hareket azaltma

   Bu bölümün KENDİ bloğu olmak zorunda: global blok yalnız SÜREYİ sıfırlar,
   gecikmeyi değil. Gecikmeli + `both` dolgulu bir animasyonda bu, öğenin
   gecikme boyunca `from` karesinde — yani GÖRÜNMEZ — beklemesi demek.
   Sonsuz `orbFloat` da aynı sebeple burada durduruluyor: süresi sıfırlanan
   sonsuz bir keyframe son karesine yapışır.
---------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  .cx-intro > *, .cx-ways li, .cx-panel, .cxjs .cx-pane.is-open {
    animation: none;
  }
  .cx-team-kido { animation: none; }
  .cx-way, .cx-way::after, .cx-way-go { transition: none; }
  .cx-way:hover { padding-left: 0; }
  .cx-way:hover::after, .cx-way:focus-visible::after { transform: scaleX(1); }
}

/* Aydınlatma bağlantısı — amaçla sınırlılık cümlesinin yanında (2026-09-04,
   hukuki denetim). Cümle "e-postanı sadece bunun için kullanırız" diyor ama
   KVKK m.10 verinin ELDE EDİLDİĞİ ANDA tam metne erişim istiyor; politikaya
   giden tek yol footer'daydı. Bağlantı satırın mürekkebini devralır ve yalnız
   altı çizilir: cümlenin ağırlığını bozmadan tıklanabilir olmalı. */
.cx-privacy a { color: inherit; text-decoration: underline; }
.cx-privacy a:hover { color: var(--blue-ink); }
