Ariver
2026-06-11 1f4ab9ad0810ad242f6dee66e8e39005adcf78a4
Refine data settings layout sections
32 files modified
143 ■■■■■ changed files
src/Apptag/Info.plist 4 ●●●● patch | view | raw | blame | history
src/Apptag/Localization/ar-Najdi.json 1 ●●●● patch | view | raw | blame | history
src/Apptag/Localization/ar.json 1 ●●●● patch | view | raw | blame | history
src/Apptag/Localization/cs.json 1 ●●●● patch | view | raw | blame | history
src/Apptag/Localization/da.json 1 ●●●● patch | view | raw | blame | history
src/Apptag/Localization/de.json 1 ●●●● patch | view | raw | blame | history
src/Apptag/Localization/en.json 1 ●●●● patch | view | raw | blame | history
src/Apptag/Localization/es.json 1 ●●●● patch | view | raw | blame | history
src/Apptag/Localization/fr.json 1 ●●●● patch | view | raw | blame | history
src/Apptag/Localization/id.json 1 ●●●● patch | view | raw | blame | history
src/Apptag/Localization/it.json 1 ●●●● patch | view | raw | blame | history
src/Apptag/Localization/ja.json 1 ●●●● patch | view | raw | blame | history
src/Apptag/Localization/ko.json 1 ●●●● patch | view | raw | blame | history
src/Apptag/Localization/ms.json 1 ●●●● patch | view | raw | blame | history
src/Apptag/Localization/nb.json 1 ●●●● patch | view | raw | blame | history
src/Apptag/Localization/nl.json 1 ●●●● patch | view | raw | blame | history
src/Apptag/Localization/nn.json 1 ●●●● patch | view | raw | blame | history
src/Apptag/Localization/no.json 1 ●●●● patch | view | raw | blame | history
src/Apptag/Localization/pl.json 1 ●●●● patch | view | raw | blame | history
src/Apptag/Localization/pt-BR.json 1 ●●●● patch | view | raw | blame | history
src/Apptag/Localization/ro.json 1 ●●●● patch | view | raw | blame | history
src/Apptag/Localization/ru.json 1 ●●●● patch | view | raw | blame | history
src/Apptag/Localization/sr-Cyrl.json 1 ●●●● patch | view | raw | blame | history
src/Apptag/Localization/sv.json 1 ●●●● patch | view | raw | blame | history
src/Apptag/Localization/th.json 1 ●●●● patch | view | raw | blame | history
src/Apptag/Localization/tr.json 1 ●●●● patch | view | raw | blame | history
src/Apptag/Localization/uk.json 1 ●●●● patch | view | raw | blame | history
src/Apptag/Localization/vi.json 1 ●●●● patch | view | raw | blame | history
src/Apptag/Localization/zh-Hans.json 1 ●●●● patch | view | raw | blame | history
src/Apptag/Localization/zh-Hant.json 1 ●●●● patch | view | raw | blame | history
src/Apptag/PreferencesView.swift 103 ●●●●● patch | view | raw | blame | history
src/CHANGELOG.md 7 ●●●●● patch | view | raw | blame | history
src/Apptag/Info.plist
@@ -19,9 +19,9 @@
    <key>CFBundlePackageType</key>
    <string>APPL</string>
    <key>CFBundleShortVersionString</key>
    <string>7.8.30</string>
    <string>7.8.31</string>
    <key>CFBundleVersion</key>
    <string>20260611.1858</string>
    <string>20260611.1928</string>
    <key>LSApplicationCategoryType</key>
    <string>public.app-category.utilities</string>
    <key>LSMinimumSystemVersion</key>
src/Apptag/Localization/ar-Najdi.json
@@ -141,6 +141,7 @@
  "settings.initialLayout": "تهيئة الترتيب:",
  "settings.initialLayoutUncategorized": "غير مصنف",
  "settings.initialLayoutSmart": "تصنيف ذكي مبدئي",
  "settings.customLayout": "تخطيط مخصص:",
  "settings.applyScheme": "تطبيق",
  "settings.applySystemSchemeWarningTitle": "الأفضل تسوي نسخة احتياطية",
  "settings.applySystemSchemeWarningMessage": "تطبيق مخطط البداية الذكي للنظام بيستبدل المخطط المحلي الحالي. ما عندك نسخة احتياطية للحين؛ نوصي بقوة تصدر نسخة احتياطية قبل التطبيق.",
src/Apptag/Localization/ar.json
@@ -141,6 +141,7 @@
  "settings.initialLayout": "تهيئة التخطيط:",
  "settings.initialLayoutUncategorized": "غير مصنف",
  "settings.initialLayoutSmart": "تصنيف أولي ذكي",
  "settings.customLayout": "تخطيط مخصص:",
  "settings.applyScheme": "تطبيق",
  "settings.applySystemSchemeWarningTitle": "يُوصى بالنسخ الاحتياطي",
  "settings.applySystemSchemeWarningMessage": "سيؤدي تطبيق مخطط البداية الذكي للنظام إلى استبدال المخطط المحلي الحالي. لم تقم بعمل نسخة احتياطية بعد؛ نوصي بشدة بتصدير نسخة احتياطية قبل التطبيق.",
src/Apptag/Localization/cs.json
@@ -141,6 +141,7 @@
  "settings.initialLayout": "Inicializace rozvrzeni:",
  "settings.initialLayoutUncategorized": "Nezarazeno",
  "settings.initialLayoutSmart": "Chytre pocatecni kategorie",
  "settings.customLayout": "Vlastní rozvržení:",
  "settings.applyScheme": "Použít",
  "settings.applySystemSchemeWarningTitle": "Doporučujeme zálohu",
  "settings.applySystemSchemeWarningMessage": "Použití chytrého počátečního schématu systému nahradí aktuální místní schéma. Ještě nemáte zálohu; důrazně doporučujeme ji před použitím exportovat.",
src/Apptag/Localization/da.json
@@ -141,6 +141,7 @@
  "settings.initialLayout": "Initialiser layout:",
  "settings.initialLayoutUncategorized": "Ukategoriseret",
  "settings.initialLayoutSmart": "Smarte startkategorier",
  "settings.customLayout": "Tilpasset layout:",
  "settings.applyScheme": "Anvend",
  "settings.applySystemSchemeWarningTitle": "Sikkerhedskopi anbefales",
  "settings.applySystemSchemeWarningMessage": "Anvendelse af systemets smarte startskema erstatter det aktuelle lokale skema. Du har ikke sikkerhedskopieret endnu; vi anbefaler kraftigt at eksportere en sikkerhedskopi først.",
src/Apptag/Localization/de.json
@@ -141,6 +141,7 @@
  "settings.initialLayout": "Layout initialisieren:",
  "settings.initialLayoutUncategorized": "Nicht kategorisiert",
  "settings.initialLayoutSmart": "Smarte Anfangskategorien",
  "settings.customLayout": "Benutzerdefiniertes Layout:",
  "settings.applyScheme": "Anwenden",
  "settings.applySystemSchemeWarningTitle": "Backup empfohlen",
  "settings.applySystemSchemeWarningMessage": "Das Anwenden des intelligenten System-Startschemas ersetzt das aktuelle lokale Schema. Es wurde noch nicht gesichert; wir empfehlen dringend, vor dem Anwenden ein Backup zu exportieren.",
src/Apptag/Localization/en.json
@@ -141,6 +141,7 @@
  "settings.initialLayout": "Layout initialization:",
  "settings.initialLayoutUncategorized": "Uncategorized",
  "settings.initialLayoutSmart": "Smart initial categories",
  "settings.customLayout": "Custom layout:",
  "settings.applyScheme": "Apply",
  "settings.applySystemSchemeWarningTitle": "Backup recommended",
  "settings.applySystemSchemeWarningMessage": "Applying the system smart initial scheme will replace the current local scheme. You have not backed it up yet; we strongly recommend exporting a backup before applying.",
src/Apptag/Localization/es.json
@@ -141,6 +141,7 @@
  "settings.initialLayout": "Inicializacion del diseno:",
  "settings.initialLayoutUncategorized": "Sin categorizar",
  "settings.initialLayoutSmart": "Categorias iniciales inteligentes",
  "settings.customLayout": "Diseño personalizado:",
  "settings.applyScheme": "Aplicar",
  "settings.applySystemSchemeWarningTitle": "Se recomienda hacer copia de seguridad",
  "settings.applySystemSchemeWarningMessage": "Aplicar el esquema inicial inteligente del sistema reemplazará el esquema local actual. Aún no tienes una copia de seguridad; recomendamos exportarla antes de aplicar.",
src/Apptag/Localization/fr.json
@@ -141,6 +141,7 @@
  "settings.initialLayout": "Initialisation de la mise en page :",
  "settings.initialLayoutUncategorized": "Non classe",
  "settings.initialLayoutSmart": "Categories initiales intelligentes",
  "settings.customLayout": "Disposition personnalisée :",
  "settings.applyScheme": "Appliquer",
  "settings.applySystemSchemeWarningTitle": "Sauvegarde recommandée",
  "settings.applySystemSchemeWarningMessage": "Appliquer le schéma initial intelligent du système remplacera le schéma local actuel. Vous ne l’avez pas encore sauvegardé ; nous vous recommandons fortement d’exporter une sauvegarde avant de l’appliquer.",
src/Apptag/Localization/id.json
@@ -141,6 +141,7 @@
  "settings.initialLayout": "Inisialisasi tata letak:",
  "settings.initialLayoutUncategorized": "Tanpa kategori",
  "settings.initialLayoutSmart": "Kategori awal cerdas",
  "settings.customLayout": "Tata letak kustom:",
  "settings.applyScheme": "Terapkan",
  "settings.applySystemSchemeWarningTitle": "Cadangan disarankan",
  "settings.applySystemSchemeWarningMessage": "Menerapkan skema awal pintar sistem akan mengganti skema lokal saat ini. Anda belum mencadangkannya; kami sangat menyarankan mengekspor cadangan sebelum menerapkan.",
src/Apptag/Localization/it.json
@@ -141,6 +141,7 @@
  "settings.initialLayout": "Inizializzazione layout:",
  "settings.initialLayoutUncategorized": "Non categorizzato",
  "settings.initialLayoutSmart": "Categorie iniziali smart",
  "settings.customLayout": "Layout personalizzato:",
  "settings.applyScheme": "Applica",
  "settings.applySystemSchemeWarningTitle": "Backup consigliato",
  "settings.applySystemSchemeWarningMessage": "Applicare lo schema iniziale intelligente di sistema sostituirà lo schema locale attuale. Non hai ancora un backup; consigliamo vivamente di esportarne uno prima di applicare.",
src/Apptag/Localization/ja.json
@@ -141,6 +141,7 @@
  "settings.initialLayout": "レイアウト初期化:",
  "settings.initialLayoutUncategorized": "未分類",
  "settings.initialLayoutSmart": "スマート初期分類",
  "settings.customLayout": "カスタムレイアウト:",
  "settings.applyScheme": "適用",
  "settings.applySystemSchemeWarningTitle": "バックアップをおすすめします",
  "settings.applySystemSchemeWarningMessage": "システム初期スマート分類を適用すると、現在のローカルスキームが置き換えられます。まだバックアップがありません。適用前に「カテゴリとレイアウトをエクスポート」でバックアップすることを強くおすすめします。",
src/Apptag/Localization/ko.json
@@ -141,6 +141,7 @@
  "settings.initialLayout": "레이아웃 초기화:",
  "settings.initialLayoutUncategorized": "미분류",
  "settings.initialLayoutSmart": "스마트 초기 분류",
  "settings.customLayout": "사용자 지정 레이아웃:",
  "settings.applyScheme": "적용",
  "settings.applySystemSchemeWarningTitle": "백업 권장",
  "settings.applySystemSchemeWarningMessage": "시스템 스마트 초기 분류를 적용하면 현재 로컬 방식이 대체됩니다. 아직 백업하지 않았으므로 적용 전에 “분류 및 레이아웃 내보내기”로 백업하는 것을 강력히 권장합니다.",
src/Apptag/Localization/ms.json
@@ -141,6 +141,7 @@
  "settings.initialLayout": "Permulaan susun atur:",
  "settings.initialLayoutUncategorized": "Tidak berkategori",
  "settings.initialLayoutSmart": "Kategori awal pintar",
  "settings.customLayout": "Tataletak tersuai:",
  "settings.applyScheme": "Guna",
  "settings.applySystemSchemeWarningTitle": "Sandaran disyorkan",
  "settings.applySystemSchemeWarningMessage": "Menggunakan skema awal pintar sistem akan menggantikan skema setempat semasa. Anda belum membuat sandaran; kami sangat mengesyorkan mengeksport sandaran sebelum menggunakan.",
src/Apptag/Localization/nb.json
@@ -141,6 +141,7 @@
  "settings.initialLayout": "Initialiser oppsett:",
  "settings.initialLayoutUncategorized": "Ukategorisert",
  "settings.initialLayoutSmart": "Smarte startkategorier",
  "settings.customLayout": "Egendefinert oppsett:",
  "settings.applyScheme": "Bruk",
  "settings.applySystemSchemeWarningTitle": "Sikkerhetskopi anbefales",
  "settings.applySystemSchemeWarningMessage": "Bruk av systemets smarte startskjema erstatter gjeldende lokale skjema. Du har ikke sikkerhetskopiert ennå; vi anbefaler sterkt å eksportere en sikkerhetskopi først.",
src/Apptag/Localization/nl.json
@@ -141,6 +141,7 @@
  "settings.initialLayout": "Layout initialiseren:",
  "settings.initialLayoutUncategorized": "Niet gecategoriseerd",
  "settings.initialLayoutSmart": "Slimme begincategorieen",
  "settings.customLayout": "Aangepaste lay-out:",
  "settings.applyScheme": "Toepassen",
  "settings.applySystemSchemeWarningTitle": "Back-up aanbevolen",
  "settings.applySystemSchemeWarningMessage": "Het slimme beginschema van het systeem toepassen vervangt het huidige lokale schema. Er is nog geen back-up; we raden sterk aan eerst een back-up te exporteren.",
src/Apptag/Localization/nn.json
@@ -141,6 +141,7 @@
  "settings.initialLayout": "Initialiser oppsett:",
  "settings.initialLayoutUncategorized": "Ukategorisert",
  "settings.initialLayoutSmart": "Smarte startkategoriar",
  "settings.customLayout": "Eigendefinert oppsett:",
  "settings.applyScheme": "Bruk",
  "settings.applySystemSchemeWarningTitle": "Sikkerhetskopi anbefales",
  "settings.applySystemSchemeWarningMessage": "Bruk av systemets smarte startskjema erstattar gjeldande lokale skjema. Du har ikkje teke sikkerheitskopi enno; vi tilrår sterkt å eksportere ein kopi først.",
src/Apptag/Localization/no.json
@@ -141,6 +141,7 @@
  "settings.initialLayout": "Initialiser oppsett:",
  "settings.initialLayoutUncategorized": "Ukategorisert",
  "settings.initialLayoutSmart": "Smarte startkategorier",
  "settings.customLayout": "Egendefinert oppsett:",
  "settings.applyScheme": "Bruk",
  "settings.applySystemSchemeWarningTitle": "Sikkerhetskopi anbefales",
  "settings.applySystemSchemeWarningMessage": "Bruk av systemets smarte startskjema erstatter gjeldende lokale skjema. Du har ikke sikkerhetskopiert ennå; vi anbefaler sterkt å eksportere en sikkerhetskopi først.",
src/Apptag/Localization/pl.json
@@ -141,6 +141,7 @@
  "settings.initialLayout": "Inicjalizacja układu:",
  "settings.initialLayoutUncategorized": "Bez kategorii",
  "settings.initialLayoutSmart": "Inteligentne kategorie poczatkowe",
  "settings.customLayout": "Niestandardowy układ:",
  "settings.applyScheme": "Zastosuj",
  "settings.applySystemSchemeWarningTitle": "Zalecana kopia zapasowa",
  "settings.applySystemSchemeWarningMessage": "Zastosowanie inteligentnego schematu początkowego systemu zastąpi bieżący schemat lokalny. Nie masz jeszcze kopii zapasowej; zdecydowanie zalecamy jej wyeksportowanie przed zastosowaniem.",
src/Apptag/Localization/pt-BR.json
@@ -141,6 +141,7 @@
  "settings.initialLayout": "Inicializacao do layout:",
  "settings.initialLayoutUncategorized": "Sem categoria",
  "settings.initialLayoutSmart": "Categorias iniciais inteligentes",
  "settings.customLayout": "Layout personalizado:",
  "settings.applyScheme": "Aplicar",
  "settings.applySystemSchemeWarningTitle": "Backup recomendado",
  "settings.applySystemSchemeWarningMessage": "Aplicar o esquema inicial inteligente do sistema substituirá o esquema local atual. Você ainda não fez backup; recomendamos exportar um backup antes de aplicar.",
src/Apptag/Localization/ro.json
@@ -141,6 +141,7 @@
  "settings.initialLayout": "Initializare aspect:",
  "settings.initialLayoutUncategorized": "Necategorizat",
  "settings.initialLayoutSmart": "Categorii initiale inteligente",
  "settings.customLayout": "Aspect personalizat:",
  "settings.applyScheme": "Aplică",
  "settings.applySystemSchemeWarningTitle": "Backup recomandat",
  "settings.applySystemSchemeWarningMessage": "Aplicarea schemei inteligente inițiale a sistemului va înlocui schema locală curentă. Nu ai încă o copie de siguranță; recomandăm să exporți una înainte de aplicare.",
src/Apptag/Localization/ru.json
@@ -141,6 +141,7 @@
  "settings.initialLayout": "Инициализация раскладки:",
  "settings.initialLayoutUncategorized": "Без категории",
  "settings.initialLayoutSmart": "Умные начальные категории",
  "settings.customLayout": "Пользовательская раскладка:",
  "settings.applyScheme": "Применить",
  "settings.applySystemSchemeWarningTitle": "Рекомендуется резервная копия",
  "settings.applySystemSchemeWarningMessage": "Применение интеллектуальной начальной схемы системы заменит текущую локальную схему. Резервная копия ещё не создана; настоятельно рекомендуем экспортировать её перед применением.",
src/Apptag/Localization/sr-Cyrl.json
@@ -141,6 +141,7 @@
  "settings.initialLayout": "Иницијализација распореда:",
  "settings.initialLayoutUncategorized": "Некатегорисано",
  "settings.initialLayoutSmart": "Паметне почетне категорије",
  "settings.customLayout": "Прилагођени распоред:",
  "settings.applyScheme": "Примени",
  "settings.applySystemSchemeWarningTitle": "Препоручује се резервна копија",
  "settings.applySystemSchemeWarningMessage": "Примена паметне почетне шеме система замениће тренутну локалну шему. Још немате резервну копију; препоручујемо да је извезете пре примене.",
src/Apptag/Localization/sv.json
@@ -141,6 +141,7 @@
  "settings.initialLayout": "Initiera layout:",
  "settings.initialLayoutUncategorized": "Okategoriserat",
  "settings.initialLayoutSmart": "Smarta startkategorier",
  "settings.customLayout": "Anpassad layout:",
  "settings.applyScheme": "Tillämpa",
  "settings.applySystemSchemeWarningTitle": "Säkerhetskopia rekommenderas",
  "settings.applySystemSchemeWarningMessage": "Att tillämpa systemets smarta startschema ersätter det aktuella lokala schemat. Du har inte säkerhetskopierat det ännu; vi rekommenderar starkt att du exporterar en säkerhetskopia först.",
src/Apptag/Localization/th.json
@@ -141,6 +141,7 @@
  "settings.initialLayout": "เริ่มต้นเลย์เอาต์:",
  "settings.initialLayoutUncategorized": "ไม่จัดหมวดหมู่",
  "settings.initialLayoutSmart": "หมวดหมู่เริ่มต้นอัจฉริยะ",
  "settings.customLayout": "เค้าโครงแบบกำหนดเอง:",
  "settings.applyScheme": "นำไปใช้",
  "settings.applySystemSchemeWarningTitle": "แนะนำให้สำรองข้อมูล",
  "settings.applySystemSchemeWarningMessage": "การใช้ชุดเริ่มต้นอัจฉริยะของระบบจะแทนที่ชุดภายในเครื่องปัจจุบัน คุณยังไม่ได้สำรองข้อมูล เราแนะนำอย่างยิ่งให้ส่งออกข้อมูลสำรองก่อนนำไปใช้",
src/Apptag/Localization/tr.json
@@ -141,6 +141,7 @@
  "settings.initialLayout": "Yerlesimi baslat:",
  "settings.initialLayoutUncategorized": "Kategorisiz",
  "settings.initialLayoutSmart": "Akilli ilk kategoriler",
  "settings.customLayout": "Özel düzen:",
  "settings.applyScheme": "Uygula",
  "settings.applySystemSchemeWarningTitle": "Yedekleme önerilir",
  "settings.applySystemSchemeWarningMessage": "Sistem akıllı başlangıç şemasını uygulamak geçerli yerel şemayı değiştirir. Henüz yedeklemediniz; uygulamadan önce bir yedek dışa aktarmanızı önemle öneririz.",
src/Apptag/Localization/uk.json
@@ -141,6 +141,7 @@
  "settings.initialLayout": "Ініціалізація розкладки:",
  "settings.initialLayoutUncategorized": "Без категорії",
  "settings.initialLayoutSmart": "Розумні початкові категорії",
  "settings.customLayout": "Користувацьке компонування:",
  "settings.applyScheme": "Застосувати",
  "settings.applySystemSchemeWarningTitle": "Рекомендується резервна копія",
  "settings.applySystemSchemeWarningMessage": "Застосування розумної початкової схеми системи замінить поточну локальну схему. Ви ще не створили резервну копію; радимо експортувати її перед застосуванням.",
src/Apptag/Localization/vi.json
@@ -141,6 +141,7 @@
  "settings.initialLayout": "Khởi tạo bố cục:",
  "settings.initialLayoutUncategorized": "Chưa phân loại",
  "settings.initialLayoutSmart": "Phân loại ban đầu thông minh",
  "settings.customLayout": "Bố cục tùy chỉnh:",
  "settings.applyScheme": "Áp dụng",
  "settings.applySystemSchemeWarningTitle": "Nên sao lưu trước",
  "settings.applySystemSchemeWarningMessage": "Áp dụng sơ đồ khởi tạo thông minh của hệ thống sẽ thay thế sơ đồ cục bộ hiện tại. Bạn chưa sao lưu; chúng tôi khuyên bạn nên xuất bản sao lưu trước khi áp dụng.",
src/Apptag/Localization/zh-Hans.json
@@ -141,6 +141,7 @@
  "settings.initialLayout": "布局初始化:",
  "settings.initialLayoutUncategorized": "未分类",
  "settings.initialLayoutSmart": "智能化初始化分类",
  "settings.customLayout": "自定义布局:",
  "settings.applyScheme": "应用",
  "settings.applySystemSchemeWarningTitle": "建议先备份",
  "settings.applySystemSchemeWarningMessage": "应用系统智能化初始分类会覆盖当前本地方案。您还没有备份,强烈建议先点击“导出分类与布局”备份后再应用。",
src/Apptag/Localization/zh-Hant.json
@@ -141,6 +141,7 @@
  "settings.initialLayout": "版面初始化:",
  "settings.initialLayoutUncategorized": "未分類",
  "settings.initialLayoutSmart": "智慧初始化分類",
  "settings.customLayout": "自訂版面:",
  "settings.applyScheme": "套用",
  "settings.applySystemSchemeWarningTitle": "建議先備份",
  "settings.applySystemSchemeWarningMessage": "套用系統智慧化初始分類會覆蓋目前本機方案。您尚未備份,強烈建議先點選「匯出分類與佈局」備份後再套用。",
src/Apptag/PreferencesView.swift
@@ -49,9 +49,9 @@
    private let generalLabelWidth: CGFloat = 190
    private let generalControlWidth: CGFloat = 500
    private let compactPickerWidth: CGFloat = 320
    private let dataPanelWidth: CGFloat = 760
    private let dataLabelWidth: CGFloat = 220
    private let dataActionWidth: CGFloat = 112
    private let dataPanelWidth: CGFloat = 820
    private let dataLabelWidth: CGFloat = 190
    private let dataActionWidth: CGFloat = 128
    @AppStorage("tagFontSize") private var tagFontSize: Double = AppDefaults.tagFontSize
    @AppStorage("iconSize") private var iconSize: Double = AppDefaults.iconSize
@@ -456,6 +456,35 @@
        .buttonStyle(.plain)
    }
    private func dataSectionTitle(_ title: String) -> some View {
        Text(title)
            .font(.system(size: 13, weight: .semibold))
            .foregroundStyle(.primary)
            .lineLimit(1)
            .minimumScaleFactor(0.82)
            .multilineTextAlignment(.trailing)
            .frame(width: dataLabelWidth, alignment: .trailing)
    }
    private func dataSection<Content: View>(
        minHeight: CGFloat,
        @ViewBuilder content: () -> Content
    ) -> some View {
        content()
            .padding(.horizontal, 20)
            .padding(.vertical, 18)
            .frame(width: dataPanelWidth, alignment: .leading)
            .frame(minHeight: minHeight, alignment: .leading)
            .background(
                RoundedRectangle(cornerRadius: 12, style: .continuous)
                    .fill(Color(nsColor: .controlBackgroundColor))
            )
            .overlay(
                RoundedRectangle(cornerRadius: 12, style: .continuous)
                    .stroke(Color.secondary.opacity(0.18), lineWidth: 1)
            )
    }
    private func syncSelectedLanguage() {
        let code = L10n.selectedLanguageCode
        guard selectedLanguage != code else { return }
@@ -824,18 +853,12 @@
                    case .data:
            // Tab 5: Data
            VStack(spacing: 0) {
                Spacer(minLength: 32)
                Spacer(minLength: 36)
                VStack(alignment: .center, spacing: 0) {
                    VStack(alignment: .leading, spacing: 12) {
                VStack(alignment: .center, spacing: 24) {
                    dataSection(minHeight: 124) {
                        HStack(alignment: .center, spacing: 12) {
                            Text(tr("settings.initialLayout"))
                                .font(.system(size: 13, weight: .semibold))
                                .foregroundStyle(.secondary)
                                .lineLimit(1)
                                .minimumScaleFactor(0.82)
                                .multilineTextAlignment(.trailing)
                                .frame(width: dataLabelWidth, alignment: .trailing)
                            dataSectionTitle(tr("settings.initialLayout"))
                            HStack(spacing: 22) {
                                initialLayoutOption(
@@ -859,52 +882,44 @@
                            .frame(width: dataActionWidth, alignment: .trailing)
                            .layoutPriority(2)
                        }
                    }
                        HStack(alignment: .center, spacing: 12) {
                    dataSection(minHeight: 190) {
                        HStack(alignment: .top, spacing: 12) {
                            dataSectionTitle(tr("settings.customLayout"))
                                .padding(.top, 4)
                            VStack(alignment: .leading, spacing: 10) {
                                HStack(alignment: .firstTextBaseline, spacing: 8) {
                            Text(tr("settings.previousScheme"))
                                .font(.system(size: 13, weight: .semibold))
                                .foregroundStyle(.secondary)
                                .lineLimit(1)
                                .minimumScaleFactor(0.82)
                                .multilineTextAlignment(.trailing)
                                .frame(width: dataLabelWidth, alignment: .trailing)
                            Text(previousCategorySchemeName)
                                .font(.system(size: 13, weight: .medium))
                                .foregroundStyle(canRestorePreviousScheme ? .primary : .tertiary)
                                .lineLimit(1)
                                .truncationMode(.middle)
                                .frame(maxWidth: .infinity, alignment: .leading)
                                .layoutPriority(0)
                            dataActionButton(
                                tr("settings.restorePreviousScheme"),
                                prominent: false,
                                enabled: canRestorePreviousScheme,
                                action: restorePreviousCategoryScheme
                            )
                            .frame(width: dataActionWidth, alignment: .trailing)
                            .layoutPriority(2)
                        }
                        HStack(alignment: .firstTextBaseline, spacing: 12) {
                                HStack(alignment: .firstTextBaseline, spacing: 8) {
                            Text(tr("settings.currentScheme"))
                                .font(.system(size: 13, weight: .semibold))
                                .foregroundStyle(.secondary)
                                .lineLimit(1)
                                .minimumScaleFactor(0.82)
                                .multilineTextAlignment(.trailing)
                                .frame(width: dataLabelWidth, alignment: .trailing)
                            Text(currentCategorySchemeName)
                                .font(.system(size: 13, weight: .medium))
                                .foregroundStyle(.primary)
                                .lineLimit(1)
                                .truncationMode(.middle)
                                .frame(maxWidth: .infinity, alignment: .leading)
                            Color.clear
                                .frame(width: dataActionWidth, height: 1)
                        }
                        Divider().opacity(0.35)
                                    .padding(.top, 2)
                        VStack(alignment: .center, spacing: 8) {
                            HStack(spacing: 12) {
@@ -920,25 +935,27 @@
                                .foregroundStyle(.secondary)
                                .multilineTextAlignment(.center)
                                .fixedSize(horizontal: false, vertical: true)
                                .frame(maxWidth: dataPanelWidth - 72, alignment: .center)
                                        .frame(maxWidth: dataPanelWidth - dataLabelWidth - dataActionWidth - 92, alignment: .center)
                        }
                        .frame(maxWidth: .infinity, alignment: .center)
                    }
                    .padding(.horizontal, 20)
                    .padding(.vertical, 16)
                    .frame(width: dataPanelWidth, alignment: .leading)
                    .background(
                        RoundedRectangle(cornerRadius: 8, style: .continuous)
                            .fill(Color(nsColor: .controlBackgroundColor))
                            .frame(maxWidth: .infinity, alignment: .leading)
                            .layoutPriority(1)
                            dataActionButton(
                                tr("settings.restorePreviousScheme"),
                                prominent: false,
                                enabled: canRestorePreviousScheme,
                                action: restorePreviousCategoryScheme
                    )
                    .overlay(
                        RoundedRectangle(cornerRadius: 8, style: .continuous)
                            .stroke(Color.secondary.opacity(0.16), lineWidth: 1)
                    )
                            .frame(width: dataActionWidth, alignment: .trailing)
                            .layoutPriority(2)
                        }
                    }
                }
                .frame(width: dataPanelWidth, alignment: .center)
                Spacer(minLength: 22)
                Spacer(minLength: 30)
                HStack(alignment: .center, spacing: 14) {
                    Text(tr("settings.bubbleDisplayScope"))
src/CHANGELOG.md
@@ -1,5 +1,12 @@
# TagLauncher Changelog
## [7.8.31] — 2026-06-11
- 设置页 Data 面板按原型拆分为两个独立边框区域:“布局初始化”和“自定义布局”分开展示,避免重置初始化、恢复、导入导出混在同一块区域里
- “布局初始化”区域保留“未分类 / 智能化初始化分类 / 应用”流程;“自定义布局”区域保留上一个方案、当前方案、恢复、导出和导入
- 新增 `settings.customLayout` 文案键并补齐 29 个语种,保证多语言环境下第二个分区标题不会显示裸 key 或中文
- 版本号更新为 `7.8.31`,Build 更新为 `20260611.1928`
## [7.8.30] — 2026-06-11
- 设置页数据面板新增“布局初始化”选择:可在“未分类”和“智能化初始化分类”之间选择后点击应用