diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -93,16 +93,17 @@ The web version shows the same catalog in the browser, with the latest download
 
 The interface is in English, Brazilian Portuguese (Português (Brasil)), Czech (Čeština), French
 (Français), German (Deutsch), Hungarian (Magyar), Japanese (日本語), Polish (Polski), Russian
-(Русский), Simplified Chinese (简体中文) or Spanish (Español). **Auto**, the default, follows the
-system or browser language; **Settings → Language** picks one and switches at once, and the choice
-is kept between runs. Czech locales (`cs-CZ`, `cs_CZ.UTF-8`…) select Czech, German ones (`de-DE`,
+(Русский), Simplified Chinese (简体中文), Spanish (Español) or Turkish (Türkçe). **Auto**, the default,
+follows the system or browser language; **Settings → Language** picks one and switches at once, and the
+choice is kept between runs. Czech locales (`cs-CZ`, `cs_CZ.UTF-8`…) select Czech, German ones (`de-DE`,
 `de-AT`, `de-CH`, `de_DE.UTF-8`…) German, French ones (`fr-FR`, `fr-CA`…) French, Hungarian ones
 (`hu`, `hu-HU`, `hu_HU.UTF-8`…) Hungarian, Japanese ones (`ja`, `ja-JP`, `ja_JP.UTF-8`…) Japanese,
 Polish ones (`pl`, `pl-PL`, `pl_PL.UTF-8`) Polish, Spanish ones (`es-ES`, `es-MX`, `es-419`…)
-Spanish, and Portuguese ones (`pt-BR`, and `pt-PT` too, for now) Brazilian Portuguese. Simplified
-Chinese locales (`zh-CN`, `zh-SG`, `zh-Hans`, and POSIX forms such as `zh_CN.UTF-8`) select
-Chinese; Traditional Chinese ones don't. To try a language without changing the setting, start the
-desktop app with `ARTCRAFT_LAUNCHER_LOCALE=pt-BR`, or add `?lang=ru` to the web address.
+Spanish, Turkish ones (`tr`, `tr-TR`, `tr_TR.UTF-8`…) Turkish, and Portuguese ones (`pt-BR`, and
+`pt-PT` too, for now) Brazilian Portuguese. Simplified Chinese locales (`zh-CN`, `zh-SG`, `zh-Hans`,
+and POSIX forms such as `zh_CN.UTF-8`) select Chinese; Traditional Chinese ones don't. To try a
+language without changing the setting, start the desktop app with `ARTCRAFT_LAUNCHER_LOCALE=tr`, or
+add `?lang=tr` to the web address.
 
 The CJK languages are drawn with the system's own CJK font (Hiragino Sans or PingFang on macOS,
 Yu Gothic, Meiryo or Microsoft YaHei on Windows, Noto Sans CJK, IPA, Takao or WenQuanYi on Linux and
diff --git a/crates/ui-egui/src/i18n/lang.rs b/crates/ui-egui/src/i18n/lang.rs
--- a/crates/ui-egui/src/i18n/lang.rs
+++ b/crates/ui-egui/src/i18n/lang.rs
@@ -22,7 +22,7 @@ impl Script {
 
 /// One supported UI language.
 pub struct LangInfo {
-    /// Canonical BCP 47 code (`en`, `ru`, `zh-CN`, `de`, `fr`, `pt-BR`, `es`, `cs`, `pl`, `hu`, `ja`).
+    /// Canonical BCP 47 code (`en`, `ru`, `zh-CN`, `de`, `fr`, `pt-BR`, `es`, `cs`, `pl`, `hu`, `ja`, `tr`).
     /// Also the `interfaceLanguage` value.
     pub code: &'static str,
     /// The language's name in itself, shown in the Preferences dropdown.
@@ -94,7 +94,7 @@ pub(super) fn plural_polish(n: u64) -> usize {
 }
 
 /// The registry. English first: it is the fallback and the source language.
-pub static LANGUAGES: [LangInfo; 11] = [
+pub static LANGUAGES: [LangInfo; 12] = [
     LangInfo {
         code: "en",
         name: "English",
@@ -216,6 +216,17 @@ pub static LANGUAGES: [LangInfo; 11] = [
         complete_menus: true,
         catalog: OnceLock::new(),
     },
+    LangInfo {
+        code: "tr",
+        name: "Türkçe",
+        english_name: "Turkish",
+        script: None,
+        source: include_str!("tr.tsv"),
+        plural: plural_none,
+        plural_forms: 1,
+        complete_menus: true,
+        catalog: OnceLock::new(),
+    },
 ];
 
 impl LangInfo {
@@ -254,6 +265,7 @@ impl Lang {
     pub const PL: Lang = Lang(&LANGUAGES[8]);
     pub const HU: Lang = Lang(&LANGUAGES[9]);
     pub const JA: Lang = Lang(&LANGUAGES[10]);
+    pub const TR: Lang = Lang(&LANGUAGES[11]);
 
     pub fn code(self) -> &'static str {
         self.0.code
diff --git a/crates/ui-egui/src/i18n/tests.rs b/crates/ui-egui/src/i18n/tests.rs
--- a/crates/ui-egui/src/i18n/tests.rs
+++ b/crates/ui-egui/src/i18n/tests.rs
@@ -400,6 +400,24 @@ fn japanese_locales_and_counts_work() {
     assert_eq!(message(Lang::JA, "PhotoCraft updated to 0.5.0"), "PhotoCraft を 0.5.0 に更新しました");
 }
 
+#[test]
+fn turkish_locales_and_plurals_work() {
+    for tag in ["tr", "tr-TR", "tr_TR.UTF-8", "TR_tr"] {
+        assert_eq!(lang_from_tag(tag), Some(Lang::TR), "{tag}");
+    }
+    assert_eq!(super::detect::first_supported(["xx-XX", "tr-TR", "en-US"]), Some(Lang::TR));
+    // Turkish nouns do not inflect for number; one plural form covers every count.
+    for n in [0, 1, 2, 11, 100] {
+        assert_eq!(trn(Lang::TR, n, "{n} app", "{n} apps"), format!("{n} uygulama"));
+        assert_eq!(trn(Lang::TR, n, "{n} day ago", "{n} days ago"), format!("{n} gün önce"));
+    }
+    assert_eq!(trn(Lang::TR, 2, "{n} unknown item", "{n} unknown items"), "2 unknown items");
+    assert_eq!(tr(Lang::TR, "Untranslated diagnostic"), "Untranslated diagnostic");
+    assert_eq!(super::tr_ctx(Lang::TR, "month", "Mar"), "Mar");
+    assert_eq!(tr(Lang::TR, "{month} {day}, {year}"), "{day} {month} {year}");
+    assert_eq!(message(Lang::TR, "PhotoCraft updated to 0.5.0"), "PhotoCraft, 0.5.0 sürümüne güncellendi");
+}
+
 /// With the system's Chinese font installed, every UI family can draw the whole Chinese catalog.
 /// Machines without one (CI, the web) skip this; the UI then stays in English.
 #[test]
@@ -558,7 +576,9 @@ fn picker_lists_english_first_then_names_alphabetically() {
     let pos = |code: &str| order.iter().position(|l| l.code() == code).unwrap_or_else(|| panic!("{code} registered"));
     assert!(pos("cs") < pos("de"), "Čeština sorts under C, not after Z");
     assert!(pos("fr") < pos("hu"), "Magyar sorts under M, not under its code");
-    assert!(pos("pt-BR") < pos("ru"), "Latin names come before Cyrillic");
+    assert!(pos("pt-BR") < pos("tr"), "Português sorts before Türkçe");
+    assert!(pos("tr") < pos("ru"), "Latin names come before Cyrillic");
     assert!(pos("ru") < pos("ja"), "Cyrillic names come before CJK");
     assert_eq!(name_sort_key("Čeština"), "cestina");
+    assert_eq!(name_sort_key("Türkçe"), "turkce");
 }
diff --git a/crates/ui-egui/src/i18n/tr.tsv b/crates/ui-egui/src/i18n/tr.tsv
new file mode 100644
--- /dev/null
+++ b/crates/ui-egui/src/i18n/tr.tsv
@@ -0,0 +1,364 @@
+# Turkish (tr) catalog for ArtCraft Launcher.
+# Format: context<TAB>source<TAB>translation
+# Empty context = plain UI string (tl!, t).
+# @id = command-id keyed (tr_id).
+# @plural = plural forms: one form for Turkish (nouns do not inflect for number).
+# @msg = status/error message template (message, msg).
+# Other context = disambiguation for tr_ctx.
+#
+# Clean-room: written from the meaning of ArtCraft Launcher's English labels, in natural,
+# idiomatic Turkish computing vocabulary.
+#
+# Coverage: the whole interface: every menu string and tl! literal (complete_menus = true).
+# Left in English on purpose: product name "ArtCraft Launcher" (and its "Launcher" tag), suite
+# name "Craft App Suite", app names (PhotoCraft, LightCraft, FilmCraft,
+# DesignCraft, VectorCraft, PdfCraft, EffectCraft, WordCraft, DeckCraft, GridCraft, CADCraft,
+# SoundCraft, FigCraft), "GitHub", "Discord", "Finder", "makers".
+# Trailing "…" (U+2026) must be preserved. Placeholders must appear in the translation:
+# {ago}, {a}, {b}, {count}, {date}, {day}, {done}, {e}, {f}, {installed}, {latest}, {min},
+# {month}, {name}, {n}, {os}, {platform}, {sources}, {total}, {version}, {v}, {year}.
+
+	Launcher	Launcher
+	Craft App Suite	Craft App Suite
+	Open Source Tools for Creatives, Makers, and Builders	Yaratıcılar, Üreticiler ve Geliştiriciler İçin Açık Kaynaklı Araçlar
+	Settings	Ayarlar
+	Check for updates	Güncellemeleri denetle
+	Grid	Izgara
+	Table	Tablo
+	Show apps as cards	Uygulamaları kart olarak göster
+	Show apps as a table	Uygulamaları tablo olarak göster
+	All	Tümü
+	Updates	Güncellemeler
+	Not installed	Yüklü değil
+	Search apps	Uygulama ara
+	Sort	Sırala
+	Suite order	Paket sırası
+	Name	Ad
+	Inspired by	Esinlenme
+	Status	Durum
+	Installed version	Yüklü sürüm
+	Latest version	En son sürüm
+	Newest release	En yeni sürüm
+	Discord	Discord
+	GitHub	GitHub
+	Website	Web sitesi
+	Classic apps	Klasik uygulamalar
+	Classic	Klasik
+	New apps	Yeni uygulamalar
+	NEW	YENİ
+	Install	Yükle
+	Update to {v}	{v} sürümüne güncelle
+	Open	Aç
+	Download for {os}	{os} için indir
+	Download	İndir
+	Coming soon	Yakında
+	Checking…	Denetleniyor…
+	Not available	Kullanılamıyor
+	Offline	Çevrimdışı
+	Downloading {done} of {total}	{total} içinden {done} indiriliyor
+	Downloading…	İndiriliyor…
+	Reconnecting…	Yeniden bağlanılıyor…
+	Verifying…	Doğrulanıyor…
+	Installing, then restarting…	Yükleniyor, ardından yeniden başlatılacak…
+	Installing…	Yükleniyor…
+	Removing…	Kaldırılıyor…
+	Pause download	İndirmeyi duraklat
+	Cancel download	İndirmeyi iptal et
+	Resume download	İndirmeyi sürdür
+	Discard download	İndirmeyi at
+	Release notes	Sürüm notları
+	Show in Finder	Finder'da göster
+	Show in Explorer	Dosya Gezgini'nde göster
+	Show in Files	Dosyalar'da göster
+	Reinstall	Yeniden yükle
+	Uninstall…	Kaldır…
+	All releases	Tüm sürümler
+	ArtCraft Launcher {version} is available.	ArtCraft Launcher {version} mevcut.
+	Dismiss	Kapat
+	Update and restart	Güncelle ve yeniden başlat
+	A new version is available. Would you like to relaunch with the updated version?	Yeni bir sürüm mevcut. Güncellenmiş sürümle yeniden başlatmak ister misiniz?
+	A new version is available. Download it to replace this version?	Yeni bir sürüm mevcut. Bu sürümün yerine indirmek ister misiniz?
+	Later	Daha sonra
+	What's new	Yenilikler
+	No notes were published with this release.	Bu sürümle birlikte herhangi bir not yayımlanmadı.
+	Released {date}	Yayımlanma: {date}
+	Open on GitHub	GitHub'da aç
+	Close	Kapat
+	ArtCraft Launcher {version}	ArtCraft Launcher {version}
+	Only when I ask	Yalnızca ben istediğimde
+	Automatically download and install updates	Güncellemeleri otomatik olarak indir ve yükle
+	Notify me when an installed app has an update	Yüklü bir uygulamanın güncellemesi olduğunda bana bildir
+	Include pre-releases (betas and release candidates)	Ön sürümleri (beta ve sürüm adayları) dahil et
+	Installing on Linux	Linux'ta yükleme
+	Installing on Windows	Windows'ta yükleme
+	Install new apps as	Yeni uygulamaları şu biçimde yükle:
+	System package (recommended)	Sistem paketi (önerilen)
+	Updates always use the format an app was installed with.	Güncellemeler her zaman uygulamanın yüklendiği biçimi kullanır.
+	Running in the background	Arka planda çalışma
+	Keep running in the tray when the window is closed	Pencere kapatıldığında sistem tepsisinde çalışmaya devam et
+	ArtCraft Launcher is still running	ArtCraft Launcher hâlâ çalışıyor
+	It's in the tray: open it or quit it from the tray icon, or turn this off in the settings.	Sistem tepsisinde: tepsi simgesinden açabilir ya da çıkabilirsiniz veya bunu ayarlardan kapatabilirsiniz.
+	Show the window on the current desktop	Pencereyi geçerli masaüstünde göster
+	Start ArtCraft Launcher when I log in	Oturum açtığımda ArtCraft Launcher'ı başlat
+	Community	Topluluk
+	Questions, ideas and news from the ArtCraft team	ArtCraft ekibinden sorular, fikirler ve haberler
+	Appearance	Görünüm
+	Quit ArtCraft Launcher	ArtCraft Launcher'dan çık
+	Done	Bitti
+	Uninstall {name}?	{name} kaldırılsın mı?
+	The app will be moved to the Trash. Your documents and settings stay.	Uygulama Çöp Sepeti'ne taşınacak. Belgeleriniz ve ayarlarınız korunur.
+	Windows will remove it like any installed program. Your documents and settings stay.	Windows bu uygulamayı normal bir program gibi kaldıracak. Belgeleriniz ve ayarlarınız korunur.
+	Your system's package manager will remove it, and may ask for your password. Your documents and settings stay.	Sisteminizin paket yöneticisi uygulamayı kaldıracak ve parolanızı isteyebilir. Belgeleriniz ve ayarlarınız korunur.
+	The app will be removed. Your documents and settings stay.	Uygulama kaldırılacak. Belgeleriniz ve ayarlarınız korunur.
+	Uninstall	Kaldır
+	Cancel	İptal
+	Checked {ago}	{ago} denetlendi
+	just now	az önce
+	yesterday	dün
+	{month} {day}, {year}	{day} {month} {year}
+	Automatically	Otomatik olarak
+	Every Craft app	Tüm Craft uygulamaları
+	Apps on this computer	Bu bilgisayardaki uygulamalar
+	Installed apps with a newer version	Daha yeni sürümü bulunan yüklü uygulamalar
+	Apps you can install	Yükleyebileceğiniz uygulamalar
+	Hide App	Uygulamayı Gizle
+	Unhide App	Uygulamayı Göster
+	Hidden Apps	Gizlenen Uygulamalar
+	Apps you hid	Gizlediğiniz uygulamalar
+	Checked {ago} · using {sources}	{ago} denetlendi · {sources} kullanılarak
+	{a} and {b}	{a} ve {b}
+	Join the Discord	Discord'a katılın
+	Learn more	Daha fazla bilgi
+	Minimize	Simge durumuna küçült
+	Maximize	Ekranı kapla
+	Restore	Geri yükle
+	New	Yeni
+	OK	Tamam
+	Open link	Bağlantıyı aç
+	Update	Güncelle
+	{name} icon	{name} simgesi
+	Loading ArtCraft Launcher…	ArtCraft Launcher yükleniyor…
+	Cancel update	Güncellemeyi iptal et
+	Stop waiting; the update can be started again later	Beklemeyi durdur; güncelleme daha sonra yeniden başlatılabilir
+	Download again	Yeniden indir
+	Install cancelled	Yükleme iptal edildi
+	Install cancelled. The download is kept for the next try.	Yükleme iptal edildi. İndirilen dosya bir sonraki deneme için saklandı.
+	Update cancelled	Güncelleme iptal edildi
+	Uninstall cancelled	Kaldırma iptal edildi
+	Retry install	Yüklemeyi yeniden dene
+	Retry update to {version}	{version} sürümüne güncellemeyi yeniden dene
+	The download is still here. It's checked again, then installed.	İndirilen dosya hâlâ burada. Tekrar kontrol edilip ardından yüklenecek.
+	Waiting for another app…	Başka bir uygulama bekleniyor…
+	Waiting for other installs…	Diğer yüklemeler bekleniyor…
+	Installer (.msi)	Yükleyici (.msi)
+	Portable (.zip)	Taşınabilir (.zip)
+	Disk image (.dmg)	Disk görüntüsü (.dmg)
+	Debian package (.deb)	Debian paketi (.deb)
+	RPM package (.rpm)	RPM paketi (.rpm)
+	Arch package (.pkg.tar.zst)	Arch paketi (.pkg.tar.zst)
+	Flatpak bundle	Flatpak paketi
+	Tarball (.tar.gz)	Tar arşivi (.tar.gz)
+photocraft	Image editing	Görsel düzenleme
+vectorcraft	Vector illustration	Vektörel çizim
+filmcraft	Video editing, color and sound	Video düzenleme, renk ve ses
+lightcraft	Photo library and raw development	Fotoğraf kitaplığı ve RAW geliştirme
+pdfcraft	Reading, organizing and protecting PDFs	PDF okuma, düzenleme ve koruma
+effectcraft	Motion graphics and visual effects	Hareketli grafikler ve görsel efektler
+designcraft	Page layout and publishing	Sayfa mizanpajı ve yayıncılık
+wordcraft	Writing and document design	Yazı ve belge tasarımı
+deckcraft	Presentations and slide shows	Sunumlar ve slayt gösterileri
+gridcraft	Spreadsheets and data	Elektronik tablolar ve veri
+cadcraft	Computer-aided design and drafting	Bilgisayar destekli tasarım ve teknik çizim
+soundcraft	Recording, editing and mixing audio	Ses kaydı, düzenleme ve miksaj
+figcraft	Interface design and prototyping	Arayüz tasarımı ve prototipleme
+month	Jan	Oca
+month	Feb	Şub
+month	Mar	Mar
+month	Apr	Nis
+month	May	May
+month	Jun	Haz
+month	Jul	Tem
+month	Aug	Ağu
+month	Sep	Eyl
+month	Oct	Eki
+month	Nov	Kas
+month	Dec	Ara
+	Not checked yet	Henüz denetlenmedi
+	GitHub's hourly limit was reached; full details return in {min} min	GitHub'ın saatlik istek sınırına ulaşıldı; tüm ayrıntılar {min} dk. içinde tekrar görüntülenebilecek
+	GitHub limit hit; back in {min} min	GitHub sınırına ulaşıldı; {min} dk. içinde geri dönecek
+	Installing for {platform}	{platform} için yükleniyor
+	Downloads for {platform}	{platform} için indirmeler
+	No downloads for this system	Bu sistem için indirme bulunmuyor
+	Join the ArtCraft community on Discord	Discord'da ArtCraft topluluğuna katılın
+	ArtCraft on {name}	{name} üzerinde ArtCraft
+	Couldn't open {name}: {e}	{name} açılamadı: {e}
+	Download cancelled	İndirme iptal edildi
+	Available to install	Yüklenmeye hazır
+	Available	Kullanılabilir
+	Installed · up to date	Yüklü · güncel
+	Update available	Güncelleme mevcut
+	Installed	Yüklü
+	installed	yüklü
+	Not available here	Burada kullanılamıyor
+	Updating…	Güncelleniyor…
+	Update paused	Güncelleme duraklatıldı
+	Download paused	İndirme duraklatıldı
+	{version} installed → {latest} released	{version} yüklü → {latest} yayımlandı
+	Version {version}	Sürüm {version}
+	{installed} installed · latest {latest}	{installed} yüklü · en son {latest}
+	Installed · latest {latest}	Yüklü · en son {latest}
+	Version {version} installed	Sürüm {version} yüklü
+	Version {latest}	Sürüm {latest}
+	No release published yet	Henüz bir sürüm yayımlanmadı
+	ArtCraft Launcher	ArtCraft Launcher
+	App	Uygulama
+	Latest	En son
+	Released	Yayımlanma
+	Auto	Otomatik
+	Language	Dil
+	Ascending	Artan
+	Descending	Azalan
+	Click to reverse the order	Sıralamayı tersine çevirmek için tıklayın
+	Click to sort by this column	Bu sütuna göre sıralamak için tıklayın
+	Like {name}	{name} benzeri
+	{done} of {total}	{total} içinden {done}
+	Downloading	İndiriliyor
+	Verifying checksum…	Sağlama toplamı doğrulanıyor…
+	Resume	Sürdür
+	{done} of {total} downloaded	{total} içinden {done} indirildi
+	{done} downloaded	{done} indirildi
+	Checking for updates…	Güncellemeler denetleniyor…
+	Downloads the new version, replaces this one and opens it again	Yeni sürümü indirir, mevcut sürümle değiştirir ve yeniden açar
+	Couldn't check for updates: {f}	Güncellemeler denetlenemedi: {f}
+	Website (coming soon)	Web sitesi (yakında)
+	GitHub repository	GitHub deposu
+	ArtCraft	ArtCraft
+	Update 1 app	1 uygulamayı güncelle
+	Update all ({count})	Tümünü güncelle ({count})
+	⊞  Grid	⊞  Izgara
+	☰  Table	☰  Tablo
+	🔍  Search apps	🔍  Uygulama ara
+	{name} {version}	{name} {version}
+	Match system	Sistemle eşleş
+	Dark	Karanlık
+	Light	Aydınlık
+	Full changelog	Tam değişiklik günlüğü
+	link	bağlantı
+	No apps match	Eşleşen uygulama yok
+	Open ArtCraft Launcher to update.	Güncellemek için ArtCraft Launcher'ı açın.
+	{name} {v} is available	{name} {v} mevcut
+	{count} updates are available	{count} güncelleme mevcut
+	These notes weren't fetched (GitHub's request limit was reached). They're on the release page.	Bu notlar alınamadı (GitHub'ın istek sınırına ulaşıldı). Sürüm sayfasında yer alıyorlar.
+	When on, opening the launcher from the menu bar brings its window to the desktop you're on. When off, macOS switches you to the desktop the window was on.	Açık olduğunda, başlatıcıyı menü çubuğundan açmak penceresini bulunduğunuz masaüstüne getirir. Kapalı olduğunda macOS sizi pencerenin bulunduğu masaüstüne geçirir.
+	Couldn't change the login item: {e}	Oturum açma öğesi değiştirilemedi: {e}
+column	App	Uygulama
+column	Installed	Yüklü
+column	Latest	En son
+column	Released	Yayımlanma
+filter	Installed	Yüklü
+	App details	Uygulama ayrıntıları
+	More actions for {name}	{name} için diğer işlemler
+	Close (Esc)	Kapat (Esc)
+	Features	Özellikler
+	Latest release	En son sürüm
+	Version	Sürüm
+	Platforms	Platformlar
+	Releases	Sürümler
+	Enlarge picture	Resmi büyüt
+	Click to enlarge	Büyütmek için tıklayın
+	Previous picture (←)	Önceki resim (←)
+	Next picture (→)	Sonraki resim (→)
+	Loading pictures…	Resimler yükleniyor…
+	Pictures couldn't be loaded. Reopen this page to try again.	Resimler yüklenemedi. Yeniden denemek için bu sayfayı tekrar açın.
+	{name} details	{name} ayrıntıları
+@plural	{n} app|{n} apps	{n} uygulama
+@plural	{n} min ago|{n} min ago	{n} dk. önce
+@plural	{n} h ago|{n} h ago	{n} sa. önce
+@plural	{n} day ago|{n} days ago	{n} gün önce
+@msg	Couldn't open {name}: {e}	{name} açılamadı: {e}
+@msg	Download cancelled	İndirme iptal edildi
+@msg	{name} updated to {version}	{name}, {version} sürümüne güncellendi
+@msg	{name} installed: {version}	{name} kuruldu: {version}
+@msg	{name} updated to {version} (this release publishes no checksum, so only its size was checked)	{name}, {version} sürümüne güncellendi (bu sürüm sağlama toplamı yayımlamadığından yalnızca boyutu doğrulandı)
+@msg	{name} installed: {version} (this release publishes no checksum, so only its size was checked)	{name} kuruldu: {version} (bu sürüm sağlama toplamı yayımlamadığından yalnızca boyutu doğrulandı)
+@msg	{name} was removed	{name} kaldırıldı
+@msg	{name} is running. Quit it, then try again.	{name} çalışıyor. Kapatıp tekrar deneyin.
+@msg	{name} was installed from the {repo} repository or the AUR ({pkg}). Update it with {cmd} or sudo pacman -Syu	{name}, {repo} deposundan veya AUR'dan ({pkg}) kuruldu. {cmd} ya da sudo pacman -Syu ile güncelleyin
+@msg	{name} was installed from the {repo} repository or the AUR ({pkg}). Update it with your AUR helper (for example: yay -S {pkg}) or sudo pacman -Syu	{name}, {repo} deposundan veya AUR'dan ({pkg}) kuruldu. AUR yardımcınızla (örneğin: yay -S {pkg}) ya da sudo pacman -Syu ile güncelleyin
+@msg	{name} was installed from the AUR ({pkg}). Update it with {cmd}	{name}, AUR'dan ({pkg}) kuruldu. {cmd} ile güncelleyin
+@msg	{name} was installed from the AUR ({pkg}). Update it with your AUR helper (for example: yay -S {pkg})	{name}, AUR'dan ({pkg}) kuruldu. AUR yardımcınızla (örneğin: yay -S {pkg}) güncelleyin
+@id	app.install	Yükle
+@id	app.update	{v} sürümüne güncelle
+@id	app.open	Aç
+@id	app.download	{os} için indir
+@id	app.reveal	Finder'da göster
+@id	app.reinstall	Yeniden yükle
+@id	app.uninstall	Kaldır…
+@id	app.notes	Sürüm notları
+@id	app.website	Web sitesi
+@id	app.github	GitHub deposu
+@id	app.releases	Tüm sürümler
+@id	launcher.update	Güncelle ve yeniden başlat
+@id	launcher.download	İndir
+@id	launcher.notes	Yenilikler
+@id	launcher.dismiss	Kapat
+@id	settings.open	Ayarlar
+@id	settings.quit	ArtCraft Launcher'dan çık
+@id	view.grid	Izgara
+@id	view.table	Tablo
+@id	filter.all	Tümü
+@id	filter.installed	Yüklü
+@id	filter.updates	Güncellemeler
+@id	filter.notinstalled	Yüklü değil
+@id	sort.suite	Paket sırası
+@id	sort.name	Ad
+@id	sort.inspired	Esinlenme
+@id	sort.status	Durum
+@id	sort.installed	Yüklü sürüm
+@id	sort.latest	En son sürüm
+@id	sort.released	En yeni sürüm
+@id	help.discord	Discord
+@id	help.github	GitHub
+@id	help.website	Web sitesi
+@id	update.check	Güncellemeleri denetle
+@id	update.check_auto	Güncellemeleri otomatik olarak denetle
+@id	update.notify	Yüklü bir uygulamanın güncellemesi olduğunda bana bildir
+@id	update.prereleases	Ön sürümleri (beta ve sürüm adayları) dahil et
+@id	linux.preferred_kind	Yeni uygulamaları şu biçimde yükle:
+@id	tray.close_to_tray	Pencere kapatıldığında sistem tepsisinde çalışmaya devam et
+@id	tray.show_on_current_desktop	Pencereyi geçerli masaüstünde göster
+@id	tray.login_item	Oturum açtığımda ArtCraft Launcher'ı başlat
+@id	appearance.theme	Görünüm
+	Show ArtCraft Launcher	ArtCraft Launcher'ı Göster
+	Check for Updates	Güncellemeleri Denetle
+	Visit getartcraft.com	getartcraft.com adresini ziyaret edin
+	ArtCraft on GitHub	GitHub'da ArtCraft
+	Join the ArtCraft Discord	ArtCraft Discord'una Katılın
+@plural	ArtCraft Launcher · {n} update available|ArtCraft Launcher · {n} updates available	ArtCraft Launcher · {n} güncelleme mevcut
+	Install folder	Kurulum klasörü
+	Default install folder	Varsayılan kurulum klasörü
+	System default	Sistem varsayılanı
+	Browse…	Gözat…
+	Use default	Varsayılanı kullan
+	New installs use this folder. Updates stay in their current location.	Yeni kurulumlar bu klasörü kullanır. Güncellemeler geçerli konumlarında kalır.
+	Custom folders use AppImage on Linux.	Özel klasörler Linux'ta AppImage kullanır.
+	On Linux, custom folders use AppImage format.	Linux'ta özel klasörler AppImage biçimini kullanır.
+	The system manages install locations here.	Sistem buradaki kurulum konumlarını yönetir.
+@msg	couldn't use install folder {path}: {reason}	{path} kurulum klasörü kullanılamadı: {reason}
+@msg	this release has no AppImage for a custom install folder	bu sürümde özel kurulum klasörü için bir AppImage yok
+@msg	custom install folders aren't supported on this system	özel kurulum klasörleri bu sistemde desteklenmiyor
+@msg	{path} already exists and wasn't installed by ArtCraft Launcher	{path} zaten mevcut ve ArtCraft Launcher tarafından kurulmamış
+@msg	couldn't move {path} to Trash ({reason}). Remove it in Finder instead.	{path} Çöp Sepeti'ne taşınamadı ({reason}). Finder üzerinden kaldırın.
+	Apps are placed inside this folder.	Uygulamalar bu klasörün içine yerleştirilir.
+	Replace what's there?	Mevcut olanla değiştirilsin mi?
+	{path} already exists. Installing {name} will overwrite it.	{path} zaten mevcut. {name} uygulamasını yüklemek üzerine yazacaktır.
+	Replace	Değiştir
+	Recently updated	Son güncellenenler
+	Name (A–Z)	Ad (A–Z)
+	Name (Z–A)	Ad (Z–A)
+	Frequently used	Sık kullanılanlar
+	Next app	Sonraki uygulama
+	Previous app	Önceki uygulama
+	Show {n} more changes	{n} değişiklik daha göster
+	Last updated: {date}	Son güncelleme: {date}
+column	Version	Sürüm
diff --git a/crates/ui-egui/tests/turkish.rs b/crates/ui-egui/tests/turkish.rs
new file mode 100644
--- /dev/null
+++ b/crates/ui-egui/tests/turkish.rs
@@ -0,0 +1,129 @@
+//! The Turkish UI, in its own test binary: the UI language is process-wide, so it can't share one
+//! with the English UI tests. `ARTCRAFT_LAUNCHER_SNAPSHOTS=<dir>` also saves screenshots (run with
+//! `-- --test-threads=1`, see `ui.rs`).
+
+use std::cell::Cell;
+use std::rc::Rc;
+
+use artcraft_launcher_core::protocol::{Backend, Capabilities, Command, Event, JobPhase, LatestRelease, Origin, Source};
+use artcraft_launcher_core::release::{Asset, Release};
+use artcraft_launcher_core::status::InstallSource;
+use artcraft_launcher_core::{Arch, Installed, Os, Platform, SUITE, version};
+use artcraft_launcher_ui_egui::settings::ViewMode;
+use artcraft_launcher_ui_egui::{Host, LauncherUi, Settings};
+use egui_kittest::Harness;
+use egui_kittest::kittest::Queryable;
+
+const NOW: i64 = 1_791_500_000;
+
+struct Fake {
+    events: Vec<Event>,
+    clock: Rc<Cell<i64>>,
+}
+
+impl Backend for Fake {
+    fn send(&mut self, _command: Command) {}
+    fn poll(&mut self) -> Vec<Event> {
+        std::mem::take(&mut self.events)
+    }
+    fn capabilities(&self) -> Capabilities {
+        Capabilities { manage_apps: true, reveal_label: "Show in Finder", self_update: true }
+    }
+    fn platform(&self) -> Option<Platform> {
+        Some(Platform { os: Os::MacOs, arch: Arch::Arm64 })
+    }
+    fn now(&self) -> i64 {
+        self.clock.get()
+    }
+}
+
+struct NoHost;
+impl Host for NoHost {}
+
+fn release(id: &str, v: &str, at: i64) -> Release {
+    let name = format!("{id}-{v}-macos-universal.dmg");
+    Release {
+        tag: format!("v{v}"),
+        version: version::parse(v),
+        name: format!("v{v}"),
+        published_at: Some(at),
+        html_url: format!("https://github.com/storytold/{id}/releases/tag/v{v}"),
+        notes: String::new(),
+        prerelease: false,
+        assets: vec![Asset {
+            name: name.clone(),
+            size: 150 << 20,
+            url: format!("https://github.com/storytold/{id}/releases/download/v{v}/{name}"),
+            sha256: None,
+        }],
+    }
+}
+
+fn events() -> Vec<Event> {
+    let mut ev = Vec::new();
+    for (i, app) in SUITE.iter().enumerate() {
+        let latest = LatestRelease::Found(release(app.id, "0.5.0", NOW - 40 * 86_400 - i as i64 * 600));
+        ev.push(Event::Latest { app: app.id.into(), latest, from: Origin::ArtCraftApi });
+        let installed = matches!(app.id, "photocraft" | "lightcraft").then(|| Installed {
+            version: version::parse(if app.id == "photocraft" { "0.4.1" } else { "0.5.0" }),
+            source: InstallSource::MacApp,
+            location: format!("/Applications/{}.app", app.name),
+            package: None,
+        });
+        ev.push(Event::Detected { app: app.id.into(), installed });
+    }
+    ev.push(Event::Progress { app: "filmcraft".into(), phase: JobPhase::Verifying });
+    ev.push(Event::CheckFinished { at: NOW - 180, source: Source::Feed, rate_limited_until: None });
+    // A backend message, translated through its `@msg` template where it's shown.
+    ev.push(Event::JobFinished { app: "lightcraft".into(), result: Ok("LightCraft updated to 0.5.0".into()) });
+    ev
+}
+
+fn harness(view: ViewMode) -> Harness<'static, Option<LauncherUi>> {
+    artcraft_launcher_ui_egui::i18n::set_test_lang(artcraft_launcher_ui_egui::i18n::Lang::EN);
+    let mut backend = Some(Fake { events: events(), clock: Rc::new(Cell::new(NOW)) });
+    let settings =
+        Settings { view, notify: false, language: "tr".into(), theme: artcraft_launcher_ui_egui::theme::ThemeChoice::Dark, ..Settings::default() };
+    Harness::builder().with_size(egui::vec2(1180.0, 900.0)).with_theme(egui::Theme::Dark).build_ui_state(
+        move |ui, state: &mut Option<LauncherUi>| {
+            if state.is_none()
+                && let Some(b) = backend.take()
+            {
+                *state = Some(LauncherUi::new(ui.ctx(), Box::new(b), settings.clone()));
+            }
+            if let Some(l) = state.as_mut() {
+                l.logic(&ui.ctx().clone(), &mut NoHost);
+                l.ui(ui, &mut NoHost);
+            }
+        },
+        None,
+    )
+}
+
+fn snapshot(h: &mut Harness<'_, Option<LauncherUi>>, name: &str) {
+    let Some(dir) = std::env::var_os("ARTCRAFT_LAUNCHER_SNAPSHOTS") else { return };
+    let img = h.render().unwrap();
+    img.save(std::path::Path::new(&dir).join(format!("{name}.png"))).unwrap();
+}
+
+// One test: the UI language is process-wide.
+#[test]
+fn turkish_ui_translates_labels_dates_and_messages() {
+    let mut h = harness(ViewMode::Grid);
+    h.run_steps(8);
+    snapshot(&mut h, "grid-tr-dark");
+    // Product names stay in English.
+    assert!(h.query_by_label("Launcher").is_none());
+    h.get_by_label("Craft App Suite");
+    h.get_by_label("Görsel düzenleme");
+    h.get_by_label("0.5.0 sürümüne güncelle");
+    h.get_by_label_contains("Sağlama toplamı doğrulanıyor…");
+    h.get_by_label_contains("3 dk. önce denetlendi · ArtCraft API kullanılarak");
+    h.get_by_label("LightCraft, 0.5.0 sürümüne güncellendi");
+
+    let mut table = harness(ViewMode::Table);
+    table.run_steps(8);
+    snapshot(&mut table, "table-tr-dark");
+    table.get_by_label("Yüklü");
+    assert!(table.query_all_by_label_contains("Ağu 2026").count() >= 1);
+}
