import {
  SITE_LOGO_URL as BRAND_DEFAULT_LOGO,
  SITE_OG_IMAGE_URL as BRAND_DEFAULT_OG,
  GAME_BLACKJACK_COVER_URL,
  GAME_SLOT_COVER_URL,
  GAME_ROULETTE_COVER_URL,
} from "../constants/brand.js";

export let SITE = null;

export let SITE_RAW = null;

export let POPUP = null;
export let GAMDOM_TURUVA = null;

export let GAMES_COVERS = null;

const GAME_COVER_DEFAULTS = {
  blackjack: GAME_BLACKJACK_COVER_URL,
  slot: GAME_SLOT_COVER_URL,
  roulette: GAME_ROULETTE_COVER_URL,
};

export function getGameCoverUrl(key) {
  const k = String(key || "");
  const fromAdmin = GAMES_COVERS && typeof GAMES_COVERS === "object" ? GAMES_COVERS[k] : "";
  if (typeof fromAdmin === "string" && fromAdmin.trim()) {
    return fromAdmin.trim();
  }
  return GAME_COVER_DEFAULTS[k] || "";
}

const LOCALE_STORAGE_KEY = "mocker_locale";
const LEGACY_LOCALE_KEY = "alpingo_locale";

export function getSiteLocale() {
  const loc = SITE &&  (SITE)._locale;
  return loc === "en" ? "en" : "tr";
}

function migrateFlatSiteJson(raw) {
  const css = typeof raw.customCss === "string" ? raw.customCss : "";
  const tg = typeof raw.telegramUrl === "string" ? raw.telegramUrl : "";
  const intro = typeof raw.contactIntro === "string" ? raw.contactIntro : "";
  const ctitle = typeof raw.contactCardTitle === "string" ? raw.contactCardTitle : "";
  const csub = typeof raw.contactCardSubtitle === "string" ? raw.contactCardSubtitle : "";
  const cbtn = typeof raw.contactButton === "string" ? raw.contactButton : "Telegram'da yaz";
  const optUrl = (k) => (typeof raw[k] === "string" ? raw[k].trim() : "");
  return {
    customCss: css,
    logoUrl: optUrl("logoUrl"),
    faviconUrl: optUrl("faviconUrl"),
    ogImageUrl: optUrl("ogImageUrl"),
    defaultLocale: "tr",
    locales: {
      tr: {
        telegramUrl: tg,
        contactIntro: intro,
        contactCardTitle: ctitle,
        contactCardSubtitle: csub,
        contactButton: cbtn,
        contactEyebrow: "İletişim",
        contactHeading: "İletişim",
      },
      en: {
        telegramUrl: tg,
        contactIntro: "",
        contactCardTitle: "",
        contactCardSubtitle: "",
        contactButton: "Message on Telegram",
        contactEyebrow: "Contact",
        contactHeading: "Contact",
      },
    },
  };
}

function resolveActiveLocale(raw) {
  try {
    const q = new URLSearchParams(window.location.search || "");
    const qLang = (q.get("lang") || "").toLowerCase();
    if (qLang === "en" || qLang === "tr") {
      try {
        localStorage.setItem(LOCALE_STORAGE_KEY, qLang);
      } catch {

      }
      return qLang;
    }
  } catch {

  }
  try {
    let stored = localStorage.getItem(LOCALE_STORAGE_KEY);
    if (!stored) {
      stored = localStorage.getItem(LEGACY_LOCALE_KEY);
      if (stored === "en" || stored === "tr") {
        localStorage.setItem(LOCALE_STORAGE_KEY, stored);
      }
    }
    if (stored === "en" || stored === "tr") return stored;
  } catch {

  }
  const def = raw && raw.defaultLocale;
  if (def === "en" || def === "tr") return def;
  try {
    const nav = (navigator.language || "").toLowerCase();
    if (nav.startsWith("en")) return "en";
  } catch {

  }
  return "tr";
}

const UI_DEFAULTS = {
  tr: {
    navHome: "Ana sayfa",
    navMarket: "Market",
    navBonuses: "Bonuslar",
    navPromoCodes: "Promosyon Kodları",
    navTickets: "Biletler",
    navEvents: "Etkinlikler",
    navNews: "Haberler",
    navLeaderboard: "Liderlik tablosu",
    navGamdomTurnuva: "Gamdom çevrim turnuvası",
    navWheel: "Şans Çarkı",
    navGames: "Oyunlar",
    navGameSelector: "Oyun Seçici",
    gameSelectorEyebrow: "Oyun seçici",
    gameSelectorTitle: "Oyun Seçici",
    gameSelectorSubtitle: "Rastgele bir oyun seç!",
    gameSelectorProvider: "Provider seç:",
    gameSelectorSpin: "Çevir ve seç!",
    gameSelectorLoading: "Oyunlar yükleniyor…",
    gameSelectorEmpty: "Bu provider için oyun bulunamadı.",
    gameSelectorError: "Oyun listesi alınamadı. Daha sonra tekrar dene.",
    gameSelectorProvidersLoading: "Provider listesi yükleniyor…",
    gameSelectorProvidersError: "Provider listesi yüklenemedi.",
    gameSelectorSelected: "Seçilen oyun: {game}",
    gameSelectorSelectedBadge: "Seçilen oyun",
    gameSelectorPlay: "Oyunu oyna",
    gameSelectorSpinAgain: "Tekrar çevir",
    gameSelectorModalSubtitle: "Partner sitelerimizde oynamaya devam et.",
    gameSelectorSponsorsTitle: "Sponsor siteler",
    gameSelectorSponsorsLead: "Aşağıdaki sitelerden birine tıklayarak oyuna geçebilirsin.",
    gameSelectorSponsorsEmpty: "Şu an yönlendirilecek sponsor bulunamadı.",
    gameSelectorRtp: "RTP: {rtp}%",
    navComplaints: "Şikayet / Öneri",
    navAffiliate: "Affiliate geçiş",
    navTelegramInvite: "Telegram davet",
    navSpecialOdds: "Özel oranlar",
    tgInviteEyebrow: "Telegram",
    tgInviteTitle: "Gruba davet et, coin kazan",
    tgInviteSubtitle:
      "Kişisel davet linkinle Telegram grubuna gelen her yeni üye için coin kazanırsın. Önce Telegram hesabını doğrula.",
    tgInviteGuestHint: "Davet linki almak ve ödül kazanmak için giriş yap.",
    tgInviteRewardPer: "Her başarılı davet: {coins} coin",
    tgInviteCampaignPaused: "Davet kampanyası şu an kapalı veya yapılandırılmamış.",
    tgInviteYourLink: "Davet linkin",
    tgInviteTelegramStatus: "Telegram durumu",
    tgInviteTelegramRequired: "Önce Telegram hesabını site profiline bağlamalısın.",
    tgInviteTelegramOk: "Bağlı: {user}",
    tgInviteVerifyBtn: "Telegram ile doğrula",
    tgInviteLinkLabel: "Grup davet linki",
    tgInviteLinkPlaceholder: "Link oluştur",
    tgInviteCopy: "Kopyala",
    tgInviteCreateLink: "Davet linki oluştur",
    tgInviteRefreshLink: "Linki yenile",
    tgInviteRule1: "Aynı Telegram hesabı ikinci kez puan getirmez.",
    tgInviteRule2: "Bot hesapları sayılmaz; kendi linkinle kendine puan veremezsin.",
    tgInviteRule3: "Sadece Telegram doğrulaması yapmış üyeler link üretebilir.",
    tgInviteYourStats: "İstatistiklerin",
    tgInviteStatInvites: "Davet",
    tgInviteStatCoins: "Kazanılan coin",
    tgInviteRank: "Sıralaman: #{rank}",
    tgInviteTop10: "En çok davet edenler",
    tgInviteLeaderboardEmpty: "Henüz davet kaydı yok.",
    tgInviteTelegramAlready: "Telegram zaten bağlı.",
    tgInviteTelegramOpenBot: "Telegram açıldı; bota /start gönder.",
    tgInviteTelegramFail: "Telegram bağlantısı alınamadı.",
    tgInviteCopied: "Link kopyalandı.",
    tgInviteCopyManual: "Linki seçip kopyala.",
    tgInviteLinkFail: "Davet linki oluşturulamadı.",
    tgInviteLinkReady: "Davet linkin hazır.",
    specialOddsEyebrow: "Özel oran",
    specialOddsTitle: "Özel Oranlar",
    specialOddsSubtitle: "Özel oranlar ve tahminler — coin ile katıl.",
    specialOddsMatchesHeading: "Bahisler",
    specialOddsLeagueDefault: "Futbol",
    specialOddsPredictionHeading: "TAHMİN",
    specialOddsNoPredictionText: "Tahmin metni yakında.",
    specialOddsStatOdds: "Oran",
    specialOddsStatStakeRange: "Bahis aralığı",
    specialOddsStatPool: "Havuz",
    specialOddsWaitingResults: "Sonuçlar bekleniyor…",
    specialOddsPlayNow: "Bahis yap",
    specialOddsNoMatches: "Şu an listelenen maç yok.",
    specialOddsStakeLabel: "Bahis (coin)",
    specialOddsPlaceBet: "Oyna",
    specialOddsBettingClosed: "Bahis kapalı veya maç başladı.",
    specialOddsLoginToBet: "Bahis için giriş yap.",
    specialOddsMyBets: "Bahislerim",
    specialOddsColTime: "Zaman",
    specialOddsColMatch: "Maç",
    specialOddsColPick: "Seçim",
    specialOddsColOdds: "Oran",
    specialOddsColStake: "Stake",
    specialOddsColStatus: "Durum",
    specialOddsStatusPending: "Bekliyor",
    specialOddsStatusWon: "Kazandı",
    specialOddsStatusLost: "Kaybetti",
    specialOddsStatusVoid: "İptal",
    specialOddsPickFirst: "Önce 1, X veya 2 seç.",
    specialOddsBetOk: "Bahis alındı.",
    specialOddsErrCoins: "Yetersiz coin.",
    specialOddsErrAlready: "Bu maça zaten oynadın.",
    specialOddsErrKickoff: "Maç başladı; bahis kapalı.",
    specialOddsErrGeneric: "İşlem yapılamadı.",
    specialOddsResult: "Sonuç",
    specialOddsParticipantsShort: "katılımcı",
    specialOddsParticipantsLabel: "Katılım",
    specialOddsNoLimit: "limit yok",
    specialOddsQuotaFull: "Kontenjan doldu; bu bahse daha fazla kişi alınamaz.",
    specialOddsTabActive: "Aktif",
    specialOddsTabHistory: "Geçmiş",
    specialOddsHistoryHeading: "Sonuçlanan bahisler",
    specialOddsNoHistory: "Henüz geçmiş kayıt yok.",
    specialOddsStatusCancelled: "İptal",
    specialOddsStatusSettled: "Sonuçlandı",
    specialOddsCancelledHint: "Bu bahis iptal edildi; bahisler iade edildi.",
    specialOddsParticipantsTotal: "Toplam oyuncu",
    specialOddsErrFull: "Kontenjan doldu.",
    navAnaSponsors: "Ana Sponsorlar",
    navSponsorlarTier: "Oynadığım siteler",
    navContact: "İletişim",
    sectionQuickAccess: "Hızlı erişim",
    sectionExplore: "Keşfet",
    sectionSupport: "Destek",
    quickPromoCode: "Promo kod",
    quickPromoHint: "Kodları gör",
    quickGames: "Oyunlar",
    quickGamesHint: "Oyunlara git",
    quickWheel: "Çark",
    quickWheelHint: "Çarkı çevir",
    sidebarDailyBonus: "Günlük puan",
    sidebarDailyBonusHint: "+25 coin",
    sidebarDailyBonusTitle: "Günde bir kez +25 coin",
    dailyBonusNeedLogin: "Günlük puan almak için giriş yapın.",
    dailyBonusSuccess: "+{n} {coin} eklendi.",
    dailyBonusAlready: "Bugünkü ödülünü zaten aldın. Yarın tekrar dene.",
    dailyBonusError: "İşlem yapılamadı. Bir süre sonra tekrar dene.",
    homeQuickActionsAria: "Promo kodu, şans çarkı, günlük puan",
    homePromoLabel: "Kod Gir",
    homePromoSubtitle: "Kodu Giriniz",
    homePromoCta: "Kod Gir",
    homeWheelLabel: "Çark",
    homeWheelSubtitle: "Çarkı Çevir",
    homeWheelCta: "Çarkı Çevir",
    homeDailyLabel: "Günlük Puan",
    homeDailySubtitle: "Talep Et",
    homeDailyCta: "Talep Et",
    promoModalSubtitle: "Kodu girerek coin kazan.",
    promoModalNeedLogin: "Promo kullanmak için giriş yapmalısın.",
    footerGeneral: "Genel",
    footerContent: "İçerikler",
    footerFollow: "Bizi Takip Et",
    footerLegal: "Yasal",
    footerLegalNav: "Yasal bağlantılar",
    footerPrivacy: "Gizlilik ve Güvenlik",
    footerTerms: "Kurallar ve Şartlar",
    footerCookies: "Çerez Politikası",
    legalNotFound: "Sayfa bulunamadı.",
    legalNavTitle: "Yasal sayfalar",
    legalTocLabel: "İçindekiler",
    legalSectionFallback: "Bölüm {n}",
    legalContactTitle: "Sorularınız mı var?",
    legalContactDesc: "Gizlilik, şartlar veya çerezler hakkında destek için iletişim kanallarımıza ulaşın.",
    footerProvidedBy: "Provided By",
    footerZentraCode: "ZENTRACODE",
    footerSponsorlarGrup: "Sponsor vitrini",
    homeSectionAnaSayfa: "ANA SAYFA",
    homeSectionAnaSponsors: "ANA SPONSORLAR",
    homeSocialStrip: "Sosyal medya",
    homeYoutubeFeedTitle: "Sosyal medya akışları",
    homeYoutubeChannelCta: "Kanala git",
    homeYoutubeLive: "CANLI",
    homeYoutubeStream: "YAYIN",
    homeYoutubeUntitled: "YouTube videosu",
    homeYoutubeCarouselPrev: "Önceki videolar",
    homeYoutubeCarouselNext: "Sonraki videolar",
    homeRecentWinnersTitle: "Kazanlar",
    homeRecentWinnersBadge: "Canlı",
    homeRecentWinnersMinutesAgo: "{n} dk önce",
    homeRecentWinnersWinLine: " Mocker Coin Kazandı",
    homeRecentWinnersMultiplier: "{n}X Kazandı",
    homeEventsTitle: "Etkinlikler",
    homeEventsJoin: "Etkinliğe katıl",
    homeEventsViewDetail: "Detayları gör",
    homeEventsCountdownDay: "G",
    homeEventsCountdownHour: "S",
    homeEventsCountdownMin: "D",
    homeEventsCountdownSec: "SN",
    homeEventsNoEnd: "Süresiz etkinlik",
    homeEventsCarouselPrev: "Önceki etkinlikler",
    homeEventsCarouselNext: "Sonraki etkinlikler",
    homeTicketsTitle: "Biletler",
    homeTicketsJoin: "Biletler",
    homeTicketsCountdownDay: "G",
    homeTicketsCountdownHour: "S",
    homeTicketsCountdownMin: "D",
    homeTicketsCountdownSec: "SN",
    homeTicketsNoEnd: "Süresiz bilet",
    badgeOynadigim: "Oynadığım siteler",
    badgeGuvenilir: "Güvenilir Siteler",
    badgeRecommended: "Oynadığım siteler",
    badgeTrusted: "Güvenilir Siteler",
    sponsorCta: "Siteye Git",
    sponsorCopy: "Linki kopyala",
    skeletonLoading: "Yükleniyor",
    seoTitleHome: "Mocker — Ana sayfa | Resmi site",
    seoDescHome: "Mocker resmi ana sayfa: ana sponsorlar, market, şans çarkı ve liderlik. Yayıncı iş birlikleri ve güncel kampanyalar.",
    seoTitleMarket: "Mocker — Market",
    seoDescMarket: "Mocker market: coin ile ürünler, ödüller ve kampanyalar. Hesabınızdan market alışverişi ve talep takibi.",
    seoTitleBonuses: "Mocker — Bonuslar",
    seoDescBonuses: "Partner sitelerin güncel hoşgeldin, deneme ve yatırım bonusları. Sponsor kampanyalarına tek sayfadan ulaşın.",
    seoTitlePromoCodes: "Mocker — Promosyon Kodları",
    seoDescPromoCodes: "Paylaşımda olan tüm promosyon kodlarımıza bu sayfa üzerinden ulaşabilirsiniz.",
    seoTitleTickets: "Mocker — Biletler",
    seoDescTickets: "Mocker bilet etkinlikleri: partner site kuralları, katılım adımları ve çekiliş sonuçları.",
    seoTitleEvents: "Mocker — Etkinlikler",
    seoDescEvents: "Mocker partner etkinlikleri: kampanya kuralları, katılım adımları ve sonuçlar.",
    seoTitleNews: "Mocker — Haberler",
    seoDescNews: "Mocker haber ve duyurular: kampanyalar, güncellemeler ve etkinlik özetleri.",
    seoTitleSponsors: "Mocker — Ana Sponsorlar",
    seoDescSponsors: "Mocker ana sponsorlar: partner siteler, bonuslar ve güncel kampanyalar. Resmi sponsor vitrini.",
    seoTitleContact: "Mocker — İletişim",
    seoDescContact: "Mocker iletişim: soru, iş birliği ve destek talepleri. Resmi kanallar üzerinden bize ulaşın.",
    seoTitlePrivacy: "Mocker — Gizlilik ve Güvenlik",
    seoDescPrivacy: "Mocker gizlilik ve güvenlik: kişisel verilerinizin nasıl işlendiği ve korunduğu.",
    seoTitleTerms: "Mocker — Kurallar ve Şartlar",
    seoDescTerms: "Mocker kullanım kuralları ve şartları. Platformu kullanırken geçerli kurallar.",
    seoTitleCookies: "Mocker — Çerez Politikası",
    seoDescCookies: "Mocker çerez politikası: hangi çerezlerin kullanıldığı ve tercihleriniz.",
    seoTitleLeaderboard: "Mocker — Liderlik tablosu",
    seoDescLeaderboard: "Mocker liderlik tablosu: sıralamalar ve ödül yarışmaları. Anlık skorlar ve topluluk rekabeti.",
    seoTitleWheel: "Mocker — Şans çarkı",
    seoDescWheel: "Mocker şans çarkı: çevir, ödül kazan. Günlük haklar ve coin ödülleri resmi platformda.",
    seoTitleProfile: "Mocker — Profil",
    seoDescProfile: "Mocker kullanıcı profili: coin bakiyesi, hesap ayarları ve kişisel bilgiler. Güvenli giriş ile yönetin.",
    seoTitleComplaints: "Mocker — Şikayet / Öneri",
    seoDescComplaints: "Mocker şikayet ve öneri formu. Geri bildiriminizi bizimle paylaşın; talepleriniz değerlendirilir.",
    seoTitleAffiliate: "Mocker — Affiliate geçiş",
    seoDescAffiliate: "Mocker affiliate geçiş ve partner yönlendirmeleri. Kurallara uygun yönlendirme ve kayıt süreçleri.",
    seoTitleTelegramInvite: "Mocker — Telegram davet",
    seoDescTelegramInvite: "Telegram grubuna davet et, coin kazan. Kişisel davet linki ve liderlik tablosu.",
    seoTitleGames: "Mocker — Oyunlar",
    seoDescGames: "Mocker oyunlar: platform içi oyunlar ve eğlence. Güvenli oyun ortamı ve kurallar.",
    seoTitleGameSelector: "Mocker — Oyun Seçici",
    seoDescGameSelector: "Rastgele slot oyunu seç: provider seç, çevir ve şansına göre bir oyun önerilsin.",
    seoTitleBlackjack: "Mocker — Blackjack",
    seoDescBlackjack: "Mocker Blackjack oyunu. Coin ile oynayın, kurallara uygun eğlence deneyimi.",
    seoTitleSlot: "Mocker — Slot",
    seoDescSlot: "Mocker 3 makara slot: bahis, çevir, anında ödeme. Coin ile güvenli sunucu sonuçları.",
    seoTitleRoulette: "Mocker — Rulet",
    seoDescRoulette: "Mocker Rulet: tek sıfır, coin bahis, sunucu tarafında adil sonuç, ses ve gerçekçi dönen teker.",
    seoTitleSpecialOdds: "Mocker — Özel oranlar",
    seoDescSpecialOdds: "Mocker özel oranlar: seçili maçlarda coin ile tahmin, sonuçlar maç bitince güncellenir.",
    tgTwofaTitle: "İki adımlı doğrulama",
    tgTwofaHint: "Authenticator uygulamanızdaki 6 haneli kodu girin.",
    tgTwofaSubmit: "Doğrula",
    tgTwofaInvalid: "Kod geçersiz. Tekrar deneyin.",
    toastLinkCopied: "Link panoya kopyalandı.",
    toastCopyFailed: "Kopyalama başarısız; bağlantıyı elle seçebilirsin.",
    headerSearchPlaceholder: "Sponsor veya içerik ara...",
    headerSearchSr: "Sitede ara",
    headerSearchClear: "Aramayı temizle",
    searchPaletteAria: "Sponsor ara",
    searchPaletteClose: "Kapat",
    searchPaletteLoading: "Sponsorlar yükleniyor…",
    headerSocial: "Sosyal",
    headerSocialNav: "Sosyal medya bağlantıları",
    headerLogin: "Giriş yap",
    headerRegister: "Kayıt ol",
    headerProfile: "Profil",
    headerProfileMenuAria: "Hesap menüsü",
    headerCoin: "Coin",
    headerCoinBalance: "Coin bakiyesi",
    headerLangAria: "Dil seçimi",
    themeToggleAria: "Açık / koyu tema",
    headerHomePage: "ana sayfa",
    headerOpenMenu: "Menüyü aç",
    chatOpenAria: "Üye sohbetini aç",
    notificationsAria: "Bildirimler",
    notificationsAriaUnread: "Bildirimler, {n} okunmamış",
    notificationsTitle: "Bildirimler",
    notificationsClose: "Kapat",
    notificationsMarkAll: "Tümünü okundu işaretle",
    notificationsEmpty: "Henüz bildirim yok.",
    notificationsLoading: "Yükleniyor…",
    notificationsLoadError: "Bildirimler yüklenemedi.",
    notificationsHasLink: "Bağlantıya git →",
    chatTitle: "Mocker Chat",
    chatSubtitle: "",
    chatClose: "Kapat",
    chatPlaceholder: "Mesajını yaz…",
    chatSend: "Gönder",
    chatEmpty: "Henüz mesaj yok — ilk sen yaz.",
    chatLoading: "Yükleniyor…",
    chatError: "Sohbet yüklenemedi. Sayfayı yenile veya sonra dene.",
    chatRateLimit: "Çok hızlı yazıyorsun; birkaç saniye bekle.",
    chatMuted: "Sohbette geçici olarak susturuldun; süre dolunca tekrar yazabilirsin.",
    chatYou: "Sen",
    chatModerator: "Moderatör",
    chatEmojiAria: "Emoji seç ve mesaja ekle",
    chatEmojiPickerTitle: "Emoji",
    chatEmojiCatFaces: "Yüz ifadeleri",
    chatEmojiCatGestures: "Jestler",
    chatEmojiCatHearts: "Kalp & özel",
    chatEmojiCatActivity: "Aktivite",
    chatGuestHint: "Mesajları okuyabilirsin. Yazmak için giriş yap veya kayıt ol.",
    chatLoginToSend: "Mesaj yazmak için giriş yap",
    bottomNavHome: "Ana",
    bottomNavMarket: "Market",
    bottomNavMenu: "Menü",
    bottomNavGames: "Oyunlar",
    bottomNavChat: "Sohbet",
    bottomNavAria: "Mobil alt menü",
    sidebarAria: "Site menüsü",
    sidebarMainNav: "Ana navigasyon",
    sidebarCollapse: "Menüyü daralt / genişlet",
    sidebarClose: "Menüyü kapat",
    navProfile: "Profil",
    footerLeaderboard: "Liderlik",
    footerAccountNav: "Hesap bağlantıları",
    footerGeneralNav: "Genel bağlantılar",
    footerContentNav: "İçerik bağlantıları",
    footerDisclaimer:
      "Mocker, kullanıcılarına eğlence amaçlı içerikler sunan bağımsız bir platformdur. Sitemizde yer alan tüm bilgiler yalnızca bilgilendirme amacıyla sunulmaktadır. Mocker herhangi bir bahis veya kumar faaliyeti yürütmemektedir. Kullanıcıların kendi yargı alanlarındaki yasalara uygun hareket etmeleri gerekmektedir. 18 yaşından küçüklerin üyeliği kabul edilmemektedir.",
    footerRights: "Tüm hakları saklıdır.",
    footerSocialSoon: "Sosyal bağlantılar yakında.",
    sponsorLoadError:
      "Sponsor verisi yüklenemedi. Bağlantını ve data/sponsors.json dosyasını kontrol et.",
    sponsorListError: "Sponsor listesi açılamadı.",
    sponsorEmptySearch: "Aramanızla eşleşen sponsor yok. Farklı bir kelime dene veya aramayı temizle.",
    sponsorEmptySection: "Bu bölümde henüz sponsor yok.",
    sponsorCopyAriaSuffix: "— linki kopyala",
    sponsorVisitAriaSuffix: "— Siteye git",
    marketPrice: "Fiyat",
    marketBuy: "Satın al",
    marketEmptyTitle: "Market şu an boş",
    marketEmptyHint: "Yakında yeni ödüller eklenecek.",
    marketBalanceLabel: "Bakiyen",
    marketGuestHint: "Satın almak için oturum aç; bakiyeni burada göreceksin.",
    marketLoginCta: "Giriş yap veya kayıt ol",
    marketPageTitle: "Market",
    marketIntro:
      "Kazandığınız puanlar ile markette bulunan kartlardan taleplerinizi gerçekleştirin!\n\nÜyeler ayda 1 kere nakit ödül alabilir.\nMulti hesapla katılım sağlayanların puanları iade edilmeyecek ve etkinliklerden men edilecektir.",
    marketSectionAria: "Ürünler",
    marketSectionSr: "Ödül ve bakiye ürünleri",
    marketCoinWord: "coin",
    marketToastInsufficient: "Yetersiz coin.",
    marketToastSession: "Oturum süresi doldu; tekrar giriş yap.",
    marketToastFailed: "İşlem tamamlanamadı.",
    marketToastPurchasedPrefix: "Satın alındı:",
    marketStockLabel: "Kalan stok",
    marketStockOut: "Stok tükendi",
    marketBuyDisabled: "Tükendi",
    marketToastOutOfStock: "Bu ürünün stoku tükendi.",
    gamesEyebrow: "Oyunlar",
    gamesTitle: "Oyun Merkezi",
    gamesBlackjackAlt: "Blackjack kapak görseli",
    gamesBlackjackTitle: "Mocker Blackjack",
    gamesCategoryCard: "Kart",
    gamesBlackjackDesc: "Krupiyeye karşı 21'e yaklaş. Bahis: 1–1000 coin.",
    gamesLoginToPlay: "Oynamak için giriş yap",
    gamesCategorySlot: "Slot",
    gamesSlotTitle: "Mocker Slot",
    gamesSlotDescGuest: "3 makara, anında ödeme. Üçlü semboller büyük çarpan. Bahis: 1–1000 coin.",
    gamesSlotDescUser: "3 makara, üçlü semboller yüksek çarpan. Bahis: 1–1000 coin.",
    gamesCategoryRoulette: "RULET",
    gamesRouletteTitle: "Mocker Rulet",
    gamesRouletteDescGuest:
      "Klasik masa düzeni, hızlı dönen teker ve ses. Kırmızı/siyah, tek sayı, düzine ve kolon. Bahis: 1–1000 coin.",
    gamesRouletteDescUser: "RULET: sunucu RNG, standart ödemeler. Bahis: 1–1000 coin.",
    gamesPlay: "Oyna",
    wheelEyebrow: "Şans çarkı",
    wheelTitleDaily: "Günlük ödül çarkı",
    wheelTitleMain: "Şans çarkı",
    wheelTitleReward: "Ödül çarkı",
    maintenanceEyebrow: "Bakım modu",
    maintenanceTitle: "Site bakımda",
    maintenanceMessage:
      "Mocker şu an kısa süreli bakım çalışması yapıyor. En kısa sürede yeniden hizmetinizdeyiz.",
    maintenanceHint: "Anlayışınız için teşekkür ederiz.",
    wheelDisabledMsg:
      "Çark alanı pasif durumda olmaktadır. En kısa sürede hizmete sunulacaktır.",
    wheelEyebrowDaily: "Günlük ödül",
    wheelGuestHint: "Çarkı çevirmek için giriş yap.",
    wheelCooldownRule: "{hours} saatte bir kez çevir; ödüller:",
    wheelCardSubtitle: "Şans çarkı",
    wheelSpinCredit: "{hours} saatte bir hak",
    wheelBalancePrefix: "Bakiye",
    wheelSpinHeading: "Çarkı çevir",
    wheelNextSpinLabel: "Sonraki çevirme:",
    wheelBtnSpinning: "Çevriliyor…",
    wheelBtnWait: "Sonraki hak için bekle",
    wheelBtnSpin: "Çarkı çevir",
    wheelPrizePass: "Pas",
    wheelPrizeCoin: "Mocker Coin",
    wheelToastDisabled: "Çark şu an pasif.",
    wheelToastCooldown: "Süre dolmadan tekrar çeviremezsin.",
    wheelToastAuth: "Oturum gerekli.",
    wheelToastUnavailable: "Çark şu an kullanılamıyor.",
    wheelToastPass: "Bu sefer Pas geldi; bir sonraki çevirmede şansın yaver gider.",
    wheelToastWin: "Tebrikler! +{amount} Mocker Coin kazandın.",
    affiliateEyebrow: "Affiliate",
    affiliateTitle: "Affiliate geçiş talebi",
    affiliateGuestHint: "Talep göndermek için giriş yapman gerekiyor.",
    affiliateLabelSponsor: "Sponsor",
    affiliateSponsorPlaceholder: "Sponsor seç",
    affiliateLabelDate: "Yatırım tarihi (isteğe bağlı)",
    affiliateDateHint: "Yatırım yaptıysan tarihi seçebilirsin; yoksa boş bırak.",
    affiliateLabelMessage: "Açıklama",
    affiliateMessagePlaceholder:
      "Affiliate geçiş talebini, kullanıcı adını veya ek notlarını yaz...",
    affiliateMessageRules: "En az 8 karakter, en fazla 2000 karakter.",
    affiliateSender: "Gönderen:",
    affiliateSubmit: "Talebi gönder",
    affiliateToastSelectSponsor: "Önce sponsor seç.",
    affiliateToastMessageShort: "Açıklama en az 8 karakter olmalı.",
    affiliateToastFail: "Gönderim başarısız. Oturum açık mı ve alanları kontrol et.",
    affiliateToastAuth: "Oturum süresi doldu; tekrar giriş yap.",
    affiliateToastSponsor: "Sponsor seçmen gerekiyor.",
    affiliateToastMessage: "Açıklama en az 8 karakter olmalı.",
    affiliateToastMessageLong: "Açıklama en fazla 2000 karakter olabilir.",
    affiliateToastInvestmentDate: "Yatırım tarihi geçersiz (tarihi sil veya doğru seç).",
    affiliateToastDb: "Sunucu veritabanına bağlanamıyor.",
    affiliateToastSchema: "Veritabanı güncel değil (affiliate tablosu). Yöneticiye bildir.",
    affiliateToastSave: "Kayıt kaydedilemedi. Biraz sonra tekrar dene veya yöneticiye bildir.",
    affiliateToastMethod: "Sunucu isteği kabul etmedi.",
    affiliateToast404: "API adresi bulunamadı (klasör / sunucu yapılandırması).",
    affiliateToastNetwork: "Ağ hatası: interneti kontrol et veya sayfayı yenile.",
    affiliateToastErrPrefix: "İşlem tamamlanamadı",
    affiliateToastServer: "Sunucu hatası. Biraz sonra tekrar dene.",
    affiliateToastSuccess: "Talebin alındı. İnceleme sonrası dönüş yapılır.",
    complaintsEyebrow: "Destek",
    complaintsTitle: "Şikayet / Öneri",
    complaintsGuestHint: "Gönderim yapmak için giriş yapman gerekiyor.",
    complaintsLabelCategory: "Kategori",
    complaintsCatSponsor: "Sponsor",
    complaintsCatOther: "Diğer",
    complaintsLabelWhichSponsor: "Hangi sponsor?",
    complaintsSponsorPlaceholder: "Sponsor seç",
    complaintsLabelMessage: "Mesaj",
    complaintsMessagePlaceholder: "Şikayetini veya önerini detaylı yaz...",
    complaintsMessageRules: "En az 8 karakter, en fazla 2000 karakter.",
    complaintsSender: "Gönderen:",
    complaintsSubmit: "Gönder",
    complaintsToastSelectSponsor: "Önce sponsor seç.",
    complaintsToastMessageShort: "Mesaj en az 8 karakter olmalı.",
    complaintsToastAuth: "Oturum süresi doldu; tekrar giriş yap.",
    complaintsToastDb: "Veritabanı bağlantı hatası.",
    complaintsToastFail: "Gönderim başarısız. Alanları kontrol et.",
    complaintsToastSuccess: "Şikayet/öneri alındı. Durum: beklemede.",
    pagePromoCodesEyebrow: "Promosyon",
    pagePromoCodesTitle: "PROMOSYON KODLARI",
    pagePromoCodesSubtitle:
      "Paylaşımda Olan Tüm Promosyon Kodlarımıza Bu Sayfa Üzerinden Ulaşabilirsiniz!",
    pageBonusesEyebrow: "Kampanya",
    pageBonusesTitle: "BONUSLAR",
    pageBonusesSubtitle:
      "Partner sitelerin güncel hoşgeldin, deneme ve yatırım bonuslarına bu sayfadan ulaşabilirsiniz.",
    bonusesLoading: "Bonuslar yükleniyor…",
    bonusesEmpty: "Şu an yayında bonus kampanyası yok. Yakında eklenecek.",
    bonusesLoadError: "Bonuslar yüklenemedi. Bir süre sonra tekrar dene.",
    bonusesPromoCodeLabel: "Promo kod (varsa)",
    bonusesNoExpiry: "Süre sınırı belirtilmedi",
    bonusesExpired: "Süresi doldu",
    bonusesExpiresInDays: "{n} gün içinde sona eriyor",
    bonusesExpiresInHours: "{n} saat içinde sona eriyor",
    bonusesExpiresInMinutes: "{n} dk içinde sona eriyor",
    bonusesExpiresOn: "Bitiş",
    promoCodesLoading: "Promosyon kodları yükleniyor…",
    promoCodesEmpty: "Şu an yayında promosyon kodu yok. Yakında eklenecek.",
    promoCodesLoadError: "Promosyon kodları yüklenemedi. Bir süre sonra tekrar dene.",
    promoCodesCodeLabel: "Promo kod",
    promoCodesCopyAria: "{site} promo kodunu kopyala",
    promoCodesNoExpiry: "Süre sınırı belirtilmedi",
    promoCodesExpired: "Süresi doldu",
    promoCodesExpiresInDays: "{n} gün içinde sona eriyor",
    promoCodesExpiresInHours: "{n} saat içinde sona eriyor",
    promoCodesExpiresInMinutes: "{n} dk içinde sona eriyor",
    promoCodesExpiresOn: "Bitiş",
    pageTicketsEyebrow: "Etkinlik",
    pageTicketsTitle: "BİLETLER",
    pageTicketsSubtitle:
      "Partner sitelerdeki Mocker bilet etkinliklerine katılım adımları ve çekiliş sonuçları bu sayfada.",
    ticketsLoading: "Bilet etkinlikleri yükleniyor…",
    ticketsEmpty: "Şu an aktif bilet etkinliği yok. Yakında yeni çekilişler eklenecek.",
    ticketsLoadError: "Biletler yüklenemedi. Bir süre sonra tekrar dene.",
    ticketsStatusOpen: "Açık",
    ticketsStatusClosed: "Kapalı",
    ticketsStatusDrawn: "Sonuçlandı",
    ticketsParticipants: "Katılım",
    ticketsPrize: "Ödül",
    ticketsCostCoins: "Bilet: {n} coin",
    ticketsCostFree: "Ücretsiz bilet",
    ticketsEndsAt: "Bitiş",
    ticketsWinnerSlots: "{n} kazanan",
    ticketsMyTickets: "Biletlerim",
    ticketsWinnerBadge: "Kazandı",
    ticketsWinnersTitle: "Kazananlar",
    ticketsNoWinnersListed: "Sonuçlandı; kazanan listesi boş.",
    ticketsRequestBtn: "Bilet talep et",
    ticketsRequestHide: "Kuralları gizle",
    ticketsRulesTitle: "Bilet kuralları",
    ticketsHowToTitle: "Nasıl katılırım?",
    ticketsRequestStep1: "{site} sitesine git ve hesabınla giriş yap.",
    ticketsRequestStep2: "Sitedeki bilet / çekiliş alanından Mocker etkinliğine talebini ilet.",
    ticketsRequestStep3: "Onaylanan talepler çekiliş havuzuna eklenir.",
    ticketsRequestStep4: "Sonuçlar burada ilan edilir; kazananlar aşağıda listelenir.",
    ticketsSiteLoginBtn: "{site} sitesine giriş yap",
    ticketsSiteLoginBtnGeneric: "İlgili siteye git",
    ticketsMockerLoginHint: "Bilet talebi için önce Mocker hesabınla giriş yap.",
    ticketsMockerLoginBtn: "Mocker'a giriş yap",
    ticketsRequestNote:
      "Bilet talebi partner sitede tamamlanır. Mocker üzerinden otomatik bilet oluşturulmaz.",
    ticketsRulesDefault:
      "Etkinlik süresince geçerli site kuralları geçerlidir. Her üye yalnızca izin verilen sayıda talep oluşturabilir. Hile, çoklu hesap veya sahte bilgi diskalifiye sebebidir.",
    ticketsClosedHint: "Bu etkinlik bilet talebine kapalı.",
    ticketsBackToList: "Etkinliklere dön",
    ticketsTabRules: "Kurallar",
    ticketsTabHowTo: "Nasıl katılırım",
    ticketsTotalTickets: "Toplam bilet",
    ticketsTotalTicketsUnit: "adet",
    ticketsStart: "Başlangıç",
    ticketsEnd: "Bitiş",
    ticketsActiveBadge: "Aktif",
    ticketsWheelSideLink: "Çarkı çevir",
    ticketsViewDetail: "Detay & talep",
    pageEventsEyebrow: "Kampanya",
    pageEventsTitle: "ETKİNLİKLER",
    pageEventsSubtitle:
      "Partner sitelerdeki Mocker etkinliklerine katılım adımları ve sonuçlar bu sayfada.",
    eventsLoading: "Etkinlikler yükleniyor…",
    eventsEmpty: "Şu an aktif etkinlik yok. Yakında yeni kampanyalar eklenecek.",
    eventsLoadError: "Etkinlikler yüklenemedi. Bir süre sonra tekrar dene.",
    eventsStatusOpen: "Açık",
    eventsStatusClosed: "Kapalı",
    eventsStatusDrawn: "Sonuçlandı",
    eventsParticipants: "Katılım",
    eventsPrize: "Ödül",
    eventsRequestBtn: "Katılım talep et",
    eventsViewDetail: "Detay & talep",
    eventsRulesDefault:
      "Etkinlik süresince geçerli site kuralları geçerlidir. Her üye yalnızca izin verilen sayıda talep oluşturabilir. Hile, çoklu hesap veya sahte bilgi diskalifiye sebebidir.",
    eventsHowToTitle: "Nasıl katılırım?",
    eventsRequestStep1: "{site} sitesine git ve hesabınla giriş yap.",
    eventsRequestStep2: "Sitedeki etkinlik / kampanya alanından Mocker etkinliğine talebini ilet.",
    eventsRequestStep3: "Onaylanan talepler etkinlik havuzuna eklenir.",
    eventsRequestStep4: "Sonuçlar burada ilan edilir; kazananlar aşağıda listelenir.",
    eventsSiteLoginBtn: "{site} sitesine giriş yap",
    eventsSiteLoginBtnGeneric: "İlgili siteye git",
    eventsMockerLoginHint: "Katılım talebi için önce Mocker hesabınla giriş yap.",
    eventsMockerLoginBtn: "Mocker'a giriş yap",
    eventsRequestNote:
      "Katılım talebi partner sitede tamamlanır. Mocker üzerinden otomatik kayıt oluşturulmaz.",
    eventsBackToList: "Etkinliklere dön",
    eventsTabRules: "Kurallar",
    eventsTabHowTo: "Nasıl katılırım",
    eventsTotalParticipants: "Toplam katılım",
    eventsTotalParticipantsUnit: "kişi",
    eventsStart: "Başlangıç",
    eventsEnd: "Bitiş",
    eventsActiveBadge: "Aktif",
    eventsWheelSideLink: "Çarkı çevir",
    pageNewsEyebrow: "Güncel",
    pageNewsTitle: "HABERLER",
    pageNewsSubtitle: "Kampanya ve duyurular — detaylar için kartlara göz at.",
    newsLoading: "Haberler yükleniyor…",
    newsEmpty: "Henüz haber yok. Yakında yeni duyurular eklenecek.",
    newsLoadError: "Haberler yüklenemedi. Bir süre sonra tekrar dene.",
    newsDetailsBtn: "Detaylar",
    newsModalNoBody: "Detay metni bulunmuyor.",
    pageRecommendedKicker: "Elit seçim",
    pageTrustedKicker: "VİP seçim",
    pageSponsorlarTierKicker: "Sponsor vitrini",
    pageAnaSponsorsTitle: "ANA SPONSORLAR",
    leaderboardEyebrow: "Liderlik",
    leaderboardTitle: "Liderlik Sıralaması",
    leaderboardSubtitle: "TOP 20 üyemizin coin sıralaması yer almaktadır.",
    leaderboardEmptyWarn: "Kayıt listelenemedi veya henüz üye yok.",
    leaderboardEmpty: "Henüz kayıtlı üye yok.",
    leaderboardPoints: "Puan",
    leaderboardColPlayer: "Oyuncu",
    leaderboardTop3Aria: "İlk üç",
    leaderboardRestAria: "Sıralama devamı",
    leaderboardRestSr: "4–20. sıralar",
    leaderboardWarnTitle: "Sunucu veritabanına ulaşılamadı.",
    leaderboardWarnBody:
      "Sıralama boş görünebilir. Hosting’de <code class=\"rounded bg-black/30 px-1.5 py-0.5 text-xs\">data/users.sqlite</code> yazılabilir olmalı; PHP’de <code class=\"rounded bg-black/30 px-1.5 py-0.5 text-xs\">pdo_sqlite</code> açık olmalı.",
    leaderboardLoad: "Yükleniyor…",
    leaderboardFail: "Sıralama yüklenemedi",
    leaderboardFailHint:
      "Doğrudan /api/leaderboard.php aç — JSON görmüyorsan PHP veya sunucu yolu hatası.",
    leaderboardFailCache: "Önbellek: Ctrl+F5. Yerel: php -S localhost:8080 router.php",
    seoTitleGamdomTurnuva: "Gamdom çevrim turnuvası | Mocker",
    seoDescGamdomTurnuva: "Gamdom çevrim turnuvası liderlik tablosu ve ödül havuzu.",
    gamdomDefaultTitle: "Gamdom Çevrim Etkinliği",
    gamdomCountdownLabel: "Bitmesine kalan süre",
    gamdomCountDays: "Gün",
    gamdomCountHours: "Saat",
    gamdomCountMinutes: "Dakika",
    gamdomCountSeconds: "Saniye",
    gamdomRules: "Kurallar ve Şartlar",
    gamdomRulesClose: "Kapat",
    gamdomRulesEmpty: "Kurallar henüz eklenmedi.",
    gamdomRulesExternalHint: "Detaylı kurallar harici bağlantıda.",
    gamdomRulesOpenLink: "Kuralları aç",
    gamdomReward: "Ödül",
    gamdomHiddenUser: "Hidden user",
    gamdomColPlayer: "Oyuncu",
    gamdomColWager: "Çevrim",
    gamdomColReward: "Ödül",
    gamdomTop3Aria: "İlk üç",
    gamdomListAria: "Sıralama 4–50",
    gamdomPeriodsAria: "Dönem seçimi",
    gamdomEmpty: "Henüz sıralama verisi yok.",
    gamdomDisabled: "Turnuva şu an kapalı.",
    gamdomLoad: "Yükleniyor…",
    gamdomFail: "Turnuva verisi yüklenemedi",
    gamdomFailHint: "Yönetim panelinden etkinleştirin veya daha sonra tekrar deneyin.",
    gamdomApiFallback: "Canlı API şu an yanıt vermiyor; kayıtlı yedek veri gösteriliyor.",
    popupEyebrow: "Duyuru",
    popupDefaultTitle: "Özel duyuru",
    popupClose: "Kapat",
    popupNever: "Bir daha gösterme",
    popupCta: "Detaya git",
    authClose: "Kapat",
    authEyebrowAccount: "Hesap",
    authEyebrowNew: "Yeni hesap",
    authLoginSubtitle: "Kullanıcı adınızı ve şifrenizi girerek giriş yapın.",
    authPlaceholderLoginPassword: "Şifrenizi girin",
    authLabelIdentity: "Kullanıcı adı veya e-posta",
    authPlaceholderIdentity: "örnek: kullanıcı_adın veya mail@site.com",
    authLabelPassword: "Şifre",
    authRegisterSubtitle: "Kullanıcı adı, e-posta ve şifrenle hesabını oluştur.",
    authLabelUsername: "Kullanıcı adı",
    authPlaceholderUsername: "Kullanıcı adın",
    authLabelEmail: "E-posta",
    authLabelPhone: "Telefon",
    authPlaceholderPhone: "05xx xxx xx xx",
    authErrPhoneInvalid: "Geçerli bir telefon numarası gir.",
    authPlaceholderEmail: "ornek@mail.com",
    authLabelPassword2: "Şifre tekrar",
    authPlaceholderPassword2: "Şifreyi tekrarla",
    authPlaceholderPassword: "En az 8 karakter",
    authNoAccount: "Hesabın yok mu?",
    authHasAccount: "Zaten hesabın var mı?",
    authErrFillAll: "Tüm alanları doldur.",
    authErrInvalidCreds: "Kullanıcı adı/e-posta veya şifre hatalı.",
    authErrAttemptsLeft: "deneme hakkı)",
    authErrCsrf: "Güvenlik doğrulaması başarısız. Sayfayı yenileyip (Ctrl+F5) tekrar dene.",
    authErrLoginFail: "Giriş yapılamadı.",
    authErrExternalAuthDisabled:
      "Eski site hesabıyla giriş şu an kapalı: sunucuda RX API Bearer token tanımlı değil. Yöneticinize başvurun veya admin panelden şifrenizi sıfırlatın.",
    authErrInactive: "Hesabınız pasif. Destek ile iletişime geçin.",
    authLabelTwofa: "Doğrulama kodu (2FA)",
    authPlaceholderTwofa: "123456",
    authTwofaHint: "Authenticator uygulamasındaki 6 haneli kodu girin.",
    authTwofaStepToast: "Şifre doğru. 2FA kodunu girin.",
    authErrTwofaRequired: "2FA kodunu girin.",
    authErrTwofaInvalid: "2FA kodu hatalı.",
    authErrTwofaExpired: "2FA süresi doldu. Tekrar giriş yapın.",
    authWelcome: "Hoş geldin.",
    authErrUsernameShort: "Kullanıcı adı en az 2 karakter olmalı.",
    authErrEmailInvalid: "Geçerli bir e-posta gir.",
    authErrPasswordShort: "Şifre en az 8 karakter olmalı.",
    authErrPasswordMismatch: "Şifreler eşleşmiyor.",
    authErrTaken: "Bu kullanıcı adı veya e-posta zaten kayıtlı.",
    authErrUsernameRules: "Kullanıcı adı 2–64 karakter olmalı.",
    authErrRegisterFail: "Kayıt tamamlanamadı.",
    authOrDivider: "veya",
    authTelegramHint: "Telegram hesabınla giriş yap veya kayıt ol.",
    authTelegramBotHint: "Botta «Başlat»a basarak Telegram hesabını doğrula.",
    authTelegramBotLogin: "Telegram ile giriş yap",
    authTelegramBotRegister: "Telegram ile kayıt ol",
    authTelegramBotOpening: "Telegram açılıyor…",
    authTelegramBotWait: "Botta doğrulamayı tamamla; site otomatik giriş yapacak.",
    authTelegramBotExpired: "Doğrulama süresi doldu. Tekrar dene.",
    authTelegramBotSession: "Oturum eşleşmedi. Sayfayı yenileyip tekrar dene.",
    authTelegramFail: "Telegram ile giriş yapılamadı.",
    authTelegramInvalid: "Telegram doğrulaması geçersiz. Tekrar dene.",
    authTelegramUnavailable: "Telegram girişi şu an kullanılamıyor.",
    authTelegramDomainInvalid:
      "Telegram butonu görünmüyorsa BotFather'da @{bot} için domain tanımlı değil. @BotFather → /setdomain → botu seç → {domain} yaz (www ile www'siz ayrı eklenebilir).",
    profileCompleteBannerTitle: "Hesabını tamamla",
    profileCompleteBannerHint: "Telegram ile kayıt oldun. Devam etmek için e-posta, telefon ve şifre belirle.",
    profileCompleteTitle: "E-posta, telefon ve şifre",
    profileCompleteSubtitle: "Bu bilgiler hesabına giriş yapman ve güvenliğin için gereklidir.",
    profileCompleteSubmit: "Kaydet ve devam et",
    profileCompleteSuccess: "Profil bilgilerin kaydedildi.",
    profileCompleteRequiredToast: "Hesabını tamamlamak için e-posta, telefon ve şifre belirle.",
    profilePasswordChangeBannerTitle: "Şifrenizi güncelleyin",
    profilePasswordChangeBannerHint:
      "Oturumunuzun süresi dolduğundan güvenliğiniz için yeni bir şifre belirlemeniz gerekmektedir.",
    profilePasswordChangeTitle: "Yeni şifre belirle",
    profilePasswordChangeSubtitle: "Yeni şifrenizi belirleyin (en az 8 karakter). Sonraki girişlerde bu şifreyi kullanacaksınız.",
    profilePasswordChangeCurrent: "Mevcut şifre",
    profilePasswordChangeSubmit: "Şifreyi güncelle",
    profilePasswordChangeSuccess: "Şifreniz güncellendi. İyi eğlenceler!",
    profilePasswordChangeRequiredToast: "Devam etmek için yeni şifrenizi belirleyin.",
    authErrPasswordChangeFail: "Şifre güncellenemedi. Tekrar deneyin.",
    authErrCurrentPassword: "Mevcut şifre hatalı.",
    authSuccessRegister: "Kayıt tamamlandı. Hesabına {bonus} coin eklendi.",
    profileEyebrow: "Hesap",
    profileTitle: "Profil",
    profileSubtitle: "Hesap bilgilerin ve satın aldığın ürünler.",
    profileLoadingTitle: "Yükleniyor",
    profileLoadingHint: "Profil bilgileri getiriliyor...",
    profileAuthTitle: "Giriş gerekli",
    profileAuthHint: "Profili görmek için sağ üstten giriş yap.",
    profileTabInfo: "Profil",
    profileTabTelegram: "Telegram Davet",
    profileTabCrypto: "Hesap",
    profileTabSponsors: "Sponsorlar",
    profileTabWheel: "Çark Geçmişi",
    profileTabPurchases: "Satın Alınanlar",
    profileTabBlackjack: "Blackjack",
    profileTabSlot: "Slot",
    profileTabRoulette: "Mocker Rulet",
    profileTabComplaints: "Şikayetler",
    profileInfoTitle: "Bilgiler",
    profileTwofaTitle: "İki adımlı doğrulama (2FA)",
    profileTwofaSubtitle: "Google Authenticator veya benzeri uygulama ile hesabınızı koruyun.",
    profileTwofaStatusOff: "Kapalı",
    profileTwofaStatusOn: "Aktif",
    profileTwofaActiveHint: "2FA açık. Kapatmak için destek ile iletişime geçin.",
    profileTwofaSetupBtn: "2FA Kur",
    profileTwofaConfirmBtn: "Etkinleştir",
    profileTwofaSecretLabel: "Manuel anahtar",
    profileTwofaCodeLabel: "Uygulamadaki kod",
    profileTwofaInvalid: "Kod hatalı. Tekrar deneyin.",
    profileTwofaEnabledToast: "2FA etkinleştirildi.",
    profileTelegramConnectTitle: "Telegram'a bağla",
    profileTelegramConnectHint: "Davet linki al, gruba davet et ve coin kazan.",
    profileTelegramConnectHintLinked: "Telegram bağlı. Davet linkini yönetmek için tıkla.",
    profileTelegramConnectCta: "Telegram davet",
    profileLevelTitle: "Seviye",
    profileLevelNext: "Sonraki seviye",
    profileLevelMax: "Maksimum seviye",
    profileLevelXp: "Toplam XP",
    profileHeroLevel: "Seviye",
    profileHeroRank: "Seviye {n}",
    profileHeroProgress: "İlerleme",
    profileHeroXpBar: "Seviye {next}: {cur} / {max} XP",
    profileHeroXpTotal: "Toplam {n} XP",
    profileHeroMemberSince: "Üye · {date}",
    profilePromoTitle: "Promo kod",
    profilePromoPlaceholder: "Örn. YILBASI2026",
    profilePromoUse: "Kullan",
    profileCryptoTitle: "Hesap bilgilerim",
    profileCryptoHint: "Kripto cüzdan adreslerini kaydet; ödeme ve doğrulama için kullanılabilir.",
    profileSave: "Kaydet",
    profileSponsorsTitle: "Sponsor hesap bilgilerim",
    profileSponsorsHint:
      "Kayıtlı olduğun sponsor sitelerinde kullandığın kullanıcı adını/ID’yi gir. Admin panelinde görünür.",
    profileWheelTitle: "Çark geçmişi",
    profilePurchasesTitle: "Satın alınanlar",
    profileBjTitle: "Blackjack geçmişi",
    profileSlotTitle: "Mocker Slot geçmişi",
    profileComplaintsTitle: "Şikayet / öneri durumları",
    profileLogout: "Çıkış yap",
    profileWalletAddress: "Cüzdan adresi",
    profileSponsorAccountPlaceholder: "Üye ID veya kullanıcı adınızı yazınız",
    profileCryptoPlaceholderBtc: "BTC Adresi Giriniz",
    profileCryptoPlaceholderEth: "ETH Adresi Giriniz",
    profileCryptoPlaceholderUsdtErc: "USDT ERC-20 Adresi Giriniz",
    profileCryptoPlaceholderUsdtTrc: "USDT TRC-20 Adresi Giriniz",
    profileCryptoPlaceholderLtc: "LTC Adresi Giriniz",
    profileCryptoPlaceholderTrx: "TRX Adresi Giriniz",
    profileCryptoPlaceholderDoge: "Doge Adresi Giriniz",
    profileCryptoPlaceholderOther: "Sizden ek istenilir ise doldurun",
    profileCryptoOtherLabel: "Diğer",
    profileBjWin: "Kazanç",
    profileBjLose: "Kayıp",
    profileBjPush: "Berabere",
    profileBjBlackjack: "Blackjack",
    profileBjBet: "Bahis",
    profileBjDouble: "Çiftle",
    profileBjNormal: "Normal",
    profileBjRisk: "Risk",
    profileBjPayout: "Ödeme",
    profileBjNet: "Net",
    profileSlotLoss: "Kayıp",
    profileSlotReel: "Makara",
    profileEmptyBj: "Henüz tamamlanmış blackjack eli yok.",
    profileEmptySlot: "Henüz slot çevirisi yok.",
    profilePageLabel: "Sayfa {cur} / {total}",
    profilePrevPage: "Önceki sayfa",
    profileNextPage: "Sonraki sayfa",
    profileLogoutToast: "Çıkış yapıldı.",
    profileDlUsername: "Kullanıcı adı",
    profileDlEmail: "E-posta",
    profileDlPhone: "Telefon",
    profileDlSpent: "Toplam harcama",
    profileDlRegistered: "Kayıt",
    profilePromoShort: "Kodu gir (en az 4 karakter).",
    profilePromoProcessing: "İşleniyor…",
    profilePromoErrNotFound: "Kod bulunamadı veya geçersiz.",
    profilePromoErrInactive: "Bu kod şu an kullanılamıyor.",
    profilePromoErrExpired: "Kodun süresi dolmuş.",
    profilePromoErrExhausted: "Kod kullanım limitine ulaştı.",
    profilePromoErrUsed: "Bu kodu bu hesapta zaten kullandın.",
    profilePromoErrCode: "Geçerli bir kod gir.",
    profilePromoErrGeneric: "İşlem yapılamadı.",
    profilePromoOkAdded: "+{added} coin eklendi. Güncel bakiye: {total} coin.",
    profilePromoOkSimple: "Coin eklendi.",
    profileSponsorsLoadFail: "Sponsor listesi yüklenemedi.",
    profileNoPurchases: "Henüz satın alınan ürün yok.",
    profilePurchaseApproved: "Onaylandı",
    profilePurchaseRejected: "Red",
    profilePurchasePending: "Beklemede",
    profileBjMaxBet: "En yüksek bahis: {n} coin",
    profileBjNoRecord: "Henüz blackjack kaydı yok",
    profileSlotMaxBet: "En yüksek bahis: {n} coin",
    profileSlotNoRecord: "Henüz slot kaydı yok",
    profileRouletteTitle: "Mocker Rulet geçmişi",
    profileRouletteMaxBet: "En yüksek bahis: {n} coin",
    profileRouletteNoRecord: "Henüz rulet kaydı yok",
    profileEmptyRoulette: "Henüz rulet turu yok.",
    profileWheelEmpty: "Henüz çark kaydı yok.",
    profileWheelPass: "Sonuç: Pas (coin yok)",
    profileWheelPrize: "Çark ödülü: +{amount} coin",
    profileWheelSegment: "Dilim:",
    profileWheelBadge: "Çark",
    profileComplaintsEmpty: "Henüz şikayet/öneri kaydı yok.",
    profileComplaintSponsor: "Sponsor",
    profileComplaintOther: "Diğer",
    profileComplaintSponsorLine: "Sponsor:",
    profileToastSession: "Oturum süresi doldu; tekrar giriş yap.",
    profileCryptoSaved: "Cüzdan adresleri kaydedildi.",
    profileSponsorSaved: "Sponsor hesap bilgileri kaydedildi.",
    bjSoft: "(yumuşak)",
    bjBackToGames: "← Oyunlar",
    bjGuestHint: "Oynamak için giriş yap.",
    bjOpenLogin: "Giriş yap",
    bjStateError:
      "Oyun durumu alınamadı veya oturum süresi doldu. Oyunlara dön veya sayfayı yenile.",
    bjRules:
      "6 deste, krupiye 17 ve üzerinde durur. Blackjack 3:2 öder. Çift: yalnız ilk iki kartta, ikinci bahis kadar coin düşer.",
    bjRulesBet: "Bahis {min}–{max} coin.",
    bjSoundToggle: "Ses aç/kapat",
    bjSoundOff: "🔇 Ses kapalı",
    bjSoundOn: "🔊 Ses açık",
    bjBalance: "Bakiye:",
    bjMsgYourTurn: "Sıra sende.",
    bjMsgHandDone: "El bitti.",
    bjMsgPickBet: "Bahis seç ve dağıt.",
    bjDealer: "Krupiye",
    bjDealerTotalAria: "Krupiye el toplamı",
    bjYou: "Sen",
    bjYourTotalAria: "Senin el toplamın",
    bjTotal: "Toplam",
    bjBetLabel: "Bahis (coin)",
    bjDeal: "Dağıt",
    bjHit: "Çek",
    bjDouble: "Çiftle",
    bjStand: "Dur",
    bjNewBet: "Yeni bahis",
    bjToastBetRange: "Bahis {min}–{max} coin arası olmalı.",
    bjToastInsufficient: "Yetersiz coin.",
    bjErrCoins: "Yetersiz coin.",
    bjErrBetRange: "Bahis 1–1000 coin olmalı.",
    bjErrPhase: "Bu işlem şu an geçerli değil.",
    bjErrDouble: "Çiftleme şu an mümkün değil.",
    bjErrInProgress: "Önce bu eli bitir.",
    bjErrGeneric: "İşlem yapılamadı.",
    slotGuestTitle: "Mocker Slot",
    slotGuestHint: "Oynamak için giriş yap.",
    slotLoadFail: "Oyun yüklenemedi. Oyunlara dön veya sayfayı yenile.",
    slotBadge3: "Progressive · 3 makara",
    slotLimitsHint: "Bahis {min}–{max} coin · jackpot havuzu · sunucu doğrulamalı",
    slotBetLabel: "Bahis",
    slotSpin: "Çevir",
    slotMaxBet: "Max",
    slotLastWin: "Son kazanç",
    slotJackpotsTitle: "Progressive jackpot",
    slotJpMini: "Mini",
    slotJpMinor: "Minor",
    slotJpMajor: "Major",
    slotJpGrand: "Grand",
    slotPayTitle: "Ödeme tablosu",
    slotPayFooter:
      "Üçlü veya yan yana ikili ödeme. Üç jackpot sembolü veya şanslı çeviride Mini / Minor / Major / Grand havuzlarından ödül. Her bahisin %3'ü havuzlara eklenir.",
    slotSymCherry: "Kiraz",
    slotSymLemon: "Limon",
    slotSymBell: "Zil",
    slotSymDiamond: "Elmas",
    slotSymSeven: "Yedi",
    slotSymJackpot: "Jackpot",
    slotToastBet: "Bahis {min}–{max} coin.",
    slotSpinning: "Çeviriliyor…",
    slotWinMsg: "{msg} +{payout} coin (net {net})",
    slotToastWin: "Kazanç: {payout} coin",
    slotErrBetRange: "Bahis {min}–{max} coin olmalı.",
    slotErrGeneric: "İşlem yapılamadı.",
    gamesNavigateBack: "Oyunlara dön",
    bjFetchErrorBeforeLink: "Oyun durumu alınamadı veya oturum süresi doldu.",
    bjFetchErrorAfterLink: "veya sayfayı yenile.",
    slotLoadErrorBeforeLink: "Oyun yüklenemedi.",
    slotLoadErrorAfterLink: "veya sayfayı yenile.",
    bjErrAuth: "Oturum gerekli.",
    bjNewHand: "Yeni el",
    slotWinExclaim: "Kazandın!",
    slotTryAgain: "Bu sefer olmadı — tekrar dene.",
    rouletteGuestTitle: "Mocker Rulet",
    rouletteGuestHint: "Oynamak için giriş yap.",
    rouletteLoadFail: "Oyun yüklenemedi. Oyunlara dön veya sayfayı yenile.",
    rouletteBadgeSuper: "Tek sıfır · Mocker Rulet",
    rouletteLimitsHint: "Bahis {min}–{max} coin · sonuç sunucuda",
    rouletteBetLabel: "Bahis",
    rouletteSpin: "Çevir",
    rouletteSpinning: "Dönüyor…",
    rouletteSelectBet: "Bahis türü",
    rouletteSelectNumber: "Sayı seç (0–36)",
    roulettePayTitle: "Ödemeler",
    roulettePayDozenShort: "Düzine (1–3)",
    roulettePayColumnShort: "Kolon (1–3)",
    roulettePayFooter:
      "Tek sayı 35:1 (kazançta 36× bahis iade), renk/tek-çift/1–18/19–36 1:1, düzine ve kolon 2:1.",
    rouletteBetStraight: "Tek sayı",
    rouletteBetRed: "Kırmızı",
    rouletteBetBlack: "Siyah",
    rouletteBetEven: "Çift",
    rouletteBetOdd: "Tek",
    rouletteBetLow: "1–18",
    rouletteBetHigh: "19–36",
    rouletteBetDozen: "Düzine {n}",
    rouletteBetColumn: "Kolon {n}",
    rouletteToastBet: "Bahis {min}–{max} coin.",
    rouletteErrBetRange: "Bahis {min}–{max} coin olmalı.",
    rouletteErrGeneric: "İşlem yapılamadı.",
    rouletteLoadErrorBeforeLink: "Oyun yüklenemedi.",
    rouletteLoadErrorAfterLink: "veya sayfayı yenile.",
    rouletteWinMsg: "{msg} · Çıkan: {num} · +{payout} coin (net {net})",
    rouletteToastWin: "Kazanç: {payout} coin",
    rouletteResult: "Sonuç",
    roulettePointer: "Top burada durur",
    rouletteFeltTitle: "Bahis masası",
    rouletteFeltHint: "Kutuya tıkla — jeton geçerli bahisi gösterir. Çevir ile oynarsın.",
    rouletteFeltDozen1: "1–12",
    rouletteFeltDozen2: "13–24",
    rouletteFeltDozen3: "25–36",
    rouletteFeltDozen1Tbl: "1'İNCİ 12",
    rouletteFeltDozen2Tbl: "2'NCİ 12",
    rouletteFeltDozen3Tbl: "3'ÜNCÜ 12",
    rouletteFeltEvenLbl: "ÇİFT",
    rouletteFeltOddLbl: "TEK",
    rouletteFeltColShort: "2:1",
    profileRouletteLoss: "Kayıp",
    profileRouletteBet: "Bahis türü",
  },
  en: {
    navHome: "Home",
    navMarket: "Market",
    navBonuses: "Bonuses",
    navPromoCodes: "Promotion codes",
    navTickets: "Tickets",
    navEvents: "Events",
    navNews: "News",
    navLeaderboard: "Leaderboard",
    navGamdomTurnuva: "Gamdom wagering tournament",
    navWheel: "Lucky wheel",
    navGames: "Games",
    navGameSelector: "Game picker",
    gameSelectorEyebrow: "Game picker",
    gameSelectorTitle: "Game picker",
    gameSelectorSubtitle: "Pick a random game!",
    gameSelectorProvider: "Select provider:",
    gameSelectorSpin: "Spin and pick!",
    gameSelectorLoading: "Loading games…",
    gameSelectorEmpty: "No games found for this provider.",
    gameSelectorError: "Could not load games. Try again later.",
    gameSelectorProvidersLoading: "Loading providers…",
    gameSelectorProvidersError: "Could not load providers.",
    gameSelectorSelected: "Selected game: {game}",
    gameSelectorSelectedBadge: "Selected game",
    gameSelectorPlay: "Play game",
    gameSelectorSpinAgain: "Spin again",
    gameSelectorModalSubtitle: "Continue on one of our partner sites.",
    gameSelectorSponsorsTitle: "Partner sites",
    gameSelectorSponsorsLead: "Tap a site below to start playing.",
    gameSelectorSponsorsEmpty: "No partner sites available right now.",
    gameSelectorRtp: "RTP: {rtp}%",
    navComplaints: "Feedback",
    navAffiliate: "Affiliate",
    navTelegramInvite: "Telegram invites",
    navSpecialOdds: "Special odds",
    tgInviteEyebrow: "Telegram",
    tgInviteTitle: "Invite to the group, earn coins",
    tgInviteSubtitle:
      "Earn coins for each new member who joins via your personal invite link. Verify Telegram first.",
    tgInviteGuestHint: "Log in to get your invite link and earn rewards.",
    tgInviteRewardPer: "Each successful invite: {coins} coins",
    tgInviteCampaignPaused: "The invite campaign is off or not configured yet.",
    tgInviteYourLink: "Your invite link",
    tgInviteTelegramStatus: "Telegram status",
    tgInviteTelegramRequired: "Link your Telegram account to your site profile first.",
    tgInviteTelegramOk: "Linked: {user}",
    tgInviteVerifyBtn: "Verify with Telegram",
    tgInviteLinkLabel: "Group invite link",
    tgInviteLinkPlaceholder: "Create link",
    tgInviteCopy: "Copy",
    tgInviteCreateLink: "Create invite link",
    tgInviteRefreshLink: "Refresh link",
    tgInviteRule1: "The same Telegram account cannot earn twice.",
    tgInviteRule2: "Bots are ignored; you cannot invite yourself.",
    tgInviteRule3: "Only members with verified Telegram can create links.",
    tgInviteYourStats: "Your stats",
    tgInviteStatInvites: "Invites",
    tgInviteStatCoins: "Coins earned",
    tgInviteRank: "Your rank: #{rank}",
    tgInviteTop10: "Top inviters",
    tgInviteLeaderboardEmpty: "No invites yet.",
    tgInviteTelegramAlready: "Telegram is already linked.",
    tgInviteTelegramOpenBot: "Telegram opened; send /start to the bot.",
    tgInviteTelegramFail: "Could not start Telegram linking.",
    tgInviteCopied: "Link copied.",
    tgInviteCopyManual: "Select and copy the link.",
    tgInviteLinkFail: "Could not create invite link.",
    tgInviteLinkReady: "Your invite link is ready.",
    specialOddsEyebrow: "Special",
    specialOddsTitle: "Special Odds",
    specialOddsSubtitle: "Special odds and picks — stake with coins.",
    specialOddsMatchesHeading: "Markets",
    specialOddsLeagueDefault: "Football",
    specialOddsPredictionHeading: "PICK",
    specialOddsNoPredictionText: "Prediction coming soon.",
    specialOddsStatOdds: "Odds",
    specialOddsStatStakeRange: "Stake range",
    specialOddsStatPool: "Pool",
    specialOddsWaitingResults: "Waiting for results…",
    specialOddsPlayNow: "Place bet",
    specialOddsNoMatches: "No matches listed right now.",
    specialOddsStakeLabel: "Stake (coins)",
    specialOddsPlaceBet: "Place bet",
    specialOddsBettingClosed: "Betting closed or match started.",
    specialOddsLoginToBet: "Sign in to place a bet.",
    specialOddsMyBets: "My bets",
    specialOddsColTime: "Time",
    specialOddsColMatch: "Match",
    specialOddsColPick: "Pick",
    specialOddsColOdds: "Odds",
    specialOddsColStake: "Stake",
    specialOddsColStatus: "Status",
    specialOddsStatusPending: "Pending",
    specialOddsStatusWon: "Won",
    specialOddsStatusLost: "Lost",
    specialOddsStatusVoid: "Void",
    specialOddsPickFirst: "Pick 1, X or 2 first.",
    specialOddsBetOk: "Bet placed.",
    specialOddsErrCoins: "Not enough coins.",
    specialOddsErrAlready: "You already bet on this match.",
    specialOddsErrKickoff: "Match started; betting closed.",
    specialOddsErrGeneric: "Could not complete.",
    specialOddsResult: "Result",
    specialOddsParticipantsShort: "players",
    specialOddsParticipantsLabel: "Entries",
    specialOddsNoLimit: "no cap",
    specialOddsQuotaFull: "This market is full; no more players can join.",
    specialOddsTabActive: "Active",
    specialOddsTabHistory: "History",
    specialOddsHistoryHeading: "Settled markets",
    specialOddsNoHistory: "No history yet.",
    specialOddsStatusCancelled: "Cancelled",
    specialOddsStatusSettled: "Settled",
    specialOddsCancelledHint: "This market was cancelled; stakes were refunded.",
    specialOddsParticipantsTotal: "Total players",
    specialOddsErrFull: "Market is full.",
    navAnaSponsors: "Main sponsors",
    navSponsorlarTier: "Sites I play",
    navContact: "Contact",
    sectionQuickAccess: "Quick access",
    sectionExplore: "Explore",
    sectionSupport: "Support",
    quickPromoCode: "Promo code",
    quickPromoHint: "View codes",
    quickGames: "Games",
    quickGamesHint: "Browse games",
    quickWheel: "Wheel",
    quickWheelHint: "Spin the wheel",
    sidebarDailyBonus: "Daily points",
    sidebarDailyBonusHint: "+25 coins",
    sidebarDailyBonusTitle: "Once per day +25 coins",
    dailyBonusNeedLogin: "Sign in to claim your daily points.",
    dailyBonusSuccess: "+{n} {coin} added.",
    dailyBonusAlready: "You already claimed today’s reward. Come back tomorrow.",
    dailyBonusError: "Something went wrong. Try again later.",
    homeQuickActionsAria: "Promo code, lucky wheel, daily points",
    homePromoLabel: "Enter code",
    homePromoSubtitle: "Enter your code",
    homePromoCta: "Enter code",
    homeWheelLabel: "Wheel",
    homeWheelSubtitle: "Spin the wheel",
    homeWheelCta: "Spin wheel",
    homeDailyLabel: "Daily points",
    homeDailySubtitle: "Claim reward",
    homeDailyCta: "Claim",
    promoModalSubtitle: "Enter a code to claim coins.",
    promoModalNeedLogin: "Sign in to redeem a promo code.",
    footerGeneral: "General",
    footerContent: "Content",
    footerFollow: "Follow us",
    footerLegal: "Legal",
    footerLegalNav: "Legal links",
    footerPrivacy: "Privacy & Security",
    footerTerms: "Terms & Conditions",
    footerCookies: "Cookie Policy",
    legalNotFound: "Page not found.",
    legalNavTitle: "Legal pages",
    legalTocLabel: "On this page",
    legalSectionFallback: "Section {n}",
    legalContactTitle: "Have questions?",
    legalContactDesc: "Reach us via our contact channels for privacy, terms or cookie enquiries.",
    footerProvidedBy: "Provided By",
    footerZentraCode: "ZENTRACODE",
    footerSponsorlarGrup: "Sponsor showcase",
    homeSectionAnaSayfa: "HOME",
    homeSectionAnaSponsors: "MAIN SPONSORS",
    homeSocialStrip: "Social media",
    homeYoutubeFeedTitle: "Social media feeds",
    homeYoutubeChannelCta: "Visit channel",
    homeYoutubeLive: "LIVE",
    homeYoutubeStream: "STREAM",
    homeYoutubeUntitled: "YouTube video",
    homeYoutubeCarouselPrev: "Previous videos",
    homeYoutubeCarouselNext: "Next videos",
    homeRecentWinnersTitle: "Winners",
    homeRecentWinnersBadge: "Live",
    homeRecentWinnersMinutesAgo: "{n} min ago",
    homeRecentWinnersWinLine: " Mocker Coin Won",
    homeRecentWinnersMultiplier: "{n}X Won",
    homeEventsTitle: "Events",
    homeEventsJoin: "Join event",
    homeEventsViewDetail: "View details",
    homeEventsCountdownDay: "D",
    homeEventsCountdownHour: "H",
    homeEventsCountdownMin: "M",
    homeEventsCountdownSec: "S",
    homeEventsNoEnd: "No end date",
    homeEventsCarouselPrev: "Previous events",
    homeEventsCarouselNext: "Next events",
    homeTicketsTitle: "Tickets",
    homeTicketsJoin: "Tickets",
    homeTicketsCountdownDay: "D",
    homeTicketsCountdownHour: "H",
    homeTicketsCountdownMin: "M",
    homeTicketsCountdownSec: "S",
    homeTicketsNoEnd: "No end date",
    badgeOynadigim: "Sites I play",
    badgeGuvenilir: "Trusted sites",
    badgeRecommended: "Sites I play",
    badgeTrusted: "Trusted sites",
    sponsorCta: "Go to site",
    sponsorCopy: "Copy link",
    skeletonLoading: "Loading",
    seoTitleHome: "Mocker — Home | Official site",
    seoDescHome: "Mocker official home: main sponsors, market, wheel of fortune and leaderboard. Creator partnerships and current campaigns.",
    seoTitleMarket: "Mocker — Market",
    seoDescMarket: "Mocker market: redeem coins for products, rewards and campaigns. Shop and track requests from your account.",
    seoTitleBonuses: "Mocker — Bonuses",
    seoDescBonuses: "Latest welcome, trial and deposit bonuses from partner sites. All sponsor campaigns in one place.",
    seoTitlePromoCodes: "Mocker — Promo codes",
    seoDescPromoCodes: "Find all active promo codes shared on this page.",
    seoTitleTickets: "Mocker — Tickets",
    seoDescTickets: "Mocker ticket events: partner rules, participation steps and draw results.",
    seoTitleEvents: "Mocker — Events",
    seoDescEvents: "Mocker partner events: campaign rules, participation steps and results.",
    seoTitleNews: "Mocker — News",
    seoDescNews: "Mocker news and announcements: campaigns, updates and event summaries.",
    seoTitleSponsors: "Mocker — Main sponsors",
    seoDescSponsors: "Mocker main sponsors: partner sites, bonuses and current campaigns.",
    seoTitleContact: "Mocker — Contact",
    seoDescContact: "Contact Mocker: questions, partnerships and support via official channels.",
    seoTitlePrivacy: "Mocker — Privacy & Security",
    seoDescPrivacy: "Mocker privacy and security: how your personal data is processed and protected.",
    seoTitleTerms: "Mocker — Terms & Conditions",
    seoDescTerms: "Mocker terms and conditions for using the platform.",
    seoTitleCookies: "Mocker — Cookie Policy",
    seoDescCookies: "Mocker cookie policy: which cookies we use and your preferences.",
    seoTitleLeaderboard: "Mocker — Leaderboard",
    seoDescLeaderboard: "Mocker leaderboard: rankings and prize competitions. Live scores and community rivalry.",
    seoTitleWheel: "Mocker — Wheel of fortune",
    seoDescWheel: "Mocker wheel: spin and win rewards. Daily spins and coin prizes on the official platform.",
    seoTitleProfile: "Mocker — Profile",
    seoDescProfile: "Mocker user profile: coin balance, account settings and personal details.",
    seoTitleComplaints: "Mocker — Feedback",
    seoDescComplaints: "Mocker feedback form. Share complaints or suggestions; we review every submission.",
    seoTitleAffiliate: "Mocker — Affiliate",
    seoDescAffiliate: "Mocker affiliate transitions and partner referrals. Compliant routing and signup flows.",
    seoTitleTelegramInvite: "Mocker — Telegram invite",
    seoDescTelegramInvite: "Invite friends to Telegram, earn coins. Personal invite link and leaderboard.",
    seoTitleGames: "Mocker — Games",
    seoDescGames: "Mocker games: in-platform games and entertainment in a safe environment.",
    seoTitleGameSelector: "Mocker — Game picker",
    seoDescGameSelector: "Pick a random slot: choose a provider, spin and get a game suggestion.",
    seoTitleBlackjack: "Mocker — Blackjack",
    seoDescBlackjack: "Mocker Blackjack. Play with coins in a fair, rules-based experience.",
    seoTitleSlot: "Mocker — Slot",
    seoDescSlot: "Mocker 3-reel slot: bet, spin, instant payouts with server-side results.",
    seoTitleRoulette: "Mocker — Roulette",
    seoDescRoulette: "Mocker Roulette: single-zero wheel, coin bets, fair server results and smooth animation.",
    seoTitleSpecialOdds: "Mocker — Special odds",
    seoDescSpecialOdds: "Mocker special odds: coin predictions on selected matches, results after full time.",
    tgTwofaTitle: "Two-step verification",
    tgTwofaHint: "Enter the 6-digit code from your authenticator app.",
    tgTwofaSubmit: "Verify",
    tgTwofaInvalid: "Invalid code. Try again.",
    toastLinkCopied: "Link copied to clipboard.",
    toastCopyFailed: "Copy failed; try selecting the link manually.",
    headerSearchPlaceholder: "Search sponsors or content...",
    headerSearchSr: "Search site",
    headerSearchClear: "Clear search",
    searchPaletteAria: "Search sponsors",
    searchPaletteClose: "Close",
    searchPaletteLoading: "Loading sponsors…",
    headerSocial: "Social",
    headerSocialNav: "Social links",
    headerLogin: "Log in",
    headerRegister: "Sign up",
    headerProfile: "Profile",
    headerProfileMenuAria: "Account menu",
    headerCoin: "Coins",
    headerCoinBalance: "Coin balance",
    headerLangAria: "Language",
    themeToggleAria: "Light / dark theme",
    headerHomePage: "home",
    headerOpenMenu: "Open menu",
    chatOpenAria: "Open member chat",
    notificationsAria: "Notifications",
    notificationsAriaUnread: "Notifications, {n} unread",
    notificationsTitle: "Notifications",
    notificationsClose: "Close",
    notificationsMarkAll: "Mark all as read",
    notificationsEmpty: "No notifications yet.",
    notificationsLoading: "Loading…",
    notificationsLoadError: "Could not load notifications.",
    notificationsHasLink: "Go to link →",
    chatTitle: "Mocker Chat",
    chatSubtitle: "",
    chatClose: "Close",
    chatPlaceholder: "Type a message…",
    chatSend: "Send",
    chatEmpty: "No messages yet — say hi.",
    chatLoading: "Loading…",
    chatError: "Could not load chat. Refresh or try again later.",
    chatRateLimit: "You’re sending too fast; wait a few seconds.",
    chatMuted: "You’re temporarily muted in chat; you can send again when it expires.",
    chatYou: "You",
    chatModerator: "Moderator",
    chatEmojiAria: "Pick emoji to insert",
    chatEmojiPickerTitle: "Emoji",
    chatEmojiCatFaces: "Smileys",
    chatEmojiCatGestures: "Gestures",
    chatEmojiCatHearts: "Hearts & symbols",
    chatEmojiCatActivity: "Activity",
    chatGuestHint: "You can read messages. Sign in or register to send.",
    chatLoginToSend: "Sign in to send messages",
    bottomNavHome: "Home",
    bottomNavMarket: "Market",
    bottomNavMenu: "Menu",
    bottomNavGames: "Games",
    bottomNavChat: "Chat",
    bottomNavAria: "Bottom navigation",
    sidebarAria: "Site menu",
    sidebarMainNav: "Main navigation",
    sidebarCollapse: "Collapse / expand menu",
    sidebarClose: "Close menu",
    navProfile: "Profile",
    footerLeaderboard: "Leaderboard",
    footerAccountNav: "Account links",
    footerGeneralNav: "General links",
    footerContentNav: "Content links",
    footerDisclaimer:
      "Mocker is an independent platform providing entertainment-focused content. All information on this site is for informational purposes only. Mocker does not operate any betting or gambling activity. Users must comply with the laws applicable in their jurisdiction. Membership is not available to anyone under 18.",
    footerRights: "All rights reserved.",
    footerSocialSoon: "Social links coming soon.",
    sponsorLoadError:
      "Could not load sponsor data. Check your connection and the data/sponsors.json file.",
    sponsorListError: "Could not open sponsor list.",
    sponsorEmptySearch: "No sponsors match your search. Try another word or clear the search.",
    sponsorEmptySection: "No sponsors in this section yet.",
    sponsorCopyAriaSuffix: "— copy link",
    sponsorVisitAriaSuffix: "— visit site",
    marketPrice: "Price",
    marketBuy: "Buy",
    marketEmptyTitle: "The market is empty",
    marketEmptyHint: "New rewards will be added soon.",
    marketBalanceLabel: "Your balance",
    marketGuestHint: "Log in to purchase; your balance appears here.",
    marketLoginCta: "Log in or sign up",
    marketPageTitle: "Market",
    marketIntro:
      "Use your earned points to claim rewards from the cards in the market!\n\nMembers can receive a cash prize once per month.\nAccounts using multiple profiles will not receive refunds and may be banned from events.",
    marketSectionAria: "Products",
    marketSectionSr: "Rewards and balance items",
    marketCoinWord: "coins",
    marketToastInsufficient: "Insufficient coins.",
    marketToastSession: "Session expired; please log in again.",
    marketToastFailed: "Could not complete the purchase.",
    marketToastPurchasedPrefix: "Purchased:",
    marketStockLabel: "Stock left",
    marketStockOut: "Out of stock",
    marketBuyDisabled: "Sold out",
    marketToastOutOfStock: "This item is out of stock.",
    gamesEyebrow: "Games",
    gamesTitle: "Game hub",
    gamesBlackjackAlt: "Blackjack cover image",
    gamesBlackjackTitle: "Mocker Blackjack",
    gamesCategoryCard: "Cards",
    gamesBlackjackDesc: "Beat the dealer toward 21. Bet: 1–1000 coins.",
    gamesLoginToPlay: "Log in to play",
    gamesCategorySlot: "Slot",
    gamesSlotTitle: "Mocker Slot",
    gamesSlotDescGuest: "3 reels, instant payouts. Triple symbols mean big multipliers. Bet: 1–1000 coins.",
    gamesSlotDescUser: "3 reels, triple symbols with high multipliers. Bet: 1–1000 coins.",
    gamesCategoryRoulette: "ROULETTE",
    gamesRouletteTitle: "Mocker Roulette",
    gamesRouletteDescGuest:
      "Classic layout, fast-spinning wheel and sound. Red/black, straight, dozens & columns. Bet: 1–1000 coins.",
    gamesRouletteDescUser: "Super Roulette: server RNG, standard payouts. Bet: 1–1000 coins.",
    gamesPlay: "Play",
    wheelEyebrow: "Lucky wheel",
    wheelTitleDaily: "Daily reward wheel",
    wheelTitleMain: "Lucky wheel",
    wheelTitleReward: "Reward wheel",
    maintenanceEyebrow: "Maintenance",
    maintenanceTitle: "Site under maintenance",
    maintenanceMessage:
      "Mocker is undergoing brief maintenance. We will be back online as soon as possible.",
    maintenanceHint: "Thank you for your patience.",
    wheelDisabledMsg:
      "The wheel is currently disabled. It will be available again as soon as possible.",
    wheelEyebrowDaily: "Daily reward",
    wheelGuestHint: "Log in to spin the wheel.",
    wheelCooldownRule: "Spin once every {hours} hours; prizes:",
    wheelCardSubtitle: "Lucky wheel",
    wheelSpinCredit: "One spin every {hours} hours",
    wheelBalancePrefix: "Balance",
    wheelSpinHeading: "Spin the wheel",
    wheelNextSpinLabel: "Next spin:",
    wheelBtnSpinning: "Spinning…",
    wheelBtnWait: "Wait for next spin",
    wheelBtnSpin: "Spin the wheel",
    wheelPrizePass: "Skip",
    wheelPrizeCoin: "Mocker Coins",
    wheelToastDisabled: "The wheel is disabled.",
    wheelToastCooldown: "You cannot spin again until the cooldown ends.",
    wheelToastAuth: "Login required.",
    wheelToastUnavailable: "The wheel is unavailable right now.",
    wheelToastPass: "Skip this time; better luck on your next spin!",
    wheelToastWin: "Congrats! You won +{amount} Mocker Coin.",
    affiliateEyebrow: "Affiliate",
    affiliateTitle: "Affiliate transfer request",
    affiliateGuestHint: "You need to log in to submit a request.",
    affiliateLabelSponsor: "Sponsor",
    affiliateSponsorPlaceholder: "Select a sponsor",
    affiliateLabelDate: "Investment date (optional)",
    affiliateDateHint: "If you invested, pick a date; otherwise leave blank.",
    affiliateLabelMessage: "Description",
    affiliateMessagePlaceholder: "Describe your affiliate transfer request, username, or extra notes…",
    affiliateMessageRules: "At least 8 and at most 2000 characters.",
    affiliateSender: "From:",
    affiliateSubmit: "Submit request",
    affiliateToastSelectSponsor: "Select a sponsor first.",
    affiliateToastMessageShort: "Description must be at least 8 characters.",
    affiliateToastFail: "Could not send. Check your session and fields.",
    affiliateToastAuth: "Session expired; please log in again.",
    affiliateToastSponsor: "You must select a sponsor.",
    affiliateToastMessage: "Description must be at least 8 characters.",
    affiliateToastMessageLong: "Description can be at most 2000 characters.",
    affiliateToastInvestmentDate: "Invalid investment date (clear or pick a valid date).",
    affiliateToastDb: "Could not connect to the database.",
    affiliateToastSchema: "Database is outdated (affiliate table). Contact an admin.",
    affiliateToastSave: "Could not save. Try again later or contact an admin.",
    affiliateToastMethod: "The server did not accept the request.",
    affiliateToast404: "API not found (folder / server configuration).",
    affiliateToastNetwork: "Network error: check your connection or refresh.",
    affiliateToastErrPrefix: "Could not complete",
    affiliateToastServer: "Server error. Try again later.",
    affiliateToastSuccess: "Request received. We will get back to you after review.",
    complaintsEyebrow: "Support",
    complaintsTitle: "Feedback",
    complaintsGuestHint: "You need to log in to submit.",
    complaintsLabelCategory: "Category",
    complaintsCatSponsor: "Sponsor",
    complaintsCatOther: "Other",
    complaintsLabelWhichSponsor: "Which sponsor?",
    complaintsSponsorPlaceholder: "Select a sponsor",
    complaintsLabelMessage: "Message",
    complaintsMessagePlaceholder: "Describe your complaint or suggestion in detail…",
    complaintsMessageRules: "At least 8 and at most 2000 characters.",
    complaintsSender: "From:",
    complaintsSubmit: "Send",
    complaintsToastSelectSponsor: "Select a sponsor first.",
    complaintsToastMessageShort: "Message must be at least 8 characters.",
    complaintsToastAuth: "Session expired; please log in again.",
    complaintsToastDb: "Database connection error.",
    complaintsToastFail: "Could not send. Check the fields.",
    complaintsToastSuccess: "Feedback received. Status: pending.",
    pagePromoCodesEyebrow: "Promotion",
    pagePromoCodesTitle: "Promotion Codes",
    pagePromoCodesSubtitle:
      "You can access all our shared promotion codes on this page!",
    pageBonusesEyebrow: "Campaign",
    pageBonusesTitle: "BONUSES",
    pageBonusesSubtitle:
      "Welcome, trial and deposit bonuses from partner sites — all in one place.",
    bonusesLoading: "Loading bonuses…",
    bonusesEmpty: "No bonus campaigns live right now. Check back soon.",
    bonusesLoadError: "Could not load bonuses. Please try again later.",
    bonusesPromoCodeLabel: "Promo code (if any)",
    bonusesNoExpiry: "No expiry set",
    bonusesExpired: "Expired",
    bonusesExpiresInDays: "Expires in {n} days",
    bonusesExpiresInHours: "Expires in {n} hours",
    bonusesExpiresInMinutes: "Expires in {n} min",
    bonusesExpiresOn: "Ends",
    promoCodesLoading: "Loading promotion codes…",
    promoCodesEmpty: "No promotion codes published right now. Check back soon.",
    promoCodesLoadError: "Could not load promotion codes. Try again later.",
    promoCodesCodeLabel: "Promo code",
    promoCodesCopyAria: "Copy {site} promo code",
    promoCodesNoExpiry: "No expiry set",
    promoCodesExpired: "Expired",
    promoCodesExpiresInDays: "Expires in {n} days",
    promoCodesExpiresInHours: "Expires in {n} hours",
    promoCodesExpiresInMinutes: "Expires in {n} min",
    promoCodesExpiresOn: "Ends",
    pageTicketsEyebrow: "Event",
    pageTicketsTitle: "TICKETS",
    pageTicketsSubtitle:
      "How to join partner-site Mocker ticket events and view draw results on this page.",
    ticketsLoading: "Loading ticket events…",
    ticketsEmpty: "No ticket events right now. New draws will be added soon.",
    ticketsLoadError: "Could not load tickets. Try again later.",
    ticketsStatusOpen: "Open",
    ticketsStatusClosed: "Closed",
    ticketsStatusDrawn: "Drawn",
    ticketsParticipants: "Entries",
    ticketsPrize: "Prize",
    ticketsCostCoins: "Ticket: {n} coins",
    ticketsCostFree: "Free ticket",
    ticketsEndsAt: "Ends",
    ticketsWinnerSlots: "{n} winners",
    ticketsMyTickets: "My tickets",
    ticketsWinnerBadge: "Winner",
    ticketsWinnersTitle: "Winners",
    ticketsNoWinnersListed: "Draw completed; no winners listed.",
    ticketsRequestBtn: "Request ticket",
    ticketsRequestHide: "Hide rules",
    ticketsRulesTitle: "Ticket rules",
    ticketsHowToTitle: "How to join",
    ticketsRequestStep1: "Go to {site} and sign in with your account.",
    ticketsRequestStep2: "Submit your request for this Mocker event in the site's ticket / draw section.",
    ticketsRequestStep3: "Approved requests are added to the draw pool.",
    ticketsRequestStep4: "Results are published here; winners are listed below.",
    ticketsSiteLoginBtn: "Sign in on {site}",
    ticketsSiteLoginBtnGeneric: "Go to partner site",
    ticketsMockerLoginHint: "Sign in to your Mocker account first to request a ticket.",
    ticketsMockerLoginBtn: "Sign in to Mocker",
    ticketsRequestNote:
      "Ticket requests are completed on the partner site. Tickets are not issued automatically on Mocker.",
    ticketsRulesDefault:
      "Partner site rules apply during the event. Each member may only submit the allowed number of requests. Fraud, multiple accounts, or false information leads to disqualification.",
    ticketsClosedHint: "This event is closed for ticket requests.",
    ticketsBackToList: "Back to events",
    ticketsTabRules: "Rules",
    ticketsTabHowTo: "How to join",
    ticketsTotalTickets: "Total tickets",
    ticketsTotalTicketsUnit: "entries",
    ticketsStart: "Start",
    ticketsEnd: "End",
    ticketsActiveBadge: "Active",
    ticketsWheelSideLink: "Spin wheel",
    ticketsViewDetail: "Details & request",
    pageEventsEyebrow: "Campaign",
    pageEventsTitle: "EVENTS",
    pageEventsSubtitle:
      "How to join partner-site Mocker events and view results on this page.",
    eventsLoading: "Loading events…",
    eventsEmpty: "No events right now. New campaigns will be added soon.",
    eventsLoadError: "Could not load events. Try again later.",
    eventsStatusOpen: "Open",
    eventsStatusClosed: "Closed",
    eventsStatusDrawn: "Completed",
    eventsParticipants: "Participants",
    eventsPrize: "Prize",
    eventsRequestBtn: "Request to join",
    eventsViewDetail: "Details & request",
    eventsRulesDefault:
      "Site rules apply for the duration of the event. Each member may only submit the allowed number of requests. Fraud, multiple accounts, or false information leads to disqualification.",
    eventsHowToTitle: "How to join",
    eventsRequestStep1: "Go to {site} and log in with your account.",
    eventsRequestStep2: "Submit your request for the Mocker event from the partner site.",
    eventsRequestStep3: "Approved requests are added to the event pool.",
    eventsRequestStep4: "Results are published here; winners are listed below.",
    eventsSiteLoginBtn: "Log in to {site}",
    eventsSiteLoginBtnGeneric: "Go to partner site",
    eventsMockerLoginHint: "Log in to your Mocker account first to submit a request.",
    eventsMockerLoginBtn: "Log in to Mocker",
    eventsRequestNote:
      "Participation requests are completed on the partner site. Mocker does not auto-register you.",
    eventsBackToList: "Back to events",
    eventsTabRules: "Rules",
    eventsTabHowTo: "How to join",
    eventsTotalParticipants: "Total participants",
    eventsTotalParticipantsUnit: "",
    eventsStart: "Start",
    eventsEnd: "End",
    eventsActiveBadge: "Active",
    eventsWheelSideLink: "Spin wheel",
    pageNewsEyebrow: "Latest",
    pageNewsTitle: "NEWS",
    pageNewsSubtitle: "Campaigns and announcements — open a card for details.",
    newsLoading: "Loading news…",
    newsEmpty: "No news yet. Check back soon.",
    newsLoadError: "Could not load news. Please try again later.",
    newsDetailsBtn: "Details",
    newsModalNoBody: "No detail text available.",
    pageRecommendedKicker: "Elite selection",
    pageTrustedKicker: "VIP selection",
    pageSponsorlarTierKicker: "Sponsor showcase",
    pageAnaSponsorsTitle: "MAIN SPONSORS",
    leaderboardEyebrow: "Ranking",
    leaderboardTitle: "Leaderboard",
    leaderboardSubtitle: "Top 20 members by coin ranking.",
    leaderboardEmptyWarn: "Could not load list or no members yet.",
    leaderboardEmpty: "No members yet.",
    leaderboardPoints: "Score",
    leaderboardColPlayer: "Player",
    leaderboardTop3Aria: "Top three",
    leaderboardRestAria: "Rest of ranking",
    leaderboardRestSr: "Ranks 4–20",
    leaderboardWarnTitle: "Could not reach database.",
    leaderboardWarnBody:
      "Ranking may appear empty. On hosting, <code class=\"rounded bg-black/30 px-1.5 py-0.5 text-xs\">data/users.sqlite</code> must be writable; PHP must have <code class=\"rounded bg-black/30 px-1.5 py-0.5 text-xs\">pdo_sqlite</code> enabled.",
    leaderboardLoad: "Loading…",
    leaderboardFail: "Could not load leaderboard",
    leaderboardFailHint:
      "Open /api/leaderboard.php directly — if you don’t see JSON, check PHP or server path.",
    leaderboardFailCache: "Cache: Ctrl+F5. Local: php -S localhost:8080 router.php",
    seoTitleGamdomTurnuva: "Gamdom wagering tournament | Mocker",
    seoDescGamdomTurnuva: "Gamdom wagering tournament leaderboard and prize pool.",
    gamdomDefaultTitle: "Gamdom Wagering Event",
    gamdomCountdownLabel: "Time remaining",
    gamdomCountDays: "Days",
    gamdomCountHours: "Hours",
    gamdomCountMinutes: "Minutes",
    gamdomCountSeconds: "Seconds",
    gamdomRules: "Terms & conditions",
    gamdomRulesClose: "Close",
    gamdomRulesEmpty: "Rules have not been added yet.",
    gamdomRulesExternalHint: "Full rules are available on an external link.",
    gamdomRulesOpenLink: "Open rules",
    gamdomReward: "Prize",
    gamdomHiddenUser: "Hidden user",
    gamdomColPlayer: "Player",
    gamdomColWager: "Wager",
    gamdomColReward: "Prize",
    gamdomTop3Aria: "Top three",
    gamdomListAria: "Ranks 4–50",
    gamdomPeriodsAria: "Period selection",
    gamdomEmpty: "No ranking data yet.",
    gamdomDisabled: "Tournament is currently off.",
    gamdomLoad: "Loading…",
    gamdomFail: "Failed to load tournament",
    gamdomFailHint: "Enable it in admin or try again later.",
    gamdomApiFallback: "Live API is unavailable; showing cached backup data.",
    popupEyebrow: "Announcement",
    popupDefaultTitle: "Special announcement",
    popupClose: "Close",
    popupNever: "Don't show again",
    popupCta: "Learn more",
    authClose: "Close",
    authEyebrowAccount: "Account",
    authEyebrowNew: "New account",
    authLoginSubtitle: "Enter your username and password to sign in.",
    authPlaceholderLoginPassword: "Enter your password",
    authLabelIdentity: "Username or email",
    authPlaceholderIdentity: "e.g. your_username or mail@site.com",
    authLabelPassword: "Password",
    authRegisterSubtitle: "Create your account with username, email, and password.",
    authLabelUsername: "Username",
    authPlaceholderUsername: "Your username",
    authLabelEmail: "Email",
    authLabelPhone: "Phone",
    authPlaceholderPhone: "05xx xxx xx xx",
    authErrPhoneInvalid: "Enter a valid phone number.",
    authPlaceholderEmail: "example@mail.com",
    authLabelPassword2: "Confirm password",
    authPlaceholderPassword2: "Repeat password",
    authPlaceholderPassword: "At least 8 characters",
    authNoAccount: "No account?",
    authHasAccount: "Already have an account?",
    authErrFillAll: "Fill in all fields.",
    authErrInvalidCreds: "Wrong username/email or password.",
    authErrAttemptsLeft: "attempts left)",
    authErrCsrf: "Security check failed. Refresh (Ctrl+F5) and try again.",
    authErrLoginFail: "Could not sign in.",
    authErrExternalAuthDisabled:
      "Legacy account sign-in is unavailable: RX API Bearer token is not configured on the server. Contact support or ask an admin to reset your password.",
    authErrInactive: "Your account is inactive. Please contact support.",
    authLabelTwofa: "Verification code (2FA)",
    authPlaceholderTwofa: "123456",
    authTwofaHint: "Enter the 6-digit code from your authenticator app.",
    authTwofaStepToast: "Password OK. Enter your 2FA code.",
    authErrTwofaRequired: "Enter your 2FA code.",
    authErrTwofaInvalid: "Invalid 2FA code.",
    authErrTwofaExpired: "2FA timed out. Please sign in again.",
    authWelcome: "Welcome.",
    authErrUsernameShort: "Username must be at least 2 characters.",
    authErrEmailInvalid: "Enter a valid email.",
    authErrPasswordShort: "Password must be at least 8 characters.",
    authErrPasswordMismatch: "Passwords do not match.",
    authErrTaken: "This username or email is already registered.",
    authErrUsernameRules: "Username must be 2–64 characters.",
    authErrRegisterFail: "Registration could not be completed.",
    authOrDivider: "or",
    authTelegramHint: "Continue with your Telegram account.",
    authTelegramBotHint: "Open the bot and tap Start to verify your Telegram account.",
    authTelegramBotLogin: "Sign in with Telegram",
    authTelegramBotRegister: "Register with Telegram",
    authTelegramBotOpening: "Opening Telegram…",
    authTelegramBotWait: "Complete verification in the bot; this page will sign you in automatically.",
    authTelegramBotExpired: "Verification expired. Try again.",
    authTelegramBotSession: "Session mismatch. Refresh the page and try again.",
    authTelegramFail: "Could not sign in with Telegram.",
    authTelegramInvalid: "Telegram verification failed. Try again.",
    authTelegramUnavailable: "Telegram sign-in is unavailable right now.",
    authTelegramDomainInvalid:
      "If the Telegram button is missing, add domain {domain} for @{bot} in @BotFather (/setdomain). Add www and non-www separately if needed.",
    profileCompleteBannerTitle: "Complete your account",
    profileCompleteBannerHint: "You signed up with Telegram. Set your email, phone, and password to continue.",
    profileCompleteTitle: "Email, phone and password",
    profileCompleteSubtitle: "Required to sign in to your account and keep it secure.",
    profileCompleteSubmit: "Save and continue",
    profileCompleteSuccess: "Profile details saved.",
    profileCompleteRequiredToast: "Set your email, phone, and password to complete your account.",
    profilePasswordChangeBannerTitle: "Update your password",
    profilePasswordChangeBannerHint:
      "Your session has expired. For your security, you must set a new password to continue.",
    profilePasswordChangeTitle: "Set a new password",
    profilePasswordChangeSubtitle: "Enter your current password, then choose a new one to continue using the site.",
    profilePasswordChangeCurrent: "Current password",
    profilePasswordChangeSubmit: "Update password",
    profilePasswordChangeSuccess: "Your password has been updated.",
    profilePasswordChangeRequiredToast: "Set a new password to continue.",
    authErrPasswordChangeFail: "Could not update password. Try again.",
    authErrCurrentPassword: "Current password is incorrect.",
    authSuccessRegister: "Registration complete. {bonus} coins added to your account.",
    profileEyebrow: "Account",
    profileTitle: "Profile",
    profileSubtitle: "Your account info and purchases.",
    profileLoadingTitle: "Loading",
    profileLoadingHint: "Loading profile…",
    profileAuthTitle: "Sign in required",
    profileAuthHint: "Sign in from the top right to view your profile.",
    profileTabInfo: "Profile",
    profileTabTelegram: "Telegram invites",
    profileTabCrypto: "Account",
    profileTabSponsors: "Sponsors",
    profileTabWheel: "Wheel history",
    profileTabPurchases: "Purchases",
    profileTabBlackjack: "Blackjack",
    profileTabSlot: "Slot",
    profileTabRoulette: "Super Roulette",
    profileTabComplaints: "Complaints",
    profileInfoTitle: "Info",
    profileTwofaTitle: "Two-factor authentication (2FA)",
    profileTwofaSubtitle: "Protect your account with Google Authenticator or a similar app.",
    profileTwofaStatusOff: "Off",
    profileTwofaStatusOn: "On",
    profileTwofaActiveHint: "2FA is on. Contact support to turn it off.",
    profileTwofaSetupBtn: "Set up 2FA",
    profileTwofaConfirmBtn: "Enable",
    profileTwofaSecretLabel: "Manual key",
    profileTwofaCodeLabel: "App code",
    profileTwofaInvalid: "Invalid code. Try again.",
    profileTwofaEnabledToast: "2FA enabled.",
    profileTelegramConnectTitle: "Connect Telegram",
    profileTelegramConnectHint: "Get your invite link, invite to the group and earn coins.",
    profileTelegramConnectHintLinked: "Telegram connected. Tap to manage your invite link.",
    profileTelegramConnectCta: "Telegram invite",
    profileLevelTitle: "Level",
    profileLevelNext: "Next level",
    profileLevelMax: "Max level",
    profileLevelXp: "Total XP",
    profileHeroLevel: "Level",
    profileHeroRank: "Level {n}",
    profileHeroProgress: "Progress",
    profileHeroXpBar: "Level {next}: {cur} / {max} XP",
    profileHeroXpTotal: "{n} XP total",
    profileHeroMemberSince: "Member · {date}",
    profilePromoTitle: "Promo code",
    profilePromoPlaceholder: "e.g. NEWYEAR2026",
    profilePromoUse: "Apply",
    profileCryptoTitle: "My account details",
    profileCryptoHint: "Save crypto wallet addresses for payments and verification.",
    profileSave: "Save",
    profileSponsorsTitle: "My sponsor account details",
    profileSponsorsHint:
      "Enter the username/ID you use on sponsor sites you registered on. Visible in admin.",
    profileWheelTitle: "Wheel history",
    profilePurchasesTitle: "Purchases",
    profileBjTitle: "Blackjack history",
    profileSlotTitle: "Super Slot history",
    profileComplaintsTitle: "Complaint / feedback status",
    profileLogout: "Sign out",
    profileWalletAddress: "Wallet address",
    profileSponsorAccountPlaceholder: "Enter member ID or username",
    profileCryptoPlaceholderBtc: "Enter BTC address",
    profileCryptoPlaceholderEth: "Enter ETH address",
    profileCryptoPlaceholderUsdtErc: "Enter USDT ERC-20 address",
    profileCryptoPlaceholderUsdtTrc: "Enter USDT TRC-20 address",
    profileCryptoPlaceholderLtc: "Enter LTC address",
    profileCryptoPlaceholderTrx: "Enter TRX address",
    profileCryptoPlaceholderDoge: "Enter Doge address",
    profileCryptoPlaceholderOther: "Fill if additional info is requested",
    profileCryptoOtherLabel: "Other",
    profileBjWin: "Win",
    profileBjLose: "Loss",
    profileBjPush: "Push",
    profileBjBlackjack: "Blackjack",
    profileBjBet: "Bet",
    profileBjDouble: "Double",
    profileBjNormal: "Normal",
    profileBjRisk: "Risk",
    profileBjPayout: "Payout",
    profileBjNet: "Net",
    profileSlotLoss: "Loss",
    profileSlotReel: "Reel",
    profileEmptyBj: "No completed blackjack hands yet.",
    profileEmptySlot: "No slot spins yet.",
    profilePageLabel: "Page {cur} / {total}",
    profilePrevPage: "Previous page",
    profileNextPage: "Next page",
    profileLogoutToast: "Signed out.",
    profileDlUsername: "Username",
    profileDlEmail: "Email",
    profileDlPhone: "Phone",
    profileDlSpent: "Total spent",
    profileDlRegistered: "Registered",
    profilePromoShort: "Enter a code (at least 4 characters).",
    profilePromoProcessing: "Processing…",
    profilePromoErrNotFound: "Code not found or invalid.",
    profilePromoErrInactive: "This code is not available right now.",
    profilePromoErrExpired: "This code has expired.",
    profilePromoErrExhausted: "This code has reached its usage limit.",
    profilePromoErrUsed: "You already used this code on this account.",
    profilePromoErrCode: "Enter a valid code.",
    profilePromoErrGeneric: "Could not complete.",
    profilePromoOkAdded: "+{added} coins added. Balance: {total} coins.",
    profilePromoOkSimple: "Coins added.",
    profileSponsorsLoadFail: "Could not load sponsor list.",
    profileNoPurchases: "No purchases yet.",
    profilePurchaseApproved: "Approved",
    profilePurchaseRejected: "Rejected",
    profilePurchasePending: "Pending",
    profileBjMaxBet: "Max bet: {n} coins",
    profileBjNoRecord: "No blackjack records yet",
    profileSlotMaxBet: "Max bet: {n} coins",
    profileSlotNoRecord: "No slot records yet",
    profileRouletteTitle: "Super Roulette history",
    profileRouletteMaxBet: "Max bet: {n} coins",
    profileRouletteNoRecord: "No roulette records yet",
    profileEmptyRoulette: "No roulette rounds yet.",
    profileWheelEmpty: "No wheel records yet.",
    profileWheelPass: "Result: Pass (no coins)",
    profileWheelPrize: "Wheel prize: +{amount} coins",
    profileWheelSegment: "Segment:",
    profileWheelBadge: "Wheel",
    profileComplaintsEmpty: "No complaints/feedback yet.",
    profileComplaintSponsor: "Sponsor",
    profileComplaintOther: "Other",
    profileComplaintSponsorLine: "Sponsor:",
    profileToastSession: "Session expired; sign in again.",
    profileCryptoSaved: "Wallet addresses saved.",
    profileSponsorSaved: "Sponsor account details saved.",
    bjSoft: "(soft)",
    bjBackToGames: "← Games",
    bjGuestHint: "Sign in to play.",
    bjOpenLogin: "Sign in",
    bjStateError:
      "Could not load game state or session expired. Return to games or refresh.",
    bjRules:
      "6 decks, dealer stands on 17+. Blackjack pays 3:2. Double: first two cards only; second bet amount is deducted.",
    bjRulesBet: "Bet {min}–{max} coins.",
    bjSoundToggle: "Toggle sound",
    bjSoundOff: "🔇 Sound off",
    bjSoundOn: "🔊 Sound on",
    bjBalance: "Balance:",
    bjMsgYourTurn: "Your turn.",
    bjMsgHandDone: "Hand over.",
    bjMsgPickBet: "Pick a bet and deal.",
    bjDealer: "Dealer",
    bjDealerTotalAria: "Dealer hand total",
    bjYou: "You",
    bjYourTotalAria: "Your hand total",
    bjTotal: "Total",
    bjBetLabel: "Bet (coins)",
    bjDeal: "Deal",
    bjHit: "Hit",
    bjDouble: "Double",
    bjStand: "Stand",
    bjNewBet: "New bet",
    bjToastBetRange: "Bet must be between {min} and {max} coins.",
    bjToastInsufficient: "Not enough coins.",
    bjErrCoins: "Not enough coins.",
    bjErrBetRange: "Bet must be 1–1000 coins.",
    bjErrPhase: "This action is not valid now.",
    bjErrDouble: "Doubling is not available now.",
    bjErrInProgress: "Finish this hand first.",
    bjErrGeneric: "Could not complete.",
    slotGuestTitle: "Super Slot",
    slotGuestHint: "Sign in to play.",
    slotLoadFail: "Could not load game. Return to games or refresh.",
    slotBadge3: "Progressive · 3 reels",
    slotLimitsHint: "Bet {min}–{max} coins · jackpot pools · server-verified",
    slotBetLabel: "Bet",
    slotSpin: "Spin",
    slotMaxBet: "Max",
    slotLastWin: "Last win",
    slotJackpotsTitle: "Progressive jackpots",
    slotJpMini: "Mini",
    slotJpMinor: "Minor",
    slotJpMajor: "Major",
    slotJpGrand: "Grand",
    slotPayTitle: "Pay table",
    slotPayFooter:
      "Triple or adjacent pair pays. Three jackpot symbols or a lucky spin awards Mini / Minor / Major / Grand pools. 3% of each bet feeds the pools.",
    slotSymCherry: "Cherry",
    slotSymLemon: "Lemon",
    slotSymBell: "Bell",
    slotSymDiamond: "Diamond",
    slotSymSeven: "Seven",
    slotSymJackpot: "Jackpot",
    slotToastBet: "Bet {min}–{max} coins.",
    slotSpinning: "Spinning…",
    slotWinMsg: "{msg} +{payout} coins (net {net})",
    slotToastWin: "Win: {payout} coins",
    slotErrBetRange: "Bet must be {min}–{max} coins.",
    slotErrGeneric: "Could not complete.",
    gamesNavigateBack: "Back to games",
    bjFetchErrorBeforeLink: "Could not load game state or session expired.",
    bjFetchErrorAfterLink: "or refresh the page.",
    slotLoadErrorBeforeLink: "Could not load game.",
    slotLoadErrorAfterLink: "or refresh the page.",
    bjErrAuth: "Sign-in required.",
    bjNewHand: "New hand",
    slotWinExclaim: "You win!",
    slotTryAgain: "Not this time — try again.",
    rouletteGuestTitle: "Super Roulette",
    rouletteGuestHint: "Sign in to play.",
    rouletteLoadFail: "Could not load game. Return to games or refresh.",
    rouletteBadgeSuper: "Single zero · Super Roulette",
    rouletteLimitsHint: "Bet {min}–{max} coins · result on server",
    rouletteBetLabel: "Bet",
    rouletteSpin: "Spin",
    rouletteSpinning: "Spinning…",
    rouletteSelectBet: "Bet type",
    rouletteSelectNumber: "Pick a number (0–36)",
    roulettePayTitle: "Payouts",
    roulettePayDozenShort: "Dozen (1–3)",
    roulettePayColumnShort: "Column (1–3)",
    roulettePayFooter:
      "Straight 35:1 (win returns 36× bet), red/black/even/odd/low/high 1:1, dozen & column 2:1.",
    rouletteBetStraight: "Straight",
    rouletteBetRed: "Red",
    rouletteBetBlack: "Black",
    rouletteBetEven: "Even",
    rouletteBetOdd: "Odd",
    rouletteBetLow: "1–18",
    rouletteBetHigh: "19–36",
    rouletteBetDozen: "Dozen {n}",
    rouletteBetColumn: "Column {n}",
    rouletteToastBet: "Bet {min}–{max} coins.",
    rouletteErrBetRange: "Bet must be {min}–{max} coins.",
    rouletteErrGeneric: "Could not complete.",
    rouletteLoadErrorBeforeLink: "Could not load game.",
    rouletteLoadErrorAfterLink: "or refresh the page.",
    rouletteWinMsg: "{msg} · Result: {num} · +{payout} coins (net {net})",
    rouletteToastWin: "Win: {payout} coins",
    rouletteResult: "Result",
    roulettePointer: "Ball lands here",
    rouletteFeltTitle: "Betting layout",
    rouletteFeltHint: "Tap a bet area — the chip shows your stake. Spin to play.",
    rouletteFeltDozen1: "1–12",
    rouletteFeltDozen2: "13–24",
    rouletteFeltDozen3: "25–36",
    rouletteFeltDozen1Tbl: "1st 12",
    rouletteFeltDozen2Tbl: "2nd 12",
    rouletteFeltDozen3Tbl: "3rd 12",
    rouletteFeltEvenLbl: "EVEN",
    rouletteFeltOddLbl: "ODD",
    rouletteFeltColShort: "2:1",
    profileRouletteLoss: "Loss",
    profileRouletteBet: "Bet type",
  },
};

function mergeUi(loc, block) {
  const lang = loc === "en" ? "en" : "tr";
  const base = { ...UI_DEFAULTS[lang] };
  const raw = block && typeof block.ui === "object" && block.ui !== null ?  (block.ui) : {};
  for (const [k, v] of Object.entries(raw)) {
    if (typeof v === "string" && v.trim() !== "") base[k] = v;
  }
  return base;
}

export function t(key) {
  const k = String(key || "");
  const ui = SITE &&  (SITE).ui;
  if (ui && typeof ui[k] === "string" && ui[k].trim() !== "") return ui[k];
  const loc = getSiteLocale();
  const lang = loc === "en" ? "en" : "tr";
  const row = UI_DEFAULTS[lang] || UI_DEFAULTS.tr;
  return row[k] ?? UI_DEFAULTS.tr[k] ?? k;
}

const JOIN_GUIDE_STEP_COUNT = 4;

function joinGuideUiKeys(kind) {
  const base = kind === "tickets" ? "tickets" : "events";
  return {
    title: `${base}HowToTitle`,
    steps: Array.from({ length: JOIN_GUIDE_STEP_COUNT }, (_, i) => `${base}RequestStep${i + 1}`),
  };
}

/**
 * Etkinlik / bilet detayında «Nasıl katılırım» metinleri (site.json → joinGuides).
 *
 * @param {"events"|"tickets"} kind
 * @returns {{ title: string, steps: string[] }}
 */
export function getJoinGuideTexts(kind) {
  const guideKind = kind === "tickets" ? "tickets" : "events";
  const keys = joinGuideUiKeys(guideKind);
  const loc = getSiteLocale();
  const raw =
    SITE_RAW?.joinGuides?.[guideKind] && typeof SITE_RAW.joinGuides[guideKind] === "object"
      ? SITE_RAW.joinGuides[guideKind]
      : null;
  const locales = raw?.locales && typeof raw.locales === "object" ? raw.locales : {};
  const block =
    (locales[loc] && typeof locales[loc] === "object" ? locales[loc] : null) ||
    (locales.tr && typeof locales.tr === "object" ? locales.tr : {});

  const titleFromSite = typeof block.title === "string" ? block.title.trim() : "";
  const title = titleFromSite || t(keys.title);

  const steps = [];
  const stepsArr = Array.isArray(block.steps) ? block.steps : [];
  for (let i = 0; i < JOIN_GUIDE_STEP_COUNT; i++) {
    const fromSite = typeof stepsArr[i] === "string" ? stepsArr[i].trim() : "";
    steps.push(fromSite || t(keys.steps[i]));
  }

  return { title, steps };
}

function resolveBrandingUrl(raw, key, fallback) {
  const v = raw && typeof raw[key] === "string" ? raw[key].trim() : "";
  return v !== "" ? v : fallback;
}

function resolveOgImageUrl(raw) {
  const og = raw && typeof raw.ogImageUrl === "string" ? raw.ogImageUrl.trim() : "";
  if (og) return og;
  const logo = raw && typeof raw.logoUrl === "string" ? raw.logoUrl.trim() : "";
  if (logo) return logo;
  return BRAND_DEFAULT_OG;
}

function resolveFaviconUrl(raw) {
  const fav = raw && typeof raw.faviconUrl === "string" ? raw.faviconUrl.trim() : "";
  if (fav) return fav;
  const logo = raw && typeof raw.logoUrl === "string" ? raw.logoUrl.trim() : "";
  if (logo) return logo;
  return BRAND_DEFAULT_OG;
}

function buildActiveSiteView(raw) {
  const locales = raw && raw.locales && typeof raw.locales === "object" ? raw.locales : {};
  const loc = resolveActiveLocale(raw);
  const block =
    locales[loc] && typeof locales[loc] === "object"
      ?  (locales[loc])
      : locales.tr && typeof locales.tr === "object"
        ?  (locales.tr)
        : {};
  const str = (k, fb = "") => (typeof block[k] === "string" ? block[k] : fb);
  const locCode = loc === "en" ? "en" : "tr";
  return {
    telegramUrl: str("telegramUrl", ""),
    contactIntro: str("contactIntro", ""),
    contactCardTitle: str("contactCardTitle", ""),
    contactCardSubtitle: str("contactCardSubtitle", ""),
    contactButton: str("contactButton", "Telegram'da yaz"),
    contactEyebrow: str("contactEyebrow", "İletişim"),
    contactHeading: str("contactHeading", "İletişim"),
    customCss: typeof raw.customCss === "string" ? raw.customCss : "",
    logoUrl: resolveBrandingUrl(raw, "logoUrl", BRAND_DEFAULT_LOGO),
    faviconUrl: resolveFaviconUrl(raw),
    ogImageUrl: resolveOgImageUrl(raw),
    ui: mergeUi(locCode, block),
    _locale: loc,
  };
}

export function getSiteLogoUrl() {
  return SITE?.logoUrl ?? BRAND_DEFAULT_LOGO;
}

export function isSiteMaintenanceActive() {
  const m = SITE_RAW?.maintenance;
  return Boolean(m && typeof m === "object" && m.enabled);
}

export function getMaintenanceView() {
  const loc = getSiteLocale();
  const m =
    SITE_RAW?.maintenance && typeof SITE_RAW.maintenance === "object" ? SITE_RAW.maintenance : {};
  const locs = m.locales && typeof m.locales === "object" ? m.locales : {};
  const block =
    (locs[loc] && typeof locs[loc] === "object" ? locs[loc] : null) ||
    (locs.tr && typeof locs.tr === "object" ? locs.tr : {});
  const imageUrl = typeof m.imageUrl === "string" ? m.imageUrl.trim() : "";
  return {
    eyebrow: (typeof block.eyebrow === "string" && block.eyebrow.trim()) || t("maintenanceEyebrow"),
    title: (typeof block.title === "string" && block.title.trim()) || t("maintenanceTitle"),
    message: (typeof block.message === "string" && block.message.trim()) || t("maintenanceMessage"),
    imageUrl,
  };
}

export function getSiteFaviconUrl() {
  return SITE?.faviconUrl ?? BRAND_DEFAULT_OG;
}

export function getSiteOgImageUrl() {
  return SITE?.ogImageUrl ?? BRAND_DEFAULT_OG;
}

/** Açılış splash + sonraki ziyaretler için önbellek (index.html erken script ile paylaşılır). */
export const BRAND_LOGO_CACHE_KEY = "mocker_brand_logo";

export function cacheBrandLogoUrl(url) {
  const u = typeof url === "string" ? url.trim() : "";
  if (!u) return;
  try {
    localStorage.setItem(BRAND_LOGO_CACHE_KEY, u);
  } catch {

  }
}

function readCachedBrandLogoUrl() {
  try {
    let v = localStorage.getItem(BRAND_LOGO_CACHE_KEY);
    if (!v) {
      v = localStorage.getItem("alpingo_brand_logo");
      if (v) cacheBrandLogoUrl(v);
    }
    return v && String(v).trim() ? String(v).trim() : "";
  } catch {
    return "";
  }
}

/** Yükleme ekranı logosunu admin panelindeki site logosu ile eşle. */
export function applySplashLogo() {
  if (typeof document === "undefined") return;
  const url = getSiteLogoUrl();
  cacheBrandLogoUrl(url);
  const img = document.getElementById("splash-logo");
  if (img && url) img.src = url;
}

function applyBrandingDom() {
  if (typeof document === "undefined") return;
  const fav = getSiteFaviconUrl();
  let link = document.querySelector('link[rel="icon"]');
  if (!link) {
    link = document.createElement("link");
    link.setAttribute("rel", "icon");
    document.head.appendChild(link);
  }
  link.setAttribute("href", fav);
  const pathOnly = fav.split("?")[0].toLowerCase();
  if (pathOnly.endsWith(".svg")) link.setAttribute("type", "image/svg+xml");
  else if (pathOnly.endsWith(".png")) link.setAttribute("type", "image/png");
  else if (pathOnly.endsWith(".jpg") || pathOnly.endsWith(".jpeg")) link.setAttribute("type", "image/jpeg");
  else if (pathOnly.endsWith(".webp")) link.setAttribute("type", "image/webp");
  else link.removeAttribute("type");

  try {
    document.querySelectorAll('script[type="application/ld+json"]').forEach((s) => {
      const t = s.textContent;
      if (!t || !t.includes('"Organization"')) return;
      const j = JSON.parse(t);
      const graph = j["@graph"];
      if (!Array.isArray(graph)) return;
      for (const node of graph) {
        if (node && node["@type"] === "Organization" && node.logo && typeof node.logo === "object") {
          node.logo.url = getSiteLogoUrl();
        }
      }
      s.textContent = JSON.stringify(j);
    });
  } catch {

  }

  applySplashLogo();
}

export function applyActiveSiteLocale() {
  if (!SITE_RAW || typeof SITE_RAW !== "object") return;
  SITE = buildActiveSiteView( (SITE_RAW));
  applySiteCustomCss();
  applyBrandingDom();
  try {
    document.documentElement.lang = getSiteLocale() === "en" ? "en" : "tr";
  } catch {

  }
}

export function setSiteLocale(code) {
  if (code !== "tr" && code !== "en") return;
  try {
    localStorage.setItem(LOCALE_STORAGE_KEY, code);
  } catch {

  }
  applyActiveSiteLocale();
  window.dispatchEvent(new CustomEvent("mocker:locale"));
}

export function bindLocaleSwitcher(root = document) {
  root.querySelectorAll("[data-locale-switch]").forEach((btn) => {
    if ( (btn).dataset.localeBound) return;
     (btn).dataset.localeBound = "1";
    btn.addEventListener("click", () => {
      const loc =  (btn).getAttribute("data-locale-switch");
      if (loc === "tr" || loc === "en") setSiteLocale(loc);
    });
  });
  updateLocaleSwitcherUi(root);
}

export function updateLocaleSwitcherUi(root = document) {
  const loc = getSiteLocale();
  root.querySelectorAll("[data-locale-switch]").forEach((btn) => {
    const v =  (btn).getAttribute("data-locale-switch");
    const on = v === loc;
    btn.classList.toggle("bg-accent/25", on);
    btn.classList.toggle("text-white", on);
    btn.classList.toggle("text-slate-400", !on);
    btn.setAttribute("aria-pressed", on ? "true" : "false");
  });
}

export function dataJsonUrl(file) {
  const name = String(file || "")
    .replace(/^\/+/, "")
    .replace(/^data\//i, "");
  const manual =
    typeof globalThis.__SITE_BASE__ === "string" ? globalThis.__SITE_BASE__.trim().replace(/\/+$/, "") : "";
  if (manual !== "") {
    const path = `${manual}/data/${name}`.replace(/\/{2,}/g, "/");
    return new URL(path, window.location.origin).href;
  }
  return new URL(`data/${name}`, window.location.href).href;
}

function isPopupDebug() {
  try {
    if (typeof window === "undefined") return false;
    const q = String(window.location.search || "");
    const h = String(window.location.hash || "");
    return /(?:^|[?&])popupDebug=1(?:&|$)/.test(q) || /[?&]popupDebug=1(?:&|$)/.test(h);
  } catch {
    return false;
  }
}

export async function loadSite() {
  const r = await fetch(dataJsonUrl("site.json"), { cache: "no-store" });
  if (!r.ok) throw new Error("Site verisi yüklenemedi");
  const text = await r.text();
  let raw = JSON.parse(text);
  if (!raw || typeof raw !== "object" || Array.isArray(raw)) {
    raw = migrateFlatSiteJson({});
  } else if (!raw.locales || typeof raw.locales !== "object") {
    raw = migrateFlatSiteJson( (raw));
  }
  SITE_RAW = raw;
  applyActiveSiteLocale();
}

function emptyPopupConfig() {
  return {
    enabled: false,
    title: "",
    imageUrl: "",
    linkUrl: "",
    startAt: null,
    endAt: null,
    frequency: "session",
  };
}

/** @type {Promise<void> | null} */
let gamesCoversLoadPromise = null;

export async function loadGamesCovers() {
  if (gamesCoversLoadPromise) return gamesCoversLoadPromise;
  gamesCoversLoadPromise = (async () => {
    try {
      const r = await fetch(dataJsonUrl("games.json"), { cache: "default" });
      if (!r.ok) {
        GAMES_COVERS = null;
        return;
      }
      const j = await JSON.parse(await r.text());
      if (!j || typeof j !== "object" || Array.isArray(j)) {
        GAMES_COVERS = null;
        return;
      }
      GAMES_COVERS = {
        blackjack: typeof j.blackjack === "string" ? j.blackjack.trim() : "",
        slot: typeof j.slot === "string" ? j.slot.trim() : "",
        roulette: typeof j.roulette === "string" ? j.roulette.trim() : "",
      };
      if (typeof window !== "undefined") {
        window.dispatchEvent(new CustomEvent("mocker:games-covers"));
      }
    } catch {
      GAMES_COVERS = null;
    }
  })();
  return gamesCoversLoadPromise;
}

export function isGamdomTurnuvaEnabled() {
  return GAMDOM_TURUVA?.enabled === true;
}

export async function loadGamdomTurnuva() {
  try {
    const r = await fetch(dataJsonUrl("gamdom-turnuva.json"), { cache: "no-store" });
    if (!r.ok) {
      GAMDOM_TURUVA = { enabled: false };
      return;
    }
    const j = await r.json();
    GAMDOM_TURUVA = j && typeof j === "object" && !Array.isArray(j) ? j : { enabled: false };
  } catch {
    GAMDOM_TURUVA = { enabled: false };
  }
}

function parsePopupResponse(text, ct, log) {
  if (ct.includes("text/html") || /^\s*</.test(text)) {
    log("Yanıt HTML — popup.json veya api/popup.php erişilemiyor olabilir.");
    return null;
  }
  let j;
  try {
    j = JSON.parse(text);
  } catch (e) {
    log(`JSON parse hatası: ${e}`);
    return null;
  }
  if (!j || typeof j !== "object" || Array.isArray(j) || !Object.prototype.hasOwnProperty.call(j, "enabled")) {
    log("Geçersiz popup şeması");
    return null;
  }
  return j;
}

export async function loadPopup() {
  const dbg = isPopupDebug();
  const log = (msg) => {
    if (dbg) console.info("[popup]", msg);
  };
  const urls = [];
  try {
    const { apiUrl } = await import("../auth/session.js");
    urls.push(apiUrl("popup.php"));
  } catch {
    /* apiUrl yoksa yalnızca statik */
  }
  urls.push(dataJsonUrl("popup.json"));

  try {
    for (const url of urls) {
      log(`fetch ${url}`);
      const r = await fetch(url, { credentials: "omit", cache: "no-store" });
      const text = await r.text();
      const ct = (r.headers.get("content-type") || "").toLowerCase();
      if (!r.ok) {
        log(`HTTP ${r.status} — ${url}`);
        continue;
      }
      const j = parsePopupResponse(text, ct, log);
      if (j) {
        POPUP = j;
        log(`yüklendi enabled=${j.enabled} (${url})`);
        return;
      }
    }
    POPUP = emptyPopupConfig();
  } catch (e) {
    log(String(e));
    POPUP = emptyPopupConfig();
  }
}

export function applySiteCustomCss() {
  const raw = SITE && typeof SITE.customCss === "string" ? SITE.customCss.trim() : "";
  let el = document.getElementById("mocker-site-custom-css");
  if (!raw) {
    el?.remove();
    return;
  }
  if (!el) {
    el = document.createElement("style");
    el.id = "mocker-site-custom-css";
    el.setAttribute("data-site-custom-css", "1");
    document.head.appendChild(el);
  }
  el.textContent = raw;
}

const POPUP_SEEN_SESSION = "mocker_popup_seen_v2";
const POPUP_SEEN_DAY = "mocker_popup_day_v2";
const POPUP_NEVER = "mocker_popup_never_v1";

function popupContentHash(p) {
  const raw = JSON.stringify({
    e: !!p?.enabled,
    t: p?.title ?? "",
    i: p?.imageUrl ?? "",
    l: p?.linkUrl ?? "",
    s: p?.startAt ?? null,
    d: p?.endAt ?? null,
    f: p?.frequency === "day" ? "day" : "session",
  });
  let h = 5381;
  for (let i = 0; i < raw.length; i++) {
    h = (h * 33) ^ raw.charCodeAt(i);
  }
  return String(h >>> 0);
}

function isPopupNeverDismissed(hash) {
  try {
    return localStorage.getItem(POPUP_NEVER) === hash;
  } catch {
    return false;
  }
}

function markPopupNever(hash) {
  try {
    localStorage.setItem(POPUP_NEVER, hash);
  } catch {
    /* noop */
  }
}

function isPopupDismissed(p, hash) {
  if (isPopupNeverDismissed(hash)) return true;
  const freq = p?.frequency === "day" ? "day" : "session";
  try {
    if (freq === "day") {
      const today = new Date().toISOString().slice(0, 10);
      return localStorage.getItem(POPUP_SEEN_DAY) === `${hash}|${today}`;
    }
    return sessionStorage.getItem(POPUP_SEEN_SESSION) === hash;
  } catch {
    return false;
  }
}

function markPopupDismissed(p, hash) {
  const freq = p?.frequency === "day" ? "day" : "session";
  try {
    if (freq === "day") {
      const today = new Date().toISOString().slice(0, 10);
      localStorage.setItem(POPUP_SEEN_DAY, `${hash}|${today}`);
    } else {
      sessionStorage.setItem(POPUP_SEEN_SESSION, hash);
    }
  } catch {
    /* noop */
  }
}

function isWithinSchedule(p) {
  const now = Math.floor(Date.now() / 1000);
  const startAt = p?.startAt != null ? Number(p.startAt) : null;
  const endAt = p?.endAt != null ? Number(p.endAt) : null;
  if (startAt != null && Number.isFinite(startAt) && now < startAt) return false;
  if (endAt != null && Number.isFinite(endAt) && now > endAt) return false;
  return true;
}

export function showSitePopupIfNeeded() {
  const dbg = isPopupDebug();
  const log = (msg) => {
    if (dbg) console.info("[popup]", msg);
  };
  const p = POPUP;
  if (!p || !p.enabled) {
    log(!p ? "POPUP null/boş (popup.json yüklenemedi veya geçersiz)" : "enabled kapalı");
    return;
  }

  const img = typeof p.imageUrl === "string" ? p.imageUrl.trim() : "";
  if (!img || !/^https?:\/\//i.test(img)) {
    log("imageUrl eksik veya https değil");
    return;
  }

  if (!isWithinSchedule(p)) {
    const now = Math.floor(Date.now() / 1000);
    log(
      `tarih aralığı dışında (now=${now}, startAt=${p.startAt ?? "null"}, endAt=${p.endAt ?? "null"})`
    );
    return;
  }

  const hash = popupContentHash(p);
  if (isPopupDismissed(p, hash)) {
    log("bu oturum/günde daha önce kapatıldı (sessionStorage/localStorage); yeni gizli sekme veya farklı sıklık deneyin");
    return;
  }
  log("gösteriliyor…");

  const prefersReduce = window.matchMedia("(prefers-reduced-motion: reduce)").matches;
  const delayMs = prefersReduce ? 320 : 880;

  window.setTimeout(() => {
    if (document.getElementById("site-welcome-popup")) return;
    if (isPopupDismissed(p, hash)) return;

    const linkRaw = typeof p.linkUrl === "string" ? p.linkUrl.trim() : "";
    const titleRaw = typeof p.title === "string" ? p.title.trim() : "";
    const dialogTitle = titleRaw || t("popupDefaultTitle");

    const backdrop = document.createElement("div");
    backdrop.id = "site-welcome-popup";
    backdrop.className = "site-popup-backdrop";
    backdrop.setAttribute("role", "dialog");
    backdrop.setAttribute("aria-modal", "true");
    backdrop.setAttribute("aria-labelledby", "site-popup-title");

    const panel = document.createElement("div");
    panel.className = "site-popup";

    const removePopup = () => {
      backdrop.remove();
      document.removeEventListener("keydown", onKey);
      document.body.classList.remove("site-popup-open");
    };

    const dismissForNow = () => {
      markPopupDismissed(p, hash);
      removePopup();
    };

    const dismissForever = () => {
      markPopupNever(hash);
      removePopup();
    };

    function onKey(ev) {
      if (ev.key === "Escape") dismissForNow();
    }

    const closeIcon = document.createElement("button");
    closeIcon.type = "button";
    closeIcon.className = "site-popup__close";
    closeIcon.setAttribute("aria-label", t("popupClose"));
    closeIcon.innerHTML =
      '<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><path d="M6 18L18 6M6 6l12 12"/></svg>';
    closeIcon.addEventListener("click", dismissForNow);

    const head = document.createElement("header");
    head.className = "site-popup__head";
    const eyebrow = document.createElement("span");
    eyebrow.className = "site-popup__eyebrow";
    eyebrow.textContent = t("popupEyebrow");
    const titleEl = document.createElement("h2");
    titleEl.id = "site-popup-title";
    titleEl.className = "site-popup__title";
    titleEl.textContent = dialogTitle;
    head.append(eyebrow, titleEl);

    const media = document.createElement("div");
    media.className = "site-popup__media";

    const im = document.createElement("img");
    im.className = "site-popup__img";
    im.src = img;
    im.alt = dialogTitle;
    im.decoding = "async";
    im.loading = "eager";

    const appendImage = (parent) => {
      parent.appendChild(im);
    };

    if (linkRaw) {
      const mediaLink = document.createElement("a");
      mediaLink.className = "site-popup__media-link";
      if (linkRaw.startsWith("#")) {
        mediaLink.href = linkRaw;
        mediaLink.addEventListener("click", (ev) => {
          ev.preventDefault();
          dismissForNow();
          let path = linkRaw.replace(/^#/, "").trim() || "/";
          if (!path.startsWith("/")) path = `/${path}`;
          if (typeof globalThis.__siteNavigateTo === "function") {
            globalThis.__siteNavigateTo(path);
          } else {
            window.location.hash = path === "/" ? "#/" : `#${path}`;
          }
        });
      } else {
        mediaLink.href = linkRaw;
        mediaLink.target = "_blank";
        mediaLink.rel = "noopener noreferrer";
        mediaLink.addEventListener("click", dismissForNow);
      }
      appendImage(mediaLink);
      media.appendChild(mediaLink);
    } else {
      appendImage(media);
    }

    const foot = document.createElement("footer");
    foot.className = "site-popup__foot";

    const neverBtn = document.createElement("button");
    neverBtn.type = "button";
    neverBtn.className = "site-popup__never";
    neverBtn.textContent = t("popupNever");
    neverBtn.addEventListener("click", dismissForever);

    const actions = document.createElement("div");
    actions.className = "site-popup__actions";

    const closeBtn = document.createElement("button");
    closeBtn.type = "button";
    closeBtn.className = "site-popup__btn site-popup__btn--ghost";
    closeBtn.textContent = t("popupClose");
    closeBtn.addEventListener("click", dismissForNow);

    actions.appendChild(closeBtn);

    if (linkRaw) {
      const cta = document.createElement("a");
      cta.className = "site-popup__btn site-popup__btn--primary";
      cta.textContent = t("popupCta");
      if (linkRaw.startsWith("#")) {
        cta.href = linkRaw;
        cta.addEventListener("click", (ev) => {
          ev.preventDefault();
          dismissForNow();
          let path = linkRaw.replace(/^#/, "").trim() || "/";
          if (!path.startsWith("/")) path = `/${path}`;
          if (typeof globalThis.__siteNavigateTo === "function") {
            globalThis.__siteNavigateTo(path);
          } else {
            window.location.hash = path === "/" ? "#/" : `#${path}`;
          }
        });
      } else {
        cta.href = linkRaw;
        cta.target = "_blank";
        cta.rel = "noopener noreferrer";
        cta.addEventListener("click", dismissForNow);
      }
      actions.appendChild(cta);
    }

    foot.append(neverBtn, actions);

    backdrop.addEventListener("click", (ev) => {
      if (ev.target === backdrop) dismissForNow();
    });
    document.addEventListener("keydown", onKey);

    panel.append(closeIcon, head, media, foot);
    backdrop.appendChild(panel);
    document.body.appendChild(backdrop);
    document.body.classList.add("site-popup-open");

    closeBtn.focus();
  }, delayMs);
}
