(() => {
  'use strict';
  if (window.__APU_DESIGN_I18N_V56__) return;
  window.__APU_DESIGN_I18N_V56__ = true;

  const THEME_KEY = 'apu-ui-theme';
  const LANGUAGE_KEY = 'apu-ui-language';
  const LEGACY_THEME_KEYS = ['apu-ui-theme-v5.5'];
  const LEGACY_LANGUAGE_KEYS = ['apu-ui-language-v5.5'];
  const LANGUAGES = {
    id: { name: 'Indonesia', short: 'ID' },
    en: { name: 'English', short: 'EN' },
    ms: { name: 'Melayu', short: 'MS' },
    de: { name: 'Deutsch', short: 'DE' },
    vi: { name: 'Tiếng Việt', short: 'VI' },
    zh: { name: '中文', short: '中文' },
    ja: { name: '日本語', short: '日本' }
  };

  const UI = {
    id: { group: 'Tampilan dan bahasa', theme: 'Ganti mode warna', light: 'Terang', dark: 'Gelap', enabledLight: 'Mode terang aktif', enabledDark: 'Mode gelap aktif', language: 'Pilih bahasa', changed: 'Bahasa diubah ke Indonesia', brand: 'Kontrol tampilan' },
    en: { group: 'Appearance and language', theme: 'Change color mode', light: 'Light', dark: 'Dark', enabledLight: 'Light mode enabled', enabledDark: 'Dark mode enabled', language: 'Choose language', changed: 'Language changed to English', brand: 'Display controls' },
    ms: { group: 'Penampilan dan bahasa', theme: 'Tukar mod warna', light: 'Cerah', dark: 'Gelap', enabledLight: 'Mod cerah diaktifkan', enabledDark: 'Mod gelap diaktifkan', language: 'Pilih bahasa', changed: 'Bahasa ditukar kepada Melayu', brand: 'Kawalan paparan' },
    de: { group: 'Darstellung und Sprache', theme: 'Farbmodus wechseln', light: 'Hell', dark: 'Dunkel', enabledLight: 'Heller Modus aktiviert', enabledDark: 'Dunkler Modus aktiviert', language: 'Sprache wählen', changed: 'Sprache auf Deutsch geändert', brand: 'Anzeigeoptionen' },
    vi: { group: 'Giao diện và ngôn ngữ', theme: 'Đổi chế độ màu', light: 'Sáng', dark: 'Tối', enabledLight: 'Đã bật chế độ sáng', enabledDark: 'Đã bật chế độ tối', language: 'Chọn ngôn ngữ', changed: 'Đã đổi ngôn ngữ sang Tiếng Việt', brand: 'Điều khiển hiển thị' },
    zh: { group: '外观与语言', theme: '切换颜色模式', light: '浅色', dark: '深色', enabledLight: '已启用浅色模式', enabledDark: '已启用深色模式', language: '选择语言', changed: '语言已切换为中文', brand: '显示控制' },
    ja: { group: '外観と言語', theme: 'カラーモードを変更', light: 'ライト', dark: 'ダーク', enabledLight: 'ライトモードを有効化', enabledDark: 'ダークモードを有効化', language: '言語を選択', changed: '言語を日本語に変更しました', brand: '表示コントロール' }
  };

  const PHRASES = {
    'Overview': ['Ikhtisar','Overview','Gambaran keseluruhan','Übersicht','Tổng quan','概览','概要'],
    'Dashboard': ['Dasbor','Dashboard','Papan pemuka','Dashboard','Bảng điều khiển','仪表板','ダッシュボード'],
    'Dataset': ['Kumpulan Data','Dataset','Set data','Datensatz','Tập dữ liệu','数据集','データセット'],
    'Model': ['Model','Model','Model','Modell','Mô hình','模型','モデル'],
    'Models': ['Model','Models','Model','Modelle','Mô hình','模型','モデル'],
    'Results': ['Hasil','Results','Keputusan','Ergebnisse','Kết quả','结果','結果'],
    'Analysis': ['Analisis','Analysis','Analisis','Analyse','Phân tích','分析','分析'],
    'Failure Analysis': ['Analisis Kegagalan','Failure Analysis','Analisis Kegagalan','Fehleranalyse','Phân tích lỗi','失败分析','失敗分析'],
    'Limitations': ['Keterbatasan','Limitations','Batasan','Einschränkungen','Hạn chế','局限性','制限事項'],
    'Source Code': ['Kode Sumber','Source Code','Kod Sumber','Quellcode','Mã nguồn','源代码','ソースコード'],
    'Technical Report': ['Laporan Teknis','Technical Report','Laporan Teknikal','Technischer Bericht','Báo cáo kỹ thuật','技术报告','技術レポート'],
    'Reports': ['Laporan','Reports','Laporan','Berichte','Báo cáo','报告','レポート'],
    'Report': ['Laporan','Report','Laporan','Bericht','Báo cáo','报告','レポート'],
    'Settings': ['Pengaturan','Settings','Tetapan','Einstellungen','Cài đặt','设置','設定'],
    'Search': ['Cari','Search','Cari','Suchen','Tìm kiếm','搜索','検索'],
    'Home': ['Beranda','Home','Laman Utama','Startseite','Trang chủ','首页','ホーム'],
    'Projects': ['Proyek','Projects','Projek','Projekte','Dự án','项目','プロジェクト'],
    'Project': ['Proyek','Project','Projek','Projekt','Dự án','项目','プロジェクト'],
    'Research': ['Riset','Research','Penyelidikan','Forschung','Nghiên cứu','研究','研究'],
    'Certificates': ['Sertifikat','Certificates','Sijil','Zertifikate','Chứng chỉ','证书','証明書'],
    'Admission': ['Penerimaan','Admission','Kemasukan','Zulassung','Tuyển sinh','招生','入学'],
    'Documents': ['Dokumen','Documents','Dokumen','Dokumente','Tài liệu','文档','ドキュメント'],
    'Contact': ['Kontak','Contact','Hubungi','Kontakt','Liên hệ','联系','お問い合わせ'],
    'Support': ['Dukungan','Support','Sokongan','Support','Hỗ trợ','支持','サポート'],
    'Resume': ['Resume','Resume','Resume','Lebenslauf','Hồ sơ','简历','履歴書'],
    'Security': ['Keamanan','Security','Keselamatan','Sicherheit','Bảo mật','安全','セキュリティ'],
    'Governance': ['Tata Kelola','Governance','Tadbir Urus','Governance','Quản trị','治理','ガバナンス'],
    'Cloud Compare': ['Perbandingan Cloud','Cloud Compare','Perbandingan Awan','Cloud-Vergleich','So sánh đám mây','云对比','クラウド比較'],
    'Blueprints': ['Cetak Biru','Blueprints','Pelan Tindakan','Blaupausen','Bản thiết kế','蓝图','ブループリント'],
    'Agents': ['Agen','Agents','Ejen','Agenten','Tác nhân','智能体','エージェント'],
    'Predict': ['Prediksi','Predict','Ramalan','Vorhersage','Dự đoán','预测','予測'],
    'Recommendations': ['Rekomendasi','Recommendations','Cadangan','Empfehlungen','Đề xuất','建议','推奨事項'],
    'Students': ['Siswa','Students','Pelajar','Studierende','Sinh viên','学生','学生'],
    'Fairness': ['Keadilan','Fairness','Keadilan','Fairness','Công bằng','公平性','公平性'],
    'Tickets': ['Tiket','Tickets','Tiket','Tickets','Phiếu hỗ trợ','工单','チケット'],
    'Incidents': ['Insiden','Incidents','Insiden','Vorfälle','Sự cố','事件','インシデント'],
    'Timeline': ['Linimasa','Timeline','Garis Masa','Zeitleiste','Dòng thời gian','时间线','タイムライン'],
    'Analytics': ['Analitik','Analytics','Analitik','Analytik','Phân tích','分析','分析'],
    'Campaigns': ['Kampanye','Campaigns','Kempen','Kampagnen','Chiến dịch','活动','キャンペーン'],
    'Create': ['Buat','Create','Cipta','Erstellen','Tạo','创建','作成'],
    'History': ['Riwayat','History','Sejarah','Verlauf','Lịch sử','历史','履歴'],
    'Calculator': ['Kalkulator','Calculator','Kalkulator','Rechner','Máy tính','计算器','計算機'],
    'Troubleshoot': ['Pemecahan Masalah','Troubleshoot','Penyelesaian Masalah','Fehlerbehebung','Khắc phục sự cố','故障排除','トラブルシューティング'],
    'Tutorial': ['Tutorial','Tutorial','Tutorial','Tutorial','Hướng dẫn','教程','チュートリアル'],
    'Segmentation': ['Segmentasi','Segmentation','Segmentasi','Segmentierung','Phân đoạn','分段','セグメンテーション'],
    'Feedback': ['Umpan Balik','Feedback','Maklum Balas','Feedback','Phản hồi','反馈','フィードバック'],
    'New Feedback': ['Umpan Balik Baru','New Feedback','Maklum Balas Baharu','Neues Feedback','Phản hồi mới','新反馈','新しいフィードバック'],
    'Keywords': ['Kata Kunci','Keywords','Kata Kunci','Schlüsselwörter','Từ khóa','关键词','キーワード'],
    'Topics': ['Topik','Topics','Topik','Themen','Chủ đề','主题','トピック'],
    'Categories': ['Kategori','Categories','Kategori','Kategorien','Danh mục','类别','カテゴリー'],
    'Costs': ['Biaya','Costs','Kos','Kosten','Chi phí','费用','費用'],
    'Housing': ['Perumahan','Housing','Perumahan','Wohnen','Nhà ở','住房','住宅'],
    'Simulator': ['Simulator','Simulator','Simulator','Simulator','Mô phỏng','模拟器','シミュレーター'],
    'Methodology': ['Metodologi','Methodology','Metodologi','Methodik','Phương pháp','方法论','方法論'],
    'Save': ['Simpan','Save','Simpan','Speichern','Lưu','保存','保存'],
    'Cancel': ['Batal','Cancel','Batal','Abbrechen','Hủy','取消','キャンセル'],
    'Delete': ['Hapus','Delete','Padam','Löschen','Xóa','删除','削除'],
    'Edit': ['Edit','Edit','Sunting','Bearbeiten','Chỉnh sửa','编辑','編集'],
    'Update': ['Perbarui','Update','Kemas Kini','Aktualisieren','Cập nhật','更新','更新'],
    'Add': ['Tambah','Add','Tambah','Hinzufügen','Thêm','添加','追加'],
    'Download': ['Unduh','Download','Muat Turun','Herunterladen','Tải xuống','下载','ダウンロード'],
    'Upload': ['Unggah','Upload','Muat Naik','Hochladen','Tải lên','上传','アップロード'],
    'Back': ['Kembali','Back','Kembali','Zurück','Quay lại','返回','戻る'],
    'Next': ['Berikutnya','Next','Seterusnya','Weiter','Tiếp theo','下一步','次へ'],
    'Previous': ['Sebelumnya','Previous','Sebelumnya','Zurück','Trước','上一步','前へ'],
    'View Details': ['Lihat Detail','View Details','Lihat Butiran','Details ansehen','Xem chi tiết','查看详情','詳細を見る'],
    'Loading...': ['Memuat...','Loading...','Memuatkan...','Wird geladen...','Đang tải...','加载中...','読み込み中...'],
    'No data available': ['Tidak ada data','No data available','Tiada data','Keine Daten verfügbar','Không có dữ liệu','暂无数据','データがありません'],
    'Language': ['Bahasa','Language','Bahasa','Sprache','Ngôn ngữ','语言','言語'],
    'Theme': ['Tema','Theme','Tema','Design','Giao diện','主题','テーマ']
  };

  Object.assign(PHRASES, {
    'Model Architecture': ['Arsitektur Model','Model Architecture','Seni Bina Model','Modellarchitektur','Kiến trúc mô hình','模型架构','モデルアーキテクチャ'],
    'Network Selection': ['Pemilihan Jaringan','Network Selection','Pemilihan Rangkaian','Netzwerkauswahl','Lựa chọn mạng','网络选择','ネットワーク選択'],
    'Training Configuration': ['Konfigurasi Pelatihan','Training Configuration','Konfigurasi Latihan','Trainingskonfiguration','Cấu hình huấn luyện','训练配置','トレーニング設定'],
    'Training Dynamics': ['Dinamika Pelatihan','Training Dynamics','Dinamik Latihan','Trainingsdynamik','Diễn biến huấn luyện','训练动态','トレーニング推移'],
    'Loss Curve': ['Kurva Loss','Loss Curve','Lengkung Kehilangan','Verlustkurve','Đường cong mất mát','损失曲线','損失曲線'],
    'Accuracy': ['Akurasi','Accuracy','Ketepatan','Genauigkeit','Độ chính xác','准确率','精度'],
    'Validation Accuracy': ['Akurasi Validasi','Validation Accuracy','Ketepatan Pengesahan','Validierungsgenauigkeit','Độ chính xác xác thực','验证准确率','検証精度'],
    'Training Loss': ['Loss Pelatihan','Training Loss','Kehilangan Latihan','Trainingsverlust','Mất mát huấn luyện','训练损失','トレーニング損失'],
    'Validation Loss': ['Loss Validasi','Validation Loss','Kehilangan Pengesahan','Validierungsverlust','Mất mát xác thực','验证损失','検証損失'],
    'Performance': ['Performa','Performance','Prestasi','Leistung','Hiệu suất','性能','パフォーマンス'],
    'Architecture': ['Arsitektur','Architecture','Seni Bina','Architektur','Kiến trúc','架构','アーキテクチャ'],
    'Data Explorer': ['Penjelajah Data','Data Explorer','Peneroka Data','Daten-Explorer','Trình khám phá dữ liệu','数据浏览器','データエクスプローラー'],
    'Model Comparison': ['Perbandingan Model','Model Comparison','Perbandingan Model','Modellvergleich','So sánh mô hình','模型对比','モデル比較'],
    'Feature Importance': ['Pentingnya Fitur','Feature Importance','Kepentingan Ciri','Merkmalsbedeutung','Tầm quan trọng của đặc trưng','特征重要性','特徴量重要度'],
    'System Status': ['Status Sistem','System Status','Status Sistem','Systemstatus','Trạng thái hệ thống','系统状态','システム状態'],
    'Recent Activity': ['Aktivitas Terbaru','Recent Activity','Aktiviti Terkini','Letzte Aktivität','Hoạt động gần đây','最近活动','最近のアクティビティ'],
    'Quick Actions': ['Tindakan Cepat','Quick Actions','Tindakan Pantas','Schnellaktionen','Thao tác nhanh','快捷操作','クイック操作'],
    'Open': ['Buka','Open','Buka','Öffnen','Mở','打开','開く'],
    'Close': ['Tutup','Close','Tutup','Schließen','Đóng','关闭','閉じる'],
    'Menu': ['Menu','Menu','Menu','Menü','Trình đơn','菜单','メニュー'],
    'Light': ['Terang','Light','Cerah','Hell','Sáng','浅色','ライト'],
    'Dark': ['Gelap','Dark','Gelap','Dunkel','Tối','深色','ダーク'],
    'Appearance': ['Tampilan','Appearance','Penampilan','Darstellung','Giao diện','外观','外観'],
    'Select language': ['Pilih bahasa','Select language','Pilih bahasa','Sprache auswählen','Chọn ngôn ngữ','选择语言','言語を選択'],
    'Change theme': ['Ganti tema','Change theme','Tukar tema','Design wechseln','Đổi giao diện','切换主题','テーマを変更'],
    'Refresh': ['Segarkan','Refresh','Muat Semula','Aktualisieren','Làm mới','刷新','更新'],
    'Apply': ['Terapkan','Apply','Gunakan','Anwenden','Áp dụng','应用','適用'],
    'Reset': ['Atur Ulang','Reset','Tetapkan Semula','Zurücksetzen','Đặt lại','重置','リセット'],
    'Submit': ['Kirim','Submit','Hantar','Senden','Gửi','提交','送信'],
    'Export': ['Ekspor','Export','Eksport','Exportieren','Xuất','导出','エクスポート'],
    'Import': ['Impor','Import','Import','Importieren','Nhập','导入','インポート'],
    'Filter': ['Filter','Filter','Tapis','Filter','Bộ lọc','筛选','フィルター'],
    'Sort': ['Urutkan','Sort','Isih','Sortieren','Sắp xếp','排序','並べ替え'],
    'Status': ['Status','Status','Status','Status','Trạng thái','状态','ステータス'],
    'Name': ['Nama','Name','Nama','Name','Tên','名称','名前'],
    'Description': ['Deskripsi','Description','Penerangan','Beschreibung','Mô tả','描述','説明'],
    'Date': ['Tanggal','Date','Tarikh','Datum','Ngày','日期','日付'],
    'Actions': ['Tindakan','Actions','Tindakan','Aktionen','Thao tác','操作','操作'],
    'Active': ['Aktif','Active','Aktif','Aktiv','Đang hoạt động','活跃','有効'],
    'Inactive': ['Tidak Aktif','Inactive','Tidak Aktif','Inaktiv','Không hoạt động','未启用','無効'],
    'Completed': ['Selesai','Completed','Selesai','Abgeschlossen','Hoàn thành','已完成','完了'],
    'Pending': ['Menunggu','Pending','Menunggu','Ausstehend','Đang chờ','待处理','保留中'],
    'Error': ['Kesalahan','Error','Ralat','Fehler','Lỗi','错误','エラー'],
    'Success': ['Berhasil','Success','Berjaya','Erfolgreich','Thành công','成功','成功'],
    'All': ['Semua','All','Semua','Alle','Tất cả','全部','すべて'],
    'Today': ['Hari Ini','Today','Hari Ini','Heute','Hôm nay','今天','今日'],
    'This Week': ['Minggu Ini','This Week','Minggu Ini','Diese Woche','Tuần này','本周','今週'],
    'This Month': ['Bulan Ini','This Month','Bulan Ini','Dieser Monat','Tháng này','本月','今月'],
    'Documentation': ['Dokumentasi','Documentation','Dokumentasi','Dokumentation','Tài liệu','文档','ドキュメント'],
    'Help': ['Bantuan','Help','Bantuan','Hilfe','Trợ giúp','帮助','ヘルプ'],
    'Log out': ['Keluar','Log out','Log keluar','Abmelden','Đăng xuất','退出登录','ログアウト'],
    'Sign in': ['Masuk','Sign in','Log masuk','Anmelden','Đăng nhập','登录','ログイン'],
    'Learn more': ['Pelajari Lebih Lanjut','Learn more','Ketahui lebih lanjut','Mehr erfahren','Tìm hiểu thêm','了解更多','詳しく見る'],
    'View all': ['Lihat Semua','View all','Lihat Semua','Alle anzeigen','Xem tất cả','查看全部','すべて表示'],
    'No results found': ['Tidak ada hasil','No results found','Tiada hasil ditemui','Keine Ergebnisse gefunden','Không tìm thấy kết quả','未找到结果','結果が見つかりません'],
    'Try again': ['Coba Lagi','Try again','Cuba Lagi','Erneut versuchen','Thử lại','重试','再試行'],
    'Loading': ['Memuat','Loading','Memuatkan','Wird geladen','Đang tải','加载中','読み込み中']
  });



  Object.assign(PHRASES, {
    'Feedback Explorer': ['Penjelajah Umpan Balik','Feedback Explorer','Peneroka Maklum Balas','Feedback-Explorer','Trình khám phá phản hồi','反馈浏览器','フィードバックエクスプローラー'],
    'Submit Feedback': ['Kirim Umpan Balik','Submit Feedback','Hantar Maklum Balas','Feedback senden','Gửi phản hồi','提交反馈','フィードバックを送信'],
    'Topic Analysis': ['Analisis Topik','Topic Analysis','Analisis Topik','Themenanalyse','Phân tích chủ đề','主题分析','トピック分析'],
    'Model Evaluation': ['Evaluasi Model','Model Evaluation','Penilaian Model','Modellbewertung','Đánh giá mô hình','模型评估','モデル評価'],
    'Enterprise RAG': ['RAG Perusahaan','Enterprise RAG','RAG Perusahaan','Enterprise-RAG','RAG doanh nghiệp','企业级 RAG','エンタープライズ RAG'],
    'AI Support': ['Dukungan AI','AI Support','Sokongan AI','KI-Support','Hỗ trợ AI','AI 支持','AI サポート'],
    'ML Predict API': ['API Prediksi ML','ML Predict API','API Ramalan ML','ML-Prognose-API','API dự đoán ML','ML 预测 API','ML 予測 API'],
    'Talent Match': ['Pencocokan Talenta','Talent Match','Padanan Bakat','Talentabgleich','Ghép nối nhân tài','人才匹配','人材マッチング'],
    'Doc Intel': ['Intelijen Dokumen','Doc Intel','Risikan Dokumen','Dokumentenintelligenz','Trí tuệ tài liệu','文档智能','文書インテリジェンス'],
    'ROI Estimator': ['Estimasi ROI','ROI Estimator','Penganggar ROI','ROI-Schätzer','Ước tính ROI','ROI 估算器','ROI 推定'],
    'Knowledge Base': ['Basis Pengetahuan','Knowledge Base','Pangkalan Pengetahuan','Wissensdatenbank','Cơ sở kiến thức','知识库','ナレッジベース'],
    'New Ticket': ['Tiket Baru','New Ticket','Tiket Baharu','Neues Ticket','Phiếu mới','新工单','新規チケット'],
    'Incident Monitoring': ['Pemantauan Insiden','Incident Monitoring','Pemantauan Insiden','Vorfallüberwachung','Giám sát sự cố','事件监控','インシデント監視'],
    'Academic Evidence': ['Bukti Akademik','Academic Evidence','Bukti Akademik','Akademische Nachweise','Minh chứng học thuật','学术证明','学術的証拠'],
    'Evidence Hub': ['Pusat Bukti','Evidence Hub','Hab Bukti','Nachweiszentrum','Trung tâm minh chứng','证据中心','証拠ハブ'],
    'Publications': ['Publikasi','Publications','Penerbitan','Publikationen','Ấn phẩm','出版物','出版物'],
    'Education': ['Pendidikan','Education','Pendidikan','Ausbildung','Giáo dục','教育','学歴'],
    'Awards': ['Penghargaan','Awards','Anugerah','Auszeichnungen','Giải thưởng','奖项','受賞歴'],
    'URL Shortener': ['Penyingkat URL','URL Shortener','Pemendek URL','URL-Kürzer','Trình rút gọn URL','URL 缩短器','URL 短縮'],
    'Cost Simulator': ['Simulator Biaya','Cost Simulator','Simulator Kos','Kostensimulator','Trình mô phỏng chi phí','费用模拟器','費用シミュレーター'],
    'Subnet Calculator': ['Kalkulator Subnet','Subnet Calculator','Kalkulator Subnet','Subnetzrechner','Máy tính mạng con','子网计算器','サブネット計算機'],
    'Student Performance': ['Performa Siswa','Student Performance','Prestasi Pelajar','Studierendenleistung','Kết quả học tập','学生表现','学生パフォーマンス'],
    'Data Studio': ['Studio Data','Data Studio','Studio Data','Datenstudio','Studio dữ liệu','数据工作室','データスタジオ'],
    'Run Prediction': ['Jalankan Prediksi','Run Prediction','Jalankan Ramalan','Prognose starten','Chạy dự đoán','运行预测','予測を実行'],
    'View Report': ['Lihat Laporan','View Report','Lihat Laporan','Bericht anzeigen','Xem báo cáo','查看报告','レポートを見る']
  });

  const languageOrder = ['id','en','ms','de','vi','zh','ja'];
  const indexByLanguage = Object.fromEntries(languageOrder.map((lang, index) => [lang, index]));
  const root = document.documentElement;
  const originalText = new WeakMap();
  const originalAttrs = new WeakMap();
  let currentLanguage = LANGUAGES[root.dataset.apuLanguage] ? root.dataset.apuLanguage : 'en';
  let observer = null;
  let translationQueued = false;
  let applyingTranslation = false;
  let toastTimer = 0;

  const normalize = value => String(value || '').replace(/\s+/g, ' ').trim();
  const escapeRegExp = value => value.replace(/[.*+?^${}()|[\]\\]/g, '\$&');
  const sourceToCanonical = new Map();
  const sourceEntries = [];

  for (const [canonical, translations] of Object.entries(PHRASES)) {
    const sources = [canonical, ...translations];
    for (const source of sources) {
      const normalized = normalize(source);
      if (!normalized) continue;
      sourceToCanonical.set(normalized.toLocaleLowerCase(), canonical);
      sourceEntries.push([normalized, canonical]);
    }
  }
  sourceEntries.sort((a, b) => b[0].length - a[0].length);

  function targetFor(canonical, language) {
    return PHRASES[canonical]?.[indexByLanguage[language] ?? 1] || canonical;
  }

  function translateValue(value, language) {
    const raw = String(value ?? '');
    const clean = normalize(raw);
    if (!clean || language === 'en') return raw;
    const exactCanonical = sourceToCanonical.get(clean.toLocaleLowerCase());
    if (exactCanonical) return raw.replace(clean, targetFor(exactCanonical, language));
    if (clean.length > 180) return raw;

    let result = raw;
    let replacements = 0;
    for (const [source, canonical] of sourceEntries) {
      if (source.length < 3 || replacements >= 8) continue;
      const target = targetFor(canonical, language);
      if (!target || target === source) continue;
      const isWordLike = /^[A-Za-zÀ-ž0-9 .'-]+$/.test(source);
      const pattern = isWordLike
        ? new RegExp(`(^|[^A-Za-zÀ-ž0-9])(${escapeRegExp(source)})(?=$|[^A-Za-zÀ-ž0-9])`, 'gi')
        : new RegExp(escapeRegExp(source), 'g');
      const next = result.replace(pattern, isWordLike ? `$1${target}` : target);
      if (next !== result) { result = next; replacements += 1; }
    }
    return result;
  }

  function shouldSkip(element) {
    return !element || Boolean(element.closest('#apu-ui-dock-v56, #apu-ui-toast-v56, script, style, code, pre, textarea, [contenteditable="true"], [data-apu-no-translate]'));
  }

  function translateTextNode(node) {
    const parent = node.parentElement;
    if (shouldSkip(parent)) return;
    const value = node.nodeValue || '';
    const clean = normalize(value);
    if (!clean || clean.length > 180) return;
    if (!originalText.has(node)) originalText.set(node, value);
    const original = originalText.get(node);
    const translated = translateValue(original, currentLanguage);
    if (node.nodeValue !== translated) node.nodeValue = translated;
  }

  function translateElementAttributes(element) {
    if (shouldSkip(element)) return;
    if (!originalAttrs.has(element)) originalAttrs.set(element, {});
    const stored = originalAttrs.get(element);
    for (const attr of ['placeholder','title','aria-label','alt']) {
      if (!element.hasAttribute(attr)) continue;
      if (!(attr in stored)) stored[attr] = element.getAttribute(attr);
      const original = stored[attr];
      if (original && normalize(original).length <= 180) {
        const translated = translateValue(original, currentLanguage);
        if (element.getAttribute(attr) !== translated) element.setAttribute(attr, translated);
      }
    }
  }

  function translateTree(container = document.body) {
    if (!container) return;
    applyingTranslation = true;
    try {
      if (container.nodeType === Node.TEXT_NODE) translateTextNode(container);
      const rootElement = container.nodeType === Node.ELEMENT_NODE ? container : container.parentElement;
      if (!rootElement || shouldSkip(rootElement)) return;
      if (rootElement.matches?.('[placeholder],[title],[aria-label],[alt]')) translateElementAttributes(rootElement);
      const walker = document.createTreeWalker(rootElement, NodeFilter.SHOW_TEXT, {
        acceptNode(node) {
          const parent = node.parentElement;
          if (shouldSkip(parent)) return NodeFilter.FILTER_REJECT;
          const text = normalize(node.nodeValue || '');
          return text && text.length <= 180 ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_REJECT;
        }
      });
      while (walker.nextNode()) translateTextNode(walker.currentNode);
      rootElement.querySelectorAll?.('[placeholder],[title],[aria-label],[alt]').forEach(translateElementAttributes);
    } finally {
      applyingTranslation = false;
    }
  }

  function queueTranslation(target) {
    if (translationQueued) return;
    translationQueued = true;
    requestAnimationFrame(() => {
      translationQueued = false;
      translateTree(target && target.isConnected ? target : document.body);
      syncNativeTheme();
      refreshAnimatedLayout();
    });
  }

  function refreshAnimatedLayout() {
    requestAnimationFrame(() => {
      try { window.ScrollTrigger?.refresh?.(true); } catch (_) {}
      window.dispatchEvent(new Event('resize'));
    });
  }

  function persist(key, value, legacyKeys = []) {
    try {
      localStorage.setItem(key, value);
      legacyKeys.forEach(legacy => localStorage.setItem(legacy, value));
    } catch (_) {}
  }


  function syncNativeTheme(theme = root.dataset.apuTheme || 'light') {
    const dark = theme === 'dark';
    root.classList.toggle('dark', dark);
    document.body?.classList.toggle('dark', dark);
    document.querySelectorAll('#root > [class~="dark"], #root > [data-theme], #root > * > [class~="dark"][data-theme]').forEach(element => {
      if (!dark && element.classList.contains('dark')) {
        element.dataset.apuOriginallyDark = 'true';
        element.classList.remove('dark');
      } else if (dark && element.dataset.apuOriginallyDark === 'true') {
        element.classList.add('dark');
      }
      if (element.hasAttribute('data-theme')) element.setAttribute('data-theme', dark ? 'dark' : 'light');
    });
  }

  function updateThemeMeta(theme) {
    let meta = document.querySelector('meta[name="theme-color"]');
    if (!meta) {
      meta = document.createElement('meta');
      meta.name = 'theme-color';
      document.head.appendChild(meta);
    }
    meta.content = theme === 'dark' ? '#0a0a0b' : '#f4f4f5';
  }

  function setTheme(theme, announce = false, persistChoice = true) {
    const resolved = theme === 'dark' ? 'dark' : 'light';
    root.dataset.apuTheme = resolved;
    root.style.colorScheme = resolved;
    syncNativeTheme(resolved);
    updateThemeMeta(resolved);
    if (persistChoice) persist(THEME_KEY, resolved, LEGACY_THEME_KEYS);
    updateDock();
    refreshAnimatedLayout();
    if (announce) showToast((UI[currentLanguage] || UI.en)[resolved === 'dark' ? 'enabledDark' : 'enabledLight']);
    window.dispatchEvent(new CustomEvent('apu:themechange', { detail: { theme: resolved } }));
  }

  function setLanguage(language, announce = false, persistChoice = true) {
    if (!LANGUAGES[language]) language = 'en';
    currentLanguage = language;
    root.dataset.apuLanguage = language;
    root.lang = language;
    root.dir = 'ltr';
    if (persistChoice) persist(LANGUAGE_KEY, language, LEGACY_LANGUAGE_KEYS);
    updateDock();
    translateTree(document.body);
    refreshAnimatedLayout();
    if (announce) showToast((UI[language] || UI.en).changed);
    window.dispatchEvent(new CustomEvent('apu:languagechange', { detail: { language } }));
  }

  function themeIcon(theme) {
    return theme === 'dark'
      ? '<svg viewBox="0 0 24 24" fill="none" aria-hidden="true"><path d="M12 3v2m0 14v2M3 12h2m14 0h2M5.64 5.64l1.42 1.42m9.88 9.88 1.42 1.42m0-12.72-1.42 1.42M7.06 16.94l-1.42 1.42M16.5 12a4.5 4.5 0 1 1-9 0 4.5 4.5 0 0 1 9 0Z" stroke-width="1.7" stroke-linecap="round"/></svg>'
      : '<svg viewBox="0 0 24 24" fill="none" aria-hidden="true"><path d="M20.6 15.7A8.5 8.5 0 0 1 8.3 3.4 8.6 8.6 0 1 0 20.6 15.7Z" stroke-width="1.7" stroke-linejoin="round"/></svg>';
  }

  function gridIcon() {
    return '<svg viewBox="0 0 24 24" fill="none" aria-hidden="true"><g fill="currentColor"><circle cx="5" cy="5" r="1.55"/><circle cx="12" cy="5" r="1.55"/><circle cx="19" cy="5" r="1.55"/><circle cx="5" cy="12" r="1.55"/><circle cx="12" cy="12" r="1.55"/><circle cx="19" cy="12" r="1.55"/><circle cx="5" cy="19" r="1.55"/><circle cx="12" cy="19" r="1.55"/><circle cx="19" cy="19" r="1.55"/></g></svg>';
  }

  function buildGridOverlay() {
    if (document.querySelector('.apu-grid-overlay-v56')) return;
    const overlay = document.createElement('div');
    overlay.className = 'apu-grid-overlay-v56';
    overlay.setAttribute('aria-hidden', 'true');
    document.body.prepend(overlay);
  }

  function buildDock() {
    if (document.getElementById('apu-ui-dock-v56')) return;
    const dock = document.createElement('div');
    dock.id = 'apu-ui-dock-v56';
    dock.setAttribute('role', 'group');
    dock.dataset.apuNoTranslate = 'true';

    const brand = document.createElement('div');
    brand.className = 'apu-ui-brand-v56';
    brand.innerHTML = `${gridIcon()}<span data-apu-brand-label>UI</span>`;

    const themeButton = document.createElement('button');
    themeButton.type = 'button';
    themeButton.className = 'apu-ui-theme-v56 apu-chunky-v56';
    themeButton.dataset.apuAction = 'theme';
    themeButton.addEventListener('click', () => setTheme(root.dataset.apuTheme === 'dark' ? 'light' : 'dark', true));

    const languageWrap = document.createElement('label');
    languageWrap.className = 'apu-ui-language-wrap-v56 apu-chunky-v56';
    languageWrap.innerHTML = '<svg viewBox="0 0 24 24" fill="none" aria-hidden="true"><circle cx="12" cy="12" r="9" stroke-width="1.7"/><path d="M3.5 12h17M12 3c2.3 2.5 3.5 5.5 3.5 9S14.3 18.5 12 21c-2.3-2.5-3.5-5.5-3.5-9S9.7 5.5 12 3Z" stroke-width="1.7"/></svg>';
    const select = document.createElement('select');
    select.className = 'apu-ui-language-v56';
    select.dataset.apuAction = 'language';
    for (const [code, info] of Object.entries(LANGUAGES)) {
      const option = document.createElement('option');
      option.value = code;
      option.textContent = info.name;
      select.appendChild(option);
    }
    select.addEventListener('change', event => setLanguage(event.target.value, true));
    languageWrap.appendChild(select);

    dock.append(brand, themeButton, languageWrap);
    document.body.appendChild(dock);

    const toast = document.createElement('div');
    toast.id = 'apu-ui-toast-v56';
    toast.setAttribute('role', 'status');
    toast.setAttribute('aria-live', 'polite');
    toast.dataset.apuNoTranslate = 'true';
    document.body.appendChild(toast);
    updateDock();
  }

  function updateDock() {
    const dock = document.getElementById('apu-ui-dock-v56');
    if (!dock) return;
    const ui = UI[currentLanguage] || UI.en;
    const currentTheme = root.dataset.apuTheme === 'dark' ? 'dark' : 'light';
    const themeButton = dock.querySelector('[data-apu-action="theme"]');
    const select = dock.querySelector('[data-apu-action="language"]');
    const brandLabel = dock.querySelector('[data-apu-brand-label]');
    dock.setAttribute('aria-label', ui.group);
    brandLabel.textContent = ui.brand;
    themeButton.innerHTML = `${themeIcon(currentTheme)}<span>${ui[currentTheme]}</span>`;
    themeButton.title = ui.theme;
    themeButton.setAttribute('aria-label', `${ui.theme} — ${ui[currentTheme]}`);
    themeButton.setAttribute('aria-pressed', String(currentTheme === 'dark'));
    select.value = currentLanguage;
    select.title = ui.language;
    select.setAttribute('aria-label', ui.language);
    dock.dataset.language = currentLanguage;
  }

  function showToast(message) {
    const toast = document.getElementById('apu-ui-toast-v56');
    if (!toast) return;
    clearTimeout(toastTimer);
    toast.textContent = message;
    toast.dataset.show = 'true';
    toastTimer = window.setTimeout(() => { toast.dataset.show = 'false'; }, 1800);
  }

  function observeChanges() {
    observer = new MutationObserver(mutations => {
      if (applyingTranslation) return;
      let target = null;
      for (const mutation of mutations) {
        if (mutation.type === 'childList' && mutation.addedNodes.length) {
          target = mutation.target.nodeType === 1 ? mutation.target : mutation.target.parentElement;
        }
      }
      if (target && !shouldSkip(target)) queueTranslation(target);
    });
    observer.observe(document.body, {
      childList: true,
      subtree: true
    });
  }

  function bindCrossTabSync() {
    window.addEventListener('storage', event => {
      if (event.key === THEME_KEY && (event.newValue === 'light' || event.newValue === 'dark')) setTheme(event.newValue, false, false);
      if (event.key === LANGUAGE_KEY && LANGUAGES[event.newValue]) setLanguage(event.newValue, false, false);
    });
  }

  function init() {
    buildGridOverlay();
    buildDock();
    setTheme(root.dataset.apuTheme || 'light', false, false);
    setLanguage(root.dataset.apuLanguage || 'en', false, false);
    observeChanges();
    bindCrossTabSync();
    root.classList.add('apu-ui-ready-v56');
  }

  if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', init, { once: true });
  else init();
})();
