refactor(ui): design-system consistency pass over dense pages + i18n de-bloat (#961)

* refactor(ui): normalize dense pages to the locked design system

Sweep of the info-dense surfaces against .claude/rules/design.md; no
behavior changes, classNames and primitive adoption only.

- Replace hand-rolled h1s with PageHeader (import, suppliers, kpi,
  salary/employees, skattekonto, settings layout) and drop the one
  double title (SalarySettingsContent under the settings h1)
- Replace hand-rolled empty states with EmptyState (skattekonto,
  banking/api-keys/oauth/counterparty settings) and hand-rolled
  pulse divs with Skeleton (deadlines, report view loaders)
- Remove semantic colors used as chrome: amber/emerald banners in
  AGIPanel and SkatteverketPanel, success/warning tints in
  kassaflodesanalys, arsredovisning and import become neutral
  surfaces with the tint kept on the icon only
- Full-opacity borders everywhere (border-border/30-60,
  border-destructive/20-40, border-foreground/30, text-destructive/80)
- Snap off-scale spacing (p-5 to p-6, p-2.5 to p-3, gap/mt-x.5 to
  scale values); KPI metric tiles p-6 to p-4 per the tile rule
- Remove the mobile Select that duplicated the invoices status Tabs
  (TabsList already scrolls horizontally); single Tabs now serves
  both breakpoints
- supplier-invoices: shared formatCurrency instead of a local
  formatAmount helper; skattekonto: formatDate/formatDateLong/
  formatDateTime instead of raw dates and toLocaleString
- arsredovisning flerarsoversikt converted to the Table primitive
  with right-aligned tabular-nums cells
- Settings: CardTitle text-base on section cards, one heading idiom
  in AccountSettingsContent, h3 to h2 in CompanyProfileView

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* refactor(i18n): trim text bloat and fix an untranslated sv string

- Fix invoice_credit.create_failed_fallback: sv catalog carried the
  English "Failed to create credit note"; now "Kunde inte skapa
  kreditfaktura". Translate new_user_checklist.step3_title in en
- Drop descriptions that paraphrase their own title (design.md
  forbidden pattern): invoice_detail.credited_description,
  invoice_credit.original_card_description, invoice_editor
  customer/notes card descriptions (keys deleted from both
  catalogs, zero remaining usages); the transaction booking
  DialogDescription becomes sr-only so screen readers keep it
- Trim redundant sentences from settings_salary.info_payroll_scope,
  settings_backup.intro, ext_cloud_backup_long_description,
  settings.name_description, salary_payments.open_payments_note and
  shorten invoice_credit.reason_card_description; statutory BFL/tax
  prose untouched
- Normalize toast punctuation (dimensions/self_billing
  created_description lose the trailing period like their siblings)
- common.delete "Radera" to "Ta bort" (zero live call sites; Radera
  stays reserved for irreversible account/company deletion)

Catalogs verified key-identical (4795 keys each) and JSON-parseable.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Jakob Wennberg
2026-07-10 08:56:30 +02:00
committed by GitHub
co-authored by Claude Fable 5
parent ca8a89324c
commit da859d7236
41 changed files with 373 additions and 408 deletions
+9 -13
View File
@@ -201,7 +201,7 @@
"settings": {
"section_name": "Name",
"name_label": "Your name",
"name_description": "The name we use to address you and that appears as the contact person on some documents. We greet you by your first name, so put the name you go by first.",
"name_description": "Used when we address you and shown as the contact person on some documents.",
"name_placeholder": "First name Last name",
"name_saved": "Name updated",
"name_save_failed": "Could not save name",
@@ -837,7 +837,7 @@
"bank_title": "Connect your bank account",
"bank_description_psd2": "Connect via PSD2: transactions sync automatically every day.",
"bank_description_file": "Import bank statements from your bank: CSV, OFX and most Swedish banks.",
"step3_title": "Anslut Skatteverket",
"step3_title": "Connect Skatteverket",
"optional_suffix": ": optional",
"skatteverket_connected_title": "Skatteverket connected",
"skatteverket_connected_description": "You can now submit momsdeklaration and AGI directly, and see the balance on your skattekonto.",
@@ -1233,7 +1233,7 @@
"vacation_supplement_cba": "0.80% (common collective agreement level)",
"vacation_supplement_help": "Applied with sammalöneregeln. Can be overridden per employee.",
"info_heading": "Information",
"info_payroll_scope": "The payroll module handles salaries for your employees: tax deductions, employer contributions, vacation pay liability and the employer declaration (AGI). If you run a sole proprietorship (enskild firma), you as the owner take money out via owner's drawings (account 2013), not salary. The module is for your employees.",
"info_payroll_scope": "The payroll module handles salaries for your employees: tax deductions, employer contributions, vacation pay liability and the employer declaration (AGI). If you run a sole proprietorship (enskild firma), you as the owner take money out via owner's drawings (account 2013), not salary.",
"info_current_year": "<strong>Current year:</strong> 2026 (Arbetsgivaravgifter 31.42%, prisbasbelopp 59,200 SEK)"
},
"salary_payments": {
@@ -1253,7 +1253,7 @@
"instructions_toggle": "How to import the file in your bank",
"instructions_footer": "The amounts are pre-filled — all that remains is signing with BankID in your bank.",
"your_bank": "your bank",
"open_payments_note": "Open Payments / direct payment via PSD2 (without file import) is planned for the future via Enable Banking. Initiation requires a separate PIS agreement — we will follow up once enough customers use salary payment files regularly.",
"open_payments_note": "Automatic direct payment via open banking (without file import) is planned.",
"steps_bg_lb_swedbank": "Företagsbetalningar → Importera fil → choose LB format → upload and sign with BankID. Note: Swedbank stops accepting LB salary files after 1 August 2026.",
"steps_bg_lb_seb": "Betalningar → Filöverföring → choose Bankgiro LB → upload and approve.",
"steps_bg_lb_handelsbanken": "Betala → Filimport → choose LB → verify totals → sign. Note: Handelsbanken no longer accepts salary files via Bankgirot.",
@@ -1283,7 +1283,7 @@
},
"settings_backup": {
"heading": "Backup",
"intro": "Download your own copy of all accounting data (SIE files, receipts, supporting documents and processing history) in a single ZIP file. The backup is your own copy for safety and portability. {appName} archives all accounting data for at least 7 years per BFL 7 kap. 2 §, so your backup does not replace our legal obligation; it complements it."
"intro": "Download your own copy of all accounting data (SIE files, receipts, supporting documents and processing history) in a single ZIP file. {appName} archives all accounting data for at least 7 years per BFL 7 kap. 2 §, so your backup does not replace our legal obligation; it complements it."
},
"settings_api": {},
"settings_banking": {
@@ -2316,7 +2316,6 @@
"bank_missing_warning": "Payment details missing: you need to add them before creating an invoice.",
"bank_add_now": "Add now",
"customer_card_title": "Customer",
"customer_card_description": "Select which customer the invoice should be sent to",
"select_customer_placeholder": "Select customer",
"create_customer": "Create customer",
"create_customer_dialog_title": "Add customer",
@@ -2343,7 +2342,6 @@
"row_actions_aria": "Row actions",
"drag_handle_aria": "Drag to move the row",
"notes_card_title": "Notes",
"notes_card_description": "Optional message on the invoice",
"notes_placeholder": "E.g. payment terms or thanks for the collaboration...",
"details_card_title": "Invoice details",
"document_type_label": "Document type",
@@ -2572,7 +2570,6 @@
"reminder_marked_paid": "Customer marked as paid",
"reminder_objection": "Customer has objections",
"credited_card_title": "Credited",
"credited_description": "This invoice has been credited",
"see_credit_note": "See credit note {number}",
"credit_note_card_title": "Credit note",
"credit_note_description": "This credit note credits",
@@ -2642,7 +2639,6 @@
"warning_title": "Irreversible action",
"warning_description": "A credit note fully cancels the original invoice. All amounts become negative, a bookkeeping verifikat is created, and the original invoice is marked as credited. This action cannot be undone.",
"original_card_title": "Original invoice",
"original_card_description": "The credit note is based on this invoice",
"invoice_number_label": "Invoice number:",
"date_label": "Date:",
"customer_label": "Customer:",
@@ -2659,7 +2655,7 @@
"total": "Total",
"in_sek": "In SEK (rate {rate})",
"reason_card_title": "Reason",
"reason_card_description": "State the reason for crediting (shown on the credit note)",
"reason_card_description": "Shown on the credit note",
"reason_label": "Reason",
"reason_placeholder": "E.g. Incorrect invoicing, returned goods...",
"reason_default": "Credits invoice {number}",
@@ -3595,7 +3591,7 @@
"no_search_results_description": "No value matches “{term}”.",
"viewer_disabled_tooltip": "You have read-only access and cannot create values",
"created_title": "Value created",
"created_description": "{code} has been added to the register.",
"created_description": "{code} has been added to the register",
"updated_title": "Value updated",
"deleted_title": "Value deleted",
"save_failed_title": "Could not save",
@@ -3746,7 +3742,7 @@
"ext_mcp_server_long_description": "Exposes accounted's bookkeeping engine as MCP tools (Model Context Protocol). Connect your MCP client with an API key and do bookkeeping through conversation: list uncategorized transactions, book them, create invoices.",
"ext_cloud_backup_name": "Cloud sync",
"ext_cloud_backup_description": "Sync backups to your own cloud storage",
"ext_cloud_backup_long_description": "Connect your Google Drive account and upload a full backup with one click. Accounted creates a ZIP with SIE files, receipts and processing history and uploads it to a dedicated folder in your Drive. Perfect for meeting your own redundancy requirements.",
"ext_cloud_backup_long_description": "Connect your Google Drive account and upload a full backup with one click. Accounted creates a ZIP with SIE files, receipts and processing history and uploads it to a dedicated folder in your Drive.",
"ext_skatteverket_name": "Skatteverket integration",
"ext_skatteverket_description": "Submit the VAT declaration directly to Skatteverket via BankID.",
"ext_skatteverket_long_description": "Connect to Skatteverket with BankID and submit your VAT declaration directly from accounted. Save drafts, validate, lock and sign: without leaving the app.",
@@ -4280,7 +4276,7 @@
"viewer_disabled_tooltip": "You only have viewer access in this company",
"load_customers_failed": "Could not load customers",
"created_title": "Self-billing invoice registered",
"created_description": "Self-billing invoice {number} has been booked as a sale.",
"created_description": "Self-billing invoice {number} has been booked as a sale",
"create_failed_title": "Could not register the self-billing invoice",
"validation_customer_required": "Select a customer",
"validation_external_number_required": "Invoice number is required",
+10 -14
View File
@@ -7,7 +7,7 @@
"cancel": "Avbryt",
"create": "Skapa",
"add": "Lägg till",
"delete": "Radera",
"delete": "Ta bort",
"edit": "Redigera",
"back": "Tillbaka",
"next": "Nästa",
@@ -201,7 +201,7 @@
"settings": {
"section_name": "Namn",
"name_label": "Ditt namn",
"name_description": "Namnet vi använder för att tilltala dig och som visas som kontaktperson på vissa underlag. Vi hälsar med ditt första namn, så skriv det du vill bli kallad först.",
"name_description": "Används när vi tilltalar dig och visas som kontaktperson på vissa underlag.",
"name_placeholder": "Förnamn Efternamn",
"name_saved": "Namnet har uppdaterats",
"name_save_failed": "Kunde inte spara namnet",
@@ -1233,7 +1233,7 @@
"vacation_supplement_cba": "0,80% (vanligt kollektivavtalsbelopp)",
"vacation_supplement_help": "Tillämpas vid sammalöneregeln. Kan ändras per anställd.",
"info_heading": "Information",
"info_payroll_scope": "Lönemodulen hanterar löner till dina anställda: skatteavdrag, arbetsgivaravgifter, semesterlöneskuld och arbetsgivardeklaration (AGI). Driver du enskild firma tar du som ägare ut pengar via eget uttag (konto 2013), inte lön. Modulen är till för dina anställda.",
"info_payroll_scope": "Lönemodulen hanterar löner till dina anställda: skatteavdrag, arbetsgivaravgifter, semesterlöneskuld och arbetsgivardeklaration (AGI). Driver du enskild firma tar du som ägare ut pengar via eget uttag (konto 2013), inte lön.",
"info_current_year": "<strong>Aktuellt år:</strong> 2026 (Arbetsgivaravgifter 31,42 %, prisbasbelopp 59 200 SEK)"
},
"salary_payments": {
@@ -1253,7 +1253,7 @@
"instructions_toggle": "Så importerar du filen i din bank",
"instructions_footer": "Beloppen är förifyllda — kvar är att signera med BankID i banken.",
"your_bank": "din bank",
"open_payments_note": "Open Payments / direktbetalning via PSD2 (utan filimport) är planerat för framtiden via Enable Banking. Initiering kräver separat PIS-avtal — vi följer upp när tillräckligt många kunder använder lönebetalfiler regelbundet.",
"open_payments_note": "Automatisk direktbetalning via open banking (utan filimport) är planerad.",
"steps_bg_lb_swedbank": "Företagsbetalningar → Importera fil → välj LB-format → ladda upp och signera med BankID. OBS: Swedbank tar inte emot LB-lönefiler efter 1 augusti 2026.",
"steps_bg_lb_seb": "Betalningar → Filöverföring → välj Bankgiro LB → ladda upp och attestera.",
"steps_bg_lb_handelsbanken": "Betala → Filimport → välj LB → kontrollera summor → signera. OBS: Handelsbanken tar inte längre emot lönefiler via Bankgirot.",
@@ -1283,7 +1283,7 @@
},
"settings_backup": {
"heading": "Säkerhetsbackup",
"intro": "Ladda ner en egen kopia av all räkenskapsinformation (SIE-filer, kvitton, underlag och behandlingshistorik) i en enda ZIP-fil. Säkerhetsbackupen är din egen kopia för trygghet och portabilitet. {appName} arkiverar all räkenskapsinformation i minst 7 år enligt BFL 7 kap. 2 §, så din backup ersätter inte vårt lagkrav; den kompletterar det."
"intro": "Ladda ner en egen kopia av all räkenskapsinformation (SIE-filer, kvitton, underlag och behandlingshistorik) i en enda ZIP-fil. {appName} arkiverar all räkenskapsinformation i minst 7 år enligt BFL 7 kap. 2 §, så din backup ersätter inte vårt lagkrav; den kompletterar det."
},
"settings_api": {},
"settings_banking": {
@@ -2316,7 +2316,6 @@
"bank_missing_warning": "Betalningsuppgifter saknas: du behöver lägga till dem innan du skapar en faktura.",
"bank_add_now": "Lägg till nu",
"customer_card_title": "Kund",
"customer_card_description": "Välj vilken kund fakturan ska skickas till",
"select_customer_placeholder": "Välj kund",
"create_customer": "Skapa kund",
"create_customer_dialog_title": "Lägg till kund",
@@ -2343,7 +2342,6 @@
"row_actions_aria": "Radåtgärder",
"drag_handle_aria": "Dra för att flytta raden",
"notes_card_title": "Anteckningar",
"notes_card_description": "Valfritt meddelande på fakturan",
"notes_placeholder": "T.ex. betalningsvillkor eller tack för samarbetet...",
"details_card_title": "Fakturadetaljer",
"document_type_label": "Dokumenttyp",
@@ -2572,7 +2570,6 @@
"reminder_marked_paid": "Kunden markerat som betald",
"reminder_objection": "Kunden har invändningar",
"credited_card_title": "Krediterad",
"credited_description": "Denna faktura har krediterats",
"see_credit_note": "Se kreditfaktura {number}",
"credit_note_card_title": "Kreditfaktura",
"credit_note_description": "Denna kreditfaktura krediterar",
@@ -2642,7 +2639,6 @@
"warning_title": "Oåterkallelig åtgärd",
"warning_description": "En kreditfaktura makulerar den ursprungliga fakturan helt. Alla belopp blir negativa, en bokföringsverifikation skapas, och den ursprungliga fakturan markeras som krediterad. Denna åtgärd kan inte ångras.",
"original_card_title": "Ursprunglig faktura",
"original_card_description": "Kreditfakturan baseras på denna faktura",
"invoice_number_label": "Fakturanummer:",
"date_label": "Datum:",
"customer_label": "Kund:",
@@ -2659,7 +2655,7 @@
"total": "Totalt",
"in_sek": "I SEK (kurs {rate})",
"reason_card_title": "Anledning",
"reason_card_description": "Ange anledning till kreditering (visas på kreditfakturan)",
"reason_card_description": "Visas på kreditfakturan",
"reason_label": "Anledning",
"reason_placeholder": "T.ex. Felaktig fakturering, returnerade varor...",
"reason_default": "Krediterar faktura {number}",
@@ -2679,7 +2675,7 @@
"created_toast_title": "Kreditfaktura skapad",
"created_toast_description": "Kreditfaktura {number} har skapats",
"create_failed_title": "Kunde inte skapa kreditfaktura",
"create_failed_fallback": "Failed to create credit note",
"create_failed_fallback": "Kunde inte skapa kreditfaktura",
"try_again": "Försök igen."
},
"invoice_recurring": {
@@ -3595,7 +3591,7 @@
"no_search_results_description": "Inget värde matchar ”{term}”.",
"viewer_disabled_tooltip": "Du har läsbehörighet och kan inte skapa värden",
"created_title": "Värde skapat",
"created_description": "{code} har lagts till i registret.",
"created_description": "{code} har lagts till i registret",
"updated_title": "Värde uppdaterat",
"deleted_title": "Värde borttaget",
"save_failed_title": "Kunde inte spara",
@@ -3746,7 +3742,7 @@
"ext_mcp_server_long_description": "Exponerar accounteds bokföringsmotor som MCP-verktyg (Model Context Protocol). Koppla din MCP-klient med en API-nyckel och gör bokföring genom konversation: visa okategoriserade transaktioner, bokför dem, skapa fakturor.",
"ext_cloud_backup_name": "Molnsynkronisering",
"ext_cloud_backup_description": "Synka säkerhetsbackup till din egen molnlagring",
"ext_cloud_backup_long_description": "Koppla ditt Google Drive-konto och ladda upp en fullständig säkerhetsbackup med ett klick. Accounted skapar en ZIP med SIE-filer, kvitton och behandlingshistorik och laddar upp till en egen mapp i din Drive. Perfekt för att uppfylla egna krav på redundans.",
"ext_cloud_backup_long_description": "Koppla ditt Google Drive-konto och ladda upp en fullständig säkerhetsbackup med ett klick. Accounted skapar en ZIP med SIE-filer, kvitton och behandlingshistorik och laddar upp till en egen mapp i din Drive.",
"ext_skatteverket_name": "Skatteverket Integration",
"ext_skatteverket_description": "Skicka momsdeklaration direkt till Skatteverket via BankID.",
"ext_skatteverket_long_description": "Anslut till Skatteverket med BankID och skicka din momsdeklaration direkt från accounted. Spara utkast, validera, lås och signera: utan att lämna appen.",
@@ -4280,7 +4276,7 @@
"viewer_disabled_tooltip": "Du har endast läsbehörighet i detta företag",
"load_customers_failed": "Kunde inte ladda kunder",
"created_title": "Självfaktura registrerad",
"created_description": "Självfaktura {number} har bokförts som försäljning.",
"created_description": "Självfaktura {number} har bokförts som försäljning",
"create_failed_title": "Kunde inte registrera självfakturan",
"validation_customer_required": "Välj en kund",
"validation_external_number_required": "Fakturanummer krävs",