diff --git a/apps/web/locales/af-ZA.po b/apps/web/locales/af-ZA.po index 97f3eb900..aea07e5f6 100644 --- a/apps/web/locales/af-ZA.po +++ b/apps/web/locales/af-ZA.po @@ -738,10 +738,6 @@ msgstr "Rekening" msgid "Actions" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Activate Semantic CSS" -msgstr "Aktiveer Semantiese CSS" - #: src/features/applications/components/detail/activity.tsx msgid "Activity" msgstr "" @@ -1995,10 +1991,6 @@ msgstr "" msgid "Conversations" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Converted stylesheet draft" -msgstr "Omgeskakelde stylbladkonsep" - #: src/features/resume/public/public-resume.tsx #: src/features/resume/share/link-tab.tsx #: src/features/settings/ai/api-keys.tsx @@ -9049,10 +9041,6 @@ msgstr "" msgid "Your keys, stored encrypted" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Your legacy styles stay active until you activate this Semantic CSS draft." -msgstr "Jou ou style bly aktief totdat jy hierdie Semantic CSS-konsep aktiveer." - #: src/features/ats-checker/messages.ts msgid "Your lines are packed very tightly." msgstr "Jou lyne is baie styf gepak." diff --git a/apps/web/locales/am-ET.po b/apps/web/locales/am-ET.po index b6021e283..d9504f41c 100644 --- a/apps/web/locales/am-ET.po +++ b/apps/web/locales/am-ET.po @@ -738,10 +738,6 @@ msgstr "መለያ" msgid "Actions" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Activate Semantic CSS" -msgstr "የሴማንቲክ CSS ን ያግብሩ" - #: src/features/applications/components/detail/activity.tsx msgid "Activity" msgstr "" @@ -1995,10 +1991,6 @@ msgstr "" msgid "Conversations" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Converted stylesheet draft" -msgstr "የተቀየረ የቅጥ ሉህ ረቂቅ" - #: src/features/resume/public/public-resume.tsx #: src/features/resume/share/link-tab.tsx #: src/features/settings/ai/api-keys.tsx @@ -9049,10 +9041,6 @@ msgstr "" msgid "Your keys, stored encrypted" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Your legacy styles stay active until you activate this Semantic CSS draft." -msgstr "የቀድሞ ቅጦችዎ ይህን የ Semantic CSS ረቂቅ እስኪያነቁ ድረስ በሥራ ላይ ይቆያሉ።" - #: src/features/ats-checker/messages.ts msgid "Your lines are packed very tightly." msgstr "መስመሮችዎ በጣም በጥብቅ የታሸጉ ናቸው።" diff --git a/apps/web/locales/ar-SA.po b/apps/web/locales/ar-SA.po index d632ebe21..ef4e69246 100644 --- a/apps/web/locales/ar-SA.po +++ b/apps/web/locales/ar-SA.po @@ -738,10 +738,6 @@ msgstr "الحساب" msgid "Actions" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Activate Semantic CSS" -msgstr "تفعيل CSS الدلالي" - #: src/features/applications/components/detail/activity.tsx msgid "Activity" msgstr "" @@ -1995,10 +1991,6 @@ msgstr "" msgid "Conversations" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Converted stylesheet draft" -msgstr "مسودة ورقة الأنماط المحولة" - #: src/features/resume/public/public-resume.tsx #: src/features/resume/share/link-tab.tsx #: src/features/settings/ai/api-keys.tsx @@ -9049,10 +9041,6 @@ msgstr "" msgid "Your keys, stored encrypted" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Your legacy styles stay active until you activate this Semantic CSS draft." -msgstr "تبقى أنماطك القديمة فعّالة حتى تفعّل مسودة Semantic CSS هذه." - #: src/features/ats-checker/messages.ts msgid "Your lines are packed very tightly." msgstr "خطوطك معبأة بإحكام شديد." diff --git a/apps/web/locales/az-AZ.po b/apps/web/locales/az-AZ.po index 7c2d8410c..0ec0698c4 100644 --- a/apps/web/locales/az-AZ.po +++ b/apps/web/locales/az-AZ.po @@ -738,10 +738,6 @@ msgstr "Hesab" msgid "Actions" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Activate Semantic CSS" -msgstr "Semantik CSS-i aktivləşdirin" - #: src/features/applications/components/detail/activity.tsx msgid "Activity" msgstr "" @@ -1995,10 +1991,6 @@ msgstr "" msgid "Conversations" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Converted stylesheet draft" -msgstr "Çevirilmiş stil cədvəli qaralaması" - #: src/features/resume/public/public-resume.tsx #: src/features/resume/share/link-tab.tsx #: src/features/settings/ai/api-keys.tsx @@ -9049,10 +9041,6 @@ msgstr "" msgid "Your keys, stored encrypted" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Your legacy styles stay active until you activate this Semantic CSS draft." -msgstr "Köhnə üslublarınız siz bu Semantic CSS qaralamasını aktivləşdirənə qədər qüvvədə qalır." - #: src/features/ats-checker/messages.ts msgid "Your lines are packed very tightly." msgstr "Sətirləriniz çox sıx yığılıb." diff --git a/apps/web/locales/bg-BG.po b/apps/web/locales/bg-BG.po index 6ce23809e..935e51891 100644 --- a/apps/web/locales/bg-BG.po +++ b/apps/web/locales/bg-BG.po @@ -738,10 +738,6 @@ msgstr "Акаунт" msgid "Actions" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Activate Semantic CSS" -msgstr "Активиране на семантичен CSS" - #: src/features/applications/components/detail/activity.tsx msgid "Activity" msgstr "" @@ -1995,10 +1991,6 @@ msgstr "" msgid "Conversations" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Converted stylesheet draft" -msgstr "Конвертирана чернова на стилов лист" - #: src/features/resume/public/public-resume.tsx #: src/features/resume/share/link-tab.tsx #: src/features/settings/ai/api-keys.tsx @@ -9049,10 +9041,6 @@ msgstr "" msgid "Your keys, stored encrypted" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Your legacy styles stay active until you activate this Semantic CSS draft." -msgstr "Старите ви стилове остават активни, докато не активирате тази чернова със Semantic CSS." - #: src/features/ats-checker/messages.ts msgid "Your lines are packed very tightly." msgstr "Вашите линии са опаковани много плътно." diff --git a/apps/web/locales/bn-BD.po b/apps/web/locales/bn-BD.po index 16d160717..90b755575 100644 --- a/apps/web/locales/bn-BD.po +++ b/apps/web/locales/bn-BD.po @@ -738,10 +738,6 @@ msgstr "অ্যাকাউন্ট" msgid "Actions" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Activate Semantic CSS" -msgstr "সিমান্টিক CSS সক্রিয় করুন" - #: src/features/applications/components/detail/activity.tsx msgid "Activity" msgstr "" @@ -1995,10 +1991,6 @@ msgstr "" msgid "Conversations" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Converted stylesheet draft" -msgstr "রূপান্তরিত স্টাইলশীট খসড়া" - #: src/features/resume/public/public-resume.tsx #: src/features/resume/share/link-tab.tsx #: src/features/settings/ai/api-keys.tsx @@ -9049,10 +9041,6 @@ msgstr "" msgid "Your keys, stored encrypted" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Your legacy styles stay active until you activate this Semantic CSS draft." -msgstr "আপনি এই Semantic CSS খসড়া সক্রিয় না করা পর্যন্ত আপনার পুরোনো স্টাইলগুলোই চালু থাকবে।" - #: src/features/ats-checker/messages.ts msgid "Your lines are packed very tightly." msgstr "আপনার লাইন খুব শক্তভাবে প্যাক করা হয়." diff --git a/apps/web/locales/ca-ES.po b/apps/web/locales/ca-ES.po index b984b5564..4bb304a4d 100644 --- a/apps/web/locales/ca-ES.po +++ b/apps/web/locales/ca-ES.po @@ -738,10 +738,6 @@ msgstr "Compte" msgid "Actions" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Activate Semantic CSS" -msgstr "Activa el CSS semàntic" - #: src/features/applications/components/detail/activity.tsx msgid "Activity" msgstr "" @@ -1995,10 +1991,6 @@ msgstr "" msgid "Conversations" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Converted stylesheet draft" -msgstr "Esborrany de full d'estil convertit" - #: src/features/resume/public/public-resume.tsx #: src/features/resume/share/link-tab.tsx #: src/features/settings/ai/api-keys.tsx @@ -9049,10 +9041,6 @@ msgstr "" msgid "Your keys, stored encrypted" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Your legacy styles stay active until you activate this Semantic CSS draft." -msgstr "Els teus estils antics continuen actius fins que activis aquest esborrany de CSS semàntic." - #: src/features/ats-checker/messages.ts msgid "Your lines are packed very tightly." msgstr "Les teves línies estan molt atapeïdes." diff --git a/apps/web/locales/cs-CZ.po b/apps/web/locales/cs-CZ.po index 8d27b36a4..64968b9fc 100644 --- a/apps/web/locales/cs-CZ.po +++ b/apps/web/locales/cs-CZ.po @@ -738,10 +738,6 @@ msgstr "Účet" msgid "Actions" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Activate Semantic CSS" -msgstr "Aktivace sémantického CSS" - #: src/features/applications/components/detail/activity.tsx msgid "Activity" msgstr "" @@ -1995,10 +1991,6 @@ msgstr "" msgid "Conversations" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Converted stylesheet draft" -msgstr "Konverze konceptu stylů" - #: src/features/resume/public/public-resume.tsx #: src/features/resume/share/link-tab.tsx #: src/features/settings/ai/api-keys.tsx @@ -9049,10 +9041,6 @@ msgstr "" msgid "Your keys, stored encrypted" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Your legacy styles stay active until you activate this Semantic CSS draft." -msgstr "Vaše původní styly zůstávají aktivní, dokud neaktivujete tento koncept Semantic CSS." - #: src/features/ats-checker/messages.ts msgid "Your lines are packed very tightly." msgstr "Vaše linky jsou nabité velmi pevně." diff --git a/apps/web/locales/da-DK.po b/apps/web/locales/da-DK.po index 486b79639..c8f64ef8b 100644 --- a/apps/web/locales/da-DK.po +++ b/apps/web/locales/da-DK.po @@ -738,10 +738,6 @@ msgstr "Konto" msgid "Actions" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Activate Semantic CSS" -msgstr "Aktivér semantisk CSS" - #: src/features/applications/components/detail/activity.tsx msgid "Activity" msgstr "" @@ -1995,10 +1991,6 @@ msgstr "" msgid "Conversations" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Converted stylesheet draft" -msgstr "Konverteret stylesheet-kladde" - #: src/features/resume/public/public-resume.tsx #: src/features/resume/share/link-tab.tsx #: src/features/settings/ai/api-keys.tsx @@ -9049,10 +9041,6 @@ msgstr "" msgid "Your keys, stored encrypted" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Your legacy styles stay active until you activate this Semantic CSS draft." -msgstr "Dine hidtidige typografier forbliver aktive, indtil du aktiverer dette Semantic CSS-udkast." - #: src/features/ats-checker/messages.ts msgid "Your lines are packed very tightly." msgstr "Dine linjer er pakket meget tæt." diff --git a/apps/web/locales/de-DE.po b/apps/web/locales/de-DE.po index bca684b35..19f6c1280 100644 --- a/apps/web/locales/de-DE.po +++ b/apps/web/locales/de-DE.po @@ -738,10 +738,6 @@ msgstr "Konto" msgid "Actions" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Activate Semantic CSS" -msgstr "Semantisches CSS aktivieren" - #: src/features/applications/components/detail/activity.tsx msgid "Activity" msgstr "" @@ -1995,10 +1991,6 @@ msgstr "" msgid "Conversations" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Converted stylesheet draft" -msgstr "Konvertierter Stylesheet-Entwurf" - #: src/features/resume/public/public-resume.tsx #: src/features/resume/share/link-tab.tsx #: src/features/settings/ai/api-keys.tsx @@ -9049,10 +9041,6 @@ msgstr "" msgid "Your keys, stored encrypted" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Your legacy styles stay active until you activate this Semantic CSS draft." -msgstr "Ihre bisherigen Stile bleiben aktiv, bis Sie diesen Semantic-CSS-Entwurf aktivieren." - #: src/features/ats-checker/messages.ts msgid "Your lines are packed very tightly." msgstr "Deine Zeilen sind sehr dicht gepackt." diff --git a/apps/web/locales/el-GR.po b/apps/web/locales/el-GR.po index 042fb1911..cd2c7d2e7 100644 --- a/apps/web/locales/el-GR.po +++ b/apps/web/locales/el-GR.po @@ -738,10 +738,6 @@ msgstr "Λογαριασμός" msgid "Actions" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Activate Semantic CSS" -msgstr "Ενεργοποίηση Σημασιολογικού CSS" - #: src/features/applications/components/detail/activity.tsx msgid "Activity" msgstr "" @@ -1995,10 +1991,6 @@ msgstr "" msgid "Conversations" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Converted stylesheet draft" -msgstr "Μετατρεπόμενο προσχέδιο φύλλου στυλ" - #: src/features/resume/public/public-resume.tsx #: src/features/resume/share/link-tab.tsx #: src/features/settings/ai/api-keys.tsx @@ -9049,10 +9041,6 @@ msgstr "" msgid "Your keys, stored encrypted" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Your legacy styles stay active until you activate this Semantic CSS draft." -msgstr "Τα παλαιά σας στυλ παραμένουν ενεργά μέχρι να ενεργοποιήσετε αυτό το πρόχειρο Semantic CSS." - #: src/features/ats-checker/messages.ts msgid "Your lines are packed very tightly." msgstr "Οι γραμμές σας είναι γεμάτες πολύ σφιχτά." diff --git a/apps/web/locales/en-GB.po b/apps/web/locales/en-GB.po index f5682f2aa..b6e7a4890 100644 --- a/apps/web/locales/en-GB.po +++ b/apps/web/locales/en-GB.po @@ -738,10 +738,6 @@ msgstr "Account" msgid "Actions" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Activate Semantic CSS" -msgstr "Activate Semantic CSS" - #: src/features/applications/components/detail/activity.tsx msgid "Activity" msgstr "" @@ -1995,10 +1991,6 @@ msgstr "" msgid "Conversations" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Converted stylesheet draft" -msgstr "Converted stylesheet draft" - #: src/features/resume/public/public-resume.tsx #: src/features/resume/share/link-tab.tsx #: src/features/settings/ai/api-keys.tsx @@ -9049,10 +9041,6 @@ msgstr "" msgid "Your keys, stored encrypted" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Your legacy styles stay active until you activate this Semantic CSS draft." -msgstr "Your legacy styles stay active until you activate this Semantic CSS draft." - #: src/features/ats-checker/messages.ts msgid "Your lines are packed very tightly." msgstr "Your lines are packed very tightly." diff --git a/apps/web/locales/en-US.po b/apps/web/locales/en-US.po index 184c91924..818d5e249 100644 --- a/apps/web/locales/en-US.po +++ b/apps/web/locales/en-US.po @@ -733,10 +733,6 @@ msgstr "Account" msgid "Actions" msgstr "Actions" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Activate Semantic CSS" -msgstr "Activate Semantic CSS" - #: src/features/applications/components/detail/activity.tsx msgid "Activity" msgstr "Activity" @@ -1990,10 +1986,6 @@ msgstr "Conversation" msgid "Conversations" msgstr "Conversations" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Converted stylesheet draft" -msgstr "Converted stylesheet draft" - #: src/features/resume/public/public-resume.tsx #: src/features/resume/share/link-tab.tsx #: src/features/settings/ai/api-keys.tsx @@ -9044,10 +9036,6 @@ msgstr "Your headline changed on the resume. The letter updated too." msgid "Your keys, stored encrypted" msgstr "Your keys, stored encrypted" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Your legacy styles stay active until you activate this Semantic CSS draft." -msgstr "Your legacy styles stay active until you activate this Semantic CSS draft." - #: src/features/ats-checker/messages.ts msgid "Your lines are packed very tightly." msgstr "Your lines are packed very tightly." diff --git a/apps/web/locales/es-ES.po b/apps/web/locales/es-ES.po index 1a4e95c6d..4ab863f47 100644 --- a/apps/web/locales/es-ES.po +++ b/apps/web/locales/es-ES.po @@ -738,10 +738,6 @@ msgstr "Cuenta" msgid "Actions" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Activate Semantic CSS" -msgstr "Activar CSS semántico" - #: src/features/applications/components/detail/activity.tsx msgid "Activity" msgstr "" @@ -1995,10 +1991,6 @@ msgstr "" msgid "Conversations" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Converted stylesheet draft" -msgstr "Borrador de hoja de estilo convertido" - #: src/features/resume/public/public-resume.tsx #: src/features/resume/share/link-tab.tsx #: src/features/settings/ai/api-keys.tsx @@ -9049,10 +9041,6 @@ msgstr "" msgid "Your keys, stored encrypted" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Your legacy styles stay active until you activate this Semantic CSS draft." -msgstr "Tus estilos antiguos siguen activos hasta que actives este borrador de CSS semántico." - #: src/features/ats-checker/messages.ts msgid "Your lines are packed very tightly." msgstr "Tus líneas están muy apretadas." diff --git a/apps/web/locales/fa-IR.po b/apps/web/locales/fa-IR.po index c8ac8cdcb..261ef22b0 100644 --- a/apps/web/locales/fa-IR.po +++ b/apps/web/locales/fa-IR.po @@ -738,10 +738,6 @@ msgstr "حساب کاربری" msgid "Actions" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Activate Semantic CSS" -msgstr "فعال کردن CSS معنایی" - #: src/features/applications/components/detail/activity.tsx msgid "Activity" msgstr "" @@ -1995,10 +1991,6 @@ msgstr "" msgid "Conversations" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Converted stylesheet draft" -msgstr "پیش‌نویس شیوه‌نامه تبدیل‌شده" - #: src/features/resume/public/public-resume.tsx #: src/features/resume/share/link-tab.tsx #: src/features/settings/ai/api-keys.tsx @@ -9049,10 +9041,6 @@ msgstr "" msgid "Your keys, stored encrypted" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Your legacy styles stay active until you activate this Semantic CSS draft." -msgstr "سبک‌های قدیمی شما تا زمانی که این پیش‌نویس Semantic CSS را فعال کنید، فعال می‌مانند." - #: src/features/ats-checker/messages.ts msgid "Your lines are packed very tightly." msgstr "خطوط شما بیش از حد فشرده‌اند." diff --git a/apps/web/locales/fi-FI.po b/apps/web/locales/fi-FI.po index 1c04b02a7..c5ad690b4 100644 --- a/apps/web/locales/fi-FI.po +++ b/apps/web/locales/fi-FI.po @@ -738,10 +738,6 @@ msgstr "Tili" msgid "Actions" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Activate Semantic CSS" -msgstr "Aktivoi semanttinen CSS" - #: src/features/applications/components/detail/activity.tsx msgid "Activity" msgstr "" @@ -1995,10 +1991,6 @@ msgstr "" msgid "Conversations" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Converted stylesheet draft" -msgstr "Muunnettu tyylitiedoston luonnos" - #: src/features/resume/public/public-resume.tsx #: src/features/resume/share/link-tab.tsx #: src/features/settings/ai/api-keys.tsx @@ -9049,10 +9041,6 @@ msgstr "" msgid "Your keys, stored encrypted" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Your legacy styles stay active until you activate this Semantic CSS draft." -msgstr "Vanhat tyylisi pysyvät voimassa, kunnes otat tämän Semantic CSS -luonnoksen käyttöön." - #: src/features/ats-checker/messages.ts msgid "Your lines are packed very tightly." msgstr "Sinun rivisi on pakattu erittäin tiukasti." diff --git a/apps/web/locales/fr-FR.po b/apps/web/locales/fr-FR.po index 1d9f1fd87..7f2cc2f89 100644 --- a/apps/web/locales/fr-FR.po +++ b/apps/web/locales/fr-FR.po @@ -738,10 +738,6 @@ msgstr "Compte" msgid "Actions" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Activate Semantic CSS" -msgstr "Activer le CSS sémantique" - #: src/features/applications/components/detail/activity.tsx msgid "Activity" msgstr "" @@ -1995,10 +1991,6 @@ msgstr "" msgid "Conversations" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Converted stylesheet draft" -msgstr "Brouillon de feuille de style converti" - #: src/features/resume/public/public-resume.tsx #: src/features/resume/share/link-tab.tsx #: src/features/settings/ai/api-keys.tsx @@ -9049,10 +9041,6 @@ msgstr "" msgid "Your keys, stored encrypted" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Your legacy styles stay active until you activate this Semantic CSS draft." -msgstr "Vos anciens styles restent actifs tant que vous n'activez pas ce brouillon de CSS sémantique." - #: src/features/ats-checker/messages.ts msgid "Your lines are packed very tightly." msgstr "Vos lignes sont très serrées." diff --git a/apps/web/locales/he-IL.po b/apps/web/locales/he-IL.po index c3e51ab96..60a5776b5 100644 --- a/apps/web/locales/he-IL.po +++ b/apps/web/locales/he-IL.po @@ -738,10 +738,6 @@ msgstr "חשבון" msgid "Actions" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Activate Semantic CSS" -msgstr "הפעלת CSS סמנטי" - #: src/features/applications/components/detail/activity.tsx msgid "Activity" msgstr "" @@ -1995,10 +1991,6 @@ msgstr "" msgid "Conversations" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Converted stylesheet draft" -msgstr "טיוטת גיליון סגנונות שהומרה" - #: src/features/resume/public/public-resume.tsx #: src/features/resume/share/link-tab.tsx #: src/features/settings/ai/api-keys.tsx @@ -9049,10 +9041,6 @@ msgstr "" msgid "Your keys, stored encrypted" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Your legacy styles stay active until you activate this Semantic CSS draft." -msgstr "הסגנונות הישנים שלך נשארים פעילים עד שתפעיל את טיוטת ה-Semantic CSS הזו." - #: src/features/ats-checker/messages.ts msgid "Your lines are packed very tightly." msgstr "השורות שלך צפופות מאוד." diff --git a/apps/web/locales/hi-IN.po b/apps/web/locales/hi-IN.po index 46d69e198..b7708c391 100644 --- a/apps/web/locales/hi-IN.po +++ b/apps/web/locales/hi-IN.po @@ -738,10 +738,6 @@ msgstr "खाता" msgid "Actions" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Activate Semantic CSS" -msgstr "सिमेंटिक सीएसएस को सक्रिय करें" - #: src/features/applications/components/detail/activity.tsx msgid "Activity" msgstr "" @@ -1995,10 +1991,6 @@ msgstr "" msgid "Conversations" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Converted stylesheet draft" -msgstr "रूपांतरित स्टाइलशीट ड्राफ्ट" - #: src/features/resume/public/public-resume.tsx #: src/features/resume/share/link-tab.tsx #: src/features/settings/ai/api-keys.tsx @@ -9049,10 +9041,6 @@ msgstr "" msgid "Your keys, stored encrypted" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Your legacy styles stay active until you activate this Semantic CSS draft." -msgstr "जब तक आप यह Semantic CSS ड्राफ़्ट सक्रिय नहीं करते, तब तक आपकी पुरानी स्टाइल ही लागू रहेंगी।" - #: src/features/ats-checker/messages.ts msgid "Your lines are packed very tightly." msgstr "आपकी पंक्तियाँ बहुत कसकर भरी हुई हैं।" diff --git a/apps/web/locales/hu-HU.po b/apps/web/locales/hu-HU.po index 4851160c2..1cae123c4 100644 --- a/apps/web/locales/hu-HU.po +++ b/apps/web/locales/hu-HU.po @@ -738,10 +738,6 @@ msgstr "Fiók" msgid "Actions" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Activate Semantic CSS" -msgstr "Szemantikus CSS aktiválása" - #: src/features/applications/components/detail/activity.tsx msgid "Activity" msgstr "" @@ -1995,10 +1991,6 @@ msgstr "" msgid "Conversations" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Converted stylesheet draft" -msgstr "Stíluslap-tervezet konvertálása" - #: src/features/resume/public/public-resume.tsx #: src/features/resume/share/link-tab.tsx #: src/features/settings/ai/api-keys.tsx @@ -9049,10 +9041,6 @@ msgstr "" msgid "Your keys, stored encrypted" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Your legacy styles stay active until you activate this Semantic CSS draft." -msgstr "A korábbi stílusai aktívak maradnak, amíg nem aktiválja ezt a Semantic CSS piszkozatot." - #: src/features/ats-checker/messages.ts msgid "Your lines are packed very tightly." msgstr "A soraid nagyon szorosan vannak csomagolva." diff --git a/apps/web/locales/id-ID.po b/apps/web/locales/id-ID.po index 29170583d..f110dcd94 100644 --- a/apps/web/locales/id-ID.po +++ b/apps/web/locales/id-ID.po @@ -738,10 +738,6 @@ msgstr "Akun" msgid "Actions" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Activate Semantic CSS" -msgstr "Aktifkan CSS Semantik" - #: src/features/applications/components/detail/activity.tsx msgid "Activity" msgstr "" @@ -1995,10 +1991,6 @@ msgstr "" msgid "Conversations" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Converted stylesheet draft" -msgstr "Draf stylesheet yang telah dikonversi" - #: src/features/resume/public/public-resume.tsx #: src/features/resume/share/link-tab.tsx #: src/features/settings/ai/api-keys.tsx @@ -9049,10 +9041,6 @@ msgstr "" msgid "Your keys, stored encrypted" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Your legacy styles stay active until you activate this Semantic CSS draft." -msgstr "Gaya lama Anda tetap aktif sampai Anda mengaktifkan draf Semantic CSS ini." - #: src/features/ats-checker/messages.ts msgid "Your lines are packed very tightly." msgstr "Garis Anda dikemas sangat rapat." diff --git a/apps/web/locales/it-IT.po b/apps/web/locales/it-IT.po index 749b6c8cd..aa34cf32e 100644 --- a/apps/web/locales/it-IT.po +++ b/apps/web/locales/it-IT.po @@ -738,10 +738,6 @@ msgstr "Account" msgid "Actions" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Activate Semantic CSS" -msgstr "Attiva il CSS semantico" - #: src/features/applications/components/detail/activity.tsx msgid "Activity" msgstr "" @@ -1995,10 +1991,6 @@ msgstr "" msgid "Conversations" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Converted stylesheet draft" -msgstr "Bozza del foglio di stile convertito" - #: src/features/resume/public/public-resume.tsx #: src/features/resume/share/link-tab.tsx #: src/features/settings/ai/api-keys.tsx @@ -9049,10 +9041,6 @@ msgstr "" msgid "Your keys, stored encrypted" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Your legacy styles stay active until you activate this Semantic CSS draft." -msgstr "I tuoi stili precedenti restano attivi finché non attivi questa bozza di CSS semantico." - #: src/features/ats-checker/messages.ts msgid "Your lines are packed very tightly." msgstr "Le tue battute sono molto fitte." diff --git a/apps/web/locales/ja-JP.po b/apps/web/locales/ja-JP.po index b3c91331b..65ae2b2b6 100644 --- a/apps/web/locales/ja-JP.po +++ b/apps/web/locales/ja-JP.po @@ -738,10 +738,6 @@ msgstr "アカウント" msgid "Actions" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Activate Semantic CSS" -msgstr "セマンティックCSSを有効にする" - #: src/features/applications/components/detail/activity.tsx msgid "Activity" msgstr "" @@ -1995,10 +1991,6 @@ msgstr "" msgid "Conversations" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Converted stylesheet draft" -msgstr "変換されたスタイルシートのドラフト" - #: src/features/resume/public/public-resume.tsx #: src/features/resume/share/link-tab.tsx #: src/features/settings/ai/api-keys.tsx @@ -9049,10 +9041,6 @@ msgstr "" msgid "Your keys, stored encrypted" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Your legacy styles stay active until you activate this Semantic CSS draft." -msgstr "このセマンティック CSS の下書きを有効にするまで、これまでのスタイルがそのまま適用されます。" - #: src/features/ats-checker/messages.ts msgid "Your lines are packed very tightly." msgstr "あなたのラインは非常に密集しています。" diff --git a/apps/web/locales/km-KH.po b/apps/web/locales/km-KH.po index 005e4304c..638ecc06c 100644 --- a/apps/web/locales/km-KH.po +++ b/apps/web/locales/km-KH.po @@ -738,10 +738,6 @@ msgstr "គណនី" msgid "Actions" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Activate Semantic CSS" -msgstr "ធ្វើឱ្យ CSS ន័យវិទ្យាសកម្ម" - #: src/features/applications/components/detail/activity.tsx msgid "Activity" msgstr "" @@ -1995,10 +1991,6 @@ msgstr "" msgid "Conversations" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Converted stylesheet draft" -msgstr "សេចក្តីព្រាងសន្លឹករចនាប័ទ្មដែលបានបម្លែង" - #: src/features/resume/public/public-resume.tsx #: src/features/resume/share/link-tab.tsx #: src/features/settings/ai/api-keys.tsx @@ -9049,10 +9041,6 @@ msgstr "" msgid "Your keys, stored encrypted" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Your legacy styles stay active until you activate this Semantic CSS draft." -msgstr "រចនាប័ទ្មចាស់របស់អ្នកនៅតែដំណើរការ រហូតដល់អ្នកបើកដំណើរការសេចក្ដីព្រាង Semantic CSS នេះ។" - #: src/features/ats-checker/messages.ts msgid "Your lines are packed very tightly." msgstr "បន្ទាត់របស់អ្នកត្រូវបានខ្ចប់យ៉ាងតឹងរ៉ឹង។" diff --git a/apps/web/locales/kn-IN.po b/apps/web/locales/kn-IN.po index c62c07433..9d3bdc40d 100644 --- a/apps/web/locales/kn-IN.po +++ b/apps/web/locales/kn-IN.po @@ -738,10 +738,6 @@ msgstr "ಖಾತೆ" msgid "Actions" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Activate Semantic CSS" -msgstr "ಲಾಕ್ಷಣಿಕ CSS ಅನ್ನು ಸಕ್ರಿಯಗೊಳಿಸಿ" - #: src/features/applications/components/detail/activity.tsx msgid "Activity" msgstr "" @@ -1995,10 +1991,6 @@ msgstr "" msgid "Conversations" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Converted stylesheet draft" -msgstr "ಪರಿವರ್ತಿಸಲಾದ ಸ್ಟೈಲ್‌ಶೀಟ್ ಡ್ರಾಫ್ಟ್" - #: src/features/resume/public/public-resume.tsx #: src/features/resume/share/link-tab.tsx #: src/features/settings/ai/api-keys.tsx @@ -9049,10 +9041,6 @@ msgstr "" msgid "Your keys, stored encrypted" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Your legacy styles stay active until you activate this Semantic CSS draft." -msgstr "ಈ Semantic CSS ಕರಡನ್ನು ನೀವು ಸಕ್ರಿಯಗೊಳಿಸುವವರೆಗೆ ನಿಮ್ಮ ಹಳೆಯ ಶೈಲಿಗಳು ಸಕ್ರಿಯವಾಗಿಯೇ ಇರುತ್ತವೆ." - #: src/features/ats-checker/messages.ts msgid "Your lines are packed very tightly." msgstr "ನಿಮ್ಮ ಸಾಲುಗಳನ್ನು ತುಂಬಾ ಬಿಗಿಯಾಗಿ ಪ್ಯಾಕ್ ಮಾಡಲಾಗಿದೆ." diff --git a/apps/web/locales/ko-KR.po b/apps/web/locales/ko-KR.po index 539079fb1..0ab085838 100644 --- a/apps/web/locales/ko-KR.po +++ b/apps/web/locales/ko-KR.po @@ -738,10 +738,6 @@ msgstr "계정" msgid "Actions" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Activate Semantic CSS" -msgstr "시맨틱 CSS 활성화" - #: src/features/applications/components/detail/activity.tsx msgid "Activity" msgstr "" @@ -1995,10 +1991,6 @@ msgstr "" msgid "Conversations" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Converted stylesheet draft" -msgstr "변환된 스타일시트 초안" - #: src/features/resume/public/public-resume.tsx #: src/features/resume/share/link-tab.tsx #: src/features/settings/ai/api-keys.tsx @@ -9049,10 +9041,6 @@ msgstr "" msgid "Your keys, stored encrypted" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Your legacy styles stay active until you activate this Semantic CSS draft." -msgstr "이 시맨틱 CSS 초안을 활성화하기 전까지는 기존 스타일이 그대로 적용됩니다." - #: src/features/ats-checker/messages.ts msgid "Your lines are packed very tightly." msgstr "귀하의 라인은 매우 촘촘하게 포장되어 있습니다." diff --git a/apps/web/locales/lt-LT.po b/apps/web/locales/lt-LT.po index 8707952b5..6deaa6317 100644 --- a/apps/web/locales/lt-LT.po +++ b/apps/web/locales/lt-LT.po @@ -738,10 +738,6 @@ msgstr "Paskyra" msgid "Actions" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Activate Semantic CSS" -msgstr "Semantinio CSS aktyvavimas" - #: src/features/applications/components/detail/activity.tsx msgid "Activity" msgstr "" @@ -1995,10 +1991,6 @@ msgstr "" msgid "Conversations" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Converted stylesheet draft" -msgstr "Konvertuotas stilių lapo juodraštis" - #: src/features/resume/public/public-resume.tsx #: src/features/resume/share/link-tab.tsx #: src/features/settings/ai/api-keys.tsx @@ -9049,10 +9041,6 @@ msgstr "" msgid "Your keys, stored encrypted" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Your legacy styles stay active until you activate this Semantic CSS draft." -msgstr "Seni jūsų stiliai lieka aktyvūs, kol neaktyvuosite šio Semantic CSS juodraščio." - #: src/features/ats-checker/messages.ts msgid "Your lines are packed very tightly." msgstr "Jūsų eilutės supakuotos labai sandariai." diff --git a/apps/web/locales/lv-LV.po b/apps/web/locales/lv-LV.po index e67667420..fe811d8df 100644 --- a/apps/web/locales/lv-LV.po +++ b/apps/web/locales/lv-LV.po @@ -738,10 +738,6 @@ msgstr "Konts" msgid "Actions" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Activate Semantic CSS" -msgstr "Aktivizēt semantisko CSS" - #: src/features/applications/components/detail/activity.tsx msgid "Activity" msgstr "" @@ -1995,10 +1991,6 @@ msgstr "" msgid "Conversations" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Converted stylesheet draft" -msgstr "Konvertēts stila lapas melnraksts" - #: src/features/resume/public/public-resume.tsx #: src/features/resume/share/link-tab.tsx #: src/features/settings/ai/api-keys.tsx @@ -9049,10 +9041,6 @@ msgstr "" msgid "Your keys, stored encrypted" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Your legacy styles stay active until you activate this Semantic CSS draft." -msgstr "Jūsu vecie stili paliek aktīvi, līdz aktivizēsiet šo Semantic CSS melnrakstu." - #: src/features/ats-checker/messages.ts msgid "Your lines are packed very tightly." msgstr "Jūsu rindas ir ļoti cieši iesaiņotas." diff --git a/apps/web/locales/ml-IN.po b/apps/web/locales/ml-IN.po index 37135d4de..fd5cfc87f 100644 --- a/apps/web/locales/ml-IN.po +++ b/apps/web/locales/ml-IN.po @@ -738,10 +738,6 @@ msgstr "അക്കൗണ്ട്" msgid "Actions" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Activate Semantic CSS" -msgstr "സെമാന്റിക് CSS സജീവമാക്കുക" - #: src/features/applications/components/detail/activity.tsx msgid "Activity" msgstr "" @@ -1995,10 +1991,6 @@ msgstr "" msgid "Conversations" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Converted stylesheet draft" -msgstr "പരിവർത്തനം ചെയ്ത സ്റ്റൈൽഷീറ്റ് ഡ്രാഫ്റ്റ്" - #: src/features/resume/public/public-resume.tsx #: src/features/resume/share/link-tab.tsx #: src/features/settings/ai/api-keys.tsx @@ -9049,10 +9041,6 @@ msgstr "" msgid "Your keys, stored encrypted" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Your legacy styles stay active until you activate this Semantic CSS draft." -msgstr "ഈ Semantic CSS ഡ്രാഫ്റ്റ് നിങ്ങൾ സജീവമാക്കുന്നതുവരെ പഴയ സ്റ്റൈലുകൾ സജീവമായി തുടരും." - #: src/features/ats-checker/messages.ts msgid "Your lines are packed very tightly." msgstr "നിങ്ങളുടെ വരികൾ വളരെ കർശനമായി പായ്ക്ക് ചെയ്തിട്ടുണ്ട്." diff --git a/apps/web/locales/mr-IN.po b/apps/web/locales/mr-IN.po index 186e2d18f..3118ec0e1 100644 --- a/apps/web/locales/mr-IN.po +++ b/apps/web/locales/mr-IN.po @@ -738,10 +738,6 @@ msgstr "खाते" msgid "Actions" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Activate Semantic CSS" -msgstr "सिमँटिक CSS सक्रिय करा" - #: src/features/applications/components/detail/activity.tsx msgid "Activity" msgstr "" @@ -1995,10 +1991,6 @@ msgstr "" msgid "Conversations" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Converted stylesheet draft" -msgstr "रूपांतरित स्टाईलशीटचा मसुदा" - #: src/features/resume/public/public-resume.tsx #: src/features/resume/share/link-tab.tsx #: src/features/settings/ai/api-keys.tsx @@ -9049,10 +9041,6 @@ msgstr "" msgid "Your keys, stored encrypted" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Your legacy styles stay active until you activate this Semantic CSS draft." -msgstr "तुम्ही हा Semantic CSS मसुदा सक्रिय करेपर्यंत तुमच्या जुन्या स्टाइल्स लागू राहतील." - #: src/features/ats-checker/messages.ts msgid "Your lines are packed very tightly." msgstr "तुमच्या ओळी खूप घट्ट बांधल्या आहेत." diff --git a/apps/web/locales/ms-MY.po b/apps/web/locales/ms-MY.po index f9d4b0631..b2812b448 100644 --- a/apps/web/locales/ms-MY.po +++ b/apps/web/locales/ms-MY.po @@ -738,10 +738,6 @@ msgstr "Akaun" msgid "Actions" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Activate Semantic CSS" -msgstr "Aktifkan CSS Semantik" - #: src/features/applications/components/detail/activity.tsx msgid "Activity" msgstr "" @@ -1995,10 +1991,6 @@ msgstr "" msgid "Conversations" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Converted stylesheet draft" -msgstr "Draf helaian gaya yang ditukar" - #: src/features/resume/public/public-resume.tsx #: src/features/resume/share/link-tab.tsx #: src/features/settings/ai/api-keys.tsx @@ -9049,10 +9041,6 @@ msgstr "" msgid "Your keys, stored encrypted" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Your legacy styles stay active until you activate this Semantic CSS draft." -msgstr "Gaya lama anda kekal aktif sehingga anda mengaktifkan draf Semantic CSS ini." - #: src/features/ats-checker/messages.ts msgid "Your lines are packed very tightly." msgstr "Talian anda padat dengan sangat ketat." diff --git a/apps/web/locales/ne-NP.po b/apps/web/locales/ne-NP.po index 6401a6306..70ea77070 100644 --- a/apps/web/locales/ne-NP.po +++ b/apps/web/locales/ne-NP.po @@ -738,10 +738,6 @@ msgstr "खाता" msgid "Actions" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Activate Semantic CSS" -msgstr "सिमेन्टिक CSS सक्रिय गर्नुहोस्" - #: src/features/applications/components/detail/activity.tsx msgid "Activity" msgstr "" @@ -1995,10 +1991,6 @@ msgstr "" msgid "Conversations" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Converted stylesheet draft" -msgstr "रूपान्तरित स्टाइलसिट ड्राफ्ट" - #: src/features/resume/public/public-resume.tsx #: src/features/resume/share/link-tab.tsx #: src/features/settings/ai/api-keys.tsx @@ -9049,10 +9041,6 @@ msgstr "" msgid "Your keys, stored encrypted" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Your legacy styles stay active until you activate this Semantic CSS draft." -msgstr "तपाईंले यो Semantic CSS मस्यौदा सक्रिय नगरेसम्म तपाईंका पुराना शैलीहरू नै लागू रहनेछन्।" - #: src/features/ats-checker/messages.ts msgid "Your lines are packed very tightly." msgstr "तपाईंको लाइनहरू धेरै कडा प्याक गरिएका छन्।" diff --git a/apps/web/locales/nl-NL.po b/apps/web/locales/nl-NL.po index c9e577803..bd380260a 100644 --- a/apps/web/locales/nl-NL.po +++ b/apps/web/locales/nl-NL.po @@ -738,10 +738,6 @@ msgstr "Rekening" msgid "Actions" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Activate Semantic CSS" -msgstr "Activeer semantische CSS" - #: src/features/applications/components/detail/activity.tsx msgid "Activity" msgstr "" @@ -1995,10 +1991,6 @@ msgstr "" msgid "Conversations" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Converted stylesheet draft" -msgstr "Omgezette stylesheet-concept" - #: src/features/resume/public/public-resume.tsx #: src/features/resume/share/link-tab.tsx #: src/features/settings/ai/api-keys.tsx @@ -9049,10 +9041,6 @@ msgstr "" msgid "Your keys, stored encrypted" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Your legacy styles stay active until you activate this Semantic CSS draft." -msgstr "Je bestaande stijlen blijven actief totdat je dit Semantic CSS-concept activeert." - #: src/features/ats-checker/messages.ts msgid "Your lines are packed very tightly." msgstr "Je paginamarges zijn erg smal." diff --git a/apps/web/locales/no-NO.po b/apps/web/locales/no-NO.po index 34daa5e16..030dbe62c 100644 --- a/apps/web/locales/no-NO.po +++ b/apps/web/locales/no-NO.po @@ -738,10 +738,6 @@ msgstr "Konto" msgid "Actions" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Activate Semantic CSS" -msgstr "Aktiver semantisk CSS" - #: src/features/applications/components/detail/activity.tsx msgid "Activity" msgstr "" @@ -1995,10 +1991,6 @@ msgstr "" msgid "Conversations" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Converted stylesheet draft" -msgstr "Konvertert stilarkutkast" - #: src/features/resume/public/public-resume.tsx #: src/features/resume/share/link-tab.tsx #: src/features/settings/ai/api-keys.tsx @@ -9049,10 +9041,6 @@ msgstr "" msgid "Your keys, stored encrypted" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Your legacy styles stay active until you activate this Semantic CSS draft." -msgstr "De gamle stilene dine forblir aktive til du aktiverer dette Semantic CSS-utkastet." - #: src/features/ats-checker/messages.ts msgid "Your lines are packed very tightly." msgstr "Linjeavstanden din er svært tett." diff --git a/apps/web/locales/or-IN.po b/apps/web/locales/or-IN.po index 0856f2cc8..7d0e78c83 100644 --- a/apps/web/locales/or-IN.po +++ b/apps/web/locales/or-IN.po @@ -738,10 +738,6 @@ msgstr "ଆକାଉଣ୍ଟ" msgid "Actions" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Activate Semantic CSS" -msgstr "ସିମାଣ୍ଟିକ୍ CSS ସକ୍ରିୟ କରନ୍ତୁ" - #: src/features/applications/components/detail/activity.tsx msgid "Activity" msgstr "" @@ -1995,10 +1991,6 @@ msgstr "" msgid "Conversations" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Converted stylesheet draft" -msgstr "ରୂପାନ୍ତରିତ ଷ୍ଟାଇଲସିଟ୍ ଡ୍ରାଫ୍ଟ" - #: src/features/resume/public/public-resume.tsx #: src/features/resume/share/link-tab.tsx #: src/features/settings/ai/api-keys.tsx @@ -9049,10 +9041,6 @@ msgstr "" msgid "Your keys, stored encrypted" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Your legacy styles stay active until you activate this Semantic CSS draft." -msgstr "ଆପଣ ଏହି Semantic CSS ଡ୍ରାଫ୍ଟକୁ ସକ୍ରିୟ ନକରିବା ପର୍ଯ୍ୟନ୍ତ ଆପଣଙ୍କ ପୁରୁଣା ଶୈଳୀଗୁଡିକ ସକ୍ରିୟ ରହିଥାଏ।" - #: src/features/ats-checker/messages.ts msgid "Your lines are packed very tightly." msgstr "ଆପଣଙ୍କ ଲାଇନ୍‌ଗୁଡ଼ିକ ଅତ୍ୟଧିକ ଘନ।" diff --git a/apps/web/locales/pl-PL.po b/apps/web/locales/pl-PL.po index eb820a22e..3ce9a7760 100644 --- a/apps/web/locales/pl-PL.po +++ b/apps/web/locales/pl-PL.po @@ -738,10 +738,6 @@ msgstr "Konto" msgid "Actions" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Activate Semantic CSS" -msgstr "Aktywuj semantyczny CSS" - #: src/features/applications/components/detail/activity.tsx msgid "Activity" msgstr "" @@ -1995,10 +1991,6 @@ msgstr "" msgid "Conversations" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Converted stylesheet draft" -msgstr "Przekonwertowany projekt arkusza stylów" - #: src/features/resume/public/public-resume.tsx #: src/features/resume/share/link-tab.tsx #: src/features/settings/ai/api-keys.tsx @@ -9049,10 +9041,6 @@ msgstr "" msgid "Your keys, stored encrypted" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Your legacy styles stay active until you activate this Semantic CSS draft." -msgstr "Twoje dotychczasowe style pozostają aktywne, dopóki nie aktywujesz tej wersji roboczej Semantic CSS." - #: src/features/ats-checker/messages.ts msgid "Your lines are packed very tightly." msgstr "Wiersze są bardzo ciasno ułożone." diff --git a/apps/web/locales/pt-BR.po b/apps/web/locales/pt-BR.po index 0c2ca4d65..705d13bd1 100644 --- a/apps/web/locales/pt-BR.po +++ b/apps/web/locales/pt-BR.po @@ -738,10 +738,6 @@ msgstr "Conta" msgid "Actions" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Activate Semantic CSS" -msgstr "Ativar CSS Semântico" - #: src/features/applications/components/detail/activity.tsx msgid "Activity" msgstr "" @@ -1995,10 +1991,6 @@ msgstr "" msgid "Conversations" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Converted stylesheet draft" -msgstr "Rascunho da folha de estilo convertida" - #: src/features/resume/public/public-resume.tsx #: src/features/resume/share/link-tab.tsx #: src/features/settings/ai/api-keys.tsx @@ -9049,10 +9041,6 @@ msgstr "" msgid "Your keys, stored encrypted" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Your legacy styles stay active until you activate this Semantic CSS draft." -msgstr "Seus estilos antigos continuam ativos até você ativar este rascunho de CSS semântico." - #: src/features/ats-checker/messages.ts msgid "Your lines are packed very tightly." msgstr "Suas linhas estão muito compactadas." diff --git a/apps/web/locales/pt-PT.po b/apps/web/locales/pt-PT.po index 550bedf79..1a44f8d30 100644 --- a/apps/web/locales/pt-PT.po +++ b/apps/web/locales/pt-PT.po @@ -738,10 +738,6 @@ msgstr "Conta" msgid "Actions" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Activate Semantic CSS" -msgstr "Ativar CSS Semântico" - #: src/features/applications/components/detail/activity.tsx msgid "Activity" msgstr "" @@ -1995,10 +1991,6 @@ msgstr "" msgid "Conversations" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Converted stylesheet draft" -msgstr "Rascunho da folha de estilo convertida" - #: src/features/resume/public/public-resume.tsx #: src/features/resume/share/link-tab.tsx #: src/features/settings/ai/api-keys.tsx @@ -9049,10 +9041,6 @@ msgstr "" msgid "Your keys, stored encrypted" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Your legacy styles stay active until you activate this Semantic CSS draft." -msgstr "Os seus estilos antigos continuam ativos até ativar este rascunho de CSS semântico." - #: src/features/ats-checker/messages.ts msgid "Your lines are packed very tightly." msgstr "Suas falas estão muito compactadas." diff --git a/apps/web/locales/ro-RO.po b/apps/web/locales/ro-RO.po index f9da210d1..3b8c8e2ba 100644 --- a/apps/web/locales/ro-RO.po +++ b/apps/web/locales/ro-RO.po @@ -738,10 +738,6 @@ msgstr "Cont" msgid "Actions" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Activate Semantic CSS" -msgstr "Activează CSS-ul semantic" - #: src/features/applications/components/detail/activity.tsx msgid "Activity" msgstr "" @@ -1995,10 +1991,6 @@ msgstr "" msgid "Conversations" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Converted stylesheet draft" -msgstr "Schiță de foaie de stil convertită" - #: src/features/resume/public/public-resume.tsx #: src/features/resume/share/link-tab.tsx #: src/features/settings/ai/api-keys.tsx @@ -9049,10 +9041,6 @@ msgstr "" msgid "Your keys, stored encrypted" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Your legacy styles stay active until you activate this Semantic CSS draft." -msgstr "Stilurile vechi rămân active până când activați această ciornă Semantic CSS." - #: src/features/ats-checker/messages.ts msgid "Your lines are packed very tightly." msgstr "Liniile tale sunt foarte strâns." diff --git a/apps/web/locales/ru-RU.po b/apps/web/locales/ru-RU.po index 0bd8570c0..5415084af 100644 --- a/apps/web/locales/ru-RU.po +++ b/apps/web/locales/ru-RU.po @@ -738,10 +738,6 @@ msgstr "Аккаунт" msgid "Actions" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Activate Semantic CSS" -msgstr "Активировать семантический CSS" - #: src/features/applications/components/detail/activity.tsx msgid "Activity" msgstr "" @@ -1995,10 +1991,6 @@ msgstr "" msgid "Conversations" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Converted stylesheet draft" -msgstr "Преобразованный черновик таблицы стилей" - #: src/features/resume/public/public-resume.tsx #: src/features/resume/share/link-tab.tsx #: src/features/settings/ai/api-keys.tsx @@ -9049,10 +9041,6 @@ msgstr "" msgid "Your keys, stored encrypted" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Your legacy styles stay active until you activate this Semantic CSS draft." -msgstr "Ваши прежние стили остаются активными, пока вы не активируете этот черновик Semantic CSS." - #: src/features/ats-checker/messages.ts msgid "Your lines are packed very tightly." msgstr "Ваши строки упакованы очень плотно." diff --git a/apps/web/locales/sk-SK.po b/apps/web/locales/sk-SK.po index ef05f9a30..4a6d5b0db 100644 --- a/apps/web/locales/sk-SK.po +++ b/apps/web/locales/sk-SK.po @@ -738,10 +738,6 @@ msgstr "Účet" msgid "Actions" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Activate Semantic CSS" -msgstr "Aktivovať sémantický CSS" - #: src/features/applications/components/detail/activity.tsx msgid "Activity" msgstr "" @@ -1995,10 +1991,6 @@ msgstr "" msgid "Conversations" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Converted stylesheet draft" -msgstr "Konvertovaný koncept štýlového hárka" - #: src/features/resume/public/public-resume.tsx #: src/features/resume/share/link-tab.tsx #: src/features/settings/ai/api-keys.tsx @@ -9049,10 +9041,6 @@ msgstr "" msgid "Your keys, stored encrypted" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Your legacy styles stay active until you activate this Semantic CSS draft." -msgstr "Vaše pôvodné štýly zostávajú aktívne, kým neaktivujete tento koncept Semantic CSS." - #: src/features/ats-checker/messages.ts msgid "Your lines are packed very tightly." msgstr "Vaše linky sú nahustené." diff --git a/apps/web/locales/sl-SI.po b/apps/web/locales/sl-SI.po index 172d662ae..7791d2546 100644 --- a/apps/web/locales/sl-SI.po +++ b/apps/web/locales/sl-SI.po @@ -738,10 +738,6 @@ msgstr "Račun" msgid "Actions" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Activate Semantic CSS" -msgstr "Aktiviraj semantični CSS" - #: src/features/applications/components/detail/activity.tsx msgid "Activity" msgstr "" @@ -1995,10 +1991,6 @@ msgstr "" msgid "Conversations" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Converted stylesheet draft" -msgstr "Pretvorjen osnutek slogovne predloge" - #: src/features/resume/public/public-resume.tsx #: src/features/resume/share/link-tab.tsx #: src/features/settings/ai/api-keys.tsx @@ -9049,10 +9041,6 @@ msgstr "" msgid "Your keys, stored encrypted" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Your legacy styles stay active until you activate this Semantic CSS draft." -msgstr "Vaši stari slogi ostanejo aktivni, dokler ne aktivirate tega osnutka Semantic CSS." - #: src/features/ats-checker/messages.ts msgid "Your lines are packed very tightly." msgstr "Vaše vrstice so zelo natrpane." diff --git a/apps/web/locales/sq-AL.po b/apps/web/locales/sq-AL.po index 5da34fe4c..0417ac4b0 100644 --- a/apps/web/locales/sq-AL.po +++ b/apps/web/locales/sq-AL.po @@ -738,10 +738,6 @@ msgstr "Llogaria" msgid "Actions" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Activate Semantic CSS" -msgstr "Aktivizo CSS-në Semantike" - #: src/features/applications/components/detail/activity.tsx msgid "Activity" msgstr "" @@ -1995,10 +1991,6 @@ msgstr "" msgid "Conversations" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Converted stylesheet draft" -msgstr "Drafti i konvertuar i fletës së stilit" - #: src/features/resume/public/public-resume.tsx #: src/features/resume/share/link-tab.tsx #: src/features/settings/ai/api-keys.tsx @@ -9049,10 +9041,6 @@ msgstr "" msgid "Your keys, stored encrypted" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Your legacy styles stay active until you activate this Semantic CSS draft." -msgstr "Stilet tuaja të vjetra mbeten aktive derisa ta aktivizoni këtë draft Semantic CSS." - #: src/features/ats-checker/messages.ts msgid "Your lines are packed very tightly." msgstr "Linjat tuaja janë të mbushura shumë fort." diff --git a/apps/web/locales/sr-SP.po b/apps/web/locales/sr-SP.po index 9526be269..7ea193f7c 100644 --- a/apps/web/locales/sr-SP.po +++ b/apps/web/locales/sr-SP.po @@ -738,10 +738,6 @@ msgstr "Налог" msgid "Actions" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Activate Semantic CSS" -msgstr "Активирајте семантички CSS" - #: src/features/applications/components/detail/activity.tsx msgid "Activity" msgstr "" @@ -1995,10 +1991,6 @@ msgstr "" msgid "Conversations" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Converted stylesheet draft" -msgstr "Конвертована нацртна верзија стилског листа" - #: src/features/resume/public/public-resume.tsx #: src/features/resume/share/link-tab.tsx #: src/features/settings/ai/api-keys.tsx @@ -9049,10 +9041,6 @@ msgstr "" msgid "Your keys, stored encrypted" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Your legacy styles stay active until you activate this Semantic CSS draft." -msgstr "Ваши стари стилови остају активни док не активирате овај Semantic CSS нацрт." - #: src/features/ats-checker/messages.ts msgid "Your lines are packed very tightly." msgstr "Ваше линије су веома збијене." diff --git a/apps/web/locales/sv-SE.po b/apps/web/locales/sv-SE.po index 60166a9cc..fa8f39b9b 100644 --- a/apps/web/locales/sv-SE.po +++ b/apps/web/locales/sv-SE.po @@ -738,10 +738,6 @@ msgstr "Konto" msgid "Actions" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Activate Semantic CSS" -msgstr "Aktivera semantisk CSS" - #: src/features/applications/components/detail/activity.tsx msgid "Activity" msgstr "" @@ -1995,10 +1991,6 @@ msgstr "" msgid "Conversations" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Converted stylesheet draft" -msgstr "Konverterat utkast till stilark" - #: src/features/resume/public/public-resume.tsx #: src/features/resume/share/link-tab.tsx #: src/features/settings/ai/api-keys.tsx @@ -9049,10 +9041,6 @@ msgstr "" msgid "Your keys, stored encrypted" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Your legacy styles stay active until you activate this Semantic CSS draft." -msgstr "Dina tidigare stilar förblir aktiva tills du aktiverar det här Semantic CSS-utkastet." - #: src/features/ats-checker/messages.ts msgid "Your lines are packed very tightly." msgstr "Dina linjer är mycket tätt packade." diff --git a/apps/web/locales/ta-IN.po b/apps/web/locales/ta-IN.po index ec6d01630..26748cfe1 100644 --- a/apps/web/locales/ta-IN.po +++ b/apps/web/locales/ta-IN.po @@ -738,10 +738,6 @@ msgstr "கணக்கு" msgid "Actions" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Activate Semantic CSS" -msgstr "செமாண்டிக் CSS-ஐ செயல்படுத்துக" - #: src/features/applications/components/detail/activity.tsx msgid "Activity" msgstr "" @@ -1995,10 +1991,6 @@ msgstr "" msgid "Conversations" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Converted stylesheet draft" -msgstr "மாற்றப்பட்ட ஸ்டைல்ஷீட் வரைவு" - #: src/features/resume/public/public-resume.tsx #: src/features/resume/share/link-tab.tsx #: src/features/settings/ai/api-keys.tsx @@ -9049,10 +9041,6 @@ msgstr "" msgid "Your keys, stored encrypted" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Your legacy styles stay active until you activate this Semantic CSS draft." -msgstr "இந்த Semantic CSS வரைவை நீங்கள் செயல்படுத்தும் வரை உங்கள் பழைய பாணிகள் செயலில் இருக்கும்." - #: src/features/ats-checker/messages.ts msgid "Your lines are packed very tightly." msgstr "உங்கள் வரிகள் மிகவும் இறுக்கமாக நிரம்பியுள்ளன." diff --git a/apps/web/locales/te-IN.po b/apps/web/locales/te-IN.po index b214697b9..2babb54fa 100644 --- a/apps/web/locales/te-IN.po +++ b/apps/web/locales/te-IN.po @@ -738,10 +738,6 @@ msgstr "ఖాతా" msgid "Actions" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Activate Semantic CSS" -msgstr "సెమాంటిక్ CSSని యాక్టివేట్ చేయండి" - #: src/features/applications/components/detail/activity.tsx msgid "Activity" msgstr "" @@ -1995,10 +1991,6 @@ msgstr "" msgid "Conversations" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Converted stylesheet draft" -msgstr "మార్చబడిన స్టైల్‌షీట్ డ్రాఫ్ట్" - #: src/features/resume/public/public-resume.tsx #: src/features/resume/share/link-tab.tsx #: src/features/settings/ai/api-keys.tsx @@ -9049,10 +9041,6 @@ msgstr "" msgid "Your keys, stored encrypted" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Your legacy styles stay active until you activate this Semantic CSS draft." -msgstr "ఈ Semantic CSS ముసాయిదాను మీరు సక్రియం చేసే వరకు మీ పాత శైలులు అమల్లోనే ఉంటాయి." - #: src/features/ats-checker/messages.ts msgid "Your lines are packed very tightly." msgstr "మీ లైన్లు చాలా గట్టిగా ప్యాక్ చేయబడ్డాయి." diff --git a/apps/web/locales/th-TH.po b/apps/web/locales/th-TH.po index a741b84a7..c9a0b2df1 100644 --- a/apps/web/locales/th-TH.po +++ b/apps/web/locales/th-TH.po @@ -738,10 +738,6 @@ msgstr "บัญชี" msgid "Actions" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Activate Semantic CSS" -msgstr "เปิดใช้งาน Semantic CSS" - #: src/features/applications/components/detail/activity.tsx msgid "Activity" msgstr "" @@ -1995,10 +1991,6 @@ msgstr "" msgid "Conversations" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Converted stylesheet draft" -msgstr "แปลงร่างสไตล์ชีตแล้ว" - #: src/features/resume/public/public-resume.tsx #: src/features/resume/share/link-tab.tsx #: src/features/settings/ai/api-keys.tsx @@ -9049,10 +9041,6 @@ msgstr "" msgid "Your keys, stored encrypted" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Your legacy styles stay active until you activate this Semantic CSS draft." -msgstr "สไตล์เดิมของคุณจะยังใช้งานอยู่จนกว่าคุณจะเปิดใช้งานฉบับร่าง Semantic CSS นี้" - #: src/features/ats-checker/messages.ts msgid "Your lines are packed very tightly." msgstr "เส้นของคุณแน่นมาก" diff --git a/apps/web/locales/tr-TR.po b/apps/web/locales/tr-TR.po index a7935600f..d7bb82d5a 100644 --- a/apps/web/locales/tr-TR.po +++ b/apps/web/locales/tr-TR.po @@ -738,10 +738,6 @@ msgstr "Hesap" msgid "Actions" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Activate Semantic CSS" -msgstr "Semantik CSS'i Etkinleştir" - #: src/features/applications/components/detail/activity.tsx msgid "Activity" msgstr "" @@ -1995,10 +1991,6 @@ msgstr "" msgid "Conversations" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Converted stylesheet draft" -msgstr "Dönüştürülmüş stil sayfası taslağı" - #: src/features/resume/public/public-resume.tsx #: src/features/resume/share/link-tab.tsx #: src/features/settings/ai/api-keys.tsx @@ -9049,10 +9041,6 @@ msgstr "" msgid "Your keys, stored encrypted" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Your legacy styles stay active until you activate this Semantic CSS draft." -msgstr "Bu Semantic CSS taslağını etkinleştirene kadar eski stilleriniz etkin kalır." - #: src/features/ats-checker/messages.ts msgid "Your lines are packed very tightly." msgstr "Hatlarınız çok sıkı paketlenmiş." diff --git a/apps/web/locales/uk-UA.po b/apps/web/locales/uk-UA.po index 250240ce0..be4e3cbb3 100644 --- a/apps/web/locales/uk-UA.po +++ b/apps/web/locales/uk-UA.po @@ -738,10 +738,6 @@ msgstr "Обліковий запис" msgid "Actions" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Activate Semantic CSS" -msgstr "Активуйте семантичний CSS" - #: src/features/applications/components/detail/activity.tsx msgid "Activity" msgstr "" @@ -1995,10 +1991,6 @@ msgstr "" msgid "Conversations" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Converted stylesheet draft" -msgstr "Конвертований чернетка таблиці стилів" - #: src/features/resume/public/public-resume.tsx #: src/features/resume/share/link-tab.tsx #: src/features/settings/ai/api-keys.tsx @@ -9049,10 +9041,6 @@ msgstr "" msgid "Your keys, stored encrypted" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Your legacy styles stay active until you activate this Semantic CSS draft." -msgstr "Ваші попередні стилі залишаються активними, доки ви не активуєте цю чернетку Semantic CSS." - #: src/features/ats-checker/messages.ts msgid "Your lines are packed very tightly." msgstr "Ваші рядки зібрані дуже щільно." diff --git a/apps/web/locales/uz-UZ.po b/apps/web/locales/uz-UZ.po index d932b445d..89ba17a99 100644 --- a/apps/web/locales/uz-UZ.po +++ b/apps/web/locales/uz-UZ.po @@ -738,10 +738,6 @@ msgstr "Hisob" msgid "Actions" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Activate Semantic CSS" -msgstr "Semantik CSS-ni faollashtirish" - #: src/features/applications/components/detail/activity.tsx msgid "Activity" msgstr "" @@ -1995,10 +1991,6 @@ msgstr "" msgid "Conversations" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Converted stylesheet draft" -msgstr "O'zgartirilgan uslublar jadvali qoralamasi" - #: src/features/resume/public/public-resume.tsx #: src/features/resume/share/link-tab.tsx #: src/features/settings/ai/api-keys.tsx @@ -9049,10 +9041,6 @@ msgstr "" msgid "Your keys, stored encrypted" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Your legacy styles stay active until you activate this Semantic CSS draft." -msgstr "Eski uslublaringiz siz ushbu Semantic CSS qoralamasini faollashtirmaguningizcha amalda qoladi." - #: src/features/ats-checker/messages.ts msgid "Your lines are packed very tightly." msgstr "Sizning chiziqlaringiz juda qattiq o'ralgan." diff --git a/apps/web/locales/vi-VN.po b/apps/web/locales/vi-VN.po index 80439fee0..888507bd7 100644 --- a/apps/web/locales/vi-VN.po +++ b/apps/web/locales/vi-VN.po @@ -738,10 +738,6 @@ msgstr "Tài khoản" msgid "Actions" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Activate Semantic CSS" -msgstr "Kích hoạt CSS ngữ nghĩa" - #: src/features/applications/components/detail/activity.tsx msgid "Activity" msgstr "" @@ -1995,10 +1991,6 @@ msgstr "" msgid "Conversations" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Converted stylesheet draft" -msgstr "Bản nháp bảng định kiểu đã chuyển đổi" - #: src/features/resume/public/public-resume.tsx #: src/features/resume/share/link-tab.tsx #: src/features/settings/ai/api-keys.tsx @@ -9049,10 +9041,6 @@ msgstr "" msgid "Your keys, stored encrypted" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Your legacy styles stay active until you activate this Semantic CSS draft." -msgstr "Các kiểu cũ của bạn vẫn còn hiệu lực cho đến khi bạn kích hoạt bản nháp Semantic CSS này." - #: src/features/ats-checker/messages.ts msgid "Your lines are packed very tightly." msgstr "Đường dây của bạn được đóng gói rất chặt chẽ." diff --git a/apps/web/locales/zh-CN.po b/apps/web/locales/zh-CN.po index ebb9afc41..a35c37dc9 100644 --- a/apps/web/locales/zh-CN.po +++ b/apps/web/locales/zh-CN.po @@ -738,10 +738,6 @@ msgstr "账户" msgid "Actions" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Activate Semantic CSS" -msgstr "启用语义化 CSS" - #: src/features/applications/components/detail/activity.tsx msgid "Activity" msgstr "" @@ -1995,10 +1991,6 @@ msgstr "" msgid "Conversations" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Converted stylesheet draft" -msgstr "已转换的样式表草稿" - #: src/features/resume/public/public-resume.tsx #: src/features/resume/share/link-tab.tsx #: src/features/settings/ai/api-keys.tsx @@ -9049,10 +9041,6 @@ msgstr "" msgid "Your keys, stored encrypted" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Your legacy styles stay active until you activate this Semantic CSS draft." -msgstr "在你启用这份语义化 CSS 草稿之前,原有的样式会继续生效。" - #: src/features/ats-checker/messages.ts msgid "Your lines are packed very tightly." msgstr "你的线路排得很紧。" diff --git a/apps/web/locales/zh-TW.po b/apps/web/locales/zh-TW.po index c48dbae7d..b388768b4 100644 --- a/apps/web/locales/zh-TW.po +++ b/apps/web/locales/zh-TW.po @@ -738,10 +738,6 @@ msgstr "帳戶" msgid "Actions" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Activate Semantic CSS" -msgstr "啟用語意化 CSS" - #: src/features/applications/components/detail/activity.tsx msgid "Activity" msgstr "" @@ -1995,10 +1991,6 @@ msgstr "" msgid "Conversations" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Converted stylesheet draft" -msgstr "已轉換的樣式表草稿" - #: src/features/resume/public/public-resume.tsx #: src/features/resume/share/link-tab.tsx #: src/features/settings/ai/api-keys.tsx @@ -9049,10 +9041,6 @@ msgstr "" msgid "Your keys, stored encrypted" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Your legacy styles stay active until you activate this Semantic CSS draft." -msgstr "在您啟用這份語意化 CSS 草稿之前,原有的樣式會繼續生效。" - #: src/features/ats-checker/messages.ts msgid "Your lines are packed very tightly." msgstr "你的線路排得很緊。" diff --git a/apps/web/locales/zu-ZA.po b/apps/web/locales/zu-ZA.po index a48f256ab..6cd8b5c4c 100644 --- a/apps/web/locales/zu-ZA.po +++ b/apps/web/locales/zu-ZA.po @@ -733,10 +733,6 @@ msgstr "" msgid "Actions" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Activate Semantic CSS" -msgstr "" - #: src/features/applications/components/detail/activity.tsx msgid "Activity" msgstr "" @@ -1990,10 +1986,6 @@ msgstr "" msgid "Conversations" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Converted stylesheet draft" -msgstr "" - #: src/features/resume/public/public-resume.tsx #: src/features/resume/share/link-tab.tsx #: src/features/settings/ai/api-keys.tsx @@ -9044,10 +9036,6 @@ msgstr "" msgid "Your keys, stored encrypted" msgstr "" -#: src/features/resume/stylesheet/legacy-banner.tsx -msgid "Your legacy styles stay active until you activate this Semantic CSS draft." -msgstr "" - #: src/features/ats-checker/messages.ts msgid "Your lines are packed very tightly." msgstr "" diff --git a/apps/web/src/features/resume/stylesheet/editor.test.tsx b/apps/web/src/features/resume/stylesheet/editor.test.tsx index 1a9875ddc..982b70994 100644 --- a/apps/web/src/features/resume/stylesheet/editor.test.tsx +++ b/apps/web/src/features/resume/stylesheet/editor.test.tsx @@ -58,16 +58,6 @@ vi.mock("./worker-client", () => ({ }), })); -const fatalError: SemanticCssDiagnostic = { - code: "VERSION_MISMATCH", - severity: "error", - message: "Version mismatch", - range: { - start: { line: 2, column: 3, offset: 17 }, - end: { line: 2, column: 9, offset: 23 }, - }, -}; - const guideName = /read the applying custom styles guide.*opens in new tab/i; const expectGuideLink = (root: HTMLElement) => { @@ -294,7 +284,6 @@ describe("StylesheetEditorShell", () => { , ); - expect(screen.queryByRole("button", { name: /activate semantic css/i })).not.toBeInTheDocument(); expect(screen.queryByRole("button", { name: /save|apply/i })).not.toBeInTheDocument(); }); @@ -321,7 +310,7 @@ describe("StylesheetEditorShell", () => { expect(builder.data.metadata.stylesheet.source.text).toBe("name { color: blue; }\n"); }); - it("switches a converted legacy draft through the ordinary resume update", async () => { + it("writes a first edit to a resume without a stylesheet as Semantic CSS", () => { render( @@ -329,35 +318,17 @@ describe("StylesheetEditorShell", () => { , ); + const view = EditorView.findFromDOM(screen.getByRole("textbox", { name: "Semantic CSS stylesheet" })); + if (!view) throw new Error("Missing editor view"); - const activate = await screen.findByRole("button", { name: "Activate Semantic CSS" }); - await waitFor(() => expect(activate).toBeEnabled()); - fireEvent.click(activate); + act(() => view.dispatch({ changes: { from: 0, insert: "name { color: blue; }\n" } })); expect(builder.data?.metadata.stylesheet).toEqual({ mode: "semantic", - source: { languageVersion: 1, text: "" }, + source: { languageVersion: 1, text: "name { color: blue; }\n" }, }); }); - it("does not block legacy activation on compiler errors", async () => { - compileWorker.diagnostics = [fatalError]; - - render( - - - - - , - ); - - const activate = await screen.findByRole("button", { name: "Activate Semantic CSS" }); - expect(activate).toBeEnabled(); - fireEvent.click(activate); - - expect(builder.data?.metadata.stylesheet?.mode).toBe("semantic"); - }); - it("makes editor mutation controls read-only while the resume is locked", () => { builder.isLocked = true; builder.canUndo = true; @@ -375,7 +346,6 @@ describe("StylesheetEditorShell", () => { "contenteditable", "false", ); - expect(screen.getByRole("button", { name: "Activate Semantic CSS" })).toBeDisabled(); expect(screen.getByRole("button", { name: "Undo stylesheet edit" })).toBeDisabled(); expect(screen.getByRole("button", { name: "Redo stylesheet edit" })).toBeDisabled(); expect(screen.getByRole("button", { name: "Format stylesheet" })).toBeDisabled(); @@ -397,7 +367,6 @@ describe("StylesheetEditorShell", () => { const sheet = await screen.findByRole("dialog"); expect(within(sheet).getByRole("heading", { name: "Semantic CSS stylesheet" })).toBeInTheDocument(); - expect(within(sheet).getByRole("button", { name: "Activate Semantic CSS" })).toBeInTheDocument(); expect(within(sheet).getByRole("toolbar", { name: "Stylesheet editor" })).toBeInTheDocument(); expectGuideLink(sheet); expect(document.querySelectorAll(".cm-editor")).toHaveLength(1); diff --git a/apps/web/src/features/resume/stylesheet/editor.tsx b/apps/web/src/features/resume/stylesheet/editor.tsx index 4f4a709d9..ce8dfbe4f 100644 --- a/apps/web/src/features/resume/stylesheet/editor.tsx +++ b/apps/web/src/features/resume/stylesheet/editor.tsx @@ -20,7 +20,6 @@ import { tags } from "@lezer/highlight"; import { t } from "@lingui/core/macro"; import { Trans } from "@lingui/react/macro"; import { useCallback, useEffect, useMemo, useRef, useState } from "react"; -import { convertLegacyStyleRules } from "@reactive-resume/pdf/semantic-legacy"; import { buildSemanticTree, getTemplateSemanticManifest, @@ -43,7 +42,6 @@ import { } from "./editor-extensions"; import { formatEditorDocument } from "./formatter"; import { matchedNodeKeys } from "./highlight"; -import { LegacyStylesheetBanner } from "./legacy-banner"; import { listStyleTargets, styleTargetFor } from "./targets"; import { StylesheetToolbar } from "./toolbar"; import { createCompileWorkerClient } from "./worker-client"; @@ -430,10 +428,10 @@ function StylesheetEditorShell({ readOnly = false }: StylesheetEditorShellProps) return () => client.destroy(); }, []); const stylesheet = data?.metadata.stylesheet; - const mode = stylesheet?.mode ?? "legacy"; const source = useMemo( - () => stylesheet?.source ?? (data ? convertLegacyStyleRules(data).source : { languageVersion: 1, text: "" }), - [data, stylesheet], + // Resumes reach the builder with legacy rules already converted (the API does it), so there is one stylesheet. + () => stylesheet?.source ?? { languageVersion: 1, text: "" }, + [stylesheet], ); const metadata = useMemo(() => (data ? createEditorMetadata(data) : emptyMetadata), [data]); const disabled = readOnly || isLocked; @@ -503,14 +501,7 @@ function StylesheetEditorShell({ readOnly = false }: StylesheetEditorShellProps) const setSourceText = (next: string) => { if (disabled || next === text) return; updateResumeData((draft) => { - draft.metadata.stylesheet = { mode, source: { ...source, text: next } }; - }); - }; - - const activate = () => { - if (disabled || mode === "semantic") return; - updateResumeData((draft) => { - draft.metadata.stylesheet = { mode: "semantic", source }; + draft.metadata.stylesheet = { mode: "semantic", source: { ...source, text: next } }; }); }; @@ -536,8 +527,6 @@ function StylesheetEditorShell({ readOnly = false }: StylesheetEditorShellProps) ); const editorChrome = (
- {mode === "legacy" && } - - - - Converted stylesheet draft - - -

- Your legacy styles stay active until you activate this Semantic CSS draft. -

- -
- - ); -} diff --git a/apps/web/src/routes/builder/$resumeId/-sidebar/right/sections/design.tsx b/apps/web/src/routes/builder/$resumeId/-sidebar/right/sections/design.tsx index 1c7c7270e..9b4425bbc 100644 --- a/apps/web/src/routes/builder/$resumeId/-sidebar/right/sections/design.tsx +++ b/apps/web/src/routes/builder/$resumeId/-sidebar/right/sections/design.tsx @@ -6,7 +6,6 @@ import { useStore } from "@tanstack/react-form"; import { AnimatePresence, m } from "motion/react"; import { colorDesignSchema, levelDesignSchema } from "@reactive-resume/schema/resume/data"; import { resolveLevelDisplaySizes } from "@reactive-resume/schema/resume/level-display-sizes"; -import { resolveStyleRuleFontSize } from "@reactive-resume/schema/resume/style-rules"; import { FormControl, FormItem, FormLabel, FormMessage } from "@reactive-resume/ui/components/form"; import { Input } from "@reactive-resume/ui/components/input"; import { Separator } from "@reactive-resume/ui/components/separator"; @@ -235,12 +234,8 @@ function LevelSectionForm() { const previewType = useStore(form.store, (s) => s.values.type); const previewIcon = useStore(form.store, (s) => s.values.icon); - const iconFontSize = resolveStyleRuleFontSize(resume.data, { slot: "icon" }); - const levelFontSize = resolveStyleRuleFontSize(resume.data, { slot: "level" }); const { decorationSize, levelIconExplicitSize } = resolveLevelDisplaySizes({ bodyFontSize: resume.data.metadata.typography.body.fontSize, - iconFontSize, - levelFontSize, }); return ( diff --git a/packages/pdf/src/document.tsx b/packages/pdf/src/document.tsx index d1add08ca..ab823fc28 100644 --- a/packages/pdf/src/document.tsx +++ b/packages/pdf/src/document.tsx @@ -10,7 +10,7 @@ import { Document } from "#react-pdf-renderer"; import { RenderProvider } from "./context"; import { resolvePdfFonts, resumeContentContainsCJK, resumeContentScripts } from "./hooks/use-register-fonts"; import { SemanticRenderProvider } from "./semantic/context"; -import { resolveResumeRuntime, resolveStylesheetMode } from "./semantic/resolve"; +import { resolveResumeRuntime } from "./semantic/resolve"; import { getTemplatePage } from "./templates"; import { shouldShowResumeHeader } from "./templates/shared/cover-letter"; import { getTemplatePageMinHeightStyle, getTemplatePageSize } from "./templates/shared/page-size"; @@ -63,17 +63,14 @@ export const ResumeDocument = ({ () => (renderOptions ? { ...resumeData, renderOptions } : resumeData), [resumeData, renderOptions], ); - const stylesheetMode = resolveStylesheetMode(resumeData); // The tree is built with the render options, so a letter printed with its header keeps it. const runtime = useMemo( - () => semanticRuntime ?? resolveResumeRuntime({ data: headerResumeData, template, mode: stylesheetMode }), - [headerResumeData, semanticRuntime, stylesheetMode, template], + () => semanticRuntime ?? resolveResumeRuntime({ data: headerResumeData, template }), + [headerResumeData, semanticRuntime, template], ); - const semanticMode = semanticRuntime ? "semantic" : stylesheetMode; return ( diff --git a/packages/pdf/src/semantic/all-templates-presentation.test.ts b/packages/pdf/src/semantic/all-templates-presentation.test.ts index 9efef2cbf..3b0102b56 100644 --- a/packages/pdf/src/semantic/all-templates-presentation.test.ts +++ b/packages/pdf/src/semantic/all-templates-presentation.test.ts @@ -16,7 +16,6 @@ describe("Semantic CSS all-template presentation", () => { data, template, source: comprehensiveStylesheet, - mode: "semantic", }); expect(runtime.diagnostics.filter(({ severity }) => severity === "error")).toEqual([]); @@ -35,7 +34,6 @@ describe("Semantic CSS all-template presentation", () => { data, template, source: comprehensiveStylesheet, - mode: "semantic", }); const templateParts = new Set(); diff --git a/packages/pdf/src/semantic/combined-field-bindings.test.tsx b/packages/pdf/src/semantic/combined-field-bindings.test.tsx index a1894e274..621a4501c 100644 --- a/packages/pdf/src/semantic/combined-field-bindings.test.tsx +++ b/packages/pdf/src/semantic/combined-field-bindings.test.tsx @@ -36,7 +36,7 @@ const findTexts = (node: HostNode, text: string): HostNode[] => [ ...(node.children ?? []).flatMap((child) => findTexts(child, text)), ]; -const fixture = (mode: "legacy" | "semantic", section: "experience" | "education", rule = ""): ResumeData => { +const fixture = (section: "experience" | "education", rule = ""): ResumeData => { const data = structuredClone(defaultResumeData); data.picture.hidden = true; data.basics.name = "Ada Lovelace"; @@ -69,10 +69,7 @@ const fixture = (mode: "legacy" | "semantic", section: "experience" | "education }, ]; data.metadata.layout.pages = [{ fullWidth: true, main: [section], sidebar: [] }]; - if (mode === "semantic") { - const stylesheet = { languageVersion: 1, text: `@version 1; ${rule}` }; - data.metadata.stylesheet = { mode, source: stylesheet }; - } + data.metadata.stylesheet = { mode: "semantic", source: { languageVersion: 1, text: `@version 1; ${rule}` } }; return data; }; @@ -83,14 +80,6 @@ const renderHost = async (template: Template, data: ResumeData): Promise => { - const renderer = await vi.importActual("../forme/testing"); - const element = createElement(ResumeDocument, { data, template }) as unknown as Parameters< - typeof renderer.renderToBuffer - >[0]; - return new Uint8Array(await renderer.renderToBuffer(element)); -}; - const rasterizeFirstPage = async (bytes: Uint8Array): Promise => { const document = await getDocument({ data: bytes }).promise; const page = await document.getPage(1); @@ -197,8 +186,8 @@ describe("combined PDF field bindings", () => { combined-text { color: #334455; font-size: 14pt; opacity: 0.6; margin-left: 3pt; } field[name="degree"] { opacity: 0.4; } `; - const onyxData = fixture("semantic", "education", semanticRule); - const meowthData = fixture("semantic", "education", semanticRule); + const onyxData = fixture("education", semanticRule); + const meowthData = fixture("education", semanticRule); const onyxTree = buildSemanticTree({ data: onyxData, template: "onyx", @@ -274,9 +263,9 @@ describe("combined PDF field bindings", () => { field[name="grade"] { color: #550000; } field[name="period"] { color: #660000; } `; - const experience = await renderHost("meowth", fixture("semantic", "experience", colors)); - const inlineEducation = await renderHost("meowth", fixture("semantic", "education", colors)); - const splitEducation = await renderHost("onyx", fixture("semantic", "education", colors)); + const experience = await renderHost("meowth", fixture("experience", colors)); + const inlineEducation = await renderHost("meowth", fixture("education", colors)); + const splitEducation = await renderHost("onyx", fixture("education", colors)); expect(nodeText(experience)).toContain("Engineer (London)"); expectColor(experience, "Engineer", "#110000"); @@ -299,7 +288,6 @@ describe("combined PDF field bindings", () => { it("uses the promoted single field's real semantic key", async () => { const experienceData = fixture( - "semantic", "experience", 'field[name="period"] { color: #660000; } field[name="location"] { color: #220000; }', ); @@ -308,7 +296,6 @@ describe("combined PDF field bindings", () => { experience.location = ""; const educationData = fixture( - "semantic", "education", 'field[name="period"] { color: #660000; } field[name="degree"] { color: #440000; }', ); @@ -325,11 +312,7 @@ describe("combined PDF field bindings", () => { it("keeps non-inheritable split-field styles on their final field hosts", async () => { const document = await renderHost( "meowth", - fixture( - "semantic", - "experience", - 'field[name="position"] { opacity: 0.6; } field[name="location"] { margin-left: 3pt; }', - ), + fixture("experience", 'field[name="position"] { opacity: 0.6; } field[name="location"] { margin-left: 3pt; }'), ); const combined = findTexts(document, "Engineer (London)"); const position = findTexts(document, "Engineer"); @@ -342,7 +325,7 @@ describe("combined PDF field bindings", () => { }); it("publishes one existing Text binding for every split field key", () => { - const data = fixture("semantic", "education"); + const data = fixture("education"); const tree = buildSemanticTree({ data, template: "meowth", @@ -361,20 +344,6 @@ describe("combined PDF field bindings", () => { ); }); - it.each([ - ["meowth", "experience"], - ["meowth", "education"], - ["onyx", "education"], - ] as const)( - "keeps the real %s %s section raster-identical between legacy and empty semantic mode", - async (template, section) => { - const legacy = await rasterizeFirstPage(await renderPdf(template, fixture("legacy", section))); - const semantic = await rasterizeFirstPage(await renderPdf(template, fixture("semantic", section))); - - expect(semantic.equals(legacy)).toBe(true); - }, - ); - it.each([ { name: "Meowth experience position and location", diff --git a/packages/pdf/src/semantic/context.tsx b/packages/pdf/src/semantic/context.tsx index d79c5eaae..4b1d617db 100644 --- a/packages/pdf/src/semantic/context.tsx +++ b/packages/pdf/src/semantic/context.tsx @@ -1,5 +1,4 @@ import type { SemanticNode } from "@reactive-resume/resume/stylesheet"; -import type { StylesheetMode } from "@reactive-resume/schema/resume/stylesheet"; import type { ReactNode } from "react"; import type { ResolvedPdfNodePresentation } from "./adapter"; import { createContext, use, useMemo } from "react"; @@ -9,7 +8,6 @@ export type ResolvedResumePresentation = Readonly; sourceNodeKeys: ReadonlySet; renderedChildKeys: ReadonlyMap; @@ -61,7 +58,6 @@ const indexRenderTree = (root: SemanticNode) => { export function SemanticRenderProvider({ presentation, - mode, sourceTree, renderTree, children, @@ -80,8 +76,8 @@ export function SemanticRenderProvider({ [sourceNodes], ); const value = useMemo( - () => ({ presentation, mode, sourceNodeKeys, sourceChildKeys, sourceNodes, ...treeIndex }), - [mode, presentation, sourceChildKeys, sourceNodeKeys, sourceNodes, treeIndex], + () => ({ presentation, sourceNodeKeys, sourceChildKeys, sourceNodes, ...treeIndex }), + [presentation, sourceChildKeys, sourceNodeKeys, sourceNodes, treeIndex], ); return {children}; } @@ -92,11 +88,9 @@ export function useResolvedNode(nodeKey: string | undefined): ResolvedPdfNodePre return context.presentation[nodeKey] ?? EMPTY_NODE; } -export const useSemanticRenderMode = (): StylesheetMode => use(SemanticRenderContext)?.mode ?? "legacy"; - export const useSemanticNodeVisible = (nodeKey: string | undefined): boolean => { const context = use(SemanticRenderContext); - if (context?.mode !== "semantic" || !nodeKey) return true; + if (!context || !nodeKey) return true; return context.renderedNodeKeys.has(nodeKey); }; @@ -107,7 +101,7 @@ export const useSemanticNodeExists = (nodeKey: string | undefined): boolean => { export const useRenderedChildKeys = (nodeKey: string | undefined): readonly string[] | undefined => { const context = use(SemanticRenderContext); - if (context?.mode !== "semantic" || !nodeKey) return undefined; + if (!context || !nodeKey) return undefined; const rendered = context.renderedChildKeys.get(nodeKey) ?? []; const source = context.sourceChildKeys.get(nodeKey) ?? []; return rendered.length === source.length && rendered.every((key, index) => key === source[index]) @@ -142,7 +136,7 @@ export const useSemanticSectionNodeKey = (pageNodeKey: string, sectionId: string export const useRenderedSectionIds = (pageNodeKey: string, authoredIds: readonly string[]): string[] => { const context = use(SemanticRenderContext); - if (context?.mode !== "semantic") return [...authoredIds]; + if (!context) return [...authoredIds]; const authored = new Set(authoredIds); return context.sourceNodes @@ -171,11 +165,11 @@ export const useSemanticNodeBindings = () => { return context.presentation[nodeKey] ?? EMPTY_NODE; }, isNodeVisible: (nodeKey: string | undefined): boolean => { - if (context?.mode !== "semantic" || !nodeKey) return true; + if (!context || !nodeKey) return true; return context.renderedNodeKeys.has(nodeKey); }, renderedChildKeysFor: (nodeKey: string | undefined): readonly string[] | undefined => { - if (context?.mode !== "semantic" || !nodeKey) return undefined; + if (!context || !nodeKey) return undefined; const rendered = context.renderedChildKeys.get(nodeKey) ?? []; const source = context.sourceChildKeys.get(nodeKey) ?? []; return rendered.length === source.length && rendered.every((key, index) => key === source[index]) diff --git a/packages/pdf/src/semantic/index.ts b/packages/pdf/src/semantic/index.ts index 2e65dc41f..1b71895a9 100644 --- a/packages/pdf/src/semantic/index.ts +++ b/packages/pdf/src/semantic/index.ts @@ -6,6 +6,5 @@ export * from "./legacy-converter"; export { resolveResumePresentation, resolveResumeRuntime, - resolveStylesheetMode, } from "./resolve"; export * from "./tree"; diff --git a/packages/pdf/src/semantic/issue-fixtures.test.tsx b/packages/pdf/src/semantic/issue-fixtures.test.tsx index 836caf0a6..6d129fa09 100644 --- a/packages/pdf/src/semantic/issue-fixtures.test.tsx +++ b/packages/pdf/src/semantic/issue-fixtures.test.tsx @@ -6,7 +6,7 @@ import { defaultResumeData } from "@reactive-resume/schema/resume/default"; import { ResumeDocument } from "../document"; import { pdf } from "../forme/testing"; import { semanticNodeKeys } from "./node-keys"; -import { resolveResumePresentation, resolveStylesheetMode } from "./resolve"; +import { resolveResumePresentation } from "./resolve"; const source = (text: string) => ({ languageVersion: 1, text }); @@ -100,7 +100,6 @@ const resolveIssueFixture = (text: string) => { data, template: "onyx", source: source(text), - mode: "semantic", }); }; @@ -148,7 +147,6 @@ describe("semantic issue fixtures", () => { data, template: "onyx", source: source(`@version 1;${text}`), - mode: "semantic", }); expect(resolve("contact-item { color: red; } link { color: blue; }")[contact]?.style?.color).toBe("blue"); @@ -185,26 +183,6 @@ describe("semantic issue fixtures", () => { expect(presentation[company]?.style?.fontWeight).not.toBe("400"); }); - it("never applies legacy and semantic custom styles together", () => { - const semanticData = buildIssueFixture(); - semanticData.metadata.stylesheet = { - mode: "semantic", - source: source("@version 1;"), - }; - const legacyData = buildIssueFixture(); - - expect(resolveStylesheetMode(semanticData)).toBe("semantic"); - expect(resolveStylesheetMode(legacyData)).toBe("legacy"); - expect( - resolveResumePresentation({ - data: legacyData, - template: "onyx", - source: source("@version 1; name { color: red; }"), - mode: "legacy", - }), - ).toEqual({}); - }); - it("applies issue-regression styles to the final existing PDF primitives", async () => { const data = buildIssueFixture(); const stylesheet = source(` diff --git a/packages/pdf/src/semantic/item-header-binding.test.tsx b/packages/pdf/src/semantic/item-header-binding.test.tsx index e20a9f81c..02b28ddf7 100644 --- a/packages/pdf/src/semantic/item-header-binding.test.tsx +++ b/packages/pdf/src/semantic/item-header-binding.test.tsx @@ -58,7 +58,6 @@ const renderHeaderBoxes = async (template: Template): Promise => { const semanticRuntime = resolveResumeRuntime({ data, template, - mode: "semantic", source: { languageVersion: 1, text: STYLESHEET }, }); const element = createElement(ResumeDocument, { data, template, semanticRuntime }) as unknown as Parameters< diff --git a/packages/pdf/src/semantic/item-header-row.test.tsx b/packages/pdf/src/semantic/item-header-row.test.tsx index 737d9971f..df75590f3 100644 --- a/packages/pdf/src/semantic/item-header-row.test.tsx +++ b/packages/pdf/src/semantic/item-header-row.test.tsx @@ -65,7 +65,7 @@ const buildFixture = (): ResumeData => { const renderTitleRowStyles = async (template: Template, stylesheet?: string) => { const data = buildFixture(); const semanticRuntime = stylesheet - ? resolveResumeRuntime({ data, template, mode: "semantic", source: { languageVersion: 1, text: stylesheet } }) + ? resolveResumeRuntime({ data, template, source: { languageVersion: 1, text: stylesheet } }) : undefined; const element = createElement(ResumeDocument, { data, template, semanticRuntime }) as unknown as Parameters< typeof pdf diff --git a/packages/pdf/src/semantic/legacy-render-parity.test.tsx b/packages/pdf/src/semantic/legacy-adoption-render.test.tsx similarity index 62% rename from packages/pdf/src/semantic/legacy-render-parity.test.tsx rename to packages/pdf/src/semantic/legacy-adoption-render.test.tsx index c4c15767d..273051ff2 100644 --- a/packages/pdf/src/semantic/legacy-render-parity.test.tsx +++ b/packages/pdf/src/semantic/legacy-adoption-render.test.tsx @@ -159,94 +159,60 @@ const render = async (data: ResumeData, template: Template): Promise return new Uint8Array(await renderToBuffer(document)); }; -const semanticData = (data: ResumeData): ResumeData => { +// What the API stores on read/write: the legacy rules converted into the resume's Semantic CSS stylesheet. +const adopt = (data: ResumeData): ResumeData => { const conversion = convertLegacyStyleRules(data); - const semantic = structuredClone(data); - semantic.metadata.styleRules = [...conversion.sanitizedRules]; - semantic.metadata.stylesheet = { mode: "semantic", source: conversion.source }; - return semantic; + const adopted = structuredClone(data); + adopted.metadata.styleRules = [...conversion.sanitizedRules]; + adopted.metadata.stylesheet = { mode: "semantic", source: conversion.source }; + return adopted; }; -type RasterComparison = { - pixelDiffRatio: number; - mismatches: readonly string[]; -}; - -const comparePdfRasters = async (legacy: Uint8Array, semantic: Uint8Array): Promise => { - const legacyPages = await rasterizePdf(legacy); - const semanticPages = await rasterizePdf(semantic); +const comparePdfRasters = async (before: Uint8Array, after: Uint8Array): Promise => { + const beforePages = await rasterizePdf(before); + const afterPages = await rasterizePdf(after); const mismatches: string[] = []; - if (legacyPages.length !== semanticPages.length) { - mismatches.push(`page count: legacy=${legacyPages.length} semantic=${semanticPages.length}`); + if (beforePages.length !== afterPages.length) { + mismatches.push(`page count: ${beforePages.length} -> ${afterPages.length}`); } - - let changed = 0; - let pixels = 0; - for (const [index, legacyPage] of legacyPages.entries()) { - const semanticPage = semanticPages[index]; - if (!semanticPage) continue; - if (semanticPage.width !== legacyPage.width || semanticPage.height !== legacyPage.height) { - mismatches.push( - `page ${index + 1} dimensions: legacy=${legacyPage.width}x${legacyPage.height} semantic=${semanticPage.width}x${semanticPage.height}`, - ); + for (const [index, beforePage] of beforePages.entries()) { + const afterPage = afterPages[index]; + if (!afterPage) continue; + if (afterPage.width !== beforePage.width || afterPage.height !== beforePage.height) { + mismatches.push(`page ${index + 1} dimensions changed`); continue; } - const changedOnPage = pixelmatch( - legacyPage.data, - semanticPage.data, - undefined, - legacyPage.width, - legacyPage.height, - { threshold: 0 }, - ); - if (changedOnPage > 0) { - mismatches.push(`page ${index + 1} pixels: changed=${changedOnPage}/${legacyPage.width * legacyPage.height}`); - } - changed += changedOnPage; - pixels += legacyPage.width * legacyPage.height; + const changed = pixelmatch(beforePage.data, afterPage.data, undefined, beforePage.width, beforePage.height, { + threshold: 0, + }); + if (changed > 0) mismatches.push(`page ${index + 1} pixels: changed=${changed}`); } - return { pixelDiffRatio: pixels === 0 ? (mismatches.length > 0 ? 1 : 0) : changed / pixels, mismatches }; + return mismatches; }; -describe("legacy activation raster parity", () => { - it.each(fixtureNames)( - "has zero real-PDF pixel drift for %s", - async (fixture) => { - const legacy = buildFixture(readRules(fixture)); - const semantic = semanticData(legacy); +// Rules with no visible effect on this fixture: disabled, or restating the award title's existing weight. +const noOpFixtures = new Set(["award-unbold", "disabled-rules"]); - expect(await comparePdfRasters(await render(legacy, "onyx"), await render(semantic, "onyx"))).toEqual({ - pixelDiffRatio: 0, - mismatches: [], - }); +// Unconverted rules no longer render, so the fixture itself is the unstyled baseline. +const drift = async (data: ResumeData, template: Template) => + comparePdfRasters(await render(data, template), await render(adopt(data), template)); + +describe("adopted legacy rules in the rendered PDF", () => { + it.each(fixtureNames)( + "renders the converted %s stylesheet", + async (fixture) => { + const mismatches = await drift(buildFixture(readRules(fixture)), "onyx"); + + if (noOpFixtures.has(fixture)) expect(mismatches).toEqual([]); + else expect(mismatches).not.toEqual([]); }, 30_000, ); it.each(templates)( - "smoke-renders %s without activation pixel drift", + "renders the converted smoke stylesheet on %s", async (template) => { - const legacy = buildFixture(readRules("all-templates-smoke")); - const semantic = semanticData(legacy); - - expect(await comparePdfRasters(await render(legacy, template), await render(semantic, template))).toEqual({ - pixelDiffRatio: 0, - mismatches: [], - }); - }, - 30_000, - ); - - it.each(["onyx", "meowth"] as const)( - "has zero combined-separator and box-style pixel drift on %s", - async (template) => { - const legacy = buildFixture(readRules("combined-text-host")); - const semantic = semanticData(legacy); - - expect(await comparePdfRasters(await render(legacy, template), await render(semantic, template))).toEqual({ - pixelDiffRatio: 0, - mismatches: [], - }); + expect(await drift(buildFixture(readRules("all-templates-smoke")), template)).not.toEqual([]); }, 30_000, ); diff --git a/packages/pdf/src/semantic/link-fidelity.test.tsx b/packages/pdf/src/semantic/link-fidelity.test.tsx index 4771d6fbd..536b1e293 100644 --- a/packages/pdf/src/semantic/link-fidelity.test.tsx +++ b/packages/pdf/src/semantic/link-fidelity.test.tsx @@ -15,7 +15,7 @@ type HostNode = { const emptyStylesheet = { languageVersion: 1, text: "@version 1;" }; const buildFixture = ( - mode: "missing" | "legacy" | "semantic", + mode: "missing" | "semantic", hideLinkUnderline: boolean, text = emptyStylesheet.text, ): ResumeData => { @@ -58,8 +58,6 @@ describe("PDF link decoration fidelity", () => { it.each([ ["missing", false, "underline"], ["missing", true, "none"], - ["legacy", false, "underline"], - ["legacy", true, "none"], ["semantic", false, "underline"], ["semantic", true, "none"], ] as const)("%s stylesheet with hideLinkUnderline=%s resolves to %s", async (mode, hidden, expected) => { diff --git a/packages/pdf/src/semantic/no-wrapper.test.tsx b/packages/pdf/src/semantic/no-wrapper.test.tsx index 61fd09f5c..5cd2ead6a 100644 --- a/packages/pdf/src/semantic/no-wrapper.test.tsx +++ b/packages/pdf/src/semantic/no-wrapper.test.tsx @@ -23,7 +23,7 @@ const semanticSource = (text = "@version 1;\n") => ({ text, }); -const buildFixture = (mode: "legacy" | "semantic"): ResumeData => { +const buildFixture = (withStylesheet: boolean): ResumeData => { const data = structuredClone(sampleResumeData); data.picture.hidden = true; data.basics.name = "Ada Lovelace"; @@ -49,9 +49,9 @@ const buildFixture = (mode: "legacy" | "semantic"): ResumeData => { sidebar: ["skills", "languages"], }, ]; - if (mode === "semantic") { + if (withStylesheet) { data.metadata.stylesheet = { - mode, + mode: "semantic", source: semanticSource(), }; } @@ -74,9 +74,9 @@ const textValues = (node: HostNode): string[] => [ ...(node.children ?? []).flatMap((child) => textValues(child)), ]; -describe("semantic PDF bindings do not add layout wrappers", () => { +describe("resumes without a stylesheet render like an empty stylesheet", () => { it("uses a split-page fixture with chrome, ordinary sections, rich lists, and levels", () => { - const data = buildFixture("legacy"); + const data = buildFixture(false); expect(data.metadata.layout.pages[0]).toMatchObject({ fullWidth: false, @@ -93,11 +93,11 @@ describe("semantic PDF bindings do not add layout wrappers", () => { it.each(templateSchema.options)( "%s preserves primitive type, count, and order for an empty stylesheet", async (template) => { - const legacy = await renderHostTree(buildFixture("legacy"), template); - const semantic = await renderHostTree(buildFixture("semantic"), template); + const missing = await renderHostTree(buildFixture(false), template); + const empty = await renderHostTree(buildFixture(true), template); - expect(textValues(semantic)).toEqual(textValues(legacy)); - expect(primitiveTypes(semantic)).toEqual(primitiveTypes(legacy)); + expect(textValues(empty)).toEqual(textValues(missing)); + expect(primitiveTypes(empty)).toEqual(primitiveTypes(missing)); }, ); }); diff --git a/packages/pdf/src/semantic/pagination-cancellation.test.tsx b/packages/pdf/src/semantic/pagination-cancellation.test.tsx index 111ecc2a0..9f8e0cb99 100644 --- a/packages/pdf/src/semantic/pagination-cancellation.test.tsx +++ b/packages/pdf/src/semantic/pagination-cancellation.test.tsx @@ -70,7 +70,7 @@ describe("semantic pagination cancellation", () => { ["revert", true, false], ] as const)("maps %s over builder pagination to explicit break=%s and wrap=%s", (value, breakBefore, wrap) => { const data = buildFixture(value); - const presentation = resolveResumePresentation({ data, template: "onyx", mode: "semantic" }); + const presentation = resolveResumePresentation({ data, template: "onyx" }); const sectionKey = semanticNodeKeys.section(semanticNodeKeys.region(semanticNodeKeys.page(1), "main"), "summary"); expect(presentation[sectionKey]).toMatchObject({ break: breakBefore, wrap }); diff --git a/packages/pdf/src/semantic/public.test.ts b/packages/pdf/src/semantic/public.test.ts index 19c4c7636..b997bf882 100644 --- a/packages/pdf/src/semantic/public.test.ts +++ b/packages/pdf/src/semantic/public.test.ts @@ -7,7 +7,7 @@ describe("@reactive-resume/pdf/semantic", () => { const data = structuredClone(sampleResumeData); data.metadata.stylesheet = { mode: "semantic", source: { languageVersion: 2, text: "@version 2;" } }; - const inspection = resolveResumeRuntime({ data, template: data.metadata.template, mode: "semantic" }); + const inspection = resolveResumeRuntime({ data, template: data.metadata.template }); expect(inspection.diagnostics).toContainEqual( expect.objectContaining({ code: "UNSUPPORTED_VERSION", severity: "error" }), @@ -23,7 +23,7 @@ describe("@reactive-resume/pdf/semantic", () => { source: { languageVersion: 1, text: `@version 1;\n${selectors} { color: red; }` }, }; - const inspection = resolveResumeRuntime({ data, template: data.metadata.template, mode: "semantic" }); + const inspection = resolveResumeRuntime({ data, template: data.metadata.template }); expect(inspection.diagnostics).toContainEqual( expect.objectContaining({ code: "RESOURCE_LIMIT", severity: "error" }), @@ -42,7 +42,7 @@ describe("@reactive-resume/pdf/semantic", () => { }, }; - const inspection = resolveResumeRuntime({ data, template: data.metadata.template, mode: "semantic" }); + const inspection = resolveResumeRuntime({ data, template: data.metadata.template }); expect(inspection.presentation["page-1/region-header/header/name"]?.style?.color).toBe("#123456"); expect(inspection.diagnostics).toContainEqual( diff --git a/packages/pdf/src/semantic/resolve.ts b/packages/pdf/src/semantic/resolve.ts index a88becb29..cae5394f1 100644 --- a/packages/pdf/src/semantic/resolve.ts +++ b/packages/pdf/src/semantic/resolve.ts @@ -1,6 +1,6 @@ import type { ResolveStylesheetResult, SemanticCssDiagnostic, SemanticNode } from "@reactive-resume/resume/stylesheet"; import type { ResumeData } from "@reactive-resume/schema/resume/data"; -import type { StylesheetMode, StylesheetSource } from "@reactive-resume/schema/resume/stylesheet"; +import type { StylesheetSource } from "@reactive-resume/schema/resume/stylesheet"; import type { Template } from "@reactive-resume/schema/templates"; import type { ResolvedResumePresentation } from "./context"; import { compileStylesheet, isFatalStylesheetDiagnostic, resolveStylesheet } from "@reactive-resume/resume/stylesheet"; @@ -18,7 +18,6 @@ export type ResolveResumePresentationInput = { data: ResumeData; template: Template; source?: StylesheetSource; - mode: StylesheetMode; }; export type ResolvedResumeRuntime = { @@ -78,20 +77,12 @@ const toPresentation = ( ) as ResolvedResumePresentation; }; -export function resolveStylesheetMode(data: ResumeData): StylesheetMode { - return data.metadata.stylesheet?.mode ?? "legacy"; -} - export function resolveResumeRuntime({ data, template, source, - mode, }: ResolveResumePresentationInput): ResolvedResumeRuntime { const sourceTree = mergeAuthoredPageTrees(data, template); - if (mode !== "semantic") { - return { presentation: EMPTY_PRESENTATION, sourceTree, renderTree: sourceTree, diagnostics: [] }; - } const stylesheetSource = source ?? data.metadata.stylesheet?.source ?? { diff --git a/packages/pdf/src/semantic/rich-text-table.integration.test.tsx b/packages/pdf/src/semantic/rich-text-table.integration.test.tsx index abc997c40..090b0ff62 100644 --- a/packages/pdf/src/semantic/rich-text-table.integration.test.tsx +++ b/packages/pdf/src/semantic/rich-text-table.integration.test.tsx @@ -19,7 +19,7 @@ const table = (paragraphs = false) => ) .join("")}`; -const fixture = (html: string, mode: "legacy" | "semantic", css = ""): ResumeData => { +const fixture = (html: string, css = ""): ResumeData => { const data = structuredClone(defaultResumeData); data.basics.name = "Table probe"; data.picture.hidden = true; @@ -27,7 +27,7 @@ const fixture = (html: string, mode: "legacy" | "semantic", css = ""): ResumeDat data.metadata.layout.pages = [{ fullWidth: true, main: ["summary"], sidebar: [] }]; data.metadata.typography.body.fontFamily = "Helvetica"; data.metadata.typography.heading.fontFamily = "Helvetica"; - data.metadata.stylesheet = { mode, source: { languageVersion: 1, text: `@version 1; ${css}` } }; + data.metadata.stylesheet = { mode: "semantic", source: { languageVersion: 1, text: `@version 1; ${css}` } }; return data; }; @@ -95,96 +95,90 @@ const tableCoordinates = (items: Awaited>["items"]) = describe("imported rich-text tables", () => { for (const template of ["ditgar", "onyx"] as const) { - for (const mode of ["legacy", "semantic"] as const) { - it(`${template} ${mode} preserves bare cell text and row/column positions`, async () => { - const { items } = await readPdf(fixture(table(), mode), template); - const cell = (text: string) => { - const cell = items.find((item) => item.text === text); - if (!cell) throw new Error(`Missing table cell ${text}`); - return cell; - }; - const alpha = cell("Alpha"); - const beta = cell("Beta"); - const gamma = cell("Gamma"); - const delta = cell("Delta"); - const epsilon = cell("Epsilon"); - const zeta = cell("Zeta"); - expect(alpha.y).toBe(beta.y); - expect(alpha.y).toBe(gamma.y); - expect(delta.y).toBe(epsilon.y); - expect(delta.y).toBe(zeta.y); - expect(alpha.y).toBeGreaterThan(delta.y); - expect(alpha.x).toBe(delta.x); - expect(beta.x).toBe(epsilon.x); - expect(gamma.x).toBe(zeta.x); - expect(beta.x).toBeGreaterThan(alpha.x); - expect(gamma.x).toBeGreaterThan(beta.x); - }); - } + it(`${template} preserves bare cell text and row/column positions`, async () => { + const { items } = await readPdf(fixture(table()), template); + const cell = (text: string) => { + const cell = items.find((item) => item.text === text); + if (!cell) throw new Error(`Missing table cell ${text}`); + return cell; + }; + const alpha = cell("Alpha"); + const beta = cell("Beta"); + const gamma = cell("Gamma"); + const delta = cell("Delta"); + const epsilon = cell("Epsilon"); + const zeta = cell("Zeta"); + expect(alpha.y).toBe(beta.y); + expect(alpha.y).toBe(gamma.y); + expect(delta.y).toBe(epsilon.y); + expect(delta.y).toBe(zeta.y); + expect(alpha.y).toBeGreaterThan(delta.y); + expect(alpha.x).toBe(delta.x); + expect(beta.x).toBe(epsilon.x); + expect(gamma.x).toBe(zeta.x); + expect(beta.x).toBeGreaterThan(alpha.x); + expect(gamma.x).toBeGreaterThan(beta.x); + }); } it("preserves table cells containing recognized paragraphs", async () => { - const { items } = await readPdf(fixture(table(true), "semantic"), "ditgar"); + const { items } = await readPdf(fixture(table(true)), "ditgar"); expect(items.map((item) => item.text)).toEqual(expect.arrayContaining(["Alpha", "Beta", "Gamma", "Delta"])); }); it("preserves raw text inside an unrecognized block wrapper", async () => { - const { items } = await readPdf(fixture("
Wrapper content
", "semantic"), "ditgar"); + const { items } = await readPdf(fixture("
Wrapper content
"), "ditgar"); expect(items.map((item) => item.text)).toContain("Wrapper content"); }); it("still honors explicit semantic rich-text hiding", async () => { - const { items } = await readPdf(fixture(table(), "semantic", "rich-text { display: none; }"), "ditgar"); + const { items } = await readPdf(fixture(table(), "rich-text { display: none; }"), "ditgar"); expect(items.map((item) => item.text)).toContain("Table probe"); expect(items.map((item) => item.text)).not.toContain("Alpha"); }); - it.each(["legacy", "semantic"] as const)( - "keeps six cell coordinates, border operators, and fixed-DPI pixels through %s persistence", - async (mode) => { - const bordered = table().replaceAll("black", "#cc00cc"); - const unrelated = fixture(bordered, mode); - unrelated.basics.name = "Border Probe unrelated edit"; - const stages = [ - { name: "original", data: fixture(bordered, mode), expectedBeta: "Beta" }, - { name: "unrelated edit", data: unrelated, expectedBeta: "Beta" }, - { name: "table edit", data: fixture(bordered.replace("Beta", "Beta!"), mode), expectedBeta: "Beta!" }, + it("keeps six cell coordinates, border operators, and fixed-DPI pixels through persistence", async () => { + const bordered = table().replaceAll("black", "#cc00cc"); + const unrelated = fixture(bordered); + unrelated.basics.name = "Border Probe unrelated edit"; + const stages = [ + { name: "original", data: fixture(bordered), expectedBeta: "Beta" }, + { name: "unrelated edit", data: unrelated, expectedBeta: "Beta" }, + { name: "table edit", data: fixture(bordered.replace("Beta", "Beta!")), expectedBeta: "Beta!" }, + ]; + // The first render sets the reference: three equal columns over two rows, with the borders drawn. Neither an + // unrelated edit nor an edit inside a cell may move a cell or change a border. + let reference: { cells: Record; colored: unknown } | undefined; + for (const stage of stages) { + const pdf = await readPdf(stage.data, "ditgar"); + const cells = tableCoordinates(pdf.items); + const { colored } = await inspectTableBorders(pdf); + const cell = (text: string) => { + const [x, y] = cells[text] ?? []; + if (x === undefined || y === undefined) throw new Error(`${stage.name}: missing cell ${text}`); + return { x, y }; + }; + const [alpha, beta, gamma, delta] = ["Alpha", stage.expectedBeta, "Gamma", "Delta"].map(cell) as [ + { x: number; y: number }, + { x: number; y: number }, + { x: number; y: number }, + { x: number; y: number }, ]; - // The first render sets the reference: three equal columns over two rows, with the borders drawn. Neither an - // unrelated edit nor an edit inside a cell may move a cell or change a border. - let reference: { cells: Record; colored: unknown } | undefined; - for (const stage of stages) { - const pdf = await readPdf(stage.data, "ditgar"); - const cells = tableCoordinates(pdf.items); - const { colored } = await inspectTableBorders(pdf); - const cell = (text: string) => { - const [x, y] = cells[text] ?? []; - if (x === undefined || y === undefined) throw new Error(`${stage.name}: missing cell ${text}`); - return { x, y }; - }; - const [alpha, beta, gamma, delta] = ["Alpha", stage.expectedBeta, "Gamma", "Delta"].map(cell) as [ - { x: number; y: number }, - { x: number; y: number }, - { x: number; y: number }, - { x: number; y: number }, - ]; - expect(beta.x - alpha.x, stage.name).toBeCloseTo(gamma.x - beta.x, 1); - expect(beta.y, stage.name).toBe(alpha.y); - expect(delta.x, stage.name).toBe(alpha.x); - expect(delta.y, stage.name).toBeLessThan(alpha.y); - expect((colored as { pixels: number }).pixels, stage.name).toBeGreaterThan(0); - const { [stage.expectedBeta]: _beta, ...rest } = cells; - const comparable = { cells: { ...rest, Beta: [beta.x, beta.y] }, colored }; - if (reference) expect(comparable, stage.name).toEqual(reference); - else reference = comparable; - } - }, - 30_000, - ); + expect(beta.x - alpha.x, stage.name).toBeCloseTo(gamma.x - beta.x, 1); + expect(beta.y, stage.name).toBe(alpha.y); + expect(delta.x, stage.name).toBe(alpha.x); + expect(delta.y, stage.name).toBeLessThan(alpha.y); + expect((colored as { pixels: number }).pixels, stage.name).toBeGreaterThan(0); + const { [stage.expectedBeta]: _beta, ...rest } = cells; + const comparable = { cells: { ...rest, Beta: [beta.x, beta.y] }, colored }; + if (reference) expect(comparable, stage.name).toEqual(reference); + else reference = comparable; + } + }, 30_000); - it.each(["legacy", "semantic"] as const)("keeps borderless tables borderless in %s mode", async (mode) => { + it("keeps borderless tables borderless", async () => { const borderless = table().replaceAll("border: 1pt solid black; ", ""); - const pdf = await readPdf(fixture(borderless, mode), "ditgar"); + const pdf = await readPdf(fixture(borderless), "ditgar"); expect((await inspectTableBorders(pdf)).geometry).toEqual({ horizontal: 0, vertical: 0 }); }); }); diff --git a/packages/pdf/src/semantic/runtime-paths.test.tsx b/packages/pdf/src/semantic/runtime-paths.test.tsx index 490ba0031..b73c8f4d3 100644 --- a/packages/pdf/src/semantic/runtime-paths.test.tsx +++ b/packages/pdf/src/semantic/runtime-paths.test.tsx @@ -57,11 +57,11 @@ const buildFixture = (): ResumeData => { return data; }; -const buildNodeBudgetFixture = (mode: "legacy" | "semantic"): ResumeData => { +const buildNodeBudgetFixture = (): ResumeData => { const data = structuredClone(defaultResumeData); const source = { languageVersion: 1, text: "@version 1;\n" }; data.metadata.layout.pages = [{ fullWidth: true, main: ["skills"], sidebar: [] }]; - data.metadata.stylesheet = { mode, source }; + data.metadata.stylesheet = { mode: "semantic", source }; data.sections.skills.items = Array.from({ length: 2_000 }, (_, index) => ({ id: `skill-${index}`, hidden: false, @@ -128,8 +128,8 @@ describe("browser/server semantic runtime identity", () => { expect(browserProps).toEqual(serverProps); }, 15_000); - it("keeps legacy PDF rendering unaffected by the semantic node budget", async () => { - const data = buildNodeBudgetFixture("legacy"); + it("still renders a resume beyond the semantic node budget", async () => { + const data = buildNodeBudgetFixture(); const blob = await createResumePdfBlob({ data, template: "onyx" }); const file = await createResumePdfFile({ data, filename: "resume.pdf", template: "onyx" }); diff --git a/packages/pdf/src/semantic/sibling-ordering.test.tsx b/packages/pdf/src/semantic/sibling-ordering.test.tsx index f52f4a494..302641345 100644 --- a/packages/pdf/src/semantic/sibling-ordering.test.tsx +++ b/packages/pdf/src/semantic/sibling-ordering.test.tsx @@ -237,7 +237,7 @@ describe("semantic sibling ordering reaches final PDF output", () => { data.metadata.page.locale = locale; data.summary.content = "
  • List content
"; data.metadata.layout.pages = [{ fullWidth: true, main: ["summary"], sidebar: [] }]; - const runtime = resolveResumeRuntime({ data, template: "onyx", mode: "semantic" }); + const runtime = resolveResumeRuntime({ data, template: "onyx" }); const renderedItem = findSemanticNode(runtime.renderTree, (node) => node.kind === "list-item"); expect(runtime.diagnostics.filter(({ severity }) => severity === "error")).toEqual([]); diff --git a/packages/pdf/src/templates/ditgar/DitgarPage.test.tsx b/packages/pdf/src/templates/ditgar/DitgarPage.test.tsx index 1b597415a..c56051d00 100644 --- a/packages/pdf/src/templates/ditgar/DitgarPage.test.tsx +++ b/packages/pdf/src/templates/ditgar/DitgarPage.test.tsx @@ -7,7 +7,6 @@ import { ResumeDocument } from "../../document"; import { renderToBuffer } from "../../forme/testing"; type FixtureOptions = { - mode: "legacy" | "semantic"; columns: number; gapX: number; rtl?: boolean; @@ -19,7 +18,7 @@ type FixtureOptions = { type TextRun = { text: string; x: number; right: number; y: number }; -function fixture({ mode, columns, gapX, rtl, sidebar, longTitle, experience, css = "" }: FixtureOptions): ResumeData { +function fixture({ columns, gapX, rtl, sidebar, longTitle, experience, css = "" }: FixtureOptions): ResumeData { const data = structuredClone(defaultResumeData); data.metadata.typography.body.fontFamily = "Helvetica"; data.metadata.typography.heading.fontFamily = "Helvetica"; @@ -30,7 +29,7 @@ function fixture({ mode, columns, gapX, rtl, sidebar, longTitle, experience, css data.metadata.layout.pages = [ { fullWidth: false, main: sidebar ? [] : [section], sidebar: sidebar ? [section] : [] }, ]; - data.metadata.stylesheet = { mode, source: { languageVersion: 1, text: `@version 1; ${css}` } }; + data.metadata.stylesheet = { mode: "semantic", source: { languageVersion: 1, text: `@version 1; ${css}` } }; data.sections.projects.columns = columns; data.sections.experience.columns = columns; for (let index = 0; index < 3; index++) { @@ -82,29 +81,26 @@ function assertAligned(runs: TextRun[], rtl = false, expectedOffset = 0) { } describe("Ditgar item-header alignment (#3068)", () => { - for (const mode of ["legacy", "semantic"] as const) { - for (const columns of [1, 2]) { - it.each([0, 4, 12])(`aligns ${mode} Projects in ${columns} columns at gapX %i`, async (gapX) => { - assertAligned(await renderText({ mode, columns, gapX })); - }); - } - it(`aligns wrapped ${mode} project titles with their descriptions and links`, async () => { - assertAligned(await renderText({ mode, columns: 2, gapX: 4, longTitle: true })); - }); - it(`aligns the shared ${mode} Experience header`, async () => { - assertAligned(await renderText({ mode, columns: 2, gapX: 4, experience: true })); - }); - it(`preserves ${mode} sidebar alignment`, async () => { - assertAligned(await renderText({ mode, columns: 1, gapX: 4, sidebar: true })); - }); - it(`preserves ${mode} RTL alignment`, async () => { - assertAligned(await renderText({ mode, columns: 2, gapX: 4, rtl: true }), true); + for (const columns of [1, 2]) { + it.each([0, 4, 12])(`aligns Projects in ${columns} columns at gapX %i`, async (gapX) => { + assertAligned(await renderText({ columns, gapX })); }); } + it("aligns wrapped project titles with their descriptions and links", async () => { + assertAligned(await renderText({ columns: 2, gapX: 4, longTitle: true })); + }); + it("aligns the shared Experience header", async () => { + assertAligned(await renderText({ columns: 2, gapX: 4, experience: true })); + }); + it("preserves sidebar alignment", async () => { + assertAligned(await renderText({ columns: 1, gapX: 4, sidebar: true })); + }); + it("preserves RTL alignment", async () => { + assertAligned(await renderText({ columns: 2, gapX: 4, rtl: true }), true); + }); it("retains an authored Semantic CSS header inset", async () => { assertAligned( await renderText({ - mode: "semantic", columns: 2, gapX: 4, css: "item-header { margin-left: 7pt; padding-left: 3pt; border-left: 2pt solid #0000ff; }", diff --git a/packages/pdf/src/templates/gengar/gengar-skills.test.tsx b/packages/pdf/src/templates/gengar/gengar-skills.test.tsx index 812702e6f..841c1a21b 100644 --- a/packages/pdf/src/templates/gengar/gengar-skills.test.tsx +++ b/packages/pdf/src/templates/gengar/gengar-skills.test.tsx @@ -13,7 +13,6 @@ import { rasterizePdf } from "../../semantic/test/rasterize-pdf"; type SkillLayout = "default" | "inline"; type Placement = "main" | "sidebar"; type LevelDesign = "circle" | "rectangle" | "rectangle-full"; -type StylesheetMode = "legacy" | "semantic"; type GengarFixtureOptions = { keywordLayout?: "inline" | "list"; @@ -25,7 +24,6 @@ type GengarFixtureOptions = { proficiency?: string; keywords?: string[]; custom?: boolean; - mode?: StylesheetMode; count?: number; overflow?: boolean; }; @@ -45,7 +43,6 @@ const gengarFixture = ({ proficiency = "Experienced", keywords = ["Alpha", "Beta"], custom = false, - mode = "legacy", count = 1, overflow = false, }: GengarFixtureOptions = {}): ResumeData => { @@ -89,8 +86,6 @@ const gengarFixture = ({ mode: "semantic", source: { languageVersion: 1, text: "@version 1; page { size: 300pt 220pt; }" }, }; - } else if (mode === "semantic") { - data.metadata.stylesheet = { mode, source: { languageVersion: 1, text: "@version 1;" } }; } if (custom) data.customSections = [{ ...section, id: sectionId, type: "skills" }]; else data.sections.skills = section; @@ -125,11 +120,7 @@ describe("Gengar skill rating placement (#2611)", () => { { layout: "default" as const, placement: "main" as const, columns: 2, design: "rectangle-full" as const, level: 5 }, ])("orders name, rating, proficiency, keywords in $layout/$placement/$design", (options) => { const data = gengarFixture(options); - const runtime = resolveResumeRuntime({ - data, - template: "gengar", - mode: options.layout === "inline" ? "semantic" : "legacy", - }); + const runtime = resolveResumeRuntime({ data, template: "gengar" }); const item = required(getSkillItem(runtime)); const level = required(item.children.find((node) => node.kind === "level")); const header = required(item.children.find((node) => node.kind === "item-header")); @@ -143,7 +134,7 @@ describe("Gengar skill rating placement (#2611)", () => { it.each([0, 3, 5])("keeps level %s semantic decorations", (level) => { const data = gengarFixture({ level }); - const runtime = resolveResumeRuntime({ data, template: "gengar", mode: "legacy" }); + const runtime = resolveResumeRuntime({ data, template: "gengar" }); const item = required(getSkillItem(runtime)); const rating = item.children.find((node) => node.kind === "level"); if (level === 0) expect(rating).toBeUndefined(); @@ -153,7 +144,7 @@ describe("Gengar skill rating placement (#2611)", () => { it("hides rating without leaving a rating node or spacing", async () => { const data = gengarFixture({ design: "circle", level: 5 }); data.metadata.design.level = { type: "hidden", icon: "star" }; - const runtime = resolveResumeRuntime({ data, template: "gengar", mode: "semantic" }); + const runtime = resolveResumeRuntime({ data, template: "gengar" }); expect(required(getSkillItem(runtime)).children.map((node) => node.kind)).toEqual([ "item-header", "field", @@ -169,7 +160,7 @@ describe("Gengar skill rating placement (#2611)", () => { it("omits level-zero rating without adding rating spacing and keeps empty proficiency", async () => { const data = gengarFixture({ level: 0, proficiency: "", keywords: ["Short"] }); - const runtime = resolveResumeRuntime({ data, template: "gengar", mode: "legacy" }); + const runtime = resolveResumeRuntime({ data, template: "gengar" }); const item = required(getSkillItem(runtime)); expect(item.children.map((node) => node.kind)).toEqual(["item-header", "field"]); expect(item.children.at(-1)?.attributes.name).toBe("keywords"); @@ -177,9 +168,9 @@ describe("Gengar skill rating placement (#2611)", () => { expect(result.pages.flat().map((item) => item.str)).toContain("Short"); }); - it.each([false, true])("keeps Gengar ordering for %s stylesheet mode", async (semantic) => { - const data = gengarFixture({ mode: semantic ? "semantic" : "legacy", custom: semantic, columns: 1 }); - const runtime = resolveResumeRuntime({ data, template: "gengar", mode: semantic ? "semantic" : "legacy" }); + it.each([false, true])("keeps Gengar ordering for custom=%s Skills", async (custom) => { + const data = gengarFixture({ custom, columns: 1 }); + const runtime = resolveResumeRuntime({ data, template: "gengar" }); const item = required(getSkillItem(runtime)); expect(item.children.map((node) => node.kind)).toEqual(["item-header", "level", "field", "field"]); const result = await renderGengar(data); @@ -204,7 +195,7 @@ describe("Gengar skill rating placement (#2611)", () => { it("keeps long keywords and mixed-height ratings across overflow pages", async () => { const data = gengarFixture({ count: 12, columns: 2, overflow: true, keywords: ["Long keyword"] }); - const runtime = resolveResumeRuntime({ data, template: "gengar", mode: "semantic" }); + const runtime = resolveResumeRuntime({ data, template: "gengar" }); expect(required(getSkillItem(runtime)).children.map((node) => node.kind)).toEqual([ "item-header", "level", @@ -224,7 +215,7 @@ describe("Gengar skill rating placement (#2611)", () => { it("does not change Onyx semantic ordering", () => { const data = gengarFixture(); - const runtime = resolveResumeRuntime({ data, template: "onyx", mode: "legacy" }); + const runtime = resolveResumeRuntime({ data, template: "onyx" }); const item = required(getSkillItem(runtime)); expect(item.children.map((node) => node.kind)).toEqual(["item-header", "field", "field", "level"]); }); diff --git a/packages/pdf/src/templates/shared/context.tsx b/packages/pdf/src/templates/shared/context.tsx index 82378118a..71105391a 100644 --- a/packages/pdf/src/templates/shared/context.tsx +++ b/packages/pdf/src/templates/shared/context.tsx @@ -1,6 +1,4 @@ -import type { StyleSlot } from "@reactive-resume/schema/resume/data"; import type { ReactNode } from "react"; -import type { SectionStyleRuleContext } from "./style-rules"; import type { StyleInput, TemplatePlacement } from "./styles"; import type { SectionTimelineStyleSlots, @@ -13,9 +11,6 @@ import type { TemplateStyleSlots, } from "./types"; import { createContext, use, useMemo } from "react"; -import { useRender } from "../../context"; -import { useSemanticRenderMode } from "../../semantic/context"; -import { resolveStyleRuleSlot } from "./style-rules"; type TemplateContextValue = { styles: TemplateStyleSlots; @@ -37,14 +32,8 @@ type TemplatePlacementProviderProps = { children: ReactNode; }; -type SectionStyleProviderProps = { - context: SectionStyleRuleContext; - children: ReactNode; -}; - const TemplateContext = createContext(null); const TemplatePlacementContext = createContext("main"); -const SectionStyleContext = createContext(null); const resolveStyleSlot = (slot: TemplateStyleSlot | undefined, context: TemplateStyleContextValue): StyleInput => { if (!slot) return undefined; @@ -91,10 +80,6 @@ export const TemplatePlacementProvider = ({ placement, children }: TemplatePlace return {children}; }; -export const SectionStyleProvider = ({ context, children }: SectionStyleProviderProps) => { - return {children}; -}; - const useTemplateContext = () => { const context = use(TemplateContext); @@ -127,16 +112,6 @@ export const useTemplateStyle = (slot: keyof TemplateStyleSlots): StyleInput => return resolveStyleSlot(styles[slot] as TemplateStyleSlot | undefined, context); }; -export const useSectionStyleRule = (slot: StyleSlot): StyleInput => { - const data = useRender(); - const context = use(SectionStyleContext); - const mode = useSemanticRenderMode(); - - if (!context || mode === "semantic") return undefined; - - return resolveStyleRuleSlot(data, { ...context, slot }); -}; - export const useTemplateFeatureStyle = ( feature: keyof TemplateFeatureStyleSlots, slot: keyof SectionTimelineStyleSlots, diff --git a/packages/pdf/src/templates/shared/date-layout.test.tsx b/packages/pdf/src/templates/shared/date-layout.test.tsx index c9174d16e..6c2e15bf4 100644 --- a/packages/pdf/src/templates/shared/date-layout.test.tsx +++ b/packages/pdf/src/templates/shared/date-layout.test.tsx @@ -612,7 +612,7 @@ describe("date layout characterization (#3155, #2841)", () => { data.metadata.layout.pages = [{ fullWidth: true, main: ["skills"], sidebar: [] }]; for (const type of ["hidden", "circle", "square", "rectangle", "rectangle-full", "progress-bar", "icon"] as const) { data.metadata.design.level = { type, icon: "star" }; - const runtime = resolveResumeRuntime({ data, template: "chikorita", mode: "legacy" }); + const runtime = resolveResumeRuntime({ data, template: "chikorita" }); const level = flatten(runtime.sourceTree).find((node) => node.kind === "level"); if (type === "hidden") expect(level).toBeUndefined(); else expect(level?.children.every((node) => node.attributes.type === type)).toBe(true); diff --git a/packages/pdf/src/templates/shared/level-display.tsx b/packages/pdf/src/templates/shared/level-display.tsx index 19848dfa4..981f41092 100644 --- a/packages/pdf/src/templates/shared/level-display.tsx +++ b/packages/pdf/src/templates/shared/level-display.tsx @@ -11,7 +11,7 @@ import { useSemanticNodeVisible, } from "../../semantic/context"; import { semanticNodeKeys } from "../../semantic/node-keys"; -import { useSectionStyleRule, useTemplateIconSlot, useTemplateStyle } from "./context"; +import { useTemplateIconSlot, useTemplateStyle } from "./context"; import { resolveStyleFontSize } from "./icon-size"; import { getTemplateMetrics } from "./metrics"; import { Icon } from "./primitives"; @@ -37,12 +37,9 @@ export const LevelDisplay = ({ level }: LevelDisplayProps) => { const levelItemStyle = useTemplateStyle("levelItem"); const levelItemActiveStyle = useTemplateStyle("levelItemActive"); const levelItemInactiveStyle = useTemplateStyle("levelItemInactive"); - const iconRuleStyle = useSectionStyleRule("icon"); - const levelRuleStyle = useSectionStyleRule("level"); const { decorationSize, levelIconExplicitSize } = resolveLevelDisplaySizes({ bodyFontSize: data.metadata.typography.body.fontSize, - iconFontSize: resolveStyleFontSize(iconRuleStyle), - levelFontSize: resolveStyleFontSize(levelRuleStyle, resolved.style), + levelFontSize: resolveStyleFontSize(resolved.style), }); const color = typeof iconProps.color === "string" ? iconProps.color : "#000000"; @@ -66,7 +63,6 @@ export const LevelDisplay = ({ level }: LevelDisplayProps) => { style={composeStyles( { flexDirection: "row", alignItems: "center", marginTop: 2, columnGap: gap }, levelContainerStyle, - levelRuleStyle, resolved.style, )} > diff --git a/packages/pdf/src/templates/shared/level-gap.test.tsx b/packages/pdf/src/templates/shared/level-gap.test.tsx index 958130141..4159bbbd6 100644 --- a/packages/pdf/src/templates/shared/level-gap.test.tsx +++ b/packages/pdf/src/templates/shared/level-gap.test.tsx @@ -11,7 +11,7 @@ import { rasterizePdf } from "../../semantic/test/rasterize-pdf"; const pdfRasterScale = 1.5; const circleDiameterPt = 8; -async function circlePositions(declaration = "", mode: "semantic" | "legacy" = "semantic") { +async function circlePositions(declaration = "") { const data = structuredClone(defaultResumeData); data.metadata.typography.body.fontFamily = "Helvetica"; data.metadata.typography.heading.fontFamily = "Helvetica"; @@ -19,7 +19,7 @@ async function circlePositions(declaration = "", mode: "semantic" | "legacy" = " data.metadata.design.colors.primary = "rgba(255, 0, 0, 1)"; data.metadata.layout.pages = [{ fullWidth: true, main: ["skills"], sidebar: [] }]; data.metadata.stylesheet = { - mode, + mode: "semantic", source: { languageVersion: 1, text: `@version 1; section[type="skills"] level { ${declaration} }` }, }; data.sections.skills.items = [ @@ -34,7 +34,7 @@ async function circlePositions(declaration = "", mode: "semantic" | "legacy" = " keywords: [], }, ]; - const runtime = resolveResumeRuntime({ data, template: "onyx", mode }); + const runtime = resolveResumeRuntime({ data, template: "onyx" }); const bytes = await act(() => renderToBuffer()); const [page] = await rasterizePdf(new Uint8Array(bytes)); if (!page) throw new Error("Missing PDF page"); @@ -67,9 +67,6 @@ async function circlePositions(declaration = "", mode: "semantic" | "legacy" = " } describe("semantic level gaps (#3040)", () => { - it("preserves default circle geometry in legacy and semantic modes", async () => { - expect(await circlePositions()).toEqual(await circlePositions("", "legacy")); - }); it.each([ ["gap: 0;", 0], ["gap: 4pt;", 4], diff --git a/packages/pdf/src/templates/shared/list-pagination.test.tsx b/packages/pdf/src/templates/shared/list-pagination.test.tsx index 09067dd86..b618381e6 100644 --- a/packages/pdf/src/templates/shared/list-pagination.test.tsx +++ b/packages/pdf/src/templates/shared/list-pagination.test.tsx @@ -35,7 +35,7 @@ async function listPages( text: `@version 1; page { size: 300pt 300pt; } rich-text { margin-top: ${margin}pt; } ${css}`, }, }; - const runtime = resolveResumeRuntime({ data, template: "onyx", mode: "semantic" }); + const runtime = resolveResumeRuntime({ data, template: "onyx" }); expect(runtime.diagnostics).toEqual([]); const bytes = await act(() => renderToBuffer()); const task = getDocument({ data: new Uint8Array(bytes), useSystemFonts: true }); diff --git a/packages/pdf/src/templates/shared/ordered-marker.test.tsx b/packages/pdf/src/templates/shared/ordered-marker.test.tsx index c2d5a9976..d1e54ad5a 100644 --- a/packages/pdf/src/templates/shared/ordered-marker.test.tsx +++ b/packages/pdf/src/templates/shared/ordered-marker.test.tsx @@ -45,7 +45,7 @@ async function renderList({ // Distinct body weight keeps marker and content separate in PDF.js text runs. description: `${nested ? "
  • Outer" : ""}
      ${Array.from({ length: count }, (_, index) => `
    1. ITEM${column}_${String(index + 1).padStart(3, "0")}
    2. `).join("")}
    ${nested ? "
" : ""}`, })); - expect(resolveResumeRuntime({ data, template: "rhyhorn", mode: "semantic" }).diagnostics).toEqual([]); + expect(resolveResumeRuntime({ data, template: "rhyhorn" }).diagnostics).toEqual([]); const bytes = await act(() => renderToBuffer()); const loading = getDocument({ data: new Uint8Array(bytes), useSystemFonts: true }); try { diff --git a/packages/pdf/src/templates/shared/page-margins.test.tsx b/packages/pdf/src/templates/shared/page-margins.test.tsx index 67c15f0bf..8eee1e978 100644 --- a/packages/pdf/src/templates/shared/page-margins.test.tsx +++ b/packages/pdf/src/templates/shared/page-margins.test.tsx @@ -13,14 +13,13 @@ const renderOverflow = async ( template: Template, placement: "main" | "sidebar", locale = "en-US", - mode: "semantic" | "legacy" = "semantic", explicitPage?: { fullWidth: boolean }, stylesheet = "@version 1;", fullWidth = false, ) => { const data = structuredClone(defaultResumeData); data.basics.name = "Margin Audit"; - data.metadata.stylesheet = { mode, source: { languageVersion: 1, text: stylesheet } }; + data.metadata.stylesheet = { mode: "semantic", source: { languageVersion: 1, text: stylesheet } }; data.metadata.typography.body.fontFamily = "Helvetica"; data.metadata.typography.heading.fontFamily = "Helvetica"; data.metadata.page.marginY = 48; @@ -90,7 +89,6 @@ describe("physical page margins (#3337, #3175)", () => { "glalie", "main", "en-US", - "semantic", undefined, `@version 1; template-part[name="sidebar-background"] { background-color: ${color}; }`, ); @@ -102,7 +100,7 @@ describe("physical page margins (#3337, #3175)", () => { expect(backgroundAt(overflow, 3, overflow.height - 4)).toEqual(inside); }); it("preserves the existing Glalie sidebar background on full-width overflow", async () => { - const { rasters } = await renderOverflow("glalie", "main", "en-US", "semantic", undefined, "@version 1;", true); + const { rasters } = await renderOverflow("glalie", "main", "en-US", undefined, "@version 1;", true); const overflow = rasters[1]; if (!overflow) throw new Error("Missing overflow raster"); expect(backgroundAt(overflow, 3, 100)).toEqual([242, 177, 177]); @@ -174,20 +172,11 @@ describe("physical page margins (#3337, #3175)", () => { expect(line.transform[5]).toBeGreaterThanOrEqual(47); } }); - it.each(templates)("keeps legacy overflow within margins (%s)", async (template) => { - const { pages } = await renderOverflow(template, "sidebar", "en-US", "legacy"); - expect(pages.length).toBeGreaterThan(1); - for (const page of pages) - for (const line of page.lines) { - expect(page.height - line.transform[5] - line.height).toBeGreaterThanOrEqual(45.8); - expect(line.transform[5]).toBeGreaterThanOrEqual(47); - } - }); for (const fullWidth of [false, true]) { it.each(templates)( `starts explicit headerless pages at the margin (fullWidth: ${fullWidth}, %s)`, async (template) => { - const { pages } = await renderOverflow(template, "main", "en-US", "semantic", { fullWidth }); + const { pages } = await renderOverflow(template, "main", "en-US", { fullWidth }); expect(pages).toHaveLength(2); const page = pages[1]; if (!page) throw new Error("Missing explicit second page"); diff --git a/packages/pdf/src/templates/shared/picture-border.test.tsx b/packages/pdf/src/templates/shared/picture-border.test.tsx index ee12272ad..bd9df9442 100644 --- a/packages/pdf/src/templates/shared/picture-border.test.tsx +++ b/packages/pdf/src/templates/shared/picture-border.test.tsx @@ -16,7 +16,6 @@ context.fillRect(0, 0, 100, 100); async function picturePixels( template: "onyx" | "ditto" | "glalie", borderWidth: number, - mode: "semantic" | "legacy" = "semantic", stylesheet = "@version 1;", shadowWidth = 0, url = source.toDataURL("image/png"), @@ -26,7 +25,7 @@ async function picturePixels( data.basics.name = "Picture"; data.metadata.typography.body.fontFamily = "Helvetica"; data.metadata.typography.heading.fontFamily = "Helvetica"; - data.metadata.stylesheet = { mode, source: { languageVersion: 1, text: stylesheet } }; + data.metadata.stylesheet = { mode: "semantic", source: { languageVersion: 1, text: stylesheet } }; data.metadata.layout.pages = [{ fullWidth: false, main: [], sidebar: [] }]; Object.assign(data.picture, { url, @@ -38,7 +37,7 @@ async function picturePixels( shadowWidth, shadowColor: "rgba(0, 0, 255, 1)", }); - let runtime = resolveResumeRuntime({ data, template, mode }); + let runtime = resolveResumeRuntime({ data, template }); if (styleOverride) { const entry = Object.entries(runtime.presentation).find(([key]) => key.endsWith("/picture")); if (!entry) throw new Error("Missing picture presentation"); @@ -115,13 +114,12 @@ async function picturePixels( describe("picture border visibility (#3017)", () => { it("keeps the shadow centered on the outer border box when borders and padding change", async () => { - const plain = await picturePixels("onyx", 0, "semantic", "@version 1;", 10); - const bordered = await picturePixels("onyx", 10, "semantic", "@version 1; picture { padding: 5pt; }", 10); + const plain = await picturePixels("onyx", 0, "@version 1;", 10); + const bordered = await picturePixels("onyx", 10, "@version 1; picture { padding: 5pt; }", 10); expect(bordered.shadowBounds).toEqual(plain.shadowBounds); const asymmetric = await picturePixels( "onyx", 0, - "semantic", "@version 1; picture { border-top: 12pt solid #ff00ff; border-right: 3pt solid #ff00ff; border-bottom: 8pt solid #ff00ff; border-left: 5pt solid #ff00ff; padding: 3pt 4pt 5pt 6pt; }", 10, ); @@ -130,9 +128,9 @@ describe("picture border visibility (#3017)", () => { it("preserves percentage dimensions, padding, rounded borders, rotation and opacity", async () => { const css = "@version 1; picture { width: 40%; height: 100pt; padding: 1%; border-radius: 25%; transform: rotate(15deg); }"; - const opaque = await picturePixels("onyx", 10, "semantic", css); - const plain = await picturePixels("onyx", 10, "semantic", css, 0, undefined, { opacity: 0.5 }); - const shadow = await picturePixels("onyx", 10, "semantic", css, 10, undefined, { opacity: 0.5 }); + const opaque = await picturePixels("onyx", 10, css); + const plain = await picturePixels("onyx", 10, css, 0, undefined, { opacity: 0.5 }); + const shadow = await picturePixels("onyx", 10, css, 10, undefined, { opacity: 0.5 }); expect(opaque.borderPixels).toBeGreaterThan(1000); expect(plain.imagePixels).toBeGreaterThan(1000); expect(shadow).toEqual(plain); // Unresolved percentage dimensions omit the shadow. @@ -141,15 +139,15 @@ describe("picture border visibility (#3017)", () => { }); // Forme 0.25 takes percentages only for box sizes, so percentage padding is left out; this passes once it isn't. it.fails.each([0, 10])("keeps percentage picture padding outside the border inset (%s)", async (shadowWidth) => { - const plain = await picturePixels("onyx", 10, "semantic", "@version 1;", shadowWidth); - const padded = await picturePixels("onyx", 10, "semantic", "@version 1; picture { padding: 1%; }", shadowWidth); + const plain = await picturePixels("onyx", 10, "@version 1;", shadowWidth); + const padded = await picturePixels("onyx", 10, "@version 1; picture { padding: 1%; }", shadowWidth); expect(padded.borderPixels).toBe(plain.borderPixels); expect(padded.imagePixels).toBeLessThan(plain.imagePixels); }); it.each([0, 10])("preserves border and authored padding with shadow width %s", async (shadowWidth) => { - const plain = await picturePixels("onyx", 10, "semantic", "@version 1;", shadowWidth); - const zero = await picturePixels("onyx", 10, "semantic", "@version 1; picture { padding: 0; }", shadowWidth); - const padded = await picturePixels("onyx", 10, "semantic", "@version 1; picture { padding: 5pt; }", shadowWidth); + const plain = await picturePixels("onyx", 10, "@version 1;", shadowWidth); + const zero = await picturePixels("onyx", 10, "@version 1; picture { padding: 0; }", shadowWidth); + const padded = await picturePixels("onyx", 10, "@version 1; picture { padding: 5pt; }", shadowWidth); expect(zero).toEqual(plain); expect(padded.borderPixels).toBe(plain.borderPixels); expect(padded.imagePixels).toBeLessThan(plain.imagePixels); @@ -167,23 +165,14 @@ describe("picture border visibility (#3017)", () => { }); it("honors semantic border width overrides", async () => { const metadataBorder = await picturePixels("onyx", 10); - const overridden = await picturePixels( - "onyx", - 0, - "semantic", - "@version 1; picture { border: 10pt solid #ff00ff; }", - ); + const overridden = await picturePixels("onyx", 0, "@version 1; picture { border: 10pt solid #ff00ff; }"); expect(overridden).toEqual(metadataBorder); }); - it("keeps legacy picture borders visible", async () => { - const bordered = await picturePixels("onyx", 10, "legacy"); - expect(bordered.borderPixels).toBeGreaterThan(1000); - }); it.each(["onyx", "ditto", "glalie"] as const)( "draws a soft centered shadow without moving the photo (%s)", async (template) => { const plain = await picturePixels(template, 0); - const shadow = await picturePixels(template, 0, "semantic", "@version 1;", 10); + const shadow = await picturePixels(template, 0, "@version 1;", 10); expect(plain.shadowPixels).toBe(0); expect(shadow.shadowPixels).toBeGreaterThan(100); expect(shadow.bounds).toEqual(plain.bounds); @@ -194,7 +183,6 @@ describe("picture border visibility (#3017)", () => { const shadow = await picturePixels( "onyx", 0, - "semantic", "@version 1; picture { -resume-shadow-width: 10pt; -resume-shadow-color: rgba(0, 0, 255, 0.5); border-radius: 50pt; }", ); expect(shadow.shadowPixels).toBeGreaterThan(100); @@ -206,25 +194,25 @@ describe("picture border visibility (#3017)", () => { context.fillStyle = "#00aa00"; context.fillRect(0, 0, 100, 100); context.clearRect(30, 30, 40, 40); - const shadow = await picturePixels("onyx", 0, "semantic", "@version 1;", 10, transparent.toDataURL("image/png")); + const shadow = await picturePixels("onyx", 0, "@version 1;", 10, transparent.toDataURL("image/png")); expect(shadow.shadowPixels).toBeGreaterThan(100); expect(shadow.center).toEqual([255, 255, 255]); }); it("preserves rotated photo geometry and opacity", async () => { const css = "@version 1; picture { transform: rotate(25deg); }"; - const plain = await picturePixels("onyx", 0, "semantic", css, 0, undefined, { opacity: 0.5 }); - const shadow = await picturePixels("onyx", 0, "semantic", css, 10, undefined, { opacity: 0.5 }); + const plain = await picturePixels("onyx", 0, css, 0, undefined, { opacity: 0.5 }); + const shadow = await picturePixels("onyx", 0, css, 10, undefined, { opacity: 0.5 }); expect(shadow.shadowPixels).toBeGreaterThan(100); expect(shadow.bounds).toEqual(plain.bounds); expect(shadow.center).toEqual(plain.center); }); it("keeps the outer shadow visible when the picture clips its contents", async () => { - const shadow = await picturePixels("onyx", 0, "semantic", "@version 1;", 10, undefined, { overflow: "hidden" }); + const shadow = await picturePixels("onyx", 0, "@version 1;", 10, undefined, { overflow: "hidden" }); expect(shadow.shadowPixels).toBeGreaterThan(100); }); it("matches percentage and absolute picture corner radii", async () => { - const absolute = await picturePixels("onyx", 0, "semantic", "@version 1; picture { border-radius: 50pt; }", 10); - const percent = await picturePixels("onyx", 0, "semantic", "@version 1; picture { border-radius: 50%; }", 10); + const absolute = await picturePixels("onyx", 0, "@version 1; picture { border-radius: 50pt; }", 10); + const percent = await picturePixels("onyx", 0, "@version 1; picture { border-radius: 50%; }", 10); expect(percent).toEqual(absolute); }); }); diff --git a/packages/pdf/src/templates/shared/primitives.tsx b/packages/pdf/src/templates/shared/primitives.tsx index 3de1676ec..204f75305 100644 --- a/packages/pdf/src/templates/shared/primitives.tsx +++ b/packages/pdf/src/templates/shared/primitives.tsx @@ -17,7 +17,7 @@ import { } from "../../semantic/context"; import { semanticNodeKeys } from "../../semantic/node-keys"; import { Link as PdfLink, Text as PdfText } from "../../text"; -import { useSectionStyleRule, useTemplateIconSlot, useTemplatePageNodeKey, useTemplateStyle } from "./context"; +import { useTemplateIconSlot, useTemplatePageNodeKey, useTemplateStyle } from "./context"; import { resolveIconSize } from "./icon-size"; import { getPictureShadow } from "./picture-shadow"; import { safeTextStyle } from "./safe-text-style"; @@ -135,7 +135,6 @@ export const Text = ({ ...props }: ComponentProps & SemanticProps) => { const textStyle = useTemplateStyle("text"); - const textRuleStyle = useSectionStyleRule("text"); const resolvedNodeKey = usePrimitiveNodeKey({ nodeKey, semanticField, @@ -150,7 +149,7 @@ export const Text = ({ ); }; @@ -164,7 +163,6 @@ export const Heading = ({ ...props }: ComponentProps & SemanticProps) => { const headingStyle = useTemplateStyle("heading"); - const headingRuleStyle = useSectionStyleRule("heading"); const resolvedNodeKey = usePrimitiveNodeKey({ nodeKey, semanticField, @@ -180,7 +178,7 @@ export const Heading = ({ ); }; @@ -196,7 +194,6 @@ export const Link = ({ }: ComponentProps & SemanticLinkProps) => { const { metadata } = useRender(); const linkStyle = useTemplateStyle("link"); - const linkRuleStyle = useSectionStyleRule("link"); const parentKey = useSemanticNodeKey(); const resolvedNodeKey = nodeKey ?? @@ -211,12 +208,7 @@ export const Link = ({ {...props} {...resolvedPdfTextProps(resolved)} style={composeStyles( - composeLinkStyles( - { hideUnderline: metadata.page.hideLinkUnderline }, - linkStyle, - linkRuleStyle, - asStyleInput(style), - ), + composeLinkStyles({ hideUnderline: metadata.page.hideLinkUnderline }, linkStyle, asStyleInput(style)), resolved.style, safeTextStyle, )} @@ -234,7 +226,6 @@ export const Small = ({ }: ComponentProps & SemanticProps) => { const textStyle = useTemplateStyle("text"); const smallStyle = useTemplateStyle("small"); - const secondaryTextRuleStyle = useSectionStyleRule("secondaryText"); const resolvedNodeKey = usePrimitiveNodeKey({ nodeKey, semanticField, @@ -249,14 +240,7 @@ export const Small = ({ ); }; @@ -271,7 +255,6 @@ export const Bold = ({ }: ComponentProps & SemanticProps) => { const textStyle = useTemplateStyle("text"); const boldStyle = useTemplateStyle("bold"); - const textRuleStyle = useSectionStyleRule("text"); const resolvedNodeKey = usePrimitiveNodeKey({ nodeKey, semanticField, @@ -286,7 +269,7 @@ export const Bold = ({ ); }; @@ -298,8 +281,7 @@ export const Icon = ({ ...props }: ComponentProps & { nodeKey?: string | undefined }) => { const { style: iconStyle, size: templateSize, ...iconProps } = useTemplateIconSlot("icon"); - const iconRuleStyle = useSectionStyleRule("icon"); - const composedStyle = composeStyles(asStyleInput(iconStyle), iconRuleStyle, asStyleInput(style)); + const composedStyle = composeStyles(asStyleInput(iconStyle), asStyleInput(style)); const templateIconSize = typeof templateSize === "number" || typeof templateSize === "string" ? templateSize : undefined; const parentKey = useSemanticNodeKey(); @@ -312,7 +294,7 @@ export const Icon = ({ const resolvedSize = resolveIconSize({ size: sizeProp, - styles: [iconRuleStyle, asStyleInput(style), resolved.style], + styles: [asStyleInput(style), resolved.style], }) ?? templateIconSize; if (iconProps.display === "none" || !visible) return null; diff --git a/packages/pdf/src/templates/shared/rich-text.tsx b/packages/pdf/src/templates/shared/rich-text.tsx index ab95f52dd..fc3f93155 100644 --- a/packages/pdf/src/templates/shared/rich-text.tsx +++ b/packages/pdf/src/templates/shared/rich-text.tsx @@ -14,7 +14,7 @@ import { import { semanticNodeKeys } from "../../semantic/node-keys"; import { getRichTextSemanticNodeKey } from "../../semantic/rich-text-keys"; import { Html, Link as PdfLink, Text as PdfText } from "../../text"; -import { useSectionStyleRule, useTemplateStyle } from "./context"; +import { useTemplateStyle } from "./context"; import { normalizeRichTextHtml, projectNormalizedRichTextHtml, @@ -93,19 +93,7 @@ export const RichText = ({ children, semanticField }: RichTextProps) => { const richListItemRowStyle = useTemplateStyle("richListItemRow"); const richListItemMarkerStyle = useTemplateStyle("richListItemMarker"); const richListItemContentStyle = useTemplateStyle("richListItemContent"); - const richParagraphRuleStyle = useSectionStyleRule("richParagraph"); - const richListRuleStyle = useSectionStyleRule("richList"); - const richListItemRowRuleStyle = useSectionStyleRule("richListItemRow"); - const richListItemContentRuleStyle = useSectionStyleRule("richListItemContent"); - const richLinkRuleStyle = useSectionStyleRule("richLink"); - const richBoldRuleStyle = useSectionStyleRule("richBold"); - const richMarkRuleStyle = useSectionStyleRule("richMark"); - const bodyLineHeight = resolveRichTextBodyLineHeight( - richParagraphStyle, - richParagraphRuleStyle, - richListItemContentStyle, - richListItemContentRuleStyle, - ); + const bodyLineHeight = resolveRichTextBodyLineHeight(richParagraphStyle, richListItemContentStyle); const proseSpacing = createRichTextProseSpacing(bodyLineHeight); const normalizedHtml = normalizeRichTextHtml(children, { @@ -317,7 +305,6 @@ export const RichText = ({ children, semanticField }: RichTextProps) => { {...resolvedPdfTextProps(contentResolved)} style={composeStyles( richListItemContentStyle, - richListItemContentRuleStyle, contentItemStyles, contentResolved.style, safeTextStyle, @@ -333,7 +320,6 @@ export const RichText = ({ children, semanticField }: RichTextProps) => { {...resolvedPdfFlowProps(contentResolved)} style={composeStyles( richListItemContentStyle, - richListItemContentRuleStyle, contentItemStyles, contentResolved.style, richListItemContentStackStyle, @@ -365,7 +351,6 @@ export const RichText = ({ children, semanticField }: RichTextProps) => { {...resolvedPdfFlowProps(itemResolved)} style={composeStyles( richListItemRowStyle, - richListItemRowRuleStyle, itemStyles, getRichTextEdgeTrimStyle(element), itemResolved.style, @@ -385,11 +370,6 @@ export const RichText = ({ children, semanticField }: RichTextProps) => { hideLinkUnderline: metadata.page.hideLinkUnderline, linkStyle, richParagraphStyle, - richParagraphRuleStyle, - richListRuleStyle, - richBoldRuleStyle, - richLinkRuleStyle, - richMarkRuleStyle, proseSpacing, })} > diff --git a/packages/pdf/src/templates/shared/section-header-alignment.test.tsx b/packages/pdf/src/templates/shared/section-header-alignment.test.tsx index 13982a1a7..68239f7d6 100644 --- a/packages/pdf/src/templates/shared/section-header-alignment.test.tsx +++ b/packages/pdf/src/templates/shared/section-header-alignment.test.tsx @@ -75,15 +75,12 @@ const expectTrailingAlignment = (items: TextItem[], rtl = false) => { }; describe("optional experience and education header fields (#3338)", () => { - it.each(["legacy", "semantic"] as const)( - "keeps dates at the trailing edge with empty leading fields in %s mode", - async (mode) => { - const data = fixture(); - data.metadata.stylesheet = { mode, source: { languageVersion: 1, text: "@version 1;" } }; - const items = await renderText(data); - expectTrailingAlignment(items); - }, - ); + it("keeps dates at the trailing edge with empty leading fields", async () => { + const data = fixture(); + data.metadata.stylesheet = { mode: "semantic", source: { languageVersion: 1, text: "@version 1;" } }; + const items = await renderText(data); + expectTrailingAlignment(items); + }); it("preserves RTL row alignment when leading fields are empty", async () => { const data = fixture(); diff --git a/packages/pdf/src/templates/shared/sections.test.ts b/packages/pdf/src/templates/shared/sections.test.ts index ee30b2781..3262476dc 100644 --- a/packages/pdf/src/templates/shared/sections.test.ts +++ b/packages/pdf/src/templates/shared/sections.test.ts @@ -32,12 +32,10 @@ describe("SectionShell", () => { expect(getSectionHeadingTextStyle({ paddingLeft: 6 })).toEqual([{ paddingLeft: 1 }]); }); - it("keeps section and heading style rules when section heading icons are hidden", () => { - expect(source).toContain( - "const resolvedSectionStyle = composeStyles(sectionStyle, sectionRuleStyle, resolved.style)", - ); + it("keeps section and heading styles when section heading icons are hidden", () => { + expect(source).toContain("const resolvedSectionStyle = composeStyles(sectionStyle, resolved.style)"); expect(source).toContain(""); - expect(source).toContain(""); + expect(source).toContain(""); }); it("wires the section heading container style slot into the icon row", () => { @@ -51,7 +49,7 @@ describe("SectionShell", () => { ); expect(headingContainerBlock?.groups?.body).toContain('alignItems: "flex-start"'); - expect(source).toMatch(/getSectionHeadingTextStyle\(\s*sectionHeadingStyle,\s*sectionHeadingRuleStyle(?:,|\))/); + expect(source).toMatch(/getSectionHeadingTextStyle\(\s*sectionHeadingStyle(?:,|\))/); expect(source).toContain("width: _width"); expect(source).not.toContain('width: "auto"'); }); diff --git a/packages/pdf/src/templates/shared/sections.tsx b/packages/pdf/src/templates/shared/sections.tsx index 2ea394345..9e5ee1c27 100644 --- a/packages/pdf/src/templates/shared/sections.tsx +++ b/packages/pdf/src/templates/shared/sections.tsx @@ -46,9 +46,7 @@ import { ITEM_HEADER_ROW_PART_KEYS } from "../../semantic/shared-parts"; import { getSectionItemRows, getSectionItemsLayout, shouldUseSectionTimeline } from "./columns"; import { getWebsiteDisplayText } from "./contact"; import { - SectionStyleProvider, TemplatePlacementProvider, - useSectionStyleRule, useTemplateFeature, useTemplateFeatureStyle, useTemplatePageNodeKey, @@ -74,7 +72,6 @@ import { RichText } from "./rich-text"; import { createRtlStyleHelpers } from "./rtl"; import { getInlineItemWebsiteUrl, shouldRenderSeparateItemWebsite } from "./section-links"; import { hasSplitRowText } from "./split-row"; -import { getSectionStyleRuleContext } from "./style-rules"; import { composeStyles, mergeStyles } from "./styles"; type SectionItemsContextValue = { @@ -321,10 +318,8 @@ const SectionShell = ({ sectionId, title, showHeading = true, children }: Sectio const resolved = useResolvedNode(sectionNodeKey); const visible = useSemanticNodeVisible(sectionNodeKey); const sectionStyle = useTemplateStyle("section"); - const sectionRuleStyle = useSectionStyleRule("section"); const sectionHeadingStyle = useTemplateStyle("sectionHeading"); const sectionHeadingContainerStyle = useTemplateStyle("sectionHeadingContainer"); - const sectionHeadingRuleStyle = useSectionStyleRule("heading"); const sectionTitle = getResumeSectionTitle(data, sectionId, title); const sectionHeadingEnabled = (() => { if (sectionId === "summary") return data.summary.showHeading !== false; @@ -346,7 +341,7 @@ const SectionShell = ({ sectionId, title, showHeading = true, children }: Sectio if (keepTogether) breakProps.wrap = false; if (startOnNewPage) breakProps.break = true; const flowProps = { ...breakProps, ...resolvedPdfFlowProps(resolved) }; - const resolvedSectionStyle = composeStyles(sectionStyle, sectionRuleStyle, resolved.style); + const resolvedSectionStyle = composeStyles(sectionStyle, resolved.style); if (!visible) return null; if (!showIcon) { @@ -355,7 +350,7 @@ const SectionShell = ({ sectionId, title, showHeading = true, children }: Sectio {showHeading && sectionHeadingEnabled && ( - {sectionTitle} + {sectionTitle} )} {children} @@ -374,7 +369,6 @@ const SectionShell = ({ sectionId, title, showHeading = true, children }: Sectio sectionHeadingStyle, defaultSectionHeadingContainerStyle, sectionHeadingContainerStyle, - sectionHeadingRuleStyle, sectionHeadingResolved.style, )} > @@ -386,7 +380,6 @@ const SectionShell = ({ sectionId, title, showHeading = true, children }: Sectio bindSemanticNode={false} style={getSectionHeadingTextStyle( sectionHeadingStyle, - sectionHeadingRuleStyle, sectionHeadingResolved.style?.color === undefined ? undefined : { color: sectionHeadingResolved.style.color }, @@ -506,7 +499,6 @@ const SectionItem = ({ itemId, children, style }: SectionItemProps) => { const visible = useSemanticNodeVisible(itemNodeKey); const { itemStyle: sectionItemStyle, useTimeline } = useSectionItemsContext(); const itemStyle = useTemplateStyle("item"); - const itemRuleStyle = useSectionStyleRule("item"); const timelineItemStyle = useTemplateFeatureStyle("sectionTimeline", "item"); const timelineMarkerStyle = useTemplateFeatureStyle("sectionTimeline", "marker"); const timelineDotStyle = useTemplateFeatureStyle("sectionTimeline", "dot"); @@ -518,7 +510,7 @@ const SectionItem = ({ itemId, children, style }: SectionItemProps) => { if (!useTimeline) { return ( -
+
{children}
@@ -542,7 +534,7 @@ const SectionItem = ({ itemId, children, style }: SectionItemProps) => {
{children}
@@ -1597,9 +1589,7 @@ export const Section = ({ section, placement, showHeading = true }: SectionProps return ( - - {render ? render() : } - + {render ? render() : } ); }; diff --git a/packages/pdf/src/templates/shared/skill-keyword-presentation.test.tsx b/packages/pdf/src/templates/shared/skill-keyword-presentation.test.tsx index a69bd73ac..261813327 100644 --- a/packages/pdf/src/templates/shared/skill-keyword-presentation.test.tsx +++ b/packages/pdf/src/templates/shared/skill-keyword-presentation.test.tsx @@ -110,7 +110,7 @@ describe("skill keyword presentation", () => { text: '@version 1; section[type="skills"] field[name="keywords"] { font-size: 18pt; } section[type="skills"] item[id="css-hidden"] { display: none; }', }, }; - const runtime = resolveResumeRuntime({ data, template: "leafish", mode: "semantic" }); + const runtime = resolveResumeRuntime({ data, template: "leafish" }); expect(runtime.diagnostics).toEqual([]); const { text, pages } = await renderKeywords(data); expect(text).toContain("Engineering"); diff --git a/packages/pdf/src/templates/shared/skill-level-alignment.test.tsx b/packages/pdf/src/templates/shared/skill-level-alignment.test.tsx index 317513baf..aece43f17 100644 --- a/packages/pdf/src/templates/shared/skill-level-alignment.test.tsx +++ b/packages/pdf/src/templates/shared/skill-level-alignment.test.tsx @@ -11,7 +11,6 @@ import { rasterizePdf } from "../../semantic/test/rasterize-pdf"; type FixtureOptions = { columns: number; count: number; - mode?: "semantic" | "legacy"; configure?: (data: ResumeData) => void; }; @@ -19,14 +18,14 @@ function setCss(data: ResumeData, css: string) { data.metadata.stylesheet = { mode: "semantic", source: { languageVersion: 1, text: `@version 1; ${css}` } }; } -async function renderRatings({ columns, count, mode = "semantic", configure }: FixtureOptions) { +async function renderRatings({ columns, count, configure }: FixtureOptions) { const data = structuredClone(defaultResumeData); data.metadata.typography.body.fontFamily = "Helvetica"; data.metadata.typography.heading.fontFamily = "Helvetica"; data.metadata.page.hideIcons = true; data.metadata.design.colors.primary = "rgba(255, 0, 0, 1)"; data.metadata.layout.pages = [{ fullWidth: true, main: ["skills"], sidebar: [] }]; - data.metadata.stylesheet = { mode, source: { languageVersion: 1, text: "@version 1;" } }; + data.metadata.stylesheet = { mode: "semantic", source: { languageVersion: 1, text: "@version 1;" } }; data.sections.skills.columns = columns; data.sections.skills.items = Array.from({ length: count }, (_, index) => ({ id: `skill-${index}`, @@ -39,7 +38,7 @@ async function renderRatings({ columns, count, mode = "semantic", configure }: F keywords: index === 1 ? Array.from({ length: 12 }, (_, word) => `Keyword${word}`) : ["Short"], })); configure?.(data); - expect(resolveResumeRuntime({ data, template: "onyx", mode }).diagnostics).toEqual([]); + expect(resolveResumeRuntime({ data, template: "onyx" }).diagnostics).toEqual([]); const bytes = await act(() => renderToBuffer()); const pages = await rasterizePdf(new Uint8Array(bytes)); const loading = getDocument({ data: new Uint8Array(bytes) }); @@ -82,21 +81,18 @@ async function renderRatings({ columns, count, mode = "semantic", configure }: F } describe("skill rating alignment (#3343)", () => { - it.each(["semantic", "legacy"] as const)( - "aligns mixed-height skills and preserves an incomplete row in %s mode", - async (mode) => { - const { - rows: [rows], - text, - } = await renderRatings({ columns: 2, count: 3, mode }); - expect(rows).toHaveLength(2); - if (!rows?.[0] || !rows[1]) throw new Error("Missing rating rows"); - // Ten circles share the first row; the remaining skill has five. - expect(rows.map((row) => row.circles)).toEqual([10, 5]); - expect(text).toContain("Keyword11"); - expect(text).toContain("Skill 2"); - }, - ); + it("aligns mixed-height skills and preserves an incomplete row", async () => { + const { + rows: [rows], + text, + } = await renderRatings({ columns: 2, count: 3 }); + expect(rows).toHaveLength(2); + if (!rows?.[0] || !rows[1]) throw new Error("Missing rating rows"); + // Ten circles share the first row; the remaining skill has five. + expect(rows.map((row) => row.circles)).toEqual([10, 5]); + expect(text).toContain("Keyword11"); + expect(text).toContain("Skill 2"); + }); it("aligns three columns and preserves an incomplete row", async () => { const { rows: [rows], diff --git a/packages/pdf/src/templates/shared/style-rules.test.ts b/packages/pdf/src/templates/shared/style-rules.test.ts index 386aef12b..237332add 100644 --- a/packages/pdf/src/templates/shared/style-rules.test.ts +++ b/packages/pdf/src/templates/shared/style-rules.test.ts @@ -1,7 +1,8 @@ import type { ResumeData } from "@reactive-resume/schema/resume/data"; import { describe, expect, it } from "vitest"; import { defaultResumeData } from "@reactive-resume/schema/resume/default"; -import { getSectionStyleRuleContext, resolveStyleRuleSlot } from "./style-rules"; +import { getSectionStyleRuleContext } from "@reactive-resume/schema/resume/style-rules"; +import { resolveStyleRuleSlot } from "./style-rules"; const createResumeData = (styleRules: ResumeData["metadata"]["styleRules"]): ResumeData => ({ ...defaultResumeData, diff --git a/packages/pdf/src/templates/shared/style-rules.ts b/packages/pdf/src/templates/shared/style-rules.ts index 6d7759171..028d3fa96 100644 --- a/packages/pdf/src/templates/shared/style-rules.ts +++ b/packages/pdf/src/templates/shared/style-rules.ts @@ -1,17 +1,13 @@ import type { ResumeData, StyleIntent, StyleSlot } from "@reactive-resume/schema/resume/data"; import type { SectionStyleRuleContext } from "@reactive-resume/schema/resume/style-rules"; import type { Style } from "../../forme/style-types"; -import { getSectionStyleRuleContext, resolveStyleIntentForSlot } from "@reactive-resume/schema/resume/style-rules"; +import { resolveStyleIntentForSlot } from "@reactive-resume/schema/resume/style-rules"; import { rgbaStringToHex } from "@reactive-resume/utils/color"; -export type { SectionStyleRuleContext }; - export type ResolveStyleRuleSlotOptions = SectionStyleRuleContext & { slot: StyleSlot; }; -export { getSectionStyleRuleContext }; - const spacingProperties = [ "padding", "paddingTop", diff --git a/packages/schema/src/resume/style-rules.test.ts b/packages/schema/src/resume/style-rules.test.ts deleted file mode 100644 index 65df3e083..000000000 --- a/packages/schema/src/resume/style-rules.test.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { describe, expect, it } from "vitest"; -import { defaultResumeData } from "./default"; -import { resolveStyleRuleFontSize } from "./style-rules"; - -describe("resolveStyleRuleFontSize", () => { - it("returns global icon font sizes without section context", () => { - const data = { - ...defaultResumeData, - metadata: { - ...defaultResumeData.metadata, - styleRules: [ - { - id: "icon-global", - label: "", - enabled: true, - target: { scope: "global" as const }, - slots: { icon: { fontSize: 22 } }, - }, - ], - }, - }; - - expect(resolveStyleRuleFontSize(data, { slot: "icon" })).toBe(22); - }); - - it("does not apply level font sizes to the icon slot", () => { - const data = { - ...defaultResumeData, - metadata: { - ...defaultResumeData.metadata, - styleRules: [ - { - id: "level-global", - label: "", - enabled: true, - target: { scope: "global" as const }, - slots: { level: { fontSize: 18 } }, - }, - ], - }, - }; - - expect(resolveStyleRuleFontSize(data, { slot: "icon" })).toBeUndefined(); - }); -}); diff --git a/packages/schema/src/resume/style-rules.ts b/packages/schema/src/resume/style-rules.ts index 0cdb5c84e..206ff8011 100644 --- a/packages/schema/src/resume/style-rules.ts +++ b/packages/schema/src/resume/style-rules.ts @@ -26,8 +26,6 @@ const builtInSectionTypes = new Set([ "references", ]); -const clamp = (value: number, min: number, max: number) => Math.min(max, Math.max(min, value)); - export const getSectionStyleRuleContext = (data: ResumeData, sectionId: string): SectionStyleRuleContext => { if (sectionId === "summary") return { sectionId, sectionType: "summary" }; if (builtInSectionTypes.has(sectionId as SectionType)) { @@ -62,13 +60,3 @@ export const resolveStyleIntentForSlot = (data: ResumeData, options: ResolveStyl return Object.assign({}, ...bySpecificity.map((rule) => rule.slots[options.slot])); }; - -export const resolveStyleRuleFontSize = ( - data: ResumeData, - options: ResolveStyleRuleSlotOptions, -): number | undefined => { - const fontSize = resolveStyleIntentForSlot(data, options).fontSize; - if (fontSize === undefined) return undefined; - - return clamp(fontSize, 6, 48); -}; diff --git a/tests/e2e/fixtures/db.ts b/tests/e2e/fixtures/db.ts index e0b71ebd6..e04a1d0f9 100644 --- a/tests/e2e/fixtures/db.ts +++ b/tests/e2e/fixtures/db.ts @@ -1,15 +1,6 @@ import type { E2EAccount } from "./data"; -import { readFileSync } from "node:fs"; -import { resolve } from "node:path"; import { Pool } from "pg"; -const legacyParityRules = JSON.parse( - readFileSync( - resolve(process.cwd(), "packages/pdf/src/semantic/__fixtures__/legacy/custom-section-type.json"), - "utf8", - ), -) as unknown[]; - function getDatabaseUrl() { const databaseUrl = process.env.DATABASE_URL; if (!databaseUrl) throw new Error("DATABASE_URL is required for E2E cleanup."); @@ -28,7 +19,7 @@ export async function deleteE2EUser(account: E2EAccount) { } type SemanticStylesheetSeed = { - mode: "legacy" | "semantic"; + mode: "semantic"; source: { languageVersion: number; text: string }; }; @@ -38,7 +29,6 @@ async function _updateSemanticCssFixture( stylesheet?: SemanticStylesheetSeed; portableLayout?: "balanced" | "pagination-stress"; experienceItemId?: string; - legacyStyleRule?: boolean; hidePicture?: boolean; basicsName?: string; }, @@ -116,11 +106,6 @@ async function _updateSemanticCssFixture( }, ]; } - if (update.legacyStyleRule) { - const metadata = data.metadata as Record; - delete metadata.stylesheet; - metadata.styleRules = structuredClone(legacyParityRules); - } if (update.hidePicture) { const picture = data.picture as Record; picture.hidden = true;