/* ==========================================================================
   BIO: Proje arşivi — bilalgurkansanli.com ile aynı tasarım dili.
   Ölçüler tarayıcının %110 yakınlaştırmasına denk gelecek şekilde ayarlıdır:
   tüm boyutlar ~%10 büyük, kapsayıcı genişliği ~%10 dar.
   ========================================================================== */

:root {
  /* BIO: Derin lacivert taban — siyah yerine mavi tonlu gece. */
  --bg:        #071229;
  --bg-deep:   #040c1c;
  --bg-lift:   #0d2044;
  --cyan:      #00f5ff;
  --pink:      #ff006e;
  --card-bg:   rgba(10, 24, 50, 0.66);
  --line:      rgba(96, 190, 255, 0.20);
  --line-hot:  rgba(96, 190, 255, 0.5);
  /* BIO: Kart yazıları beyaz — mavi zemin üzerinde okunurluk için. */
  --text:      #ffffff;
  --text-soft: rgba(255, 255, 255, 0.78);
  /* BIO: Alfa 0.50'ydi: #071229 zemininde 4.13:1 ediyordu ve WCAG AA'nın
     normal metin için istediği 4.5:1'in altında kalıyordu (#footer-note
     12px bunu doğrudan kullanıyor). 0.60 -> 5.43:1; ton ve renk aynı,
     gözle fark edilmeyecek kadar küçük bir açılma. */
  --text-dim:  rgba(198, 222, 245, 0.6);
  /* BIO: Kart ızgarası — sütun sayısı tek yerden. */
  --cols: 3;
  --gap: 24px;
  /* BIO: 1160 × 1.1 — kapsayıcı da içerikle aynı oranda büyür, yoksa her şey
     %10 büyürken sayfa daralır ve tersi etki oluşurdu. */
  --maxw: 1276px;
}

* { box-sizing: border-box; }

/* BIO: Kaydırma çubuğu — varsayılan Windows çubuğu (gri gövde + ok düğmeleri)
   koyu uzay zemininin yanında sırıtıyordu. İki standart birden yazılıyor:
   scrollbar-color Firefox ve yeni Chrome'da, ::-webkit-scrollbar ise Safari ve
   eski Chrome'da geçerli; hangisini destekliyorsa onu kullanır.
   Alt sayfalar kendi paletini kurabilir (bkz. bioband/styles.css). */
html {
  scrollbar-width: thin;
  scrollbar-color: var(--cyan) rgba(255, 255, 255, 0.04);
}

::-webkit-scrollbar {
  width: 10px;
  height: 10px;
}

::-webkit-scrollbar-track { background: rgba(255, 255, 255, 0.03); }

/* BIO: Saydam kenarlık gövdeyi rayın içinden kesiyor — çubuk raya yapışık
   değil, içinde yüzüyor gibi duruyor. */
::-webkit-scrollbar-thumb {
  border-radius: 999px;
  background: color-mix(in srgb, var(--cyan) 70%, transparent);
  border: 2px solid transparent;
  background-clip: content-box;
}

::-webkit-scrollbar-thumb:hover {
  background: var(--cyan);
  background-clip: content-box;
}

/* BIO: Windows'taki yukarı/aşağı ok düğmeleri tasarım diline aykırı. */
::-webkit-scrollbar-button { display: none; }
::-webkit-scrollbar-corner { background: transparent; }

html, body {
  margin: 0;
  padding: 0;
  min-height: 100%;
  color: var(--text);
  font-family: 'Share Tech Mono', Consolas, monospace;
  -webkit-font-smoothing: antialiased;
  /* BIO: Dil geçişinde içerik yanlara kayıyor — o anda yatay çubuk çıkmasın. */
  overflow-x: hidden;
}

/* ==========================================================================
   BIO: Arka plan — "yörünge ufku"
   Üç katman: (1) gövdede derin uzay geçişi, (2) ::before yavaşça sürüklenen
   nebula bulutları, (3) ::after ekranın altındaki gezegenin kavisli kenarı ve
   atmosfer halkası. Yıldız yok; derinlik renk ve eğriden geliyor.
   ========================================================================== */

/* BIO: Üstte açık lacivert, aşağı indikçe koyulaşan derin uzay. */
body {
  background-color: var(--bg);
  background-image:
    radial-gradient(ellipse 120% 70% at 50% -8%, var(--bg-lift) 0%, transparent 60%),
    linear-gradient(180deg, #0a1a38 0%, var(--bg) 42%, var(--bg-deep) 100%);
  background-attachment: fixed;
}

/* BIO: Nebula — geniş, yumuşak gaz bulutları. Blur filtresi yok (tam ekran
   sabit katmanda pahalı olurdu); yumuşaklık gradyanların kendisinden geliyor. */
body::before {
  content: '';
  position: fixed;
  inset: -10%;
  z-index: 0;
  pointer-events: none;
  background:
    radial-gradient(38% 30% at 18% 20%, rgba(56, 150, 255, 0.20), transparent 70%),
    radial-gradient(34% 26% at 84% 16%, rgba(148, 92, 255, 0.17), transparent 70%),
    radial-gradient(46% 34% at 64% 58%, rgba(0, 198, 220, 0.11), transparent 72%),
    radial-gradient(32% 26% at 24% 74%, rgba(120, 70, 220, 0.14), transparent 72%);
  animation: nebula-drift 96s ease-in-out infinite alternate;
}

@keyframes nebula-drift {
  0%   { transform: translate3d(0, 0, 0) scale(1); }
  100% { transform: translate3d(-2.4%, 1.6%, 0) scale(1.09); }
}

/* BIO: Gezegen kenarı — ekranın altına oturan dev bir daire.
   `top` doğrudan ufuk çizgisini verir: daire yuvarlak olduğu için en üst
   noktası tam oraya denk gelir. Genişlik viewport'un birkaç katı olduğundan
   yay yumuşak bir kavis olarak görünür, bariz bir daire gibi durmaz. */
body::after {
  content: '';
  position: fixed;
  left: 50%;
  top: 82vh;
  /* BIO: Ne kadar geniş olursa kavis o kadar yumuşak. 400vw'de ekran kenarında
     ~80px düşüş kalıyor — gezegen eğrisi belli oluyor ama balon gibi durmuyor. */
  width: 400vw;
  height: 400vw;
  transform: translateX(-50%);
  border-radius: 50%;
  z-index: 0;
  pointer-events: none;
  /* BIO: Görünen kısım dairenin en üst dilimi — gradyanın ilk yüzdeleri. */
  background: linear-gradient(
    180deg,
    rgba(26, 74, 146, 0.55) 0%,
    rgba(10, 30, 66, 0.78) 2.5%,
    rgba(4, 10, 26, 0.9) 100%
  );
  border-top: 1.5px solid rgba(150, 220, 255, 0.45);
  /* BIO: Atmosfer ışıması — çizginin hemen üstünde yumuşak bir hale. */
  box-shadow:
    0 -20px 70px rgba(70, 170, 255, 0.22),
    0 -3px 14px rgba(150, 220, 255, 0.3);
}

#main {
  position: relative;
  z-index: 1;
  max-width: var(--maxw);
  margin: 0 auto;
  padding: 0 26px 106px;
}

.skip-link {
  position: fixed;
  top: -60px;
  left: 13px;
  z-index: 50;
  padding: 11px 18px;
  font-size: 14px;
  letter-spacing: 0.08em;
  color: var(--bg);
  background: var(--cyan);
  text-decoration: none;
  transition: top 0.18s ease;
}
.skip-link:focus { top: 9px; }

/* ── Köşe süsleri ───────────────────────────────────────────────────────── */
.cor {
  position: fixed;
  width: 29px;
  height: 29px;
  z-index: 3;
  pointer-events: none;
  opacity: 0.5;
  transition: opacity 0.3s ease;
}
.cor::before,
.cor::after {
  content: '';
  position: absolute;
  background: var(--cyan);
}
.cor::before { top: 0; left: 0; width: 100%; height: 1px; }
.cor::after  { top: 0; left: 0; width: 1px; height: 100%; }
.cor.tl { top: 15px;    left: 15px; }
.cor.tr { top: 15px;    right: 15px; transform: scaleX(-1); }
.cor.bl { bottom: 15px; left: 15px;  transform: scaleY(-1); }
.cor.br { bottom: 15px; right: 15px; transform: scale(-1, -1); }

/* BIO: Yukarı çık tuşu belirdiğinde sağ alt köşe süsü çekilir — üst üste binmesin. */
body.totop-on .cor.br { opacity: 0; }

/* ── Araç çubuğu ────────────────────────────────────────────────────────── */
/* BIO: Sabit değil — sayfayla birlikte kayıp gider. Arka planı da yok ki
   üstte koyu bir şerit oluşmasın; gövdenin mavi geçişi kesintisiz görünsün. */
#toolbar {
  position: relative;
  z-index: 6;
  display: flex;
  align-items: center;
  gap: 11px;
  /* BIO: Geri bağlantısı solda, kalan her şey sağda toplanır — araç çubuğuna
     yeni bir öğe eklendiğinde (ses düğmesi gibi) yerleşim bozulmaz. */
  justify-content: flex-end;
  max-width: var(--maxw);
  margin: 0 auto;
  padding: 18px 26px 22px;
  background: none;
}

/* BIO: Geri bağlantısı — çerçeveli hap; hover'da dolar ve oku sola kayar. */
.tb-home {
  display: inline-flex;
  align-items: center;
  margin-right: auto;
  flex: none;
  gap: 10px;
  padding: 10px 18px;
  border-radius: 999px;
  font-size: 12.7px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  white-space: nowrap;
  color: rgba(255, 255, 255, 0.88);
  text-decoration: none;
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid var(--line);
  transition: color 0.28s ease, background 0.28s ease, border-color 0.28s ease, box-shadow 0.28s ease;
}

.tb-home .tb-home-arrow {
  display: inline-block;
  font-size: 14px;
  line-height: 1;
  color: var(--cyan);
  transition: transform 0.28s cubic-bezier(0.2, 0.7, 0.3, 1);
}

.tb-home:hover,
.tb-home:focus-visible {
  color: #fff;
  background: color-mix(in srgb, var(--cyan) 14%, transparent);
  border-color: color-mix(in srgb, var(--cyan) 58%, transparent);
  box-shadow: 0 0 22px color-mix(in srgb, var(--cyan) 22%, transparent);
}

.tb-home:hover .tb-home-arrow,
.tb-home:focus-visible .tb-home-arrow { transform: translateX(-4px); }

.tb-home:focus-visible { outline: 2px solid var(--cyan); outline-offset: 3px; }

/* ── Ses kontrolü (sfx.js araç çubuğuna ekler) ─────────────────────────── */
/* BIO: Açılır panel yerine araç çubuğunun içinde yana doğru genişleyen bir hap.
   Böylece hiçbir katman içeriğin üstüne binmez ve dil seçicisiyle aynı dili
   konuşur. Kapalıyken yalnızca yuvarlak hoparlör düğmesi görünür. */
.sfx-wrap {
  position: relative;
  flex: none;
  display: inline-flex;
  align-items: center;
  height: 40px;
  margin-right: 8px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid var(--line);
  overflow: hidden;
  transition: border-color 0.28s ease, box-shadow 0.28s ease;
}

.sfx-wrap.is-open {
  border-color: color-mix(in srgb, var(--cyan) 45%, transparent);
  box-shadow: 0 0 20px color-mix(in srgb, var(--cyan) 16%, transparent);
}

.sfx-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: 38px;
  height: 38px;
  padding: 0;
  border: none;
  border-radius: 50%;
  cursor: pointer;
  color: var(--cyan);
  background: transparent;
  transition: color 0.24s ease, background 0.24s ease;
}

.sfx-toggle svg { width: 18px; height: 18px; display: block; }

.sfx-toggle:hover,
.sfx-toggle:focus-visible { color: #fff; background: rgba(255, 255, 255, 0.08); }

/* BIO: Sessizken sönük dursun — durum bir bakışta belli olsun. */
.sfx-toggle.is-off { color: rgba(255, 255, 255, 0.42); }
.sfx-toggle.is-off:hover,
.sfx-toggle.is-off:focus-visible { color: #fff; }

.sfx-toggle:focus-visible { outline: 2px solid var(--cyan); outline-offset: -2px; }

/* BIO: Kapalıyken genişliği sıfır; visibility sayesinde sekme sırasına da girmez. */
.sfx-panel {
  display: flex;
  align-items: center;
  gap: 9px;
  max-width: 0;
  padding-right: 0;
  opacity: 0;
  visibility: hidden;
  white-space: nowrap;
  transition:
    max-width 0.34s cubic-bezier(0.2, 0.7, 0.3, 1),
    padding-right 0.34s cubic-bezier(0.2, 0.7, 0.3, 1),
    opacity 0.2s ease,
    visibility 0s linear 0.34s;
}

.sfx-panel.is-open {
  max-width: 190px;
  padding-right: 14px;
  opacity: 1;
  visibility: visible;
  transition:
    max-width 0.34s cubic-bezier(0.2, 0.7, 0.3, 1),
    padding-right 0.34s cubic-bezier(0.2, 0.7, 0.3, 1),
    opacity 0.24s ease 0.06s,
    visibility 0s linear 0s;
}

.sfx-mute {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: 24px;
  height: 24px;
  padding: 0;
  border: none;
  border-radius: 50%;
  cursor: pointer;
  color: rgba(255, 255, 255, 0.6);
  background: transparent;
  transition: color 0.2s ease, background 0.2s ease;
}
.sfx-mute svg { width: 14px; height: 14px; display: block; }
.sfx-mute:hover { color: #fff; background: rgba(255, 255, 255, 0.09); }
.sfx-mute:focus-visible { outline: 2px solid var(--cyan); outline-offset: 1px; }

/* BIO: Dolu kısım --fill ile sürülür (sfx.js her değişimde günceller). */
.sfx-range {
  -webkit-appearance: none;
  appearance: none;
  flex: none;
  width: 96px;
  height: 4px;
  border-radius: 2px;
  background: linear-gradient(
    90deg,
    var(--cyan) 0%,
    var(--cyan) var(--fill, 70%),
    rgba(255, 255, 255, 0.18) var(--fill, 70%),
    rgba(255, 255, 255, 0.18) 100%
  );
  cursor: pointer;
  outline: none;
}

.sfx-range::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: var(--cyan);
  border: none;
  box-shadow: 0 0 9px color-mix(in srgb, var(--cyan) 65%, transparent);
  cursor: pointer;
}

.sfx-range::-moz-range-thumb {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: var(--cyan);
  border: none;
  box-shadow: 0 0 9px color-mix(in srgb, var(--cyan) 65%, transparent);
  cursor: pointer;
}

.sfx-range:focus-visible { outline: 2px solid var(--cyan); outline-offset: 4px; }

.sfx-pct {
  min-width: 34px;
  text-align: right;
  font-size: 11px;
  letter-spacing: 0.04em;
  color: rgba(255, 255, 255, 0.66);
  font-variant-numeric: tabular-nums;
}

@media (prefers-reduced-motion: reduce) {
  .sfx-panel, .sfx-wrap, .sfx-toggle, .sfx-mute { transition: none; }
}

/* BIO: Dil seçici — tek çerçeve içinde segment kontrolü. */
/* BIO: Mod geçişi. Ana sitedeki .tb-mode'un arşiv karşılığı — aynı ölçüler
   (11px, 1.5px aralık, 4px 11px iç boşluk) ama `cursor: none` YOK: ana sitede
   imleci 205 KB'lık script.js çiziyor, burada sistem imleci kullanılıyor.
   Yakında durumunda düğme tıklanabilir kalır (bir not gösterir) ama görsel
   olarak sönük durur — kartlardaki .is-soon ile aynı dil. */
.tb-mode,
.tb-full {
  flex: none;
  background: transparent;
  border: 1px solid var(--line);
  border-radius: 999px;
  color: var(--cyan);
  font-family: 'Share Tech Mono', monospace;
  font-size: 11px;
  letter-spacing: 1.5px;
  text-transform: uppercase;
  padding: 7px 14px;
  cursor: pointer;
  opacity: 0.55;
  white-space: nowrap;
  transition: opacity 0.2s, border-color 0.2s, background 0.2s, box-shadow 0.2s;
}
.tb-mode:hover,
.tb-mode:focus-visible,
.tb-full:hover,
.tb-full:focus-visible {
  opacity: 1;
  border-color: color-mix(in srgb, var(--cyan) 58%, transparent);
  background: color-mix(in srgb, var(--cyan) 8%, transparent);
  box-shadow: 0 0 22px color-mix(in srgb, var(--cyan) 18%, transparent);
}
.tb-mode:focus-visible,
.tb-full:focus-visible { outline: 2px solid var(--cyan); outline-offset: 2px; }
/* BIO: DÜNYA AÇIKKEN — DOLU HALİ. `cursor: default` BURADAN KALKTI.

   Sınıfın eski anlamı "bulunduğun mod, tıklanamaz"dı ve imleci de
   ona göre söndürüyordu. Ama düğmenin söylediği şey değişti:
   artık NEREDE OLDUĞUNU değil NEREYE GİDECEĞİNİ yazıyor
   ("LİSTE MODUNA GEÇ"), yani açıkken de pekala tıklanıyor. Kural
   kalsaydı imleç tam da en çok tıklanan anda ok olarak kalırdı —
   sahibi bunu gördü. `.tb-mode`un `cursor: pointer`ı artık iki
   durumda da geçerli; kalan yalnızca renk. */
.tb-mode.active,
.tb-full.active {
  color: var(--bg);
  background: var(--cyan);
  border-color: var(--cyan);
  opacity: 1;
}

/* BIO: TAM EKRAN DÜĞMESİ MOD DÜĞMESİYLE AYNI KURALLARI PAYLAŞIYOR.

   Ayrı bir blok yazıp aynı değerleri kopyalamak işe yarardı — ta ki
   biri değişene kadar. İkisi yan yana duran ve aynı işi yapan
   ("şu kipe geç") düğmeler; görünümlerinin ayrışması için bir sebep
   yok, ayrışmamaları için ise tek kural yeter.

   GÖRÜNÜRLÜĞÜ BETİĞE BAĞLI: script.js düğmeyi yalnızca tarayıcı
   tam ekranı destekliyorsa basıyor. iPhone'daki Safari eleman tam
   ekranını hiç desteklemiyor ve orada basılmayan bir düğme,
   basılıp bir şey yapmayan düğmeden iyidir. */
.tb-full svg {
  width: 13px;
  height: 13px;
  /* BIO: Yazıyla aynı taban çizgisine oturması için — inline-flex
     hizası monospace yazıda bir piksel yukarı kaçıyordu. */
  margin-inline-end: 7px;
  vertical-align: -2px;
}
.tb-langs {
  display: inline-flex;
  align-items: center;
  flex: none;
  gap: 2px;
  padding: 4px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid var(--line);
}

.tb-lang {
  padding: 8px 15px;
  border: none;
  border-radius: 999px;
  font-family: inherit;
  font-size: 12.7px;
  letter-spacing: 0.1em;
  color: rgba(255, 255, 255, 0.55);
  background: transparent;
  cursor: pointer;
  transition: color 0.24s ease, background 0.24s ease;
}

.tb-lang:hover { color: #fff; background: rgba(255, 255, 255, 0.07); }

/* BIO: Etkin dil — dolu segment. */
.tb-lang.active {
  color: #04101f;
  background: var(--cyan);
  box-shadow: 0 0 18px color-mix(in srgb, var(--cyan) 45%, transparent);
}

.tb-lang:focus-visible { outline: 2px solid var(--cyan); outline-offset: 2px; }

/* ── Başlık ─────────────────────────────────────────────────────────────── */
#hero {
  padding: 60px 0 50px;
  text-align: center;
}

#hero-kicker {
  margin: 0 0 17px;
  font-size: clamp(14px, 1.5vw, 17px);
  letter-spacing: 0.38em;
  text-indent: 0.38em;
  color: var(--pink);
  text-shadow: 0 0 18px rgba(255, 0, 110, 0.6);
}

#hero-title {
  margin: 0;
  font-family: 'Orbitron', sans-serif;
  font-weight: 900;
  font-size: clamp(33px, 6.8vw, 64px);
  letter-spacing: 0.14em;
  text-indent: 0.14em;
  color: var(--text);
  text-shadow: 0 0 30px rgba(0, 245, 255, 0.34);
}

#hero-sub {
  margin: 18px auto 0;
  /* BIO: Geri bildirim cümlesi eklendikten sonra 46ch'de 5 satıra çıkıyordu. */
  max-width: 64ch;
  font-size: 14.3px;
  line-height: 1.75;
  color: var(--text-soft);
}

/* BIO: İletişim düğmeleri — geri bildirim davetinin hemen altında. */
.hero-contact {
  display: flex;
  justify-content: center;
  gap: 12px;
  margin: 22px 0 0;
}

.hc-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  color: rgba(255, 255, 255, 0.82);
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid var(--line);
  transition: color 0.28s ease, background 0.28s ease, border-color 0.28s ease,
              box-shadow 0.28s ease, transform 0.28s cubic-bezier(0.2, 0.7, 0.3, 1);
}

.hc-btn svg {
  width: 19px;
  height: 19px;
  display: block;
}

.hc-btn:hover,
.hc-btn:focus-visible {
  color: #04101f;
  background: var(--cyan);
  border-color: var(--cyan);
  transform: translateY(-3px);
  box-shadow: 0 0 24px color-mix(in srgb, var(--cyan) 45%, transparent);
}

.hc-btn:focus-visible { outline: 2px solid var(--cyan); outline-offset: 3px; }

#hero-rule {
  width: 81px;
  height: 1px;
  margin: 33px auto 0;
  background: linear-gradient(90deg, transparent, var(--cyan), transparent);
  box-shadow: 0 0 12px rgba(0, 245, 255, 0.6);
}

/* ==========================================================================
   BIO: Açılış animasyonu
   Öğeler yukarıdan kademeli süzülür. Yalnızca ilk yüklemede çalışır:
   body.is-entering sınıfı script.js tarafından eklenir ve animasyon bitince
   kaldırılır — böylece dil değiştirip kartlar yeniden çizildiğinde tekrarlamaz.
   Toplam süre ~1.6 sn (son kart 1.55'te, alt bilgi 1.6'da tamamlanır).
   ========================================================================== */
@keyframes bgs-enter {
  from { opacity: 0; transform: translateY(-26px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* BIO: `both` dolgusu gecikme boyunca başlangıç durumunu tutar; sınıf yoksa
   kural hiç uygulanmaz, yani animasyon çalışmazsa öğeler görünmez kalmaz. */
body.is-entering #toolbar,
body.is-entering #hero-kicker,
body.is-entering #hero-title,
body.is-entering #hero-sub,
body.is-entering #hero-contact,
body.is-entering #hero-rule,
body.is-entering #footer,
body.is-entering .card {
  animation: bgs-enter 0.7s cubic-bezier(0.2, 0.7, 0.3, 1) both;
}

body.is-entering #toolbar      { animation-delay: 0ms; }
body.is-entering #hero-kicker  { animation-delay: 80ms; }
body.is-entering #hero-title   { animation-delay: 160ms; }
body.is-entering #hero-sub     { animation-delay: 250ms; }
body.is-entering #hero-contact { animation-delay: 330ms; }
body.is-entering #hero-rule    { animation-delay: 400ms; }
body.is-entering #footer       { animation-delay: 900ms; }

/* BIO: Kartlar sırayla — --enter-i değeri renderGrid içinde atanır. */
body.is-entering .card {
  animation-delay: calc(500ms + var(--enter-i, 0) * 70ms);
}

/* ==========================================================================
   BIO: Dil geçişi
   Diller TR · EN · DE sırasında. Sağdaki bir dile geçilirse sayfa sola çıkıp
   sağdan gelir; soldakine geçilirse tersi. Araç çubuğu #main'in dışında
   olduğu için dil düğmeleri yerinde kalır, yalnızca içerik kayar.
   ========================================================================== */
@keyframes lang-out-left {
  from { opacity: 1; transform: translateX(0); }
  to   { opacity: 0; transform: translateX(-44px); }
}
@keyframes lang-in-right {
  from { opacity: 0; transform: translateX(44px); }
  to   { opacity: 1; transform: translateX(0); }
}
@keyframes lang-out-right {
  from { opacity: 1; transform: translateX(0); }
  to   { opacity: 0; transform: translateX(44px); }
}
@keyframes lang-in-left {
  from { opacity: 0; transform: translateX(-44px); }
  to   { opacity: 1; transform: translateX(0); }
}

#main.lang-out-left  { animation: lang-out-left  0.17s ease-in both; }
#main.lang-out-right { animation: lang-out-right 0.17s ease-in both; }
#main.lang-in-right  { animation: lang-in-right  0.32s cubic-bezier(0.2, 0.7, 0.3, 1) both; }
#main.lang-in-left   { animation: lang-in-left   0.32s cubic-bezier(0.2, 0.7, 0.3, 1) both; }

/* ── Izgara ─────────────────────────────────────────────────────────────── */
.grid {
  display: grid;
  grid-template-columns: repeat(var(--cols), minmax(0, 1fr));
  gap: var(--gap);
  outline: none;
}

/* ── Kart ───────────────────────────────────────────────────────────────── */
.card {
  --accent: var(--cyan);
  position: relative;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  background: var(--card-bg);
  border: 1px solid var(--line);
  text-decoration: none;
  color: inherit;
  transition:
    transform 0.4s cubic-bezier(0.2, 0.7, 0.3, 1),
    border-color 0.4s ease,
    box-shadow 0.4s ease,
    background 0.4s ease;
}

a.card:hover,
a.card:focus-visible {
  transform: translateY(-8px) scale(1.015);
  background: color-mix(in srgb, var(--accent) 6%, var(--card-bg));
  border-color: color-mix(in srgb, var(--accent) 60%, transparent);
  box-shadow:
    0 20px 46px rgba(2, 8, 22, 0.62),
    0 0 0 1px color-mix(in srgb, var(--accent) 26%, transparent),
    0 0 44px color-mix(in srgb, var(--accent) 22%, transparent);
}

a.card:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
}

/* BIO: Hover'da beliren köşe ayraçları. */
.card-corner {
  position: absolute;
  z-index: 3;
  width: 14px;
  height: 14px;
  opacity: 0;
  transition: opacity 0.28s ease;
  pointer-events: none;
}
.card-corner::before,
.card-corner::after {
  content: '';
  position: absolute;
  background: var(--accent);
}
.card-corner::before { top: 0; left: 0; width: 100%; height: 1px; }
.card-corner::after  { top: 0; left: 0; width: 1px; height: 100%; }
.card-corner.tl { top: 8px;    left: 8px; }
.card-corner.tr { top: 8px;    right: 8px;  transform: scaleX(-1); }
.card-corner.bl { bottom: 8px; left: 8px;   transform: scaleY(-1); }
.card-corner.br { bottom: 8px; right: 8px;  transform: scale(-1, -1); }

a.card:hover .card-corner,
a.card:focus-visible .card-corner { opacity: 0.85; }

/* ── Banner ─────────────────────────────────────────────────────────────── */
.card-banner {
  position: relative;
  aspect-ratio: 16 / 10;
  overflow: hidden;
  background-color: #08152e;
  /* BIO: Logo bu kenarın üstüne biner — ayırıcı çizgi burada. */
  border-bottom: 1px solid var(--line);
}

/* BIO: Görsel ayrı bir katmanda — hover'da yalnızca o büyür, kenarlık sabit kalır. */
.card-banner-bg {
  position: absolute;
  inset: 0;
  background-size: cover;
  background-position: center;
  transform: scale(1);
  transition: transform 0.55s cubic-bezier(0.2, 0.7, 0.3, 1);
}

/* BIO: Banner görseli yokken prosedürel arka plan — accent rengiyle ızgara + ışıma. */
.card-banner-bg.is-generated {
  background-image:
    radial-gradient(ellipse at 50% 45%, color-mix(in srgb, var(--accent) 34%, transparent) 0%, transparent 62%),
    linear-gradient(140deg, color-mix(in srgb, var(--accent) 15%, transparent) 0%, transparent 58%),
    linear-gradient(color-mix(in srgb, var(--accent) 12%, transparent) 1px, transparent 1px),
    linear-gradient(90deg, color-mix(in srgb, var(--accent) 12%, transparent) 1px, transparent 1px),
    linear-gradient(180deg, #0b1c3c 0%, #061128 100%);
  background-size: 100% 100%, 100% 100%, 29px 29px, 29px 29px, 100% 100%;
}

/* BIO: Hover videosu — poster görselinin üstünde, tarama çizgilerinin altında.
   Yalnızca oynarken görünür; durunca poster geri gelir. */
.card-banner-video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.45s ease;
}

.card-banner-video.is-playing { opacity: 1; }

/* BIO: Tarama çizgileri — hologram hissi. */
.card-banner::after {
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: repeating-linear-gradient(
    0deg,
    rgba(0, 0, 0, 0) 0px,
    rgba(0, 0, 0, 0) 2px,
    rgba(0, 0, 0, 0.16) 3px,
    rgba(0, 0, 0, 0) 4px
  );
}

/* BIO: Banner altını karartıp logoyu öne çıkarır. */
.card-banner::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background: linear-gradient(180deg, rgba(6, 15, 34, 0.10) 0%, rgba(6, 15, 34, 0.62) 100%);
}

/* BIO: Hover'da banner boyunca geçen ışık süpürmesi. */
.card-sheen {
  position: absolute;
  top: 0;
  left: -60%;
  z-index: 2;
  width: 45%;
  height: 100%;
  pointer-events: none;
  opacity: 0;
  transform: skewX(-18deg);
  background: linear-gradient(
    90deg,
    transparent 0%,
    color-mix(in srgb, var(--accent) 22%, transparent) 50%,
    transparent 100%
  );
}

/* BIO: İmleç kartın üstünde kaldığı sürece süpürme tekrarlanır. */
a.card:hover .card-sheen,
a.card:focus-visible .card-sheen {
  animation: card-sheen-sweep 2.8s linear infinite;
}

/* BIO: Süpürme döngünün ilk %32'sinde geçer (~0.9sn), kalan süre bekleme —
   böylece hareket 2.8 saniyede bir tekrarlanır.

   Hareket 'left' yerine 'transform' ile: 'left' bir yerleşim özelliği, her
   karede style recalc + layout + paint demekti ve bu animasyon imleç kartın
   üstünde durduğu SÜRECE (yani videonun oynadığı süreyle birebir aynı
   koşulda) dönüyordu. transform compositor'a devredilir, yerleşimi hiç
   tetiklemez. Görüntü birebir aynı.

   Ölçü: 'left' -60% → 115%, yani banner genişliğinin %175'i kadar yol.
   translateX yüzdesi elemanın KENDİ genişliğine göredir (banner'ın %45'i),
   dolayısıyla 175 / 45 = %388.9. Başlangıç 'left: -60%' kuralda duruyor.

   Animasyon adı korunmalı — sfx.js süpürme sesini bu ada bağlı çalıyor. */
@keyframes card-sheen-sweep {
  0%   { transform: translateX(0) skewX(-18deg); opacity: 0; }
  3%   { opacity: 1; }
  27%  { opacity: 1; }
  32%  { transform: translateX(388.9%) skewX(-18deg); opacity: 0; }
  100% { transform: translateX(388.9%) skewX(-18deg); opacity: 0; }
}

a.card:hover .card-banner-bg,
a.card:focus-visible .card-banner-bg {
  transform: scale(1.08);
}

/* ── Kaydırırken hover'ı askıya al ─────────────────────────────────────────
   Sayfa imlecin altından kayarken kartlar sırayla hover'a girip çıkıyor.
   Her giriş 44px'lik gölgeyi, kart taşımasını, banner ölçeklemesini ve
   left'i animasyonlayan ışık süpürmesini tetikliyordu — kaydırmayla aynı
   ana iş parçacığında, kart başına bir kez. Kaydırma sürerken hiçbiri
   uygulanmaz; durunca imlecin altındaki kart normal geçişiyle açılır.
   (script.js body'ye is-scrolling sınıfını koyar.) */
/* BIO: transform ARTIK ASKIYA ALINMIYOR. Kartın yükselmesi, logonun ve
   banner'ın büyümesi hep transform ile yapılıyor; transform compositor'a
   devredilir, düzen ve boyama tetiklemez — yani kaydırmaya maliyeti yok.
   Onu da kapatınca kart imlecin altına girdiğinde hiç tepki vermiyordu ve
   arayüz bozuk görünüyordu.

   Askıda kalanlar yalnızca BOYAMA gerektirenler: 44px yayılımlı box-shadow,
   zemin ve kenarlık rengi. Bunlar kaydırma bitince (140ms) yerine oturuyor. */
body.is-scrolling a.card:hover,
body.is-scrolling a.card:focus-visible {
  box-shadow: none;
  background: var(--card-bg);
  border-color: var(--line);
}

/* BIO: 'animation: none' DEĞİL. O, animasyonu iptal ederdi; kaydırma bitince
   0%'dan yeniden başlar, taze bir animationstart atar ve sfx.js süpürme
   sesini yeniden çalardı — kart üstünde durup kaydıran kullanıcı 2.8sn'de
   bir yerine bir ses yağmuru duyardı. 'paused' animasyonu askıya alır:
   kare üretilmez, olay atılmaz, süpürme kaldığı yerden devam eder. */
body.is-scrolling a.card:hover .card-sheen,
body.is-scrolling a.card:focus-visible .card-sheen {
  animation-play-state: paused;
}

/* BIO: Logonun hover'ında üç şey değişiyor: transform (büyüme), border-color
   ve box-shadow (0 0 26px → 0 0 42px). Son ikisi compositor'a devredilemez,
   geçiş boyunca her karede yeniden boyanır ve logo 'margin-top: -51px' ile
   banner'ın üstüne bindiği için o bölge oynayan videonun alanına düşüyor.

   Bu yüzden yalnızca renk ve gölge taban değerine sabitleniyor — hesaplanan
   değer hiç değişmediği için geçiş başlamıyor, sıfır boyama. Büyüme
   (transform) ise serbest: kart yükselirken logo da onunla büyüyor. */
body.is-scrolling a.card:hover .card-logo,
body.is-scrolling a.card:focus-visible .card-logo {
  border-color: color-mix(in srgb, var(--accent) 70%, transparent);
  box-shadow:
    0 0 0 6px rgba(7, 18, 41, 0.72),
    0 0 26px color-mix(in srgb, var(--accent) 42%, transparent);
}

/* BIO: Banner'ın boyaması kartın dışını geçersiz kılmasın — video oynarken
   ve arka plan ölçeklenirken yeniden boyama bu kutuyla sınırlı kalır. */
.card-banner {
  contain: paint;
}

/* ── Yuvarlak logo — banner ile metin alanının sınırına biner ───────────── */
.card-logo {
  position: relative;
  z-index: 3;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 102px;
  height: 102px;
  /* BIO: Negatif üst boşluk yarısı kadar — logo sınırın tam ortasına oturur.
     Banner'ın içinde değil kardeşi olduğu için overflow:hidden onu kırpmaz. */
  margin: -51px auto 0;
  border-radius: 50%;
  overflow: hidden;
  background: rgba(7, 18, 41, 0.94);
  border: 2px solid color-mix(in srgb, var(--accent) 70%, transparent);
  box-shadow:
    0 0 0 6px rgba(7, 18, 41, 0.72),
    0 0 26px color-mix(in srgb, var(--accent) 42%, transparent);
  transition: transform 0.4s cubic-bezier(0.2, 0.7, 0.3, 1), box-shadow 0.4s ease, border-color 0.4s ease;
}

.card-logo img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* BIO: Logo görseli yokken baş harfler. */
.card-logo-initials {
  font-family: 'Orbitron', sans-serif;
  font-weight: 700;
  font-size: 29px;
  letter-spacing: 0.06em;
  color: var(--accent);
  text-shadow: 0 0 14px color-mix(in srgb, var(--accent) 60%, transparent);
}

a.card:hover .card-logo,
a.card:focus-visible .card-logo {
  transform: translateY(-6px) scale(1.1);
  border-color: var(--accent);
  box-shadow:
    0 0 0 6px rgba(7, 18, 41, 0.72),
    0 0 42px color-mix(in srgb, var(--accent) 70%, transparent);
}

/* ── Kart alt bilgisi ───────────────────────────────────────────────────── */
.card-meta {
  position: relative;
  z-index: 2;
  flex: 1;
  /* BIO: Üst boşluk logonun alt yarısını (51px) çoktan geçmiş durumda —
     buradaki değer sadece logo ile etiket arasındaki nefes payı. */
  padding: 15px 20px 21px;
  background: rgba(9, 21, 45, 0.62);
  /* BIO: Ad, açıklama ve etiketler ortada hizalı. */
  text-align: center;
}

/* BIO: Etiket satırı — kartın tam genişliğini kaplar, boşluk kalmaz. */
.card-tags {
  display: flex;
  gap: 7px;
  margin: 0 0 12px;
}

/* BIO: flex:1 1 auto — her etiket kendi metnine göre başlar, sonra kalan
   boşluğu paylaşarak satırı doldurur. Uzun etiket daha çok yer alır. */
.card-tag {
  flex: 1 1 auto;
  min-width: 0;
  padding: 5px 7px;
  font-size: 11.5px;
  letter-spacing: 0.04em;
  text-align: center;
  white-space: nowrap;
  color: var(--accent);
  border: 1px solid color-mix(in srgb, var(--accent) 38%, transparent);
  background: color-mix(in srgb, var(--accent) 10%, transparent);
  transition: background 0.3s ease, border-color 0.3s ease;
}

a.card:hover .card-tag,
a.card:focus-visible .card-tag {
  border-color: color-mix(in srgb, var(--accent) 62%, transparent);
  background: color-mix(in srgb, var(--accent) 18%, transparent);
}

/* BIO: Kartın başlığı — belirgin şekilde en büyük öğe. */
.card-name {
  margin: 0 0 9px;
  font-family: 'Orbitron', sans-serif;
  font-weight: 700;
  font-size: 22px;
  letter-spacing: 0.05em;
  line-height: 1.25;
  color: #ffffff;
}

.card-desc {
  margin: 0;
  font-size: 13.7px;
  line-height: 1.66;
  color: var(--text-soft);
}

/* BIO: Bağlantısı olmayan kart — tıklanamaz, "yakında" olarak işaretli. */
.card.is-soon { opacity: 0.72; }
.card.is-soon .card-name { color: var(--text-soft); }

.card-soon-badge {
  position: absolute;
  top: 13px;
  right: 13px;
  z-index: 4;
  padding: 5px 10px;
  font-size: 10px;
  letter-spacing: 0.18em;
  color: var(--bg);
  background: var(--accent);
}

/* BIO: Tıklanabilir kartlarda sağ alt ok. */
.card-go {
  position: absolute;
  right: 18px;
  bottom: 18px;
  z-index: 3;
  font-size: 14px;
  color: var(--accent);
  opacity: 0;
  transform: translateX(-4px);
  transition: opacity 0.28s ease, transform 0.28s ease;
}
a.card:hover .card-go,
a.card:focus-visible .card-go {
  opacity: 0.9;
  transform: translateX(0);
}

/* ── Yukarı çık tuşu ────────────────────────────────────────────────────── */
.to-top {
  position: fixed;
  right: 28px;
  bottom: 28px;
  z-index: 20;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 50px;
  height: 50px;
  padding: 0;
  border-radius: 50%;
  cursor: pointer;
  color: var(--cyan);
  /* BIO: backdrop-filter kaldırıldı. Sabit konumlu bir elemanda her karede
     arkasındaki alanı geri okuyup Gauss bulanıklık uygulamak gerekiyordu;
     arkadaki içerik kaydırma boyunca (ve body::before'un 96sn'lik animasyonu
     yüzünden boştayken bile) hiç sabit kalmadığı için maliyet önbelleğe
     alınmıyordu. Bulanıklık gidince arkadaki atmosfer çizgisi diskin
     ardından keskin geçiyordu; alfa 0.86'dan 0.92'ye çıkarıldı — telafi
     kozmetik değil gerekli. */
  background: rgba(7, 18, 41, 0.92);
  border: 1px solid color-mix(in srgb, var(--cyan) 42%, transparent);
  /* BIO: Görünmezken tıklanamaz ve aşağıdan gelir. */
  opacity: 0;
  transform: translateY(14px) scale(0.9);
  pointer-events: none;
  transition: opacity 0.32s ease, transform 0.32s cubic-bezier(0.2, 0.7, 0.3, 1),
              background 0.28s ease, border-color 0.28s ease, box-shadow 0.28s ease;
}

.to-top.is-on {
  opacity: 1;
  transform: translateY(0) scale(1);
  pointer-events: auto;
}

.to-top svg {
  width: 20px;
  height: 20px;
  display: block;
  transition: transform 0.28s cubic-bezier(0.2, 0.7, 0.3, 1);
}

.to-top:hover,
.to-top:focus-visible {
  color: #04101f;
  background: var(--cyan);
  border-color: var(--cyan);
  box-shadow: 0 0 26px color-mix(in srgb, var(--cyan) 50%, transparent);
}

.to-top:hover svg,
.to-top:focus-visible svg { transform: translateY(-3px); }

.to-top:focus-visible { outline: 2px solid var(--cyan); outline-offset: 3px; }

/* BIO: JavaScript kapalıyken görünen düz proje listesi. */
.noscript-list {
  margin: 0;
  padding: 0;
  list-style: none;
  text-align: center;
  font-size: 15px;
  line-height: 2;
}
.noscript-list a {
  color: var(--cyan);
  text-decoration: underline;
}

/* ── Alt bilgi ──────────────────────────────────────────────────────────── */
#footer {
  margin-top: 84px;
  padding-top: 29px;
  border-top: 1px solid var(--line);
  text-align: center;
}

#footer-brand {
  margin: 0 0 7px;
  font-size: 12px;
  letter-spacing: 0.26em;
  color: var(--cyan);
  opacity: 0.6;
}

#footer-note {
  margin: 0;
  font-size: 12px;
  letter-spacing: 0.05em;
  color: var(--text-dim);
}

/* ── Duyarlı ────────────────────────────────────────────────────────────── */
/* BIO: Üç sütun 1055px kapsayıcıda dar kalmaya başlayınca ikiye düşer. */
@media (max-width: 980px) {
  :root { --cols: 2; --gap: 20px; }
  #hero { padding: 46px 0 38px; }
  .card-logo { width: 94px; height: 94px; margin-top: -47px; }
}

/* ── Mobil ──────────────────────────────────────────────────────────────── */
@media (max-width: 640px) {
  :root { --cols: 1; --gap: 18px; }

  #main { padding: 0 16px 84px; }
  .cor { display: none; }

  /* BIO: Araç çubuğu dar ekranda ortalanır ve gerekirse alt satıra sarar. */
  #toolbar {
    padding: 14px 16px 18px;
    gap: 10px;
    flex-wrap: wrap;
    justify-content: center;
  }
  .tb-home {
    padding: 9px 14px;
    gap: 7px;
    font-size: 11px;
    letter-spacing: 0.08em;
  }
  .tb-home .tb-home-arrow { font-size: 13px; }
  .tb-lang {
    padding: 8px 13px;
    font-size: 11.5px;
    letter-spacing: 0.06em;
  }

  /* BIO: Dar ekranda satır içi genişleme sığmıyor (geri + diller zaten yeri
     dolduruyor). Açılınca kontrol kendi satırına geçer ve tam genişlik alır —
     kaydırıcı da parmakla rahat sürüklenecek kadar uzar. `order` sayesinde
     diller yukarıda kalır, araç çubuğu üç satıra çıkmaz. */
  .sfx-wrap.is-open {
    order: 3;
    width: 100%;
    margin-right: 0;
  }
  .sfx-wrap.is-open .sfx-panel {
    flex: 1;
    max-width: none;
    padding-right: 16px;
  }
  .sfx-wrap.is-open .sfx-range {
    flex: 1;
    width: auto;
    height: 6px;
  }
  /* BIO: Dokunmatikte tutamak daha büyük olmalı. */
  .sfx-wrap.is-open .sfx-range::-webkit-slider-thumb { width: 16px; height: 16px; }
  .sfx-wrap.is-open .sfx-range::-moz-range-thumb { width: 16px; height: 16px; }
  .sfx-mute { width: 30px; height: 30px; }
  .sfx-mute svg { width: 16px; height: 16px; }

  #hero { padding: 34px 0 30px; }
  /* BIO: Mobilde de belirgin kalsın — harf aralığı daraltılıp punto korunuyor. */
  #hero-kicker { font-size: 13px; letter-spacing: 0.24em; text-indent: 0.24em; }
  /* BIO: Sütun zaten dar; ayrıca ch sınırı koymak metni gereksiz uzatıyordu. */
  #hero-sub { font-size: 13.5px; max-width: 100%; }
  /* BIO: Dokunma hedefi 44px'in altına düşmesin. */
  .hero-contact { gap: 14px; margin-top: 20px; }
  #hero-rule { margin-top: 26px; }

  /* BIO: Tek sütunda kart genişleyince banner fazla uzuyor — oran kısaltılır. */
  .card-banner { aspect-ratio: 16 / 9; }
  .card-logo { width: 88px; height: 88px; margin-top: -44px; }
  .card-logo-initials { font-size: 26px; }
  .card-name { font-size: 20px; }
  .card-desc { font-size: 13.2px; }
  .card-meta { padding: 14px 16px 18px; }
  .card-tag { font-size: 11px; padding: 5px 6px; }

  /* BIO: Dokunmatikte hover yok — ok ve köşe ayraçları hep görünür dursun. */
  a.card .card-go { opacity: 0.75; transform: none; }

  .to-top {
    right: 16px;
    bottom: 16px;
    width: 46px;
    height: 46px;
  }
  .to-top svg { width: 18px; height: 18px; }

  #footer { margin-top: 60px; padding-top: 24px; }
}

/* BIO: Çok dar ekranlar (küçük telefonlar). */
@media (max-width: 380px) {
  #main { padding: 0 12px 76px; }
  .tb-home { font-size: 10px; letter-spacing: 0.06em; padding: 8px 12px; }
  .tb-lang { padding: 7px 11px; font-size: 11px; }
  .card-tag { font-size: 10.2px; letter-spacing: 0.02em; padding: 5px 4px; }
  .card-name { font-size: 18.5px; }
}

/* BIO: Dokunmatik cihazlarda hover durumları yapışıp kalmasın. */
@media (hover: none) {
  a.card:hover {
    transform: none;
    box-shadow: none;
    background: var(--card-bg);
    border-color: var(--line);
  }
  a.card:hover .card-sheen { animation: none; }
  a.card:hover .card-banner-bg { transform: none; }
  a.card:hover .card-logo { transform: none; }
}

@media (prefers-reduced-motion: reduce) {
  .card,
  .card-logo,
  .card-banner-bg,
  .card-corner,
  .card-tag,
  .card-go,
  .to-top,
  .to-top svg,
  .hc-btn,
  .skip-link {
    transition: none;
  }
  .hc-btn:hover,
  .hc-btn:focus-visible { transform: none; }
  a.card:hover,
  a.card:focus-visible { transform: none; }
  a.card:hover .card-logo,
  a.card:focus-visible .card-logo { transform: none; }
  a.card:hover .card-banner-bg,
  a.card:focus-visible .card-banner-bg { transform: none; }
  /* BIO: Işık süpürmesi hareket duyarlılığında tamamen kapalı. */
  a.card:hover .card-sheen,
  a.card:focus-visible .card-sheen { animation: none; opacity: 0; }
  /* BIO: Nebula sürüklenmesi de durur — arka plan sabit kalır. */
  body::before { animation: none; }
}

/* ── Açılış perdesi ─────────────────────────────────────────────────────
   BIO: Sahibi iki kez gördü: "site açılırken böyle ilk önce liste modu
   1-2 saniyelik gözüküyor", sonra "dil değiştirirken yine böyle saliselik
   liste görünümü sitesi gözüküyor".

   Sebep: liste HTML'i sunucudan HAZIR geliyor (build-seo.mjs kartları
   statik basıyor, JS'siz ziyaretçi ve arama motoru için) ama gezegen
   ancak three.js indikten sonra açılıyor. Aradaki boşlukta liste
   görünüyor. Dil değişimi de yeni bir sayfa yüklemesi olduğu için aynı
   boşluğu yeniden açıyor.

   LİSTEYİ GİZLEMEK YANLIŞ OLURDU: JS çalışmazsa hiç görünmez ve statik
   kartların bütün varlık sebebi giderdi. Onun yerine üstüne opak bir
   perde çekiliyor.

   SINIF <html> ÜZERİNDE, PERDE İSE ::before — ve ikisi de bilinçli.
   Sınıfı boot.js <head>'de, ilk boyadan ÖNCE yazıyor; JS ile bir <div>
   eklemek bu yarışı kazanamıyordu. ::before olması perdeyi tuvalin
   ÜSTÜNE koyuyor ama onu gizlemiyor — `visibility: hidden` kullansaydık
   gezegenin tuvali de gizlenirdi.

   RENK SABİT YAZILMIYOR: perde, dünya kipinde listeyi asıl örten
   #w-stage'in erken duran vekili ve o da var(--bg-deep) kullanıyor.
   Ayrı bir değer yazsaydık perde kalkarken görülebilir bir renk
   sıçraması olurdu.

   z-index 60: world.css'in tavanı 20 (ölçüm ekranı), styles.css'in
   tavanı 50 (.skip-link). Perde ikisinin de üstünde. */
html.w-booting::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 60;
  background: var(--bg-deep);
  /* BIO: Opak perdenin ALTINDAKİ kartlara körlemesine tıklanmasın.
     Kilitlenme riskini boot.js'teki emniyet zamanlayıcısı kapatıyor. */
  pointer-events: auto;
}

/* BIO: YÜKLEME İŞARETİ — KARARMANIN İÇİNDE, TEK BİR ÇİZGİ.

   Kararma tek başına "donmuş" görünüyor; yavaş bir makinede
   gezegenin ~579 KB'ı inerken ziyaretçinin elinde hiçbir işaret
   olmuyordu. Bu çizgi "çalışıyor" diyor.

   METNİ YOK ve bu kasıtlı: üç dilimiz var, perde ise ilk boyadan
   önce kuruluyor — o anda hangi dilin sözlüğünün yüklendiği belli
   değil. Dilsiz bir işaret üçünde de doğru.

   İKİ YERDE AYNI: çıkan sayfanın perdesinde de, giren sayfanınkinde
   de. Aynı göründükleri için gezinme tek bir kesintisiz ekran gibi
   okunuyor. */
html.w-booting::after,
#w-leave .w-leave__mark {
  position: fixed;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  z-index: 61;
  /* BIO: Sözcük üstte, çizgi ONUN ALTINDA — tek bir kutuda. İki ayrı
     öğe kullanamıyoruz: perde bir sözde-öğe ve bir öğenin iki sözde
     çocuğu var, biri (::before) zaten karartma. O yüzden çizgi bu
     kutunun ARKA PLANI: 2 piksel yüksekliğinde, alta yaslı. */
  padding-bottom: 13px;
  font-family: 'Share Tech Mono', ui-monospace, monospace;
  font-size: 11px;
  letter-spacing: 0.34em;
  text-indent: 0.34em;      /* BIO: Harf aralığının son boşluğunu dengeler. */
  line-height: 1;
  white-space: nowrap;
  color: var(--cyan);
  opacity: 0.92;
  background-image: linear-gradient(90deg, transparent, var(--cyan), transparent);
  background-repeat: no-repeat;
  background-size: 55% 2px;
  background-position: -60% 100%;
  animation: w-load 1.15s linear infinite;
}

@keyframes w-load {
  from { background-position: -60% 100%; }
  to   { background-position: 160% 100%; }
}

/* BIO: SÖZCÜK DİLE GÖRE — VE PERDE ONU BİLİYOR.

   Perde ilk boyadan önce kuruluyor, yani script.js'in sözlüğü henüz
   yok. Ama <html lang> HTML'in kendisinde yazılı ve ayrıştırıcı oraya
   çoktan geldi — dolayısıyla CSS doğru sözcüğü seçebiliyor.
   Varsayılan İngilizce: bilinmeyen bir dilde de okunur bir şey kalır. */
html.w-booting::after { content: "LOADING"; }
html[lang="tr"].w-booting::after { content: "YÜKLENİYOR"; }
html[lang="de"].w-booting::after { content: "WIRD GELADEN"; }

/* BIO: Soru açıldığı an yükleme bitti demektir — karar verildi.
   İşaret orada kalırsa "hâlâ bir şey oluyor" der ve soruyu yalanlar. */
html.w-asking::after { display: none; }

@media (prefers-reduced-motion: reduce) {
  html.w-booting::after,
  #w-leave .w-leave__mark {
    animation: none;
    background-position: 50% 100%;
  }
}

/* BIO: ÇIKIŞ PERDESİ — DİL DEĞİŞTİRİRKEN.

   Açılış perdesi ANINDA opak olmak zorunda (yoksa liste bir an
   görünür), bu yüzden onda geçiş YOK. Ayrılırken ise tam tersi
   gerekiyor: ekran yumuşakça kararmalı. İki farklı iş, iki ayrı öğe
   — ama aynı renk ve aynı yükleme çizgisi, yani göz için tek bir
   perde.

   z-index 63: soru kartının da üstünde. Ayrılırken ekranda ne
   varsa üstünü örtüyor. */
#w-leave {
  position: fixed;
  inset: 0;
  z-index: 63;
  background: var(--bg-deep);
  opacity: 0;
  pointer-events: none;
  transition: opacity 190ms ease;
}

#w-leave.is-on {
  opacity: 1;
  /* BIO: Karardıktan sonra alttaki hiçbir şeye tıklanmasın — sayfa
     zaten gitmek üzere. */
  pointer-events: auto;
}


@media (prefers-reduced-motion: reduce) {
  #w-leave { transition: none; }
}


/* ==========================================================================
   BIO: YATAY MOD KAPISI — PRO MODE'UN MOBİL KARTININ DİLİ.

   Sahibi kokpitin kartını gösterip "bunları kullan, daha güzel
   gözüküyor" dedi. Ölçüler oradan bire bir: 400 piksel genişlik
   tavanı, 12 piksel yuvarlak köşe, 52x86 telefon simgesi, Orbitron 17
   başlık, Share Tech Mono 12 gövde, yığılmış iki düğme.

   ARSİVİN CEVAP KARTINDAN (#w-ask) AYRI — o pahlı ve büyük harfli,
   masaüstünde de çıkıyor. Bu ise yalnızca telefonda ve kokpitin
   dilinde. İkisini tek gövdeye zorlamak birinin dilini bozardı.

   Renkler arşivin kendi değişkenlerinden türüyor (--cyan, --bg-deep);
   kokpitteki sabit rgba değerleri kopyalanmadı, yoksa tema değişse
   burada eski renk kalırdı.
   ========================================================================== */
#w-ls {
  position: fixed;
  inset: 0;
  /* BIO: world.css'teki #w-stage ile aynı gerekçe — adres çubuğu
     açıkken 100vh ekrandan taşıyor ve ortalanmış kart görsel olarak
     aşağı kaçıyor. Kartın merkezi, gerçekten görünen alanın merkezi
     olmalı. */
  height: 100vh;
  height: 100dvh;
  /* BIO: 62 — perde 60, yükleme çizgisi 61. Cihaz sorusuyla aynı kat. */
  z-index: 62;
  display: flex;
  align-items: center;
  justify-content: center;
  /* BIO: Çentik ve ev tuşu çubuğu — kart onların altına girmesin. */
  padding:
    calc(22px + env(safe-area-inset-top, 0px))
    calc(22px + env(safe-area-inset-right, 0px))
    calc(22px + env(safe-area-inset-bottom, 0px))
    calc(22px + env(safe-area-inset-left, 0px));
  /* BIO: TAM OPAK — ve sebebi perdenin ömrü.

     Cihaz sorusu (#w-ask) arkasını hafifçe gösteriyor çünkü orada
     arkada duran şey ziyaretçinin zaten gördüğü liste. Burada ise
     arkadaki liste tam olarak GÖSTERMEK İSTEMEDİĞİMİZ şey: bu kart
     "gezegeni açacağız, telefonu çevir" diyor. boot.js'in perdesi
     8 saniye sonra kendiliğinden kalkıyor (SAFETY_MS) ve telefonu
     çevirmek bundan uzun sürebilir; o an şeffaflık listeyi
     sızdırırdı. Kartın kendi zemini opak olunca perdenin ne zaman
     kalktığının bir önemi kalmıyor. */
  background: var(--bg-deep);
}

#w-ls .w-ls__card {
  width: min(100%, 400px);
  text-align: center;
  padding: 20px 18px;
  border: 1px solid color-mix(in srgb, var(--cyan) 42%, transparent);
  border-radius: 12px;
  background: color-mix(in srgb, var(--bg-deep) 96%, transparent);
  box-shadow:
    0 0 0 1px color-mix(in srgb, var(--cyan) 8%, transparent) inset,
    0 20px 60px rgba(0, 0, 0, 0.55);
}

/* BIO: Telefon simgesi saf CSS — dosya yok, istek yok. Alttaki çizgi
   ev tuşu; yatıp doğrulan animasyon ne yapılması gerektiğini
   sözcükten önce söylüyor. */
#w-ls .w-ls__phone {
  width: 52px;
  height: 86px;
  margin: 0 auto 14px;
  border: 3px solid color-mix(in srgb, var(--cyan) 65%, transparent);
  border-radius: 10px;
  position: relative;
  box-sizing: border-box;
  animation: w-ls-phone 4.8s ease-in-out infinite;
}

#w-ls .w-ls__phone::before {
  content: "";
  position: absolute;
  left: 50%;
  bottom: 7px;
  width: 20px;
  height: 3px;
  margin-left: -10px;
  border-radius: 2px;
  background: color-mix(in srgb, var(--cyan) 45%, transparent);
}

@keyframes w-ls-phone {
  0%, 55%, 100% { transform: rotate(0deg); }
  72%, 88%      { transform: rotate(-90deg); }
}

#w-ls .w-ls__title {
  margin: 0 0 10px;
  font-family: 'Orbitron', sans-serif;
  font-weight: 700;
  font-size: 17px;
  letter-spacing: 0.06em;
  color: var(--text);
}

#w-ls .w-ls__msg {
  margin: 0 0 18px;
  font-family: 'Share Tech Mono', monospace;
  font-size: 12px;
  line-height: 1.52;
  letter-spacing: 0.02em;
  color: var(--text-soft, rgba(255, 255, 255, 0.72));
}

/* BIO: Dar ekranda alt alta, genişleyince yan yana — kokpitteki
   kuralın aynısı. Telefon yatay tutulunca kart da genişliyor. */
#w-ls .w-ls__row {
  display: flex;
  flex-direction: column;
  gap: 9px;
}

#w-ls .w-ls__primary,
#w-ls .w-ls__secondary {
  font-family: 'Share Tech Mono', monospace;
  font-size: 12px;
  letter-spacing: 0.06em;
  border-radius: 8px;
  /* BIO: 44 piksel — dokunma hedefi alt sınırı; 12+12+12x1.5 bunu
     geçiyor. Parmakla vurulamayan bir düğme yok hükmünde. */
  padding: 12px 14px;
  cursor: pointer;
}

#w-ls .w-ls__primary {
  border: 1px solid color-mix(in srgb, var(--cyan) 55%, transparent);
  background: color-mix(in srgb, var(--cyan) 16%, transparent);
  color: var(--cyan);
  font-weight: 700;
}

#w-ls .w-ls__secondary {
  border: 1px solid color-mix(in srgb, var(--line) 90%, transparent);
  background: transparent;
  color: var(--text-soft, rgba(255, 255, 255, 0.72));
}

#w-ls .w-ls__primary:active,
#w-ls .w-ls__secondary:active { opacity: 0.9; }

#w-ls button:focus-visible { outline: 2px solid var(--cyan); outline-offset: 3px; }

@media (min-width: 460px) {
  #w-ls .w-ls__row { flex-direction: row; justify-content: center; }
  #w-ls .w-ls__primary,
  #w-ls .w-ls__secondary { flex: 1; min-width: 0; max-width: 200px; }
}

@media (prefers-reduced-motion: reduce) {
  #w-ls .w-ls__phone { animation: none; }
}


/* BIO: CİHAZ SORUSU — PERDENİN ÜSTÜNDE, LİSTENİN DEĞİL.

   Yalnızca bir durumda beliriyor: gezegen AÇILABİLİR ama açılmamalı
   (üç boyut işlemcide çiziliyor). Karar boot.js'te, 'ask' cevabı.

   Neden listenin üstünde değil: soru perdeyle birlikte geliyor, yani
   ziyaretçi önce listeyi görüp sonra "liste mi gezegen mi" diye
   sorulmuyor — öyle olsaydı cevabı zaten ekranda duran bir soru
   sorulmuş olurdu.

   z-index 61: perde 60. Tek basamak yetiyor, ikisi kardeş değil —
   perde ::before, bu gerçek bir öğe. */
#w-ask {
  position: fixed;
  inset: 0;
  /* BIO: 62 — perde 60, yükleme çizgisi 61. Soru ikisinin de üstünde. */
  z-index: 62;
  display: grid;
  place-items: center;
  padding: 24px;
  background: color-mix(in srgb, var(--bg-deep) 82%, transparent);
  /* BIO: Perde zaten opak; buradaki hafif koyulaştırma kartı zeminden
     ayırıyor, örtmüyor. */
}

#w-ask .w-ask__card {
  width: min(560px, 100%);
  padding: 30px 30px 26px;
  border: 1px solid var(--line);
  border-radius: 4px;
  background: color-mix(in srgb, var(--bg) 92%, var(--cyan) 3%);
  box-shadow: 0 24px 80px rgba(0, 0, 0, 0.55);
  /* BIO: Panelin pahlı dili — aynı 45 derece, küçük ölçekte. */
  clip-path: polygon(0 0, calc(100% - 18px) 0, 100% 18px, 100% 100%, 18px 100%, 0 calc(100% - 18px));
}

#w-ask .w-ask__kicker {
  margin: 0 0 10px;
  font-family: 'Share Tech Mono', monospace;
  font-size: 11px;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--cyan);
  opacity: 0.85;
}

#w-ask .w-ask__title {
  margin: 0 0 14px;
  font-family: 'Orbitron', sans-serif;
  font-weight: 700;
  font-size: clamp(17px, 2.4vw, 22px);
  line-height: 1.25;
  letter-spacing: 0.02em;
}

#w-ask .w-ask__body {
  margin: 0 0 22px;
  font-family: 'Share Tech Mono', monospace;
  font-size: 13px;
  line-height: 1.75;
  color: var(--text-soft, rgba(255, 255, 255, 0.72));
}

#w-ask .w-ask__row {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}

/* BIO: İKİ DÜĞME, İKİ AĞIRLIK. Önerilen olan dolu, öbürü çerçeveli —
   ama ikisi de aynı boyda ve aynı yerde. Tavsiye ediyoruz, saklamıyoruz. */
#w-ask button {
  flex: 1 1 auto;
  min-width: 190px;
  padding: 11px 16px;
  border-radius: 999px;
  font-family: 'Share Tech Mono', monospace;
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  cursor: pointer;
  transition: opacity 0.2s, border-color 0.2s, background 0.2s, box-shadow 0.2s;
}

#w-ask .w-ask__rec {
  border: 1px solid var(--cyan);
  background: var(--cyan);
  color: var(--bg);
}

#w-ask .w-ask__alt {
  border: 1px solid var(--line);
  background: transparent;
  color: var(--text);
  opacity: 0.8;
}

#w-ask .w-ask__alt:hover,
#w-ask .w-ask__alt:focus-visible {
  opacity: 1;
  border-color: color-mix(in srgb, var(--cyan) 58%, transparent);
  background: color-mix(in srgb, var(--cyan) 8%, transparent);
}

#w-ask button:focus-visible { outline: 2px solid var(--cyan); outline-offset: 3px; }

@media (max-width: 470px) {
  #w-ask button { flex: 1 1 100%; }
}

@media (prefers-reduced-motion: reduce) {
  #w-ask button { transition: none; }
}


/* ==========================================================================
   BIO: İMLEÇ — KARE, ÇÜNKÜ BU SİTENİN BİÇİMİ KARE.

   Ana sitede imleç YUVARLAK: Default Mode'da mavi, Pro Mode'da
   rengarenk (bkz. styles.css#cur ve pro-mode/styles.css). Sahibi
   arşive de bir imleç istedi ama biçimini ayırdı — haklı: bu sitenin
   her öğesi dikdörtgen (kartlar, panel camı, levha, harita plakası,
   pahlı düğmeler). Yuvarlak bir imleç buraya başka bir yerden
   gelmiş gibi dururdu.

   İKİ KİP, AYNI BİÇİM:
     liste    — mavi (camgöbeği), sitenin kendi vurgu rengi
     gezegen  — rengarenk, Pro Mode'un imlecindeki aynı yedi durak

   Renk KİPİ anlatıyor: liste sakin bir dizin, gezegen ise gösterinin
   kendisi. Aynı ayrım ana sitede de var, yalnızca orada yuvarlakla.

   YALNIZCA GERÇEK İMLEÇTE: script.js bu sınıfı ancak
   (hover: hover) and (pointer: fine) eşleşirse yazıyor. Dokunmatikte
   `cursor: none` demek, kaybolacak bir şeyi gizlemek ve geride
   son dokunuşun yerinde duran bir kutu bırakmak olurdu.
   ========================================================================== */
html.bgs-cursor,
html.bgs-cursor * { cursor: none !important; }

/* BIO: Metin girişleri ve seçilebilir metin İSTİSNA — orada sistem
   imleci bir bilgi taşıyor (I-beam), süs değil. Bugün formda bir alan
   yok ama kural önden doğru yazılsın. */
html.bgs-cursor input,
html.bgs-cursor textarea,
html.bgs-cursor select { cursor: auto !important; }

#bgs-cur {
  position: fixed;
  left: 0; top: 0;
  width: 16px; height: 16px;
  margin: -8px 0 0 -8px;
  pointer-events: none;
  z-index: 10000;
  border: 2px solid var(--cyan);
  box-shadow: 0 0 8px rgba(0, 245, 255, 0.55), 0 0 18px rgba(0, 245, 255, 0.18);
  /* BIO: `left/top` DEĞİL `translate` — konum her karede yazılıyor ve
     translate düzen hesabı tetiklemiyor; left/top tetikliyor. */
  will-change: transform;
  transition: width 0.16s ease, height 0.16s ease, margin 0.16s ease,
              background 0.16s ease, box-shadow 0.2s ease, opacity 0.18s ease;
}

/* BIO: Tıklanabilir bir şeyin üstünde büyüyor ve içi hafifçe doluyor —
   ana sitedeki .hov ile aynı sözleşme.

   `body.w-hot` GEZEGEN İÇİN: anıtlar DOM öğesi değil, ışın testiyle
   bulunan üç boyutlu nesneler — bir seçiciyle yakalanamazlar.
   Dünya zaten her karede hangi anıtın altında olduğumuzu biliyor;
   o bilgiyi gövdeye yazıyor (world/index.js/frame). */
#bgs-cur.is-hot,
body.w-hot #bgs-cur {
  width: 28px; height: 28px;
  margin: -14px 0 0 -14px;
  background: rgba(0, 245, 255, 0.07);
  box-shadow: 0 0 12px rgba(0, 245, 255, 0.7), 0 0 26px rgba(0, 245, 255, 0.28);
}

/* BIO: Pencereden çıkınca kayboluyor — yoksa kenarda takılı kalıyor. */
#bgs-cur.is-out { opacity: 0; }

@keyframes bgs-cur-rainbow {
  0%   { background-position: 0% 50%; }
  100% { background-position: 300% 50%; }
}

/* BIO: GEZEGENDE RENGARENK — VE ÇERÇEVE GRADYANI BİR MASKEYLE.

   Kenarlığa gradyan verilemiyor (border-image kare köşelerde kırılıyor),
   o yüzden kutunun TAMAMI gradyan ve maske ortasını oyuyor: dolgu
   kutusu hariç tutulunca geriye 2 piksellik bir çerçeve kalıyor.
   Pro Mode'un yuvarlak imleci aynı işi radial maskeyle yapıyor;
   burada kare olduğu için dolgu kutusu yeterli.

   Yedi durak Pro Mode'unkiyle AYNI — iki site aynı aileden. */
body.w-on #bgs-cur {
  border-color: transparent;
  background: linear-gradient(
    90deg,
    #ff006e, #ff7b00, #ffee00, #00ff88, #00f5ff, #bf00ff, #ff006e
  );
  background-size: 300% 100%;
  animation: bgs-cur-rainbow 2.6s linear infinite;
  box-shadow:
    0 0 6px rgba(255, 0, 110, 0.35),
    0 0 14px rgba(0, 245, 255, 0.28),
    0 0 22px rgba(191, 0, 255, 0.2);
  -webkit-mask:
    linear-gradient(#000 0 0) content-box,
    linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask:
    linear-gradient(#000 0 0) content-box,
    linear-gradient(#000 0 0);
  mask-composite: exclude;
  padding: 2px;
  border-width: 0;
  box-sizing: border-box;
}

body.w-on #bgs-cur.is-hot,
body.w-on.w-hot #bgs-cur {
  background-color: transparent;
  animation-duration: 1.4s;
  padding: 3px;
}

/* BIO: Hareket duyarlılığında dönen gradyan duruyor; imleç yine
   rengarenk ama sabit bir kare. Sürekli hareket eden bir şey, o
   ayarı açanın istemediği şeyin ta kendisi. */
@media (prefers-reduced-motion: reduce) {
  #bgs-cur { transition: none; }
  body.w-on #bgs-cur { animation: none; }
}
