diff --git a/.gitignore b/.gitignore index 3c03c07..d093c4a 100644 --- a/.gitignore +++ b/.gitignore @@ -31,7 +31,7 @@ data/ *.swp *.swo .codex - +AGENTS.md # Claude Code — share skills/agents/rules/hooks/settings; keep local permissions and worktrees out .claude/settings.local.json diff --git a/public/index.html b/public/index.html index e4a50ca..953a94c 100644 --- a/public/index.html +++ b/public/index.html @@ -48,6 +48,8 @@ document.documentElement.setAttribute('data-theme', 'dark'); } else if (stored === 'light') { document.documentElement.setAttribute('data-theme', 'light'); + } else { + document.documentElement.removeAttribute('data-theme'); } // System/null: tokens.css @media (prefers-color-scheme: dark) übernimmt })(); diff --git a/public/locales/ar.json b/public/locales/ar.json index 61db283..bdb1594 100644 --- a/public/locales/ar.json +++ b/public/locales/ar.json @@ -28,7 +28,8 @@ "all": "الكل", "unknownError": "خطأ غير معروف", "confirm": "تأكيد", - "undo": "تراجع" + "undo": "تراجع", + "reset": "إعادة التعيين للأصل" }, "nav": { "dashboard": "لوحة التحكم", @@ -550,6 +551,8 @@ "tabBudget": "الميزانية", "tabShopping": "التسوق", "tabCalendar": "التقويم", + "tabFamily": "إدارة العائلة", + "tabApiTokens": "رموز API", "tabAccount": "الحساب", "tabsAriaLabel": "أقسام الإعدادات", "sectionDesign": "التصميم", @@ -730,7 +733,14 @@ "private": "خاص", "shared": "مشترك" } - } + }, + "memberPhoneLabel": "Phone number (optional)", + "memberEmailLabel": "Email (optional)", + "memberBirthDateLabel": "Birthday date (optional)", + "memberContactBirthdayHint": "This member is automatically synchronized with Contacts and Birthdays.", + "memberBirthDateInvalid": "Use a valid birthday date in the selected date format.", + "memberPhoneMeta": "Phone: {{value}}", + "memberBirthdayMeta": "Birthday: {{date}}" }, "login": { "tagline": "تخطيط عائلي. آمن. يحترم الخصوصية. مفتوح المصدر.", diff --git a/public/locales/de.json b/public/locales/de.json index 798a228..7836d42 100644 --- a/public/locales/de.json +++ b/public/locales/de.json @@ -28,7 +28,8 @@ "all": "Alle", "unknownError": "Unbekannter Fehler", "confirm": "Bestätigen", - "undo": "Rückgängig" + "undo": "Rückgängig", + "reset": "Auf Original zurücksetzen" }, "nav": { "dashboard": "Übersicht", @@ -575,6 +576,8 @@ "tabBudget": "Budget", "tabShopping": "Einkauf", "tabCalendar": "Kalender", + "tabFamily": "Familienverwaltung", + "tabApiTokens": "API-Tokens", "tabAccount": "Konto", "tabsAriaLabel": "Einstellungsbereiche", "sectionDesign": "Design", @@ -755,7 +758,14 @@ "addedToast": "Abonnement hinzugefügt.", "syncedToast": "Abonnement synchronisiert.", "deletedToast": "Abonnement gelöscht." - } + }, + "memberPhoneLabel": "Telefonnummer (optional)", + "memberEmailLabel": "E-Mail (optional)", + "memberBirthDateLabel": "Geburtstag (optional)", + "memberContactBirthdayHint": "Dieses Mitglied wird automatisch mit Kontakten und Geburtstagen synchronisiert.", + "memberBirthDateInvalid": "Bitte ein gültiges Geburtstagsdatum im ausgewählten Format verwenden.", + "memberPhoneMeta": "Telefon: {{value}}", + "memberBirthdayMeta": "Geburtstag: {{date}}" }, "login": { "tagline": "Familienplanung. Sicher. Datenschutzfreundlich. Open Source.", diff --git a/public/locales/el.json b/public/locales/el.json index 8fac0bb..604f400 100644 --- a/public/locales/el.json +++ b/public/locales/el.json @@ -28,7 +28,8 @@ "all": "Όλα", "unknownError": "Άγνωστο σφάλμα", "confirm": "Επιβεβαίωση", - "undo": "Αναίρεση" + "undo": "Αναίρεση", + "reset": "Επαναφορά στο αρχικό" }, "nav": { "dashboard": "Επισκόπηση", @@ -550,6 +551,8 @@ "tabBudget": "Προϋπολογισμός", "tabShopping": "Αγορές", "tabCalendar": "Ημερολόγιο", + "tabFamily": "Διαχείριση οικογένειας", + "tabApiTokens": "API Tokens", "tabAccount": "Λογαριασμός", "tabsAriaLabel": "Τμήματα ρυθμίσεων", "sectionDesign": "Εμφάνιση", @@ -730,7 +733,14 @@ "private": "Ιδιωτικό", "shared": "Κοινόχρηστο" } - } + }, + "memberPhoneLabel": "Phone number (optional)", + "memberEmailLabel": "Email (optional)", + "memberBirthDateLabel": "Birthday date (optional)", + "memberContactBirthdayHint": "This member is automatically synchronized with Contacts and Birthdays.", + "memberBirthDateInvalid": "Use a valid birthday date in the selected date format.", + "memberPhoneMeta": "Phone: {{value}}", + "memberBirthdayMeta": "Birthday: {{date}}" }, "login": { "tagline": "Οικογενειακός προγραμματισμός. Ασφαλής. Φιλικός προς την ιδιωτικότητα. Ανοιχτός κώδικας.", diff --git a/public/locales/en.json b/public/locales/en.json index 99dbc67..3bcf10b 100644 --- a/public/locales/en.json +++ b/public/locales/en.json @@ -28,7 +28,8 @@ "all": "All", "unknownError": "Unknown error", "confirm": "Confirm", - "undo": "Undo" + "undo": "Undo", + "reset": "Reset to original" }, "nav": { "dashboard": "Overview", @@ -550,6 +551,8 @@ "tabBudget": "Budget", "tabShopping": "Shopping", "tabCalendar": "Calendar", + "tabFamily": "Family Management", + "tabApiTokens": "API Tokens", "tabAccount": "Account", "tabsAriaLabel": "Settings sections", "sectionDesign": "Appearance", @@ -730,7 +733,14 @@ "private": "Private", "shared": "Shared" } - } + }, + "memberPhoneLabel": "Phone number (optional)", + "memberEmailLabel": "Email (optional)", + "memberBirthDateLabel": "Birthday date (optional)", + "memberContactBirthdayHint": "This member is automatically synchronized with Contacts and Birthdays.", + "memberBirthDateInvalid": "Use a valid birthday date in the selected date format.", + "memberPhoneMeta": "Phone: {{value}}", + "memberBirthdayMeta": "Birthday: {{date}}" }, "login": { "tagline": "Family planning. Secure. Privacy-friendly. Open source.", diff --git a/public/locales/es.json b/public/locales/es.json index 68b3af8..7fba826 100644 --- a/public/locales/es.json +++ b/public/locales/es.json @@ -28,7 +28,8 @@ "all": "Todo", "unknownError": "Error desconocido", "confirm": "Confirmar", - "undo": "Deshacer" + "undo": "Deshacer", + "reset": "Restaurar original" }, "nav": { "dashboard": "Inicio", @@ -550,6 +551,8 @@ "tabBudget": "Presupuesto", "tabShopping": "Compras", "tabCalendar": "Calendario", + "tabFamily": "Gestión familiar", + "tabApiTokens": "API Tokens", "tabAccount": "Cuenta", "tabsAriaLabel": "Secciones de configuración", "sectionDesign": "Diseño", @@ -730,7 +733,14 @@ "private": "Privado", "shared": "Compartido" } - } + }, + "memberPhoneLabel": "Phone number (optional)", + "memberEmailLabel": "Email (optional)", + "memberBirthDateLabel": "Birthday date (optional)", + "memberContactBirthdayHint": "This member is automatically synchronized with Contacts and Birthdays.", + "memberBirthDateInvalid": "Use a valid birthday date in the selected date format.", + "memberPhoneMeta": "Phone: {{value}}", + "memberBirthdayMeta": "Birthday: {{date}}" }, "login": { "tagline": "Planificación familiar. Segura. Privada. Código abierto.", diff --git a/public/locales/fr.json b/public/locales/fr.json index d5d408d..b4d32aa 100644 --- a/public/locales/fr.json +++ b/public/locales/fr.json @@ -28,7 +28,8 @@ "all": "Tout", "unknownError": "Erreur inconnue", "confirm": "Confirmer", - "undo": "Annuler" + "undo": "Annuler", + "reset": "Réinitialiser" }, "nav": { "dashboard": "Accueil", @@ -550,6 +551,8 @@ "tabBudget": "Budget", "tabShopping": "Courses", "tabCalendar": "Calendrier", + "tabFamily": "Gestion familiale", + "tabApiTokens": "API Tokens", "tabAccount": "Compte", "tabsAriaLabel": "Sections des paramètres", "sectionDesign": "Apparence", @@ -730,7 +733,14 @@ "private": "Privé", "shared": "Partagé" } - } + }, + "memberPhoneLabel": "Phone number (optional)", + "memberEmailLabel": "Email (optional)", + "memberBirthDateLabel": "Birthday date (optional)", + "memberContactBirthdayHint": "This member is automatically synchronized with Contacts and Birthdays.", + "memberBirthDateInvalid": "Use a valid birthday date in the selected date format.", + "memberPhoneMeta": "Phone: {{value}}", + "memberBirthdayMeta": "Birthday: {{date}}" }, "login": { "tagline": "Planification familiale. Sécurisée. Respectueuse de la vie privée. Open source.", diff --git a/public/locales/hi.json b/public/locales/hi.json index b12ef8f..b83e25b 100644 --- a/public/locales/hi.json +++ b/public/locales/hi.json @@ -28,7 +28,8 @@ "all": "सभी", "unknownError": "अज्ञात त्रुटि", "confirm": "पुष्टि करें", - "undo": "पूर्ववत करें" + "undo": "पूर्ववत करें", + "reset": "मूल पर वापस जाएं" }, "nav": { "dashboard": "डैशबोर्ड", @@ -550,6 +551,8 @@ "tabBudget": "बजट", "tabShopping": "खरीदारी", "tabCalendar": "कैलेंडर", + "tabFamily": "परिवार प्रबंधन", + "tabApiTokens": "API टोकन", "tabAccount": "खाता", "tabsAriaLabel": "सेटिंग्स अनुभाग", "sectionDesign": "डिज़ाइन", @@ -730,7 +733,14 @@ "private": "निजी", "shared": "साझा" } - } + }, + "memberPhoneLabel": "Phone number (optional)", + "memberEmailLabel": "Email (optional)", + "memberBirthDateLabel": "Birthday date (optional)", + "memberContactBirthdayHint": "This member is automatically synchronized with Contacts and Birthdays.", + "memberBirthDateInvalid": "Use a valid birthday date in the selected date format.", + "memberPhoneMeta": "Phone: {{value}}", + "memberBirthdayMeta": "Birthday: {{date}}" }, "login": { "tagline": "पारिवारिक योजना। सुरक्षित। गोपनीयता-अनुकूल। ओपन सोर्स।", diff --git a/public/locales/it.json b/public/locales/it.json index e09b1d9..0b3f4e1 100644 --- a/public/locales/it.json +++ b/public/locales/it.json @@ -28,7 +28,8 @@ "all": "Tutto", "unknownError": "Errore sconosciuto", "confirm": "Conferma", - "undo": "Annulla" + "undo": "Annulla", + "reset": "Ripristina originale" }, "nav": { "dashboard": "Panoramica", @@ -550,6 +551,8 @@ "tabBudget": "Budget", "tabShopping": "Spesa", "tabCalendar": "Calendario", + "tabFamily": "Gestione famiglia", + "tabApiTokens": "API Tokens", "tabAccount": "Account", "tabsAriaLabel": "Sezioni impostazioni", "sectionDesign": "Aspetto", @@ -730,7 +733,14 @@ "private": "Privato", "shared": "Condiviso" } - } + }, + "memberPhoneLabel": "Phone number (optional)", + "memberEmailLabel": "Email (optional)", + "memberBirthDateLabel": "Birthday date (optional)", + "memberContactBirthdayHint": "This member is automatically synchronized with Contacts and Birthdays.", + "memberBirthDateInvalid": "Use a valid birthday date in the selected date format.", + "memberPhoneMeta": "Phone: {{value}}", + "memberBirthdayMeta": "Birthday: {{date}}" }, "login": { "tagline": "Pianificazione familiare. Sicura. Rispettosa della privacy. Open source.", diff --git a/public/locales/ja.json b/public/locales/ja.json index c1d2325..0487682 100644 --- a/public/locales/ja.json +++ b/public/locales/ja.json @@ -28,7 +28,8 @@ "all": "すべて", "unknownError": "不明なエラー", "confirm": "確認", - "undo": "元に戻す" + "undo": "元に戻す", + "reset": "元に戻す" }, "nav": { "dashboard": "ダッシュボード", @@ -550,6 +551,8 @@ "tabBudget": "家計", "tabShopping": "買い物", "tabCalendar": "カレンダー", + "tabFamily": "家族管理", + "tabApiTokens": "APIトークン", "tabAccount": "アカウント", "tabsAriaLabel": "設定カテゴリー", "sectionDesign": "デザイン", @@ -730,7 +733,14 @@ "private": "プライベート", "shared": "共有" } - } + }, + "memberPhoneLabel": "Phone number (optional)", + "memberEmailLabel": "Email (optional)", + "memberBirthDateLabel": "Birthday date (optional)", + "memberContactBirthdayHint": "This member is automatically synchronized with Contacts and Birthdays.", + "memberBirthDateInvalid": "Use a valid birthday date in the selected date format.", + "memberPhoneMeta": "Phone: {{value}}", + "memberBirthdayMeta": "Birthday: {{date}}" }, "login": { "tagline": "家族計画。安全。プライバシー重視。オープンソース。", diff --git a/public/locales/pt.json b/public/locales/pt.json index 3360f41..9a85cea 100644 --- a/public/locales/pt.json +++ b/public/locales/pt.json @@ -28,7 +28,8 @@ "all": "Todos", "unknownError": "Erro desconhecido", "confirm": "Confirmar", - "undo": "Desfazer" + "undo": "Desfazer", + "reset": "Restaurar original" }, "nav": { "dashboard": "Painel", @@ -550,6 +551,8 @@ "tabBudget": "Orçamento", "tabShopping": "Compras", "tabCalendar": "Calendário", + "tabFamily": "Gestão da família", + "tabApiTokens": "API Tokens", "tabAccount": "Conta", "tabsAriaLabel": "Seções de configurações", "sectionDesign": "Design", @@ -730,7 +733,14 @@ "private": "Privado", "shared": "Partilhado" } - } + }, + "memberPhoneLabel": "Telefone (opcional)", + "memberEmailLabel": "E-mail (opcional)", + "memberBirthDateLabel": "Data de aniversário (opcional)", + "memberContactBirthdayHint": "Este membro é sincronizado automaticamente com Contatos e Aniversários.", + "memberBirthDateInvalid": "Use uma data de aniversário válida no formato selecionado.", + "memberPhoneMeta": "Telefone: {{value}}", + "memberBirthdayMeta": "Aniversário: {{date}}" }, "login": { "tagline": "Planejamento familiar. Seguro. Privado. Código aberto.", diff --git a/public/locales/ru.json b/public/locales/ru.json index 12d5ab0..46bc0ac 100644 --- a/public/locales/ru.json +++ b/public/locales/ru.json @@ -28,7 +28,8 @@ "all": "Все", "unknownError": "Неизвестная ошибка", "confirm": "Подтвердить", - "undo": "Отменить" + "undo": "Отменить", + "reset": "Сбросить к исходному" }, "nav": { "dashboard": "Обзор", @@ -550,6 +551,8 @@ "tabBudget": "Бюджет", "tabShopping": "Покупки", "tabCalendar": "Календарь", + "tabFamily": "Управление семьей", + "tabApiTokens": "API-токены", "tabAccount": "Аккаунт", "tabsAriaLabel": "Разделы настроек", "sectionDesign": "Внешний вид", @@ -730,7 +733,14 @@ "private": "Личное", "shared": "Общее" } - } + }, + "memberPhoneLabel": "Phone number (optional)", + "memberEmailLabel": "Email (optional)", + "memberBirthDateLabel": "Birthday date (optional)", + "memberContactBirthdayHint": "This member is automatically synchronized with Contacts and Birthdays.", + "memberBirthDateInvalid": "Use a valid birthday date in the selected date format.", + "memberPhoneMeta": "Phone: {{value}}", + "memberBirthdayMeta": "Birthday: {{date}}" }, "login": { "tagline": "Семейное планирование. Безопасно. С уважением к приватности. Открытый исходный код.", diff --git a/public/locales/sv.json b/public/locales/sv.json index 4638f78..0e2eaf7 100644 --- a/public/locales/sv.json +++ b/public/locales/sv.json @@ -28,7 +28,8 @@ "all": "Alla", "unknownError": "Okänt fel", "confirm": "Bekräfta", - "undo": "Ångra" + "undo": "Ångra", + "reset": "Återställ till original" }, "nav": { "dashboard": "Översikt", @@ -550,6 +551,8 @@ "tabBudget": "Budget", "tabShopping": "Inköp", "tabCalendar": "Kalender", + "tabFamily": "Familjehantering", + "tabApiTokens": "API Tokens", "tabAccount": "Konto", "tabsAriaLabel": "Inställningsavsnitt", "sectionDesign": "Utseende", @@ -730,7 +733,14 @@ "private": "Privat", "shared": "Delad" } - } + }, + "memberPhoneLabel": "Phone number (optional)", + "memberEmailLabel": "Email (optional)", + "memberBirthDateLabel": "Birthday date (optional)", + "memberContactBirthdayHint": "This member is automatically synchronized with Contacts and Birthdays.", + "memberBirthDateInvalid": "Use a valid birthday date in the selected date format.", + "memberPhoneMeta": "Phone: {{value}}", + "memberBirthdayMeta": "Birthday: {{date}}" }, "login": { "tagline": "Familjeplanering. Säker. Sekretessvänlig. Öppen källkod.", diff --git a/public/locales/tr.json b/public/locales/tr.json index e8caafb..45a7a95 100644 --- a/public/locales/tr.json +++ b/public/locales/tr.json @@ -28,7 +28,8 @@ "all": "Tümü", "unknownError": "Bilinmeyen hata", "confirm": "Onayla", - "undo": "Geri al" + "undo": "Geri al", + "reset": "Orijinale sıfırla" }, "nav": { "dashboard": "Genel Bakış", @@ -550,6 +551,8 @@ "tabBudget": "Bütçe", "tabShopping": "Alışveriş", "tabCalendar": "Takvim", + "tabFamily": "Aile Yönetimi", + "tabApiTokens": "API Tokenları", "tabAccount": "Hesap", "tabsAriaLabel": "Ayar bölümleri", "sectionDesign": "Görünüm", @@ -730,7 +733,14 @@ "private": "Özel", "shared": "Paylaşımlı" } - } + }, + "memberPhoneLabel": "Phone number (optional)", + "memberEmailLabel": "Email (optional)", + "memberBirthDateLabel": "Birthday date (optional)", + "memberContactBirthdayHint": "This member is automatically synchronized with Contacts and Birthdays.", + "memberBirthDateInvalid": "Use a valid birthday date in the selected date format.", + "memberPhoneMeta": "Phone: {{value}}", + "memberBirthdayMeta": "Birthday: {{date}}" }, "login": { "tagline": "Aile planlaması. Güvenli. Gizlilik dostu. Açık kaynak.", diff --git a/public/locales/uk.json b/public/locales/uk.json index 3074e65..e8b2822 100644 --- a/public/locales/uk.json +++ b/public/locales/uk.json @@ -28,7 +28,8 @@ "all": "Усі", "unknownError": "Невідома помилка", "confirm": "Підтвердити", - "undo": "Скасувати" + "undo": "Скасувати", + "reset": "Скинути до оригіналу" }, "nav": { "dashboard": "Огляд", @@ -550,6 +551,8 @@ "tabBudget": "Бюджет", "tabShopping": "Покупки", "tabCalendar": "Календар", + "tabFamily": "Керування родиною", + "tabApiTokens": "API-токени", "tabAccount": "Обліковий запис", "tabsAriaLabel": "Розділи налаштувань", "sectionDesign": "Зовнішній вигляд", @@ -730,7 +733,14 @@ "private": "Приватне", "shared": "Спільне" } - } + }, + "memberPhoneLabel": "Phone number (optional)", + "memberEmailLabel": "Email (optional)", + "memberBirthDateLabel": "Birthday date (optional)", + "memberContactBirthdayHint": "This member is automatically synchronized with Contacts and Birthdays.", + "memberBirthDateInvalid": "Use a valid birthday date in the selected date format.", + "memberPhoneMeta": "Phone: {{value}}", + "memberBirthdayMeta": "Birthday: {{date}}" }, "login": { "tagline": "Планування для родини. Безпечно. Конфіденційно. Відкритий код.", diff --git a/public/locales/zh.json b/public/locales/zh.json index 4c85846..cb803b6 100644 --- a/public/locales/zh.json +++ b/public/locales/zh.json @@ -28,7 +28,8 @@ "all": "全部", "unknownError": "未知错误", "confirm": "确认", - "undo": "撤销" + "undo": "撤销", + "reset": "重置为原始" }, "nav": { "dashboard": "概览", @@ -550,6 +551,8 @@ "tabBudget": "预算", "tabShopping": "购物", "tabCalendar": "日历", + "tabFamily": "家庭管理", + "tabApiTokens": "API 令牌", "tabAccount": "账户", "tabsAriaLabel": "设置类别", "sectionDesign": "外观", @@ -730,7 +733,14 @@ "private": "私人", "shared": "共享" } - } + }, + "memberPhoneLabel": "Phone number (optional)", + "memberEmailLabel": "Email (optional)", + "memberBirthDateLabel": "Birthday date (optional)", + "memberContactBirthdayHint": "This member is automatically synchronized with Contacts and Birthdays.", + "memberBirthDateInvalid": "Use a valid birthday date in the selected date format.", + "memberPhoneMeta": "Phone: {{value}}", + "memberBirthdayMeta": "Birthday: {{date}}" }, "login": { "tagline": "家庭规划。安全。注重隐私。开源。", diff --git a/public/pages/calendar.js b/public/pages/calendar.js index 14e772c..20dc2c9 100644 --- a/public/pages/calendar.js +++ b/public/pages/calendar.js @@ -60,12 +60,12 @@ const EVENT_COLOR_NAMES = () => ({ }); const EVENT_ICON_ALIASES = { - tooth: 'drill', + drill: 'tooth', }; const EVENT_ICONS = [ { value: 'calendar', label: 'Calendar' }, - { value: 'drill', label: 'Dentist' }, + { value: 'tooth', label: 'Dentist' }, { value: 'alarm-clock', label: 'Alarm' }, { value: 'clock', label: 'Time' }, { value: 'bell', label: 'Reminder' }, @@ -168,6 +168,8 @@ const EVENT_ICONS = [ { value: 'cloud-sun', label: 'Weather' }, ]; +const CUSTOM_EVENT_ICONS = new Set(['tooth']); + const HOUR_HEIGHT = 56; // px pro Stunde in Wochen-/Tagesansicht /** @@ -266,8 +268,48 @@ function eventIconName(icon) { return EVENT_ICONS.some((item) => item.value === normalized) ? normalized : 'calendar'; } +function customEventIconHtml(icon, className) { + if (icon !== 'tooth') return ''; + return ``; +} + function eventIconHtml(icon, className = 'event-icon') { - return ``; + const name = eventIconName(icon); + if (CUSTOM_EVENT_ICONS.has(name)) return customEventIconHtml(name, className); + return ``; +} + +function eventIconElement(icon, className = 'event-icon') { + const name = eventIconName(icon); + if (name === 'tooth') { + const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg'); + svg.setAttribute('class', `${className} event-icon--custom`); + svg.setAttribute('viewBox', '0 0 24 24'); + svg.setAttribute('fill', 'none'); + svg.setAttribute('stroke', 'currentColor'); + svg.setAttribute('stroke-width', '2'); + svg.setAttribute('stroke-linecap', 'round'); + svg.setAttribute('stroke-linejoin', 'round'); + svg.setAttribute('aria-hidden', 'true'); + + const outline = document.createElementNS('http://www.w3.org/2000/svg', 'path'); + outline.setAttribute('d', 'M8.5 3.5c1.2 0 2.1.5 3.5.5s2.3-.5 3.5-.5c2.4 0 4 1.8 4 4.4 0 2.2-1 4.2-1.7 5.7-.7 1.6-.8 3.1-1.1 4.7-.3 1.7-1.1 3.2-2.4 3.2-1.1 0-1.5-1.1-1.8-2.7-.2-1.2-.4-2.1-.5-2.1s-.3.9-.5 2.1c-.3 1.6-.7 2.7-1.8 2.7-1.3 0-2.1-1.5-2.4-3.2-.3-1.6-.4-3.1-1.1-4.7C5.5 12.1 4.5 10.1 4.5 7.9c0-2.6 1.6-4.4 4-4.4Z'); + + const ridge = document.createElementNS('http://www.w3.org/2000/svg', 'path'); + ridge.setAttribute('d', 'M10 6.2c.7.3 1.3.5 2 .5s1.3-.2 2-.5'); + + svg.append(outline, ridge); + return svg; + } + + const el = document.createElement('i'); + el.className = className; + el.dataset.lucide = name; + el.setAttribute('aria-hidden', 'true'); + return el; } function bindDateInputs(root) { @@ -1086,8 +1128,7 @@ function openEventModal({ mode, event = null, date = null, reminder = null }) { if (iconInput) iconInput.value = nextIcon; if (iconTrigger) { iconTrigger.dataset.icon = nextIcon; - const iconEl = iconTrigger.querySelector('[data-lucide]'); - iconEl?.setAttribute('data-lucide', nextIcon); + iconTrigger.replaceChildren(eventIconElement(nextIcon, 'event-icon-picker__trigger-icon')); } iconGrid?.querySelectorAll('.event-icon-picker__option').forEach((btn) => { const active = btn.dataset.icon === nextIcon; @@ -1158,7 +1199,7 @@ function buildEventModalContent({ mode, event, date, reminder = null }) { aria-checked="${selectedIcon === icon.value ? 'true' : 'false'}" aria-label="${esc(icon.label)}" title="${esc(icon.label)}"> - + ${eventIconHtml(icon.value, 'event-icon-picker__option-icon')} ` ).join(''); @@ -1181,7 +1222,7 @@ function buildEventModalContent({ mode, event, date, reminder = null }) { aria-haspopup="true" aria-expanded="false" aria-label="${t('calendar.iconLabel')}"> - + ${eventIconHtml(selectedIcon, 'event-icon-picker__trigger-icon')}