From d948325a456bc8df95291b13a575d04a4d56f8af Mon Sep 17 00:00:00 2001 From: elpatron Date: Sun, 7 Jun 2026 13:44:27 +0200 Subject: [PATCH] feat: add French and Spanish locales and update language selector --- client/src/components/LanguageDropdown.tsx | 15 + client/src/i18n/index.ts | 6 +- client/src/i18n/localeKeys.test.ts | 6 +- client/src/i18n/locales/da.json | 1276 +++++++++---------- client/src/i18n/locales/de.json | 4 +- client/src/i18n/locales/en.json | 4 +- client/src/i18n/locales/es.json | 1080 ++++++++++++++++ client/src/i18n/locales/fr.json | 1080 ++++++++++++++++ client/src/i18n/locales/nb.json | 1188 +++++++++--------- client/src/i18n/locales/sv.json | 1292 ++++++++++---------- client/src/utils/i18nLanguages.test.ts | 13 +- client/src/utils/i18nLanguages.ts | 6 +- client/src/utils/seo.ts | 4 +- scripts/translate-locales.mjs | 4 +- scripts/validate-i18n-keys.mjs | 2 +- 15 files changed, 4089 insertions(+), 1891 deletions(-) create mode 100644 client/src/i18n/locales/es.json create mode 100644 client/src/i18n/locales/fr.json diff --git a/client/src/components/LanguageDropdown.tsx b/client/src/components/LanguageDropdown.tsx index 0ae7e02..7a47842 100644 --- a/client/src/components/LanguageDropdown.tsx +++ b/client/src/components/LanguageDropdown.tsx @@ -63,6 +63,21 @@ function FlagIcon({ lang, className, style }: { lang: string; className?: string ) + case 'fr': + return ( + + + + + + ) + case 'es': + return ( + + + + + ) default: return null } diff --git a/client/src/i18n/index.ts b/client/src/i18n/index.ts index d6333d6..d70d3b0 100644 --- a/client/src/i18n/index.ts +++ b/client/src/i18n/index.ts @@ -6,6 +6,8 @@ import deJson from './locales/de.json' import daJson from './locales/da.json' import svJson from './locales/sv.json' import nbJson from './locales/nb.json' +import frJson from './locales/fr.json' +import esJson from './locales/es.json' import { initSeo } from '../utils/seo.js' import { SUPPORTED_LANGUAGES } from '../utils/i18nLanguages.js' @@ -15,7 +17,9 @@ const resources = { de: { translation: deJson.translation }, da: { translation: daJson.translation }, sv: { translation: svJson.translation }, - nb: { translation: nbJson.translation } + nb: { translation: nbJson.translation }, + fr: { translation: frJson.translation }, + es: { translation: esJson.translation } } i18n diff --git a/client/src/i18n/localeKeys.test.ts b/client/src/i18n/localeKeys.test.ts index ab316ad..407ca0a 100644 --- a/client/src/i18n/localeKeys.test.ts +++ b/client/src/i18n/localeKeys.test.ts @@ -4,6 +4,8 @@ import enJson from '../i18n/locales/en.json' import daJson from '../i18n/locales/da.json' import svJson from '../i18n/locales/sv.json' import nbJson from '../i18n/locales/nb.json' +import frJson from '../i18n/locales/fr.json' +import esJson from '../i18n/locales/es.json' function collectKeys(obj: Record, prefix = ''): string[] { const keys: string[] = [] @@ -23,7 +25,9 @@ const bundles = { en: enJson.translation, da: daJson.translation, sv: svJson.translation, - nb: nbJson.translation + nb: nbJson.translation, + fr: frJson.translation, + es: esJson.translation } as const describe('i18n locale key parity', () => { diff --git a/client/src/i18n/locales/da.json b/client/src/i18n/locales/da.json index 7bf2930..6f17a43 100644 --- a/client/src/i18n/locales/da.json +++ b/client/src/i18n/locales/da.json @@ -2,20 +2,22 @@ "translation": { "app": { "name": "Kapteins Daagbok", - "tagline": "Privat yacht-logbog", + "tagline": "Privat yachtlogbog", "beta": "Beta", - "beta_hint": "Betaversion - funktioner kan stadig ændres" + "beta_hint": "Betaversion — funktionerne kan stadig ændres" }, "footer": { "kofi_label": "Ko-fi", - "kofi_title": "Støt projektet, videreudvikling og driftsomkostninger på Ko-fi" + "kofi_title": "Støt projektet, videreudviklingen og driftsomkostningerne på Ko-fi" }, "languages": { "de": "Deutsch", "en": "English", "da": "Dansk", "sv": "Svenska", - "nb": "Norsk" + "nb": "Norsk", + "fr": "Français", + "es": "Español" }, "dialog": { "ok": "OK", @@ -23,303 +25,303 @@ "no": "Nej" }, "errors": { - "load_failed": "Data kunne ikke indlæses.", - "save_failed": "Ændringer kunne ikke gemmes.", - "delete_failed": "Sletning mislykkedes.", - "export_failed": "Eksport mislykkedes." + "load_failed": "Det var ikke muligt at indlæse data.", + "save_failed": "Ændringerne kunne ikke gemmes.", + "delete_failed": "Sletningen mislykkedes.", + "export_failed": "Eksporten mislykkedes." }, "common": { - "unsaved_changes_title": "Ikke gemte ændringer", - "unsaved_changes_message": "Du har ændringer, der ikke er gemt. Vil du virkelig forlade siden? Dine ændringer vil gå tabt.", - "unsaved_changes_stay": "Bliv her", - "unsaved_changes_save_leave": "Gem og forlad", - "unsaved_changes_discard": "Kassér", - "unsaved_changes_leave": "Forladelse" + "unsaved_changes_title": "Ugemte ændringer", + "unsaved_changes_message": "Du har ugemte ændringer. Vil du virkelig forlade siden? Dine ændringer går tabt.", + "unsaved_changes_stay": "Blive", + "unsaved_changes_save_leave": "Gem og afslut", + "unsaved_changes_discard": "Afvis", + "unsaved_changes_leave": "Forladt" }, "nav": { "dashboard": "Dashboard", "vessel": "Skibsdata", - "crew": "Crew", - "deviation": "Tabel over distraktioner", - "logs": "Indlæg i logbogen", + "crew": "Besætning", + "deviation": "Afledningstabel", + "logs": "Logbogsnotater", "stats": "Statistik", "settings": "Indstillinger", "admin": "Admin" }, "auth": { - "welcome": "Velkommen til Kapteins Daagbok.", - "tagline": "Din sikre, E2E-krypterede maritime logbog.", - "register": "Registrer dig med Passkey.", - "login": "Log ind med Passkey.", + "welcome": "Velkommen til Kapteins Daagbok", + "tagline": "Dit sikre, E2E-krypterede skibslogbog.", + "register": "Tilmeld dig med Passkey", + "login": "Log ind med Passkey", "login_as": "Log ind som {{name}}", - "quick_login": "Hurtigt login", + "quick_login": "Hurtig login", "forget_account": "Glemt konto på denne enhed", "not_user": "Ikke {{name}}?", - "recovery_title": "Din genoprettelsesnøgle", + "recovery_title": "Din gendannelsesnøgle", "recovery_warning": "VIGTIGT: Skriv disse 12 ord ned. Hvis du mister din Passkey og disse ord, kan dine data ikke gendannes.", "confirm_recovery": "Jeg har skrevet ordene ned", "status_logged_in": "Logget ind", - "status_logged_out": "Aflyst", + "status_logged_out": "Logget ud", "copied": "Kopieret!", - "copy_phrase": "Kopieringstast", - "enter_recovery": "Indtast genoprettelsesnøgle", - "recovery_fallback_warning": "Din Passkey er blevet godkendt, men din enhed understøtter ikke hardwarebaseret nøgleafledning. Indtast din genoprettelsesnøgle på 12 ord for at dekryptere din logbog.", - "recovery_placeholder": "Indtast din genoprettelsesnøgle, som består af 12 ord adskilt af mellemrum...", + "copy_phrase": "Kopier nøgle", + "enter_recovery": "Indtast gendannelsesnøglen", + "recovery_fallback_warning": "Din Passkey er blevet godkendt, men din enhed understøtter ikke hardwarebaseret nøgleudledning. Indtast din 12-ords gendannelseskode for at dekryptere din logbog.", + "recovery_placeholder": "Indtast din gendannelseskode, der består af 12 ord adskilt af mellemrum...", "back": "Tilbage", - "decrypting": "Dekryptering...", - "decrypt_logbook": "Afkodning af logbog", - "error_incorrect_recovery": "Forkert genoprettelsesnøgle. Dekryptering mislykkedes.", - "error_decryption_failed": "Dekryptering mislykkedes. Tjek venligst din genoprettelsesnøgle.", - "or_register": "eller registrer dig", - "explore_demo": "Udforsk demoen uden en konto", - "username_placeholder": "Brugernavn / skippernavn", - "processing": "Behandling...", + "decrypting": "Afkodning...", + "decrypt_logbook": "Afkode logbogen", + "error_incorrect_recovery": "Forkert gendannelsesnøgle. Dekryptering mislykkedes.", + "error_decryption_failed": "Dekrypteringen mislykkedes. Kontroller venligst din gendannelsesnøgle.", + "or_register": "eller Opret konto", + "explore_demo": "Udforsk demoen uden at oprette en konto", + "username_placeholder": "Brugernavn / Skippernavn", + "processing": "Behandler...", "help": "Hjælp", "setup_pin_title": "Opsæt lokal PIN-kode (valgfrit)", - "setup_pin_warning": "Da din enhed ikke understøtter direkte Passkey-nøgleafledning, ville du ellers være nødt til at indtaste din 12-ordsnøgle, hver gang du logger ind på denne enhed. Opsæt en lokal PIN-kode for at undgå dette.", - "pin_placeholder": "E.G. 123456", - "pin_label": "Lokal PIN-kode (4-8 cifre)", + "setup_pin_warning": "Da din enhed ikke understøtter direkte Passkey-nøgleafledning, ville du ellers være nødt til at indtaste din 12-ords-nøgle ved hver login på denne enhed. Opret en lokal PIN-kode for at undgå dette.", + "pin_placeholder": "F.eks. 123456", + "pin_label": "Lokal PIN-kode (4–8 cifre)", "save_pin": "Gem PIN-kode og fortsæt", - "skip_pin": "Spring over og brug gendannelse", - "enter_pin_title": "Afkodning med PIN-kode", - "enter_pin_warning": "Indtast din lokale PIN-kode for at låse op for dekrypteringsnøglen på denne enhed.", - "enter_pin_placeholder": "Indtast din pinkode...", - "decrypt_with_pin": "Afkodning", - "use_recovery_instead": "Brug genoprettelsesnøgler i stedet", + "skip_pin": "Spring over og brug genopretning", + "enter_pin_title": "Dekrypter med PIN-kode", + "enter_pin_warning": "Indtast din lokale PIN-kode for at aktivere dekrypteringsnøglen på denne enhed.", + "enter_pin_placeholder": "Indtast din PIN-kode...", + "decrypt_with_pin": "Dekryptere", + "use_recovery_instead": "Brug i stedet gendannelsesnøglen", "error_incorrect_pin": "Forkert PIN-kode. Dekryptering mislykkedes.", - "error_invalid_host": "Passkeys virker ikke via 127.0.0.1. Åbn appen via localhost.", + "error_invalid_host": "Passkey fungerer ikke via 127.0.0.1. Åbn venligst appen via localhost.", "use_localhost_link": "Skift til localhost", - "error_passkey_cancelled": "Passkey-login blev annulleret eller udløb. Prøv igen.", - "error_invalid_rp_id": "Passkey-domæne matcher ikke (RP ID). Brug http://localhost:5173 med RP_ID=localhost i .env til lokal udvikling.", - "error_session_incomplete": "Login ufuldstændig. Log ind med passkey igen.", - "restore_checking": "Tjekker session…", + "error_passkey_cancelled": "Passkey-login afbrudt eller udløbet. Prøv igen.", + "error_invalid_rp_id": "Passkey-domænet passer ikke (RP-ID). Brug kun http://localhost:5173 med RP_ID=localhost i .env lokalt.", + "error_session_incomplete": "Tilmeldingen er ufuldstændig. Log venligst ind igen med Passkey.", + "restore_checking": "Sessionen kontrolleres…", "restore_title": "Gendan session", - "restore_subtitle": "Du er stadig logget ind. Lås din logbog op med passkey eller PIN.", - "restore_unlocking": "Låser op…", - "restore_with_passkey": "Lås op med passkey ({{name}})", - "restore_with_pin": "Lås op med PIN", - "restore_pin_warning": "Indtast din lokale PIN for at låse logbogen op efter genindlæsning.", + "restore_subtitle": "Din tilmelding er stadig aktiv. Lås din logbog op med Passkey eller din PIN-kode.", + "restore_unlocking": "Låses op…", + "restore_with_passkey": "Lås op med Passkey ({{name}})", + "restore_with_pin": "Lås op med PIN-kode", + "restore_pin_warning": "Indtast din lokale PIN-kode for at låse din logbog op efter genindlæsningen.", "restore_other_account": "Log ind med en anden konto" }, "pwa": { - "title": "Installer app", - "generic_benefit": "Installer Kapteins Daagbok på din enhed for at få hurtigere adgang, offline-brug og permanent datalagring.", - "ios_instructions": "På iPad/iPhone: Føj appen til startskærmen, så dine logbogsdata forbliver beskyttet, og appen starter som en indbygget app.", - "ios_step_share": "Tryk på aktiesymbolet i Safari-linjen", - "ios_step_add": "Vælg \"Gå til startskærm\"", + "title": "Installer appen", + "generic_benefit": "Installer Kapteins Daagbok på din enhed for at få hurtigere adgang, mulighed for offlinebrug og permanent datalagring.", + "ios_instructions": "På iPad/iPhone: Føj appen til startskærmen, så dine logbogdata forbliver beskyttet, og appen starter som en indbygget app.", + "ios_step_share": "Tryk på del-ikonet i Safari-bjælken", + "ios_step_add": "Vælg „Til startskærmen“", "install_now": "Installer nu", - "installing": "Installation...", + "installing": "Installation…", "later": "Senere", - "never": "Vis ikke mere", - "platform_ios": "Installation via Safari.", + "never": "Vis ikke længere", + "platform_ios": "Installation via Safari", "platform_android": "Installation via browseren", "platform_desktop": "Installation som desktop-app", - "settings_section": "Installation af app", - "update_title": "Opdatering tilgængelig", + "settings_section": "App-installation", + "update_title": "Der er en opdatering tilgængelig", "update_desc": "En ny version af Kapteins Daagbok er klar. Opdater venligst for at få de seneste ændringer.", "update_now": "Opdater nu", - "update_reloading": "Indlæser...", - "storage_persist_hint": "Browseren kan slette offline-data. Tillad permanent lagring, så din logbog forbliver beskyttet." + "update_reloading": "Indlæser…", + "storage_persist_hint": "Browseren kan slette offline-data. Tillad permanent lagring, så din logbog forbliver beskyttet (i browserindstillingerne eller ved næste påmindelse)." }, "sync": { "status_synced": "Synkroniseret", - "status_syncing": "Synkroniser...", + "status_syncing": "Synkroniser…", "status_offline": "Offline-cache", - "status_unsynced": "Usynkroniserede ændringer", + "status_unsynced": "Ikke-synkroniserede ændringer", "conflict_title": "Synkroniseringskonflikt", - "conflict_message": "{{count}} ændring(er) kunne ikke synkroniseres (post {{id}}…). Vælg hvilken version der skal gælde.", - "conflict_use_server": "Brug serverversion", + "conflict_message": "{{count}} Ændring(er) kunne ikke synkroniseres (post {{id}}…). Vælg venligst, hvilken version der skal gælde.", + "conflict_use_server": "Overfør serverversion", "conflict_keep_local": "Behold min version" }, "vessel": { - "title": "Skibets stamdata", - "name": "Yacht-navn", - "type": "Yacht-type", - "type_unset": "- ikke specificeret -", + "title": "Skibsstamdata", + "name": "Yachtnavn", + "type": "Bådtype", + "type_unset": "— ikke angivet —", "type_sailing": "Sejlbåd", - "type_motor": "Motorbåd", + "type_motor": "Motoryacht", "length_m": "Længde (m)", "draft_m": "Dybgang (m)", "air_draft_m": "Højde (m)", - "invalid_metric": "Ugyldig numerisk værdi - indtast venligst meter som et decimaltal (f.eks. 12,5).", + "invalid_metric": "Ugyldig talværdi — indtast venligst måleenheden som et decimaltal (f.eks. 12,5).", "port": "Hjemmehavn", - "owner": "Ejer", - "charter": "Charterselskab", + "owner": "Ejeren", + "charter": "Charterfirma", "registration": "Nummerplade/registreringsnummer", "callsign": "Radiokaldesignal", - "atis": "ATIS nr.", - "mmsi": "MMSI-nr.", + "atis": "ATIS-nr.", + "mmsi": "MMSI-nummer", "save": "Gem skibsdata", - "saving": "Vil blive reddet...", - "saved": "Skibsdata er gemt med succes!", - "loading": "Skibsdata er indlæst...", + "saving": "Gemmes...", + "saved": "Skibsdata gemt!", + "loading": "Skibsdata indlæses...", "sails_list": "Sejl (eksisterende sejl)", - "sails_help": "Indtast de sejl, der er tilgængelige på din båd her (f.eks. storsejl, genua, fok).", + "sails_help": "Indtast her de sejl, der er til rådighed på dit skib (f.eks. storsejl, genua, fok).", "add_sail": "Tilføj sejl", - "sail_name_placeholder": "z. f.eks. storsejl", - "no_sails": "Ingen sejl opbevaret.", + "sail_name_placeholder": "f.eks. storsejl", + "no_sails": "Der er ikke registreret nogen sejl.", "photo_add": "Tilføj foto", - "photo_change": "Skift foto", + "photo_change": "Skift billede", "photo_delete": "Slet foto", "tanks_section": "Tanke (kapacitet)", - "tanks_help": "Valgfrit i liter - muliggør slider i journalen for kendte tankstørrelser.", + "tanks_help": "Valgfrit i liter — muliggør brug af skyderen i journalen ved kendte tankstørrelser.", "freshwater_capacity_l": "Drikkevand (liter)", "fuel_capacity_l": "Brændstof (liter)", "greywater_capacity_l": "Gråt vand (liter)", - "invalid_tank_liters": "Ugyldig numerisk værdi - indtast venligst liter som et tal (f.eks. 200)." + "invalid_tank_liters": "Ugyldig talværdi — indtast venligst liter som et tal (f.eks. 200)." }, "logs": { - "title": "Logbogsdagbog", - "new_entry": "Ny rejsedag", - "travel_details": "Detaljer om rejsen", - "add_event": "Tilføj ny logbogspost", + "title": "Logbog", + "new_entry": "En ny rejsedag", + "travel_details": "Rejseoplysninger", + "add_event": "Tilføj en ny logbogspost", "add_event_btn": "Tilføj begivenhed", "edit_event": "Rediger begivenhed", "save_event_btn": "Gem ændring", "cancel_event_edit": "Annuller", "delete_event": "Slet begivenhed", - "sign_cleared_skipper_re_sign_title": "Skippers underskrift fjernet", + "sign_cleared_skipper_re_sign_title": "Skipperens underskrift fjernet", "sign_cleared_skipper_re_sign": "Hændelsesloggen er blevet ændret. Skipperens underskrift er blevet fjernet. Godkend venligst igen.", - "date": "dato", + "date": "Dato", "day_of_travel": "Rejsedag", "travel_day_number": "Rejsedag {{number}}", - "departure": "Starthavn (rejse fra)", - "destination": "Destinationsport (til)", - "route": "Reje fra/til", + "departure": "Afgangshavn (rejse fra)", + "destination": "Ankomsthavn (til)", + "route": "Rejse fra/til", "tanks": "Tanke", "customize_columns": "Tilpas kolonner", - "column_selector_title": "Kolonner at vise", + "column_selector_title": "Kolonner, der skal vises", "freshwater": "Ferskvand (liter)", - "fuel": "Treibstoff / Brændstof (liter)", + "fuel": "Brændstof (liter)", "greywater": "Gråt vand (liter)", - "greywater_level": "Fyldningsniveau", + "greywater_level": "Niveaumåler", "tank_slider_of_max": "{{current}} / {{max}} L", - "tank_capacity_tooltip": "Hvis tankkapaciteten (liter) er gemt i skibsdataene, kan du indtaste fyldningsniveauerne her ved hjælp af skyderen.", - "morning": "Stå op om morgenen", + "tank_capacity_tooltip": "Hvis tankkapaciteten (i liter) er angivet i skibsdataene, kan du indtaste fyldningsniveauerne her ved hjælp af skyderen.", + "morning": "Situationen om morgenen", "refilled": "Genopfyldt", - "evening": "Stand om aftenen", - "consumption": "Dagligt forbrug", - "signatures": "Underskrifter / frigivelse", - "sign_skipper": "Skippers underskrift", - "sign_crew": "Crew-signatur", - "sign_hint": "Tegn med finger, pen eller mus", - "sign_clear": "Sletning", + "evening": "Situationen om aftenen", + "consumption": "Dagsforbrug", + "signatures": "Underskrifter / Godkendelse", + "sign_skipper": "Skipperens underskrift", + "sign_crew": "Besætningens underskrift", + "sign_hint": "Underskriv med fingeren, en pen eller musen", + "sign_clear": "Slet", "sign_export_image": "[Underskrift]", - "sign_with_passkey": "Frigør med Passkey.", - "sign_passkey_signing": "Der anmodes om Passkey...", - "sign_passkey_signed": "Udgivet af {{username}}", + "sign_with_passkey": "Del med Passkey", + "sign_passkey_signing": "Passkey anmodes om…", + "sign_passkey_signed": "Godkendt af {{username}}", "sign_passkey_export": "Passkey: {{username}} ({{date}})", "sign_attribution_export": "{{username}} ({{date}})", - "sign_passkey_clear": "Fjern Passkey-frigivelse", + "sign_passkey_clear": "Fjern Passkey-godkendelse", "sign_mode_passkey": "Passkey", "sign_mode_classic": "Klassisk", - "sign_passkey_failed": "Passkey Frigivelse mislykkedes", - "sign_passkey_cancelled": "Passkey Frigivelse annulleret", - "sign_invalid": "Signatur ugyldig - indholdet er blevet ændret", + "sign_passkey_failed": "Passkey-godkendelse mislykkedes", + "sign_passkey_cancelled": "Passkey-godkendelse afbrudt", + "sign_invalid": "Signaturen er ugyldig — indholdet er blevet ændret", "sign_badge_skipper": "Skipper", "sign_badge_skipper_invalid": "Ugyldig", - "sign_badge_skipper_title_valid": "Skipper har udgivet", - "sign_badge_skipper_title_invalid": "Skippers signatur er ugyldig - indholdet er blevet ændret", - "sign_classic_or_passkey": "Valgfrit: klassisk underskrift eller Passkey-frigivelse ovenfor", - "sign_crew_passkey_hint": "Crew-medlemmer med skriveadgang kan frigive via Passkey.", - "sign_offline_hint": "Passkey-Godkendelse kræver internet - klassisk underskrift mulig offline", - "sign_lock_notice": "Efter underskrivelsen kan der ikke foretages ændringer i logbogen (undtagen fotos), uden at skipper og crew skal skrive under igen.", - "sign_lock_active": "Denne post er underskrevet. Ændringer i logbogen (undtagen fotos) fjerner automatisk skipperens og crews underskrifter.", + "sign_badge_skipper_title_valid": "Skipper har godkendt", + "sign_badge_skipper_title_invalid": "Skipper-signatur ugyldig — indholdet er blevet ændret", + "sign_classic_or_passkey": "Valgfrit: klassisk underskrift eller Passkey-godkendelse øverst", + "sign_crew_passkey_hint": "Medarbejdere med skriveadgang kan dele via Passkey", + "sign_offline_hint": "Passkey-godkendelse kræver internetforbindelse — klassisk underskrift er mulig offline", + "sign_lock_notice": "Når logbogsindskriften er underskrevet, kan der ikke foretages ændringer (undtagen i fotos) uden at skipperen og besætningen skal underskrive igen.", + "sign_lock_active": "Denne indtastning er underskrevet. Ændringer i logbogen (undtagen fotos) fjerner automatisk skipperens og besætningens underskrifter.", "sign_lock_warning_title": "Bekræft underskrift", - "sign_lock_warning": "Efter underskrivelsen er det ikke længere muligt at foretage ændringer i logbogen (undtagen fotos), uden at skipper og crew skal skrive under igen.\n\nVil du gerne fortsætte?", - "sign_proceed": "Tegn", + "sign_lock_warning": "Når logbogsindførelsen er underskrevet, kan der ikke længere foretages ændringer (undtagen i fotos), uden at skipperen og besætningen skal underskrive igen.\n\nVil du fortsætte?", + "sign_proceed": "Underskriv", "sign_cancel": "Annuller", "sign_cleared_re_sign_title": "Underskrifter fjernet", - "sign_cleared_re_sign": "Logbogsoptegnelsen er blevet ændret. Skipperens og crews underskrifter er blevet fjernet. Underskriv venligst igen.", - "no_entries": "Ingen logbogsposter fundet for denne yacht. Opret din første rejsedag!", - "back_to_list": "Tilbage til tidsskriftslisten", - "save": "Gem logbogsside", - "saving": "Vil blive reddet...", - "saved": "Logbogsside gemt med succes!", - "loading": "Dagbogen er ved at blive indlæst.", + "sign_cleared_re_sign": "Logbogsnotatet er blevet ændret. Skipperens og besætningens underskrifter er blevet fjernet. Underskriv venligst igen.", + "no_entries": "Der blev ikke fundet nogen logbogspost for denne yacht. Opret din første rejsedag!", + "back_to_list": "Tilbage til tidsskriftlisten", + "save": "Gem logbogsiden", + "saving": "Gemmes...", + "saved": "Logbogsiden er gemt!", + "loading": "Journalen indlæses...", "view_mode_label": "Visning", "view_list": "Liste", "live_mode": "Live", - "live_title": "Live-journal", - "live_loading": "Live-journal indlæses...", + "live_title": "Live-Journal", + "live_loading": "Live-Journal indlæses...", "live_retry": "Prøv igen", - "live_load_error": "Live-journal kunne ikke indlæses.", - "live_action_error": "Indtastning kunne ikke gemmes.", - "live_open_editor": "Fuld editor", - "live_actions_label": "Hurtighandlinger", + "live_load_error": "Live-Journal kunne ikke indlæses.", + "live_action_error": "Indlægget kunne ikke gemmes.", + "live_open_editor": "Fuldstændig editor", + "live_actions_label": "Hurtige tilbud", "live_stream_label": "Hændelseslog", - "live_stream_title": "Journal", - "live_no_events": "Ingen indtastninger endnu — tryk på en handling.", - "live_motor_start": "Motor Start", - "live_motor_stop": "Motor Stop", - "live_cast_off": "Afsejling", - "live_moor": "Anløb", + "live_stream_title": "Tidsskrift", + "live_no_events": "Der er endnu ingen indlæg — tryk på en handling.", + "live_motor_start": "Motorstart", + "live_motor_stop": "Motorstop", + "live_cast_off": "Lægge fra", + "live_moor": "Opret", "live_sails_btn": "Sejl", "live_sails_pick": "Vælg sejl", "live_sails_pick_hint": "Tryk på flere sejl (tryk igen for at fravælge), og indtast derefter.", - "live_sails_selected": "Valgt: {{sails}}", - "live_sails_confirm": "Indtast", + "live_sails_selected": "Valg: {{sails}}", + "live_sails_confirm": "Tilmeld dig", "live_sails_confirm_count": "Indtast ({{count}})", "live_sails": "Sejl: {{sails}}", - "live_position": "Position", + "live_position": "Stillingen", "live_position_coords": "Position {{lat}}, {{lng}}", - "live_position_manual_hint": "GPS ikke tilgængelig. Indtast bredde- og længdegrad manuelt, eller prøv igen med GPS-knappen.", - "live_position_gps_loading": "Henter GPS-position…", - "live_position_invalid": "Indtast gyldige koordinater (bredde −90…90, længde −180…180).", + "live_position_manual_hint": "GPS er ikke tilgængelig. Indtast bredde- og længdegrad manuelt, eller prøv igen ved at trykke på GPS-knappen.", + "live_position_gps_loading": "GPS-positionen beregnes…", + "live_position_invalid": "Indtast venligst gyldige koordinater (breddegrad −90…90, længdegrad −180…180).", "live_position_lat_placeholder": "Bredde (Lat)", "live_position_lng_placeholder": "Længde (Lng)", "live_photo_btn": "Foto (kamera)", - "live_photo_capture_btn": "Tag billede", + "live_photo_capture_btn": "Optag", "live_photo_save_btn": "Gem", - "live_photo_retake_btn": "Tag igen", - "live_photo_capture_failed": "Optagelse mislykkedes. Prøv igen.", - "live_photo_open_camera_btn": "Åbn kamera", - "live_photo_native_hint": "Tag et foto med enhedens kamera og gem det her bagefter.", - "live_photo_camera_starting": "Starter kamera…", - "live_photo_camera_denied": "Kameraadgang nægtet eller utilgængelig.", - "live_photo_camera_unavailable": "Kamera understøttes ikke i denne browser.", - "live_photo_no_camera": "Der er intet kamera tilgængeligt på denne enhed.", - "live_photo_error": "Foto kunne ikke gemmes.", + "live_photo_retake_btn": "Optag på ny", + "live_photo_capture_failed": "Optagelsen mislykkedes. Prøv igen.", + "live_photo_open_camera_btn": "Åbn kameraet", + "live_photo_native_hint": "Tag et billede med enhedens kamera, og gem det derefter her.", + "live_photo_camera_starting": "Kameraet starter…", + "live_photo_camera_denied": "Kameraadgang nægtet eller ikke tilgængelig.", + "live_photo_camera_unavailable": "Denne browser understøtter ikke kameraet.", + "live_photo_no_camera": "Denne enhed har ikke noget kamera.", + "live_photo_error": "Det var ikke muligt at gemme billedet.", "live_photo_entry": "Foto: {{caption}}", "live_photo_entry_plain": "Foto taget", "live_undo_photo_hint": "Foto gemt", - "live_voice_btn": "Stemmenotat", - "live_voice_hint": "Optag en kort stemmenotat (maks. 60 sekunder).", + "live_voice_btn": "Talebesked", + "live_voice_hint": "Optag en kort lydbesked (maks. 60 sekunder).", "live_voice_record": "Start optagelse", - "live_voice_stop": "Stop optagelse", - "live_voice_recording": "Optager {{time}}", + "live_voice_stop": "Afslut optagelse", + "live_voice_recording": "Optagelse {{time}}", "live_voice_save": "Gem", - "live_voice_saving": "Gemmer…", - "live_voice_retake": "Optag igen", - "live_voice_mic_denied": "Mikrofonadgang nægtet eller utilgængelig.", - "live_voice_record_failed": "Optagelse mislykkedes. Prøv igen.", - "live_voice_unavailable": "Stemmenotat utilgængelig", - "live_voice_too_large": "Optagelsen er for stor. Optag venligst kortere.", - "live_voice_error": "Kunne ikke gemme stemmenotat.", - "live_voice_entry": "Stemmenotat: {{caption}}", - "live_voice_entry_plain": "Stemmenotat", - "live_voice_caption_label": "Billedtekst (valgfrit)", - "live_voice_caption_placeholder": "f.eks. radiokontakt med havnemester", - "live_voice_transcribe_action": "Transkribere", - "live_voice_transcribing": "Transkriberer…", - "live_voice_transcribe_failed": "Stemmebesked gemt, men transkribering mislykkedes.", - "live_undo_voice_hint": "Stemmenotat gemt", + "live_voice_saving": "Gemmes…", + "live_voice_retake": "Optag på ny", + "live_voice_mic_denied": "Der er ingen adgang til mikrofonen, eller den er ikke tilgængelig.", + "live_voice_record_failed": "Optagelsen mislykkedes. Prøv igen.", + "live_voice_unavailable": "Talebesked ikke tilgængelig", + "live_voice_too_large": "Optagelsen er for lang. Optag venligst en kortere version.", + "live_voice_error": "Det var ikke muligt at gemme lydbeskeden.", + "live_voice_entry": "Talebesked: {{caption}}", + "live_voice_entry_plain": "Talebesked", + "live_voice_caption_label": "Tekst (valgfrit)", + "live_voice_caption_placeholder": "f.eks. radiokommunikation med havnefogeden", + "live_voice_transcribe_action": "Transskribere", + "live_voice_transcribing": "Transkriber...", + "live_voice_transcribe_failed": "Talememo gemt, men transskriptionen mislykkedes.", + "live_undo_voice_hint": "Talebesked gemt", "live_comment_btn": "Kommentar", - "live_comment_placeholder": "Indtast tekst…", - "live_comment_confirm": "Indtast", - "live_gps_error": "GPS-position kunne ikke bestemmes.", - "live_gps_start_hint": "Begynd altid dagens rejse med en position.", - "live_event_generic": "Hændelse", + "live_comment_placeholder": "Indtast fritekst…", + "live_comment_confirm": "Tilmeld dig", + "live_gps_error": "GPS-positionen kunne ikke fastslås.", + "live_gps_start_hint": "Start altid din dagstur med at finde en position.", + "live_event_generic": "Begivenhed", "live_weather_btn": "Vejr", - "live_weather_owm_btn": "Hent OpenWeatherMap-vejr", - "live_weather_owm_loading": "Henter vejr…", - "live_weather_position_required": "Log først en position (Position-knap) for at hente OpenWeatherMap-vejr. Positionen må højst være 6 timer gammel.", - "live_weather_position_stale": "Den seneste position er ældre end 6 timer. Log en ny position, før du henter vejr.", + "live_weather_owm_btn": "OpenWeatherMap Hent vejrudsigt", + "live_weather_owm_loading": "Vejret indlæses…", + "live_weather_position_required": "For vejr fra OpenWeatherMap skal du først indtaste en position (knappen „Position“). Positionen må højst være 6 timer gammel.", + "live_weather_position_stale": "Den seneste position er mere end 6 timer gammel. Log venligst en ny position, før du henter vejrudsigten.", "live_wind_btn": "Vind", "live_temp_btn": "T °C", "live_pressure_btn": "Lufttryk", "live_precip_btn": "Nedbør", - "live_sea_state_btn": "Søgang", + "live_sea_state_btn": "Havets bevægelser", "live_visibility_btn": "Sigtbarhed", "live_course_btn": "Kurs", "live_fuel_btn": "+ Diesel", @@ -328,53 +330,53 @@ "live_temp_entry": "Temperatur {{temp}} °C", "live_pressure_entry": "Lufttryk {{value}} hPa", "live_precip_entry": "Nedbør {{value}}", - "live_sea_state_entry": "Søgang {{value}}", + "live_sea_state_entry": "Havets tilstand {{value}}", "live_visibility_entry": "Sigtbarhed {{value}}", "live_course_entry": "Kurs {{course}}", "live_fuel_entry": "Diesel +{{liters}} L", "live_water_entry": "Vand +{{liters}} L", - "live_auto_position": "Auto-position", - "live_undo_hint": "Indtastning gemt", + "live_auto_position": "Automatisk position", + "live_undo_hint": "Indtastningen er gemt", "live_undo_btn": "Fortryd", - "live_cancel": "Annuller", + "live_cancel": "Afbrydelse", "live_pressure_placeholder": "f.eks. 1013", "live_temp_placeholder": "f.eks. 18", "live_precip_placeholder": "f.eks. let regn", "live_sea_state_placeholder": "f.eks. 3", "live_visibility_placeholder": "f.eks. 10 km", "live_course_placeholder": "f.eks. 245", - "live_fuel_placeholder": "Optankede liter", - "live_water_placeholder": "Optankede liter", + "live_fuel_placeholder": "Genopfyldte liter", + "live_water_placeholder": "Genopfyldte liter", "live_sog_btn": "SOG", "live_stw_btn": "STW", "live_sog_entry": "SOG {{speed}} kn", "live_stw_entry": "STW {{speed}} kn", "live_sog_placeholder": "f.eks. 5,2", "live_stw_placeholder": "f.eks. 4,8", - "live_sog_hint": "Fart over grund (kn) — GPS-værdi forudfyldes, hvis tilgængelig.", - "delete_entry": "Slet tag", - "delete_confirm": "Er du sikker på, at du vil slette denne rejsedag permanent?", - "carry_over_tanks_title": "Overføre data fra den foregående dag?", - "carry_over_tanks_confirm": "Overtage starthavn, ferskvand, brændstof og gråvand fra den sidste dag på turen?\n\nStarthavn: {{departure}}\nFerskvand: {{fw}} L\nBrændstof: {{fuel}} L\nGråt vand: {{greywater}} L", - "carry_over_tanks_yes": "Tag over", - "carry_over_tanks_no": "Start med 0", + "live_sog_hint": "Afstand over jordoverfladen (kn) — GPS-værdien udfyldes automatisk, hvis den er tilgængelig.", + "delete_entry": "Slet dag", + "delete_confirm": "Er du sikker på, at du vil slette denne rejsedag endeligt?", + "carry_over_tanks_title": "Skal data fra i går overføres?", + "carry_over_tanks_confirm": "Skal starthavn, startmængder for ferskvand, brændstof og gråt vand fra den sidste rejsedag overføres?\n\nStarthavn: {{departure}}\nFerskvand: {{fw}} L\nBrændstof: {{fuel}} L\nGråt vand: {{greywater}} L", + "carry_over_tanks_yes": "Anvend", + "carry_over_tanks_no": "Starte fra 0", "event_title": "Kronologisk hændelseslog", - "event_creator": "Indtastet af", - "no_events": "Der er endnu ikke indtastet nogen begivenheder for denne rejsedag.", - "event_time": "Tidspunkt på dagen", + "event_creator": "Indsendt af", + "no_events": "Der er endnu ikke registreret nogen begivenheder for denne rejsedag.", + "event_time": "Tidspunkt", "event_mgk": "MgK-kursus", - "event_rwk": "RwK-kursus", + "event_rwk": "RwK-kurs", "event_course_section": "Kursus", - "course_dial_hint": "Drej ringen eller indtast grader", - "course_dial_step_label": "Trinstørrelse", + "course_dial_hint": "Drej på ringen eller indtast en vinkel", + "course_dial_step_label": "Trinvidde", "course_step_fine": "1°", "course_step_medium": "5°", "course_step_coarse": "10°", "course_tab_mgk": "MgK", "course_tab_rwk": "rwK", - "course_invalid": "Ugyldigt kursus (0-360)", - "course_placeholder_degrees": "z. B. 180", - "course_placeholder_cardinal": "z. E.G. NW", + "course_invalid": "Ugyldig kurs (0–360)", + "course_placeholder_degrees": "f.eks. 180", + "course_placeholder_cardinal": "f.eks. NW", "compass_n": "N", "compass_e": "O", "compass_s": "S", @@ -383,324 +385,324 @@ "wind_mode_degrees": "Som grad", "event_wind_direction": "Vindretning", "event_wind_strength": "Vindstyrke", - "event_sea_state": "Havets tilstand", + "event_sea_state": "Havets bevægelser", "event_visibility": "Sigtbarhed", "event_visibility_placeholder": "f.eks. 10 km", "weather_slider_unset": "—", "weather_slider_pressure": "{{value}} hPa", - "weather_slider_sea_state": "Trin {{value}}", + "weather_slider_sea_state": "Niveau {{value}}", "weather_slider_heel": "{{value}}°", "event_weather": "Vejret", - "event_log": "Log (sm)", + "event_log": "Logge (sm)", "event_gps": "GPS-position", - "event_location": "Sted/havn", - "event_location_placeholder": "z. f.eks. Kiel", - "event_remarks": "Bemærkninger / hændelser", + "event_location": "Sted / Havn", + "event_location_placeholder": "f.eks. Kiel", + "event_remarks": "Bemærkninger / Hændelser", "gps_btn": "Hent GPS-koordinater", - "gps_permission_denied": "Adgang til placering blev nægtet. Tillad det i browser- eller enhedsindstillinger og prøv igen.", - "gps_timeout": "GPS fik timeout. Prøv igen udendørs med frit udsyn til himlen.", - "gps_position_unavailable": "Intet GPS-signal tilgængeligt. Vent og prøv igen, eller indtast koordinater manuelt.", - "gps_unavailable": "GPS understøttes ikke af denne browser eller enhed.", - "gps_failed": "GPS-position kunne ikke bestemmes.", - "gps_fallback_no_location": "GPS mislykkedes. Angiv et sted under placering/havn, afgang eller destination, eller indtast koordinater manuelt.", - "gps_fallback_success": "Koordinater for \"{{location}}\" fundet via stedsnavn (ikke GPS).", - "gps_fallback_failed": "GPS og stedsnavnssøgning mislykkedes. Indtast koordinater manuelt.", + "gps_permission_denied": "Adgang til placering blev afvist. Tillad det i browser- eller enhedsindstillingerne, og prøv igen.", + "gps_timeout": "GPS-tidsoverskridelse. Prøv igen – helst udendørs, hvor der er god dækning.", + "gps_position_unavailable": "Der er ikke noget GPS-signal. Vent venligst, eller indtast koordinaterne manuelt.", + "gps_unavailable": "GPS understøttes ikke af denne browser eller denne enhed.", + "gps_failed": "GPS-positionen kunne ikke fastslås.", + "gps_fallback_no_location": "GPS-opkobling mislykkedes. Indtast venligst en destination under „Sted / Havn“, start- eller ankomsthavn, eller indtast koordinaterne manuelt.", + "gps_fallback_success": "Koordinaterne for „{{location}}“ er fastlagt ud fra stednavnet (ikke via GPS).", + "gps_fallback_failed": "GPS- og stednavnesøgningen mislykkedes. Indtast venligst koordinaterne manuelt.", "gps_quality_excellent": "Stærk GPS-modtagelse (±{{accuracy}} m)", "gps_quality_good": "God GPS-modtagelse (±{{accuracy}} m)", - "gps_quality_fair": "Middel GPS-modtagelse (±{{accuracy}} m) – gå udendørs for bedre signal.", - "gps_quality_poor": "Svag GPS-modtagelse (±{{accuracy}} m) – sandsynligvis få satellitter. Prøv udendørs igen eller kontroller positionen.", - "gps_quality_unknown": "GPS-position overtaget (nøjagtighed ikke rapporteret af enheden).", - "gps_live_intro_title": "Placering til live-log", - "gps_live_intro_body": "Appen har brug for din placering til automatiske positionsindlæg og GPS-knappen.\n\nTryk på „Tillad placering“ og bekræft i den næste dialog. Du kan altid indtaste position manuelt via „Position“.", - "gps_live_intro_allow": "Tillad placering", + "gps_quality_fair": "Middelmådig GPS-modtagelse (±{{accuracy}} m) – gå udendørs for at få bedre modtagelse.", + "gps_quality_poor": "Svag GPS-modtagelse (±{{accuracy}} m) – sandsynligvis få satellitter. Prøv igen udendørs, eller kontroller positionen.", + "gps_quality_unknown": "GPS-position overført (nøjagtighed ikke angivet af enheden).", + "gps_live_intro_title": "Placering for Live-Log", + "gps_live_intro_body": "For at kunne registrere positioner automatisk og bruge GPS-knappen skal appen have adgang til din placering.\n\nTryk på „Tillad placering“ – bekræft tilladelsen i den næste dialogboks. Du kan til enhver tid indtaste en position manuelt under „Position“.", + "gps_live_intro_allow": "Tillad adgang til placering", "gps_live_intro_later": "Senere", - "gps_enable_in_settings_hint": "Adgang til placering er blokeret. Du kan tillade det senere i browser- eller enhedsindstillinger (websted / app → Placering).", - "weather_btn": "OpenWeatherMap Kald vejret op", - "weather_offline": "OpenWeatherMap kræver internetforbindelse. Du er offline lige nu.", + "gps_enable_in_settings_hint": "Adgang til din placering er blokeret. Du kan senere give tilladelse i browser- eller enhedsindstillingerne (hjemmeside/app → placering).", + "weather_btn": "OpenWeatherMap Hent vejrudsigt", + "weather_offline": "OpenWeatherMap kræver en internetforbindelse. Du er i øjeblikket offline.", "event_wind_pressure": "Lufttryk (hPa)", "event_heel": "Krængning (°)", - "event_sails": "Sejlhåndtering/motor", - "motor_propulsion": "Kørsel med maskine", + "event_sails": "Sejlads / Motor", + "motor_propulsion": "Maskinkørsel", "sails_picker_show_more": "Vis alle sejl", - "sails_picker_show_less": "Vis mindre", - "motor_hours": "Maskintimer (i alt)", + "sails_picker_show_less": "Vis færre", + "motor_hours": "Maskin timer (i alt)", "fuel_per_motor_hour": "Forbrug pr. maskintime", - "event_distance": "Afstand (nm)", - "export_csv": "Download CSV.", - "share_csv": "CSV andel", - "export_pdf": "Download PDF.", - "exporting_pdf": "PDF er genereret...", - "ai_summary_title": "AI-resumé", - "ai_summary_read_only": "Oprettet af skipperen — kun læsning for besætningen.", - "ai_summary_empty": "Intet resumé endnu.", - "ai_summary_generate": "Generér resumé", - "ai_summary_regenerate": "Generér igen", - "ai_summary_generating": "Genererer…", - "ai_summary_attempts_remaining": "{{remaining}} af {{max}} forsøg tilbage", - "ai_summary_error": "AI-resumé mislykkedes. Prøv igen senere.", - "ai_summary_error_no_key": "Ingen OpenRouter API-nøgle konfigureret på serveren.", - "ai_summary_error_rate_limited": "Maksimalt antal genereringer nået for denne rejsedag.", - "ai_summary_error_forbidden": "Kun skipperen må generere AI-resuméer.", - "ai_summary_offline": "AI-resumé kræver internetforbindelse. Du er offline lige nu.", - "photos_title": "Vedhæftede billeder", - "photo_caption_label": "Fotobeskrivelse/etiket (valgfrit)", - "photo_caption_placeholder": "f.eks. at sætte sejl nær indsejlingen til havnen", - "photo_btn": "Tag foto / upload", - "photo_camera_btn": "Tag foto", - "photo_gallery_btn": "Vælg fra galleri", - "photo_processing": "Er ved at blive behandlet...", - "no_photos": "Der er endnu ingen billeder knyttet til denne rejsedag.", - "photo_delete_confirm": "Er du sikker på, at du vil slette dette foto permanent?", + "event_distance": "Afstand (sm)", + "export_csv": "CSV Download", + "share_csv": "CSV del", + "export_pdf": "PDF Download", + "exporting_pdf": "PDF genereres...", + "ai_summary_title": "AI-opsummering", + "ai_summary_read_only": "Oprettet af skipperen — kan kun læses af besætningen.", + "ai_summary_empty": "Der findes endnu ikke noget resumé.", + "ai_summary_generate": "Generer resumé", + "ai_summary_regenerate": "Generer på ny", + "ai_summary_generating": "Genereres…", + "ai_summary_attempts_remaining": "Der er endnu {{remaining}} af {{max}} forsøg tilbage", + "ai_summary_error": "AI-opsummeringen mislykkedes. Prøv igen senere.", + "ai_summary_error_no_key": "Der er ikke konfigureret en OpenRouter API-nøgle på serveren.", + "ai_summary_error_rate_limited": "Det maksimale antal genereringer for denne rejsedag er nået.", + "ai_summary_error_forbidden": "Kun skipperen må generere AI-opsummeringer.", + "ai_summary_offline": "AI-opsummeringen kræver en internetforbindelse. Du er i øjeblikket offline.", + "photos_title": "Fotobilag", + "photo_caption_label": "Fotobeskrivelse / Etiket (valgfrit)", + "photo_caption_placeholder": "f.eks. sætte sejl nær havneindsejlingen", + "photo_btn": "Tag/upload et billede", + "photo_camera_btn": "Tag et billede", + "photo_gallery_btn": "Vælg fra galleriet", + "photo_processing": "Behandles...", + "no_photos": "Der er endnu ikke vedhæftet nogen fotos fra denne rejsedag.", + "photo_delete_confirm": "Er du sikker på, at du vil slette dette billede endeligt?", "confirm_yes": "Ja", "confirm_no": "Nej", "track_upload_title": "GPS-spor (fil)", "track_upload_points": "Point", - "gps_tracking_btn_gpx": "Download sporfilen", + "gps_tracking_btn_gpx": "Download spor-fil", "gps_track_upload_help": "Træk en GPX-, KML- eller GeoJSON-fil hertil, eller klik for at vælge", "gps_track_upload_btn": "Upload GPS-spor", - "gps_track_delete": "Slet sporfilen", + "gps_track_delete": "Slet sporfil", "gps_track_delete_confirm": "Er du sikker på, at du vil slette denne sporfil permanent?", "track_distance": "GPS-rute (sm)", - "track_speed_max": "Maks. Hastighed (kn)", - "track_speed_avg": "Ø Hastighed (kn)", + "track_speed_max": "Maks. hastighed (kn)", + "track_speed_avg": "Gennemsnitlig hastighed (kn)", "track_map_title": "GPS-spor på OpenSeaMap", "track_map_start": "Start", "track_map_end": "Mål", "track_map_speed_slow": "langsomt", "track_map_speed_fast": "hurtigt", - "track_map_error": "Kortet kunne ikke indlæses.", - "exporting": "Eksport...", - "share_unsupported": "Deling understøttes ikke på denne enhed. Filen er blevet downloadet i stedet.", - "invite_crew": "Inviter crewen", - "invite_link_copied": "Invitationslink kopieret til udklipsholderen!", - "invite_link_desc": "Del dette link med Crew-medlemmer for at give dem skriveadgang til denne logbog.", - "collaborators_list": "Medlemmer / crew", - "revoke": "Fjerne", - "revoke_confirm": "Er du sikker på, at du vil tilbagekalde dette Crew-medlems adgang?", - "invite_role": "Rolle", - "invite_expires": "Linket er gyldigt i 48 timer", - "nmea_import_title": "Import NMEA log", - "nmea_import_intro": "Upload a .nmea file from your onboard logger. The app suggests journal entries — you choose what to import.", - "nmea_import_btn": "Import NMEA", - "nmea_file_label": "NMEA file", - "nmea_stats": "{{lines}} sentences parsed · types: {{types}}", - "nmea_warn_no_position": "No position sentences found — track and GPS fields may stay empty.", - "nmea_mode_label": "Generate journal entries", - "nmea_mode_interval": "By time interval", - "nmea_mode_change": "On significant change", - "nmea_mode_both": "Both (merge)", - "nmea_interval_label": "Interval (minutes)", - "nmea_import_track": "Import GPS track from NMEA", - "nmea_preview": "Preview", - "nmea_preview_hint": "{{count}} suggested journal entries", - "nmea_select_all": "Select all", - "nmea_select_none": "Select none", + "nmea_import_title": "Importer NMEA-protokol", + "nmea_import_intro": "Indlæs en .nmea-fil fra loggeren om bord. Appen foreslår logbogspost — du bestemmer selv, hvad der skal overføres.", + "nmea_import_btn": "Importer NMEA", + "nmea_file_label": "NMEA-fil", + "nmea_stats": "{{lines}} sæt genkendt · Typer: {{types}}", + "nmea_warn_no_position": "Der blev ikke fundet nogen positionssæt — spor- og GPS-felter kan stå tomme.", + "nmea_warn_duplicate_file": "Denne NMEA-fil er allerede importeret. Hvis du importerer den samme fil igen, vil der blive tilføjet dobbelte logbogspost.", + "nmea_mode_label": "Oprette journalposter", + "nmea_mode_interval": "Efter tidsinterval", + "nmea_mode_change": "Ved væsentlige ændringer", + "nmea_mode_both": "Begge dele (sammenføje)", + "nmea_interval_label": "Interval (minutter)", + "nmea_import_track": "Importer GPS-spor fra NMEA", + "nmea_preview": "Forhåndsvisning", + "nmea_preview_hint": "{{count}} foreslåede journalposter", + "nmea_select_all": "Vælg alle", + "nmea_select_none": "Vælg ingen", "nmea_source_interval": "Interval", - "nmea_source_change": "Event", - "nmea_apply": "Apply to journal", - "nmea_back": "Back", - "nmea_cancel": "Cancel", - "nmea_archive_question": "Archive raw log locally? (This device only, not synced.)", - "nmea_archive_keep": "Archive", - "nmea_archive_discard": "Discard", - "nmea_archive_stored": "NMEA archived: {{name}}", - "nmea_archive_delete_confirm": "Delete archived NMEA log from this device?", - "nmea_error_no_samples": "No usable NMEA sentences in the file.", - "nmea_error_parse": "Could not read NMEA file.", - "nmea_error_read": "Could not read file.", - "nmea_error_no_file": "Please choose an NMEA file first.", - "nmea_error_no_selection": "Please select at least one journal entry.", - "nmea_remark_interval": "NMEA interval", - "nmea_remark_uncertain": "uncertain", - "nmea_remark_depth": "Depth {{depth}} m", - "nmea_change_course": "Course change {{from}}° → {{to}}°", - "nmea_change_wind": "Wind {{from}}° → {{to}}°", - "nmea_change_wind_speed": "Wind {{from}} → {{to}} kn", - "nmea_change_pressure": "Pressure {{from}} → {{to}} hPa", - "nmea_change_depth": "Depth {{from}} → {{to}} m", - "nmea_change_engine_start": "Engine on ({{rpm}} rpm)", - "nmea_change_engine_stop": "Engine off", - "nmea_change_autopilot_on": "Autopilot on", - "nmea_change_autopilot_off": "Autopilot off", - "nmea_change_gps_lost": "GPS-position mistet", - "nmea_change_gps_regained": "GPS-position gendannet", - "nmea_change_water_temp": "Water temp. {{from}} → {{to}} °C", - "nmea_change_departure": "Departure / underway", - "nmea_change_anchor": "Anchored / stop", - "nmea_change_speed": "Speed {{from}} → {{to}} kn", - "nmea_warn_duplicate_file": "This NMEA file has already been imported. Importing the same file again will add duplicate journal entries." + "nmea_source_change": "Begivenhed", + "nmea_apply": "Overfør til journalen", + "nmea_back": "Tilbage", + "nmea_cancel": "Annuller", + "nmea_archive_question": "Skal råprotokollen arkiveres lokalt? (Kun på denne enhed, ikke synkroniseret.)", + "nmea_archive_keep": "Arkivering", + "nmea_archive_discard": "Afvis", + "nmea_archive_stored": "NMEA-arkiv: {{name}}", + "nmea_archive_delete_confirm": "Skal den arkiverede NMEA-log fra denne enhed slettes?", + "nmea_error_no_samples": "Der er ingen brugbare NMEA-sætninger i filen.", + "nmea_error_parse": "NMEA-filen kunne ikke læses.", + "nmea_error_read": "Filen kunne ikke læses.", + "nmea_error_no_file": "Vælg først en NMEA-fil.", + "nmea_error_no_selection": "Vælg mindst én journalpost.", + "nmea_remark_interval": "NMEA-interval", + "nmea_remark_uncertain": "usikker", + "nmea_remark_depth": "Dybde {{depth}} m", + "nmea_change_course": "Kursændring {{from}}° → {{to}}°", + "nmea_change_wind": "Vind {{from}}° → {{to}}°", + "nmea_change_wind_speed": "Vind {{from}} → {{to}} kn", + "nmea_change_pressure": "Lufttryk {{from}} → {{to}} hPa", + "nmea_change_depth": "Dybde {{from}} → {{to}} m", + "nmea_change_engine_start": "Motor tændt ({{rpm}} o/min)", + "nmea_change_engine_stop": "Motor slukket", + "nmea_change_autopilot_on": "Autopilot til", + "nmea_change_autopilot_off": "Autopilot slået fra", + "nmea_change_gps_lost": "GPS-positionen er gået tabt", + "nmea_change_gps_regained": "GPS-position genoprettet", + "nmea_change_water_temp": "Vandtemperatur {{from}} → {{to}} °C", + "nmea_change_departure": "Afgang / Turens start", + "nmea_change_anchor": "Anker / Stop", + "nmea_change_speed": "Hastighed {{from}} → {{to}} kn", + "track_map_error": "Kortet kunne ikke indlæses.", + "exporting": "Eksporter...", + "share_unsupported": "Deling understøttes ikke på denne enhed. Filen er i stedet blevet downloadet.", + "invite_crew": "Inviter besætningen", + "invite_link_copied": "Inviteringslinket er kopieret til udklipsholderen!", + "invite_link_desc": "Del dette link med besætningsmedlemmerne for at give dem skriveadgang til denne logbog.", + "collaborators_list": "Medlemmer / Besætning", + "revoke": "Fjern", + "revoke_confirm": "Er du sikker på, at du vil fjerne dette besætningsmedlems adgang?", + "invite_role": "Rolle", + "invite_expires": "Linket er gyldigt i 48 timer" }, "dashboard": { "title": "Dine logbøger", - "subtitle": "Vælg en logbog, eller opret en ny til at styre dine rejser.", + "subtitle": "Vælg en rejsejournal, eller opret en ny for at holde styr på dine rejser.", "create_btn": "Opret logbog", - "new_logbook_placeholder": "Navn på logbog eller yacht", + "new_logbook_placeholder": "Navnet på logbogen eller båden", "logout": "Log ud", "logged_in_as": "Logget ind som {{name}}", - "delete_confirm": "Er du sikker på, at du vil slette denne logbog permanent? Alle lokale data og serverkopier vil blive destrueret.\n\nTip: Lav en sikkerhedskopi (.daagbok) på forhånd under Indstillinger → Sikkerhedskopiering og gendannelse, hvis du vil beholde dataene senere.", - "no_logbooks": "Ingen logbøger fundet. Opret din første logbog for at komme i gang!", - "loading": "Logbøgerne er fyldt op...", + "delete_confirm": "Er du sikker på, at du vil slette denne logbog endeligt? Alle lokale data og serverkopier vil blive slettet.\n\nTip: Opret først en sikkerhedskopi (.daagbok) under Indstillinger → Sikkerhedskopiering og gendannelse, hvis du vil beholde dataene senere.", + "no_logbooks": "Der blev ikke fundet nogen logbøger. Opret din første logbog for at komme i gang!", + "loading": "Logbøger indlæses...", "status_synced": "Synkroniseret", "status_local": "Kun lokal cache", "delete_btn": "Slet logbog", "section_owned": "Mine logbøger", - "section_shared": "Fælles logbøger", - "section_shared_hint": "Du er blevet inviteret som Crew-medlem. Skipperprofil og indstillinger tilhører ejeren.", + "section_shared": "Delte logbøger", + "section_shared_hint": "Du er blevet inviteret som besætningsmedlem. Skipperens profil og indstillinger tilhører ejeren.", "role_owner": "Egen logbog", "role_owner_hint": "Du er ejer og skipper af denne logbog", - "role_crew": "Adgang for crew", - "role_crew_hint": "Inviteret logbog - du kan arbejde som crew og underskrive den", - "role_read": "Læs kun", - "role_read_hint": "Opdelt logbog - kun visning, ingen redigering", - "open_profile": "Åben profil af {{name}}", - "open_logbook": "Åbn logbog „{{title}}“", + "role_crew": "Adgang for besætningen", + "role_crew_hint": "Gæstebog — du kan bidrage som besætningsmedlem og skrive din hilsen", + "role_read": "Kun læsning", + "role_read_hint": "Delt logbog — kun visning, ingen redigering", + "open_profile": "Åbn profil for {{name}}", + "open_logbook": "Åbn logbogen „{{title}}“", "edit_title": "Omdøb logbog", - "edit_placeholder": "Nyt navn på logbogen", - "edit_success": "Logbog omdøbt med succes", + "edit_placeholder": "Logbogens nye navn", + "edit_success": "Logbogen er blevet omdøbt", "edit_btn": "Omdøb", "filter_label": "Filtrer logbøger", - "filter_placeholder": "Navn, årstal, dato, crew eller skib …", + "filter_placeholder": "Navn, år, dato, besætning eller skib …", "filter_clear": "Nulstil filter", - "filter_results": "{{count}} Hits", - "filter_no_results": "Ingen logbøger matcher din søgning. Prøv med et andet navn eller et andet år.", - "sort_label": "Sortere", + "filter_results": "{{count}} resultater", + "filter_no_results": "Der er ingen logbøger, der matcher din søgning. Prøv med et andet navn eller et andet år.", + "sort_label": "Sorter", "sort_by_label": "Sorter efter", "sort_by_name": "Navn", - "sort_by_date": "dato", - "sort_dir_label": "Sekvens", + "sort_by_date": "Dato", + "sort_dir_label": "Rækkefølge", "sort_asc": "Stigende", - "sort_desc": "Nedadgående", - "sort_name_asc": "Navn A til Z", - "sort_name_desc": "Navn Z til A", + "sort_desc": "Faldende", + "sort_name_asc": "Navn fra A til Z", + "sort_name_desc": "Navn fra Z til A", "sort_date_asc": "Ældste først", - "sort_date_desc": "Nyeste først" + "sort_date_desc": "Seneste først" }, "profile": { "title": "Brugerprofil", - "subtitle": "Konto, Passkeys og statistik for {{name}}.", - "back": "Tilbage til instrumentbrættet", - "loading": "Profilen er ved at blive indlæst...", + "subtitle": "Konto, Passkey'er og statistikker for {{name}}", + "back": "Tilbage til oversigtssiden", + "loading": "Profil indlæses…", "load_error": "Profilen kunne ikke indlæses.", - "copy_failed": "Kopiering mislykkedes.", - "processing": "Er ved at blive behandlet...", - "identity_title": "Konto-identitet", + "copy_failed": "Kopieringen mislykkedes.", + "processing": "Behandles…", + "identity_title": "Kontooplysninger", "username": "Brugernavn", "user_id": "Bruger-ID", "copy_user_id": "Kopier bruger-ID", - "account_since": "Konto siden", - "prf_status": "Passkey nøgleafledning (PRF)", + "account_since": "Konto oprettet", + "prf_status": "Passkey-nøgleafledning (PRF)", "prf_active": "Aktiv", - "prf_inactive": "Ikke sat op", + "prf_inactive": "Ikke indrettet", "passkeys_title": "Passkeys", - "passkeys_desc": "Registrer en separat Passkey på hver enhed. På den måde kan du logge ind, selv når du har skiftet platform.", - "passkeys_empty": "Ingen Passkeys fundet.", - "add_passkey_btn": "Tilføj ny Passkey.", - "add_passkey_success": "Passkey tilføjet med succes.", + "passkeys_desc": "Opret en separat Passkey på hver enhed. På den måde kan du logge ind, selvom du skifter platform.", + "passkeys_empty": "Der blev ikke fundet nogen Passkey'er.", + "add_passkey_btn": "Tilføj ny Passkey", + "add_passkey_success": "Passkey er blevet tilføjet.", "add_passkey_failed": "Passkey kunne ikke tilføjes.", "remove_passkey_btn": "Fjern Passkey", - "remove_passkey_last_title": "Sidste Passkey.", - "remove_passkey_last_desc": "Den eneste Passkey kan ikke fjernes uden at miste adgangen til din konto. Hvis du vil slette kontoen helt, skal du bruge farezonen nederst på denne side.", + "remove_passkey_last_title": "Sidste Passkey", + "remove_passkey_last_desc": "Det eneste Passkey kan ikke fjernes uden at miste adgangen til din konto. For at slette kontoen helt skal du bruge linket nederst på denne side.", "remove_passkey_failed": "Passkey kunne ikke fjernes.", - "remove_passkey_confirm_title": "Fjern Passkey?", - "remove_passkey_confirm_desc": "Denne enhed kan så ikke længere logge ind med denne Passkey.", - "remove_passkey_confirm_yes": "Fjerne", + "remove_passkey_confirm_title": "Passkey skal fjernes?", + "remove_passkey_confirm_desc": "Denne enhed kan derefter ikke længere logge ind med denne Passkey.", + "remove_passkey_confirm_yes": "Fjern", "remove_passkey_confirm_no": "Annuller", "pin_title": "Lokal PIN-kode", "pin_status": "Status", "pin_active": "Aktiv på denne enhed", - "pin_inactive": "Ikke sat op", + "pin_inactive": "Ikke indrettet", "pin_confirm_label": "Bekræft PIN-kode", - "pin_confirm_placeholder": "Indtast PIN-kode igen", - "pin_set_btn": "Opsæt PIN-kode", + "pin_confirm_placeholder": "Indtast PIN-koden igen", + "pin_set_btn": "Opret PIN-kode", "pin_change_btn": "Skift PIN-kode", "pin_remove_btn": "Fjern PIN-kode", "pin_saved": "PIN-kode gemt.", "pin_save_failed": "PIN-koden kunne ikke gemmes.", "pin_mismatch": "PIN-koderne stemmer ikke overens.", "pin_length_error": "PIN-koden skal bestå af mindst 4 tegn.", - "pin_no_session": "Sessionen er udløbet - tilmeld dig venligst igen.", - "remove_pin_confirm_title": "Fjerne PIN-kode?", - "remove_pin_confirm_desc": "Du skal logge ind igen på denne enhed med Passkey eller genoprettelsesnøglen.", + "pin_no_session": "Sessionen er udløbet — log ind igen.", + "remove_pin_confirm_title": "Skal PIN-koden fjernes?", + "remove_pin_confirm_desc": "Du skal logge ind på denne enhed igen med Passkey eller gendannelsesnøglen.", "remove_pin_confirm_yes": "Fjern PIN-kode", "remove_pin_confirm_no": "Annuller", - "security_title": "Tjekliste for sikkerhed", - "security_desc": "Oversigt over de vigtigste beskyttelsesmekanismer for din konto.", - "security_passkeys_ok": "Mindst én Passkey registreret", - "security_passkeys_missing": "Nej Passkey registreret", - "security_prf_ok": "PRF-nøgleafledning aktiv", - "security_prf_missing": "PRF ikke sat op", + "security_title": "Sikkerhedstjekliste", + "security_desc": "Oversigt over de vigtigste sikkerhedsfunktioner på din konto.", + "security_passkeys_ok": "Mindst én Passkey er registreret", + "security_passkeys_missing": "Ingen Passkey registreret", + "security_prf_ok": "PRF-nøgleudledning er aktiveret", + "security_prf_missing": "PRF er ikke konfigureret", "security_pin_ok": "Lokal PIN-kode på denne enhed", "security_pin_missing": "Ingen lokal PIN-kode", - "security_recovery_ok": "Opsætning af genoprettelsesnøgle", - "security_recovery_hint": "De 12 ord blev vist under registreringen. Opbevar dem offline og adskilt fra enheden. Du kan oprette en ny nøgle nedenfor - den gamle bliver så ugyldig.", - "recovery_rotate_btn": "Opret en ny genoprettelsesnøgle", - "recovery_rotate_confirm_title": "Opret en ny genoprettelsesnøgle?", - "recovery_rotate_confirm_desc": "Den tidligere nøgle på 12 ord bliver ugyldig med det samme. Sørg for at opbevare den nye nøgle sikkert, før du fortsætter.", - "recovery_rotate_confirm_yes": "Opret ny nøgle", + "security_recovery_ok": "Gendannelsesnøgle oprettet", + "security_recovery_hint": "De 12 ord blev vist ved registreringen. Opbevar dem offline og adskilt fra enheden. Du kan oprette en ny nøgle nedenfor — den gamle bliver da ugyldig.", + "recovery_rotate_btn": "Opret en ny gendannelsesnøgle", + "recovery_rotate_confirm_title": "Vil du oprette en ny gendannelsesnøgle?", + "recovery_rotate_confirm_desc": "Den hidtidige 12-ords-nøgle bliver straks ugyldig. Sørg for at opbevare den nye nøgle sikkert, inden du fortsætter.", + "recovery_rotate_confirm_yes": "Opret en ny nøgle", "recovery_rotate_confirm_no": "Annuller", - "recovery_rotate_new_warning": "VIGTIGT: Skriv disse 12 ord ned, og opbevar dem offline. Den tidligere genoprettelsesnøgle er nu ugyldig.", - "recovery_rotate_failed": "Genoprettelsesnøglen kunne ikke oprettes.", - "recovery_rotate_no_session": "Krypteringssessionen er udløbet - log ud og log ind igen, og prøv så igen.", - "device_title": "Denne enhed", + "recovery_rotate_new_warning": "VIGTIGT: Skriv disse 12 ord ned, og opbevar dem et sted, hvor du ikke har internetadgang. Den hidtidige gendannelseskode er nu ugyldig.", + "recovery_rotate_failed": "Det var ikke muligt at oprette en gendannelsesnøgle.", + "recovery_rotate_no_session": "Krypteringssessionen er udløbet — log venligst ud og log ind igen, og prøv derefter igen.", + "device_title": "Dette apparat", "device_desc": "Lokal cache, synkroniseringsstatus og hurtig login i denne browser.", - "device_sync_pending": "{{count}} ventende synkroniseringsposter", + "device_sync_pending": "{{count}} udestående synkroniseringsposter", "device_sync_ok": "Alle lokale ændringer synkroniseres", - "device_remembered": "Konto til hurtigt login gemt på denne enhed", - "device_not_remembered": "Kontoen er ikke på listen over hurtige login", + "device_remembered": "Konto gemt til hurtig login på denne enhed", + "device_not_remembered": "Kontoen er ikke på listen over hurtiglogin", "device_forget_btn": "Glemt konto på denne enhed", - "device_forget_confirm_title": "Fjerne hurtig login?", - "device_forget_confirm_desc": "Kontoen forsvinder fra listen over hurtige login på denne enhed. Din session og dine lokale logbøger bevares.", - "device_forget_confirm_yes": "Fjerne", + "device_forget_confirm_title": "Skal hurtiglogin fjernes?", + "device_forget_confirm_desc": "Kontoen fjernes fra listen over hurtiglogin på denne enhed. Din session og dine lokale logfiler bevares.", + "device_forget_confirm_yes": "Fjern", "device_forget_confirm_no": "Annuller", - "passkey_label": "Navn på ny Passkey (valgfrit)", - "passkey_label_placeholder": "z. f.eks. MacBook, iPhone.", + "passkey_label": "Navn til den nye Passkey (valgfrit)", + "passkey_label_placeholder": "f.eks. MacBook, iPhone", "passkey_rename_btn": "Gem navn", - "passkey_rename_success": "Passkey navn gemt.", - "passkey_rename_failed": "Passkey-Navnet kunne ikke gemmes.", - "passkey_unnamed": "Uden titel Passkey.", - "stats_title": "Statistik", + "passkey_rename_success": "Passkey-navn gemt.", + "passkey_rename_failed": "Passkey-navnet kunne ikke gemmes.", + "passkey_unnamed": "Ukendt Passkey", + "stats_title": "Statistikker", "stats_subtitle": "Om alle dine logbøger på denne enhed", "stats_logbooks": "Logbøger", "stats_account_since": "Konto siden", - "stats_shared_logbooks": "Fælles logbøger", - "appearance_title": "App og visualisering", + "stats_shared_logbooks": "Delte logbøger", + "appearance_title": "App & brugergrænseflade", "appearance_desc": "Designet og farveskemaet gælder for hele appen på denne enhed.", "theme_label": "Appens designstil", - "theme_auto": "Automatisk (OS-registrering)", + "theme_auto": "Automatisk (OS-genkendelse)", "theme_ocean": "Ocean (glasmorfisme)", "theme_material": "Materiale (Android)", "theme_cupertino": "Cupertino (iOS)", "color_scheme_label": "Lys eller mørk tilstand", "color_scheme_auto": "Automatisk (system)", "color_scheme_light": "Lys", - "color_scheme_dark": "Mørk", + "color_scheme_dark": "Mørkt", "integrations_title": "Integrationer", "owm_key": "OpenWeatherMap API-nøgle", - "owm_help": "Valgfrit: egen OpenWeatherMap API-nøgle. Hvis der ikke er nogen indtastning, bruges nøglen på serversiden fra operatørkonfigurationen.", - "ai_title": "AI-funktioner og privatliv", - "ai_desc": "Autoriser integrationer af kunstig intelligens for dine logbøger.", - "ai_help": "Aktivering af AI-funktioner giver appen mulighed for at opsummere dine rejsedage og transkribere optagede stemmememoer. For at behandle disse anmodninger sendes rå stemmedata og rejselogfiler sikkert løbende til OpenRouter. Der gemmes ingen data permanent af AI-modellen.\n\nDisse cloud-ressourcer koster penge at køre. Hvis du kan lide at bruge dem, bedes du overveje at støtte projektet frivilligt med en donation via Ko-fi-linket i footeren for at holde dem gratis og bæredygtige for alle.", - "ai_enable_label": "Aktiver transkribering og resuméer af rejsedage", - "ai_unauthorized_alert_title": "AI-funktioner er ikke autoriseret", - "ai_unauthorized_alert_desc": "For at bruge transkribering eller rejsedagsresuméer skal du autorisere dataoverførslen til OpenRouter i din brugerprofil under 'AI-funktioner og privatliv'.", - "prefs_save": "Gemme", - "prefs_saving": "Vil blive reddet...", + "owm_help": "Valgfrit: egen OpenWeatherMap-API-nøgle. Hvis der ikke angives noget, anvendes den serverbaserede nøgle fra operatørkonfigurationen.", + "ai_title": "AI-funktioner og databeskyttelse", + "ai_desc": "Godkend brugen af kunstig intelligens (lokale/cloud-integrationer) til dine logbøger.", + "ai_help": "Aktivering gør det muligt automatisk at sammenfatte rejseberetninger og transskribere lydnoter. Til behandling overføres lydoptagelser og logbogspostinger krypteret til OpenRouter. Dataene gemmes ikke permanent der.\n\nDa driften af disse cloud-ressourcer medfører omkostninger, vil vi sætte pris på en frivillig støtte via Ko-fi-donationslinket i footeren, så vi kan tilbyde disse funktioner gratis for alle på lang sigt.", + "ai_enable_label": "Aktivér transskription og dagsoversigter", + "ai_unauthorized_alert_title": "AI-funktioner er ikke godkendt", + "ai_unauthorized_alert_desc": "For at transskribere lydnoter eller sammenfatte rejseberetninger skal du give dit samtykke til dataoverførsel til OpenRouter i din brugerprofil under »AI-funktioner & databeskyttelse«.", + "prefs_save": "Gem", + "prefs_saving": "Gemmes…", "prefs_saved": "Gemt", - "tour_title": "App-tur", - "tour_desc": "Lad dig guide gennem de vigtigste områder i appen igen.", - "tour_restart": "Start turen igen", - "push_title": "Push-meddelelser", - "push_desc": "Som logbogsejer får du besked, når inviterede Crew-medlemmer synkroniserer ændringer. Intet indhold overføres i ren tekst.", - "push_enable": "Giv os besked om ændringer i crewen", - "push_active": "Push-meddelelser er aktive på denne enhed.", - "push_unsupported": "Push-meddelelser understøttes ikke i denne browser.", - "push_denied_hint": "Notifikationer er blokeret. Tillad dem i browserens eller enhedens indstillinger.", - "push_ios_install_hint": "På iPhone/iPad: Føj app til startskærmen (iOS 16.4+) for at bruge push.", - "push_error": "Push-meddelelser kunne ikke aktiveres.", + "tour_title": "App-rundvisning", + "tour_desc": "Lad dig igen blive guidet gennem appens vigtigste funktioner.", + "tour_restart": "Start turen forfra", + "push_title": "Push-beskeder", + "push_desc": "Som logbogsindehaver får du besked, når inviterede besætningsmedlemmer synkroniserer ændringer. Der overføres ikke indhold i klartekst.", + "push_enable": "Giv besked ved ændringer i besætningen", + "push_active": "Push-beskeder er aktiveret på denne enhed.", + "push_unsupported": "Push-beskeder understøttes ikke i denne browser.", + "push_denied_hint": "Meddelelser er blokeret. Tillad dem i browser- eller enhedsindstillingerne.", + "push_ios_install_hint": "På iPhone/iPad: Føj appen til startskærmen (iOS 16.4+), for at kunne modtage push-beskeder.", + "push_error": "Det var ikke muligt at aktivere push-beskeder.", "sections": { "account": "Konto og indstillinger", - "fleet": "Flåde og besætning", - "security": "Sikkerhed og enhed", + "fleet": "Flåde & besætning", + "security": "Sikkerhed & udstyr", "stats": "Statistik", "danger": "Farezone" } @@ -708,370 +710,370 @@ "vessel_pool": { "title": "Skibsflåde", "section_title": "Dine skibe", - "subtitle": "Hold alle skibe til dine logbøger her. Vælg aktivt skib per logbog fra listen.", - "loading": "Indlæser skibsflåde…", + "subtitle": "Her kan du administrere alle skibe til dine logbøger. For hver logbog skal du vælge det aktive skib fra denne liste.", + "loading": "Skibsflåden indlæses…", "add_vessel": "Tilføj skib", "edit_vessel": "Rediger skib", - "no_vessels": "Ingen skibe i puljen endnu.", - "delete_confirm": "Fjerne dette skib fra flåden?", - "max_vessels": "Højst 20 skibe i puljen." + "no_vessels": "Der er endnu ingen skibe i puljen.", + "delete_confirm": "Vil du virkelig fjerne dette skib fra flåden?", + "max_vessels": "Det maksimale antal på 20 skibe i puljen er nået." }, "logbook_vessel": { - "title": "Skib for denne logbog", - "subtitle": "Vælg skib for denne logbog. Rejsedage bruger sejl- og tankdata fra valgt skib.", - "active_vessel": "Skib for denne logbog", - "no_vessels_in_pool": "Intet skib i flåden – tilføj i brugerprofilen først.", + "title": "Skib til denne logbog", + "subtitle": "Vælg skibet til denne logbog. Rejsedagene bruger sejl- og brændstofdata fra det valgte skib.", + "active_vessel": "Skib til denne logbog", + "no_vessels_in_pool": "Der er ingen skibe i flåden – opret dem først i brugerprofilen.", "no_vessel": "Intet skib valgt", - "unnamed": "Uden navn", + "unnamed": "Uden titel", "save": "Gem skib", - "saved": "Logbog-skib gemt.", - "selection_only_hint": "Du ser skibet ejeren har valgt (delt logbog).", + "saved": "Skibet er gemt i logbogen.", + "selection_only_hint": "Du ser det skib, som ejeren har valgt (delt logbog).", "manage_in_profile": "Administrer skibe i brugerprofilen" }, "person_pool": { - "title": "Stamm-Crew og skippere", - "subtitle": "Administrer din personpulje her – skippere og crew til alle logbøger. Vælg aktiv crew per logbog og rejsedag fra puljen.", - "loading": "Indlæser personpulje…", - "skippers_section": "Skippere", - "crew_section": "Stamm-Crew", + "title": "Fast besætning & skipper", + "subtitle": "Opret din personpulje her – skippere og besætning til alle logbøger. Fra denne pulje vælger du den aktive besætning for hver logbog og hver rejsedag.", + "loading": "Personliste indlæses…", + "skippers_section": "Faste skippere", + "crew_section": "Fast besætning", "add_skipper": "Tilføj skipper", - "add_crew": "Tilføj Crew-medlem", + "add_crew": "Tilføj et besætningsmedlem", "edit_skipper": "Rediger skipper", - "no_skippers": "Ingen skipper i puljen endnu.", - "no_crew": "Ingen Crew-medlemmer i puljen endnu.", - "delete_confirm": "Fjern denne person fra puljen?" + "no_skippers": "Der er endnu ingen skipper i puljen.", + "no_crew": "Der er endnu ingen besætningsmedlemmer i puljen.", + "delete_confirm": "Vil du virkelig fjerne denne person fra gruppen?" }, "logbook_crew": { - "title": "Crew for denne logbog", - "subtitle": "Vælg skipper og crew for denne logbog. Nye rejsedage arver valget som standard.", - "loading": "Indlæser crew…", + "title": "Besætning til denne logbog", + "subtitle": "Vælg skipper og besætning til denne logbog. Nye rejsedage overtager som standard dette valg.", + "loading": "Besætningen indlæses…", "active_skipper": "Skipper for denne logbog", - "active_crew": "Crew for denne logbog", - "no_skippers_in_pool": "Ingen skipper i puljen – tilføj i brugerprofilen først.", - "no_crew_in_pool": "Ingen crew i puljen – tilføj i brugerprofilen først.", - "no_skipper": "Ingen skipper valgt", - "unnamed": "Uden navn", - "save": "Gem crew", - "saved": "Logbog-Crew gemt.", - "selection_only_hint": "Du ser den crew ejeren har valgt (delt logbog)." + "active_crew": "Besætning til denne logbog", + "no_skippers_in_pool": "Der er ingen skipper i puljen – opret først en i brugerprofilen.", + "no_crew_in_pool": "Der er ingen besætning i puljen – opret den først i brugerprofilen.", + "no_skipper": "Der er ikke valgt nogen skipper", + "unnamed": "Uden titel", + "save": "Gem besætning", + "saved": "Besætning gemt i logbogen.", + "selection_only_hint": "Du kan se den besætning, som ejeren har fastlagt (delt logbog)." }, "entry_crew": { - "title": "Crew på denne rejsedag", - "subtitle": "Kan afvige fra logbogstandard. Følgende dage arver fra foregående dag.", - "day_skipper": "Skipper denne dag", - "day_crew": "Crew denne dag", - "no_skipper": "Ingen skipper valgt", - "no_crew": "Ingen crew valgt" + "title": "Besætningen på denne rejsedag", + "subtitle": "Kan afvige fra standarden i logbogen. De efterfølgende rejsedage overtager dataene fra den foregående dag.", + "day_skipper": "Skipperen denne dag", + "day_crew": "Besætningen denne dag", + "no_skipper": "Der er ikke valgt nogen skipper", + "no_crew": "Der er ikke valgt noget hold" }, "crew": { - "title": "Skipper- og Crew-profiler", - "skipper_section": "Skipper-profil", + "title": "Skipper- og besætningsprofiler", + "skipper_section": "Skipperprofil", "skipper_read_only_hint": "Skipperprofilen kan kun redigeres af logbogens ejer.", - "crew_section": "Crew-liste", - "add_crew": "Tilføj Crew-medlem", - "edit_crew": "Rediger Crew-medlem", - "no_crew": "Ingen Crew-medlemmer tilføjet endnu.", - "max_crew": "Det maksimale antal på 12 Crew-medlemmer i puljen er nået.", + "crew_section": "Besætningsliste", + "add_crew": "Tilføj et besætningsmedlem", + "edit_crew": "Rediger besætningsmedlem", + "no_crew": "Der er endnu ikke tilføjet nogen besætningsmedlemmer.", + "max_crew": "Det maksimale antal på 12 besætningsmedlemmer i puljen er nået.", "name": "Navn", - "address": "adresse", + "address": "Adresse", "birthdate": "Fødselsdag", "phone": "Telefonnummer", "nationality": "Nationalitet", - "passport": "Pas/ID-nummer", - "bloodtype": "Blodgruppe", + "passport": "Pas-/ID-nummer", + "bloodtype": "Blodtype", "allergies": "Allergier", - "diseases": "Eksisterende tilstande/sygdomme", - "save": "Gem skipper-data", + "diseases": "Tidligere lidelser / sygdomme", + "save": "Gem skipperoplysninger", "save_member": "Gem medlem", - "saved": "Skipperprofilen er blevet gemt!", - "loading": "Crew-filerne er indlæst.", - "delete_confirm": "Er du sikker på, at du vil fjerne dette Crew-medlem?" + "saved": "Skipper-profilen er gemt!", + "loading": "Crew-filer indlæses...", + "delete_confirm": "Er du sikker på, at du vil fjerne dette medlem af holdet?" }, "deviation": { - "title": "Tabel over kompasafvigelser", - "subtitle": "Indtast den magnetiske kompasafbøjning (afbøjning) for kurser (MgK) fra 000° til 360° i trin på 10°.", + "title": "Afvigelsestabel (kompasafvigelse)", + "subtitle": "Indtast magnetkompassets afvigelse (Abl.) for kurser (MgK) fra 000° til 360° i trin på 10°.", "heading": "MgK", "deviation": "Distraktion", "save": "Gem kalibreringsgitter", - "saving": "Vil blive reddet...", - "saved": "Kalibreringsgitteret er gemt med succes!", - "loading": "Kalibreringstabellen er indlæst..." + "saving": "Gemmes...", + "saved": "Kalibreringsgitteret er gemt!", + "loading": "Kalibreringstabellen indlæses..." }, "settings": { - "title": "Indstillinger for logbog", - "subtitle": "Del, tag backup og samarbejd om denne logbog.", + "title": "Indstillinger for logbogen", + "subtitle": "Deling, sikkerhedskopiering og samarbejde for denne logbog.", "select_logbook_hint": "Vælg en logbog for at redigere dens indstillinger.", - "no_key": "Ingen OpenWeatherMap API-nøgle tilgængelig. Gem din egen nøgle i brugerprofilen, eller kontakt operatøren.", - "weather_success": "Vejrdata hentet med succes!", - "weather_error": "Hentning af vejrdata mislykkedes. Tjek API-nøglen og forbindelsen.", - "weather_unauthorized": "Hentning af vejrdata mislykkedes. API-nøglen er ugyldig eller ikke autoriseret.", - "weather_not_found": "Hentning af vejrdata mislykkedes. Den angivne placering eller koordinater blev ikke fundet.", - "weather_bad_request": "Hentning af vejrdata mislykkedes. Ingen placering eller GPS-position blev angivet.", - "weather_date_mismatch": "Vejrdata kan kun hentes for i dag ({{today}}). Dette logbogsindlæg er dateret {{date}}.", - "gps_error": "Indtast en placering, eller find GPS-koordinaterne.", + "no_key": "Der er ingen OpenWeatherMap-API-nøgle tilgængelig. Opret en egen nøgle i brugerprofilen, eller kontakt udbyderen.", + "weather_success": "Vejrdata hentet!", + "weather_error": "Hentning af vejrdata mislykkedes. Kontroller API-nøglen og forbindelsen.", + "weather_unauthorized": "Hentning af vejrdata mislykkedes. API-nøglen er ugyldig eller ikke godkendt.", + "weather_not_found": "Hentning af vejrdata mislykkedes. Det angivne sted eller koordinaterne blev ikke fundet.", + "weather_bad_request": "Hentning af vejrdata mislykkedes. Der er ikke angivet nogen by eller GPS-position.", + "weather_date_mismatch": "Vejrdata kan kun hentes for i dag ({{today}}). Denne logbogspost er dateret den {{date}}.", + "gps_error": "Angiv venligst et sted, eller find GPS-koordinaterne.", "share_title": "Del logbog (skrivebeskyttet)", - "share_desc": "Aktivér denne mulighed for at oprette et offentligt, skrivebeskyttet link. Alle med linket kan se dine rejser, yachtprofiler og crew. Krypteringsnøglerne overføres aldrig til serveren (de forbliver i hash-delen af URL'en).", - "share_privacy_warning": "Anbefaling: Del kun dette link privat (f.eks. via e-mail eller messenger), ikke på sociale medier.", + "share_desc": "Aktivér denne indstilling for at oprette et offentligt, skrivebeskyttet link. Alle, der har linket, kan se dine rejser, yachtprofiler og besætning. Krypteringsnøglerne overføres aldrig til serveren (de forbliver i hash-delen af URL'en).", + "share_privacy_warning": "Anbefaling: Del kun dette link privat (f.eks. via e-mail eller Messenger), ikke på sociale medier.", "share_enable": "Aktivér offentligt link", - "share_copied": "Link kopieret!", + "share_copied": "Linket er kopieret!", "share_copy_btn": "Kopier link", - "link_qr_hint": "Scan QR-koden med din telefon", + "link_qr_hint": "QR-kode til scanning med en smartphone", "link_qr_alt": "QR-kode til linket", "danger_zone_title": "Farezone", - "danger_zone_desc": "Når du sletter din konto, slettes alle dine Passkey'er, logbøger, skibsdata, Crew-profiler, rejseindlæg og E2E-nøgler uigenkaldeligt. Denne handling kan ikke fortrydes.", - "delete_account_btn": "Slet konto uigenkaldeligt", - "delete_account_confirm_title": "Slette konto?", - "delete_account_confirm_desc": "Er du helt sikker på, at du vil slette din konto uigenkaldeligt og alle tilknyttede logbøger og E2E-krypterede data?", - "delete_account_confirm_yes": "Ja, slet konto og alle data", + "danger_zone_desc": "Når du sletter din konto, slettes alle dine Passkey'er, logbøger, skibsdata, besætningsprofiler, rejseindlæg og E2E-nøgler uigenkaldeligt. Denne handling kan ikke fortrydes.", + "delete_account_btn": "Slet kontoen endeligt", + "delete_account_confirm_title": "Vil du slette din konto?", + "delete_account_confirm_desc": "Er du helt sikker på, at du vil slette din konto og alle tilhørende logbøger samt E2E-krypterede data endeligt?", + "delete_account_confirm_yes": "Ja, slet kontoen og alle data", "delete_account_confirm_no": "Annuller", - "delete_account_failed": "Kontoen kunne ikke slettes. Prøv venligst igen.", - "delete_backup_hint": "Tip: Lav sikkerhedskopier af dine logbøger (.daagbok) i indstillingerne for hver logbog, før du sletter dem.", - "deleting_account": "Kontoen vil blive slettet...", - "invite_push_prompt_title": "Aktivere push-meddelelser?", - "invite_push_prompt_message": "Så snart inviterede Crew-medlemmer synkroniserer ændringer, kan du blive informeret via push. Intet logbogsindhold sendes i almindelig tekst.", - "invite_push_prompt_ios_message": "Så snart Crew-medlemmerne synkroniserer ændringer, kan du blive informeret via push. På iPhone/iPad: Føj appen til startskærmen (iOS 16.4+), og aktiver derefter push i brugerprofilen.", - "invite_push_prompt_enable": "Aktiver nu", + "delete_account_failed": "Det var ikke muligt at slette kontoen. Prøv igen.", + "delete_backup_hint": "Tip: Lav sikkerhedskopier af dine logbøger (.daagbok) i indstillingerne for hver logbog, inden du sletter dem.", + "deleting_account": "Kontoen slettes…", + "invite_push_prompt_title": "Vil du aktivere push-beskeder?", + "invite_push_prompt_message": "Så snart inviterede besætningsmedlemmer synkroniserer ændringer, kan du få besked via push-besked. Der sendes ikke logbogsinhold i klartekst.", + "invite_push_prompt_ios_message": "Så snart medarbejdere synkroniserer ændringer, kan du få besked via push-besked. På iPhone/iPad: Føj appen til startskærmen (iOS 16.4+), og aktiver derefter push-beskeder i brugerprofilen.", + "invite_push_prompt_enable": "Aktivér nu", "invite_push_prompt_later": "Senere", - "invite_push_prompt_success": "Push-meddelelser er aktive på denne enhed.", + "invite_push_prompt_success": "Push-beskeder er aktiveret på denne enhed.", "backup_title": "Sikkerhedskopiering og gendannelse", - "backup_desc": "Komplet krypteret backup af denne logbog (poster, fotos, GPS-spor, crew, skib). Beskyttet med backup-passphrase - til gendannelse til denne eller en ny konto.", - "backup_export_title": "Opret backup", - "backup_export_desc": "Downloader alle lokale data som et komprimeret .daagbok-arkiv. Hold filen og adgangssætningen adskilt og sikker.", + "backup_desc": "Fuldstændig krypteret sikkerhedskopi af denne logbog (indlæg, fotos, lydnoter, GPS-ruter, besætning, skib). Beskyttet med en sikkerhedskodephrase — til gendannelse på denne eller en ny konto.", + "backup_export_title": "Opret sikkerhedskopi", + "backup_export_desc": "Downloader alle lokale data som en komprimeret .daagbok-fil. Opbevar filen og adgangskoden separat og sikkert.", "backup_restore_title": "Gendan sikkerhedskopi", - "backup_restore_desc": "Gendanner en sikkerhedskopi til din nuværende konto - selv efter registrering af en ny konto.", - "backup_passphrase": "Backup-passphrase", + "backup_restore_desc": "Gendanner en sikkerhedskopi i din nuværende konto — også efter oprettelse af en ny konto.", + "backup_passphrase": "Sikkerhedskode til sikkerhedskopiering", "backup_passphrase_placeholder": "Mindst 8 tegn", - "backup_passphrase_confirm": "Bekræft adgangssætning", - "backup_passphrase_short": "Backup-passphrasen skal være mindst 8 tegn lang.", - "backup_passphrase_mismatch": "Passphrases matcher ikke.", - "backup_wrong_passphrase": "Passphrase forkert eller backup beskadiget.", - "backup_export_btn": "Download backup", - "backup_exporting": "Sikkerhedskopien er oprettet...", - "backup_export_success": "Backup oprettet ({{count}} rejsedage).", - "backup_file_label": "Backup-fil (.daagbok)", - "backup_export_progress": "Pakker filer {{current}} / {{total}}…", - "backup_invalid_archive": "Filen er ikke et gyldigt backup-arkiv.", - "backup_version_unsupported": "Gammelt backup-format (v1). Brug en aktuel .daagbok-backup.", - "backup_import_size_confirm": "Denne backup er ca. {{size}} ukomprimeret. Gendannelse kan tage længere tid. Fortsæt?", - "backup_stat_voice": "{{count}} stemmenotater", - "backup_stat_size": "Ca. {{size}} ukomprimeret", - "backup_preview_btn": "Tjek indhold", - "backup_previewing": "Tjek...", + "backup_passphrase_confirm": "Bekræft adgangskoden", + "backup_passphrase_short": "Sikkerhedskodeordet til sikkerhedskopien skal bestå af mindst 8 tegn.", + "backup_passphrase_mismatch": "Adgangskoderne stemmer ikke overens.", + "backup_wrong_passphrase": "Adgangskoden er forkert, eller sikkerhedskopien er beskadiget.", + "backup_export_btn": "Download sikkerhedskopi", + "backup_exporting": "Der oprettes en sikkerhedskopi…", + "backup_export_success": "Sikkerhedskopi oprettet ({{count}} rejsedage).", + "backup_file_label": "Sikkerhedskopifil (.daagbok)", + "backup_export_progress": "Pak filer {{current}} / {{total}}…", + "backup_invalid_archive": "Filen er ikke et gyldigt sikkerhedskopieringsarkiv.", + "backup_version_unsupported": "Gammelt backupformat (v1). Brug venligst en opdateret .daagbok-backup.", + "backup_import_size_confirm": "Denne sikkerhedskopi er ca. {{size}} stor. Gendannelsen kan tage længere tid på enheden og optage meget lagerplads. Vil du fortsætte?", + "backup_stat_voice": "{{count}} Stemmebeskeder", + "backup_stat_size": "Ukomprimeret ca. {{size}}", + "backup_preview_btn": "Kontroller indholdet", + "backup_previewing": "Kontroller…", "backup_restore_btn": "Gendan", - "backup_restoring": "Vil blive restaureret...", - "backup_restore_success": "Logbog \"{{title}}\" er blevet gendannet.", - "backup_restore_cancelled": "Genopretning aflyst.", + "backup_restoring": "Gendannes…", + "backup_restore_success": "Logbogen „{{title}}“ er blevet gendannet.", + "backup_restore_cancelled": "Gendannelsen blev afbrudt.", "backup_invalid_json": "Filen er ikke en gyldig JSON-fil.", "backup_invalid_format": "Ukendt eller forældet backup-format.", "backup_not_owner": "Kun logbogens ejer kan oprette sikkerhedskopier.", - "backup_not_authenticated": "Log ind for at gendanne en sikkerhedskopi.", + "backup_not_authenticated": "Du skal logge ind for at gendanne en sikkerhedskopi.", "backup_id_conflict": "Der findes allerede en logbog med dette ID.", - "backup_overwrite_confirm": "Den eksisterende logbog med samme ID erstattes. Fortsætter du?", - "backup_new_id_confirm": "Importere backup'en som en ny logbog med et nyt ID?", + "backup_overwrite_confirm": "Den eksisterende logbog med samme ID vil blive erstattet. Vil du fortsætte?", + "backup_new_id_confirm": "Skal sikkerhedskopien importeres som en ny logbog med et nyt ID?", "backup_stat_entries": "{{count}} Rejsedage", "backup_stat_photos": "{{count}} Fotos", - "backup_stat_crew": "{{count}} Crew-poster", - "backup_stat_tracks": "{{count}} GPS-spor", + "backup_stat_crew": "{{count}} Besætningsmedlemmer", + "backup_stat_tracks": "{{count}} GPS-ruter", "backup_exported_at": "Eksporteret: {{date}}" }, "disclaimer": { - "title": "Vigtige bemærkninger", - "intro": "Læs venligst følgende instruktioner, før du bruger Kapteins Daagbok.", - "e2e_title": "Ende-til-ende-kryptering", - "e2e_body": "Dine logbogsdata er krypteret fra ende til anden. Kun du - eller personer med din nøgle - kan læse indholdet. Kun krypterede data gemmes på serveren.", - "pwa_title": "Progressiv web-app (PWA)", - "pwa_body": "Kapteins Daagbok kører som en progressiv webapp i din browser og kan installeres på din enhed - på samme måde som en native app, men uden en app store.", + "title": "Vigtige oplysninger", + "intro": "Læs venligst følgende oplysninger, inden du bruger Kapteins Daagbok.", + "e2e_title": "End-to-end-kryptering", + "e2e_body": "Dine logbogdata krypteres fra ende til ende. Kun du – eller personer, der har din nøgle – kan læse indholdet. Der gemmes udelukkende krypterede data på serveren.", + "pwa_title": "Progressiv webapp (PWA)", + "pwa_body": "Kapteins Daagbok kører som en progressiv webapp i din browser og kan installeres på din enhed – på samme måde som en native app, men uden at skulle hentes fra en app-butik.", "storage_title": "Lokal lagring og synkronisering", - "storage_body": "Dine data gemmes lokalt på din enhed (IndexedDB). Ændringer synkroniseres med serveren, når en internetforbindelse er aktiv. Du kan arbejde videre uden forbindelse; synkroniseringen finder sted senere.", + "storage_body": "Dine data gemmes midlertidigt lokalt på din enhed (IndexedDB). Når der er internetforbindelse, synkroniseres ændringerne med serveren. Du kan fortsætte med at arbejde, selvom der ikke er forbindelse; synkroniseringen foregår senere.", "free_title": "Gratis og uden reklamer", "free_body": "Kapteins Daagbok er gratis og indeholder ingen reklamer.", "liability_title": "Ansvarsfraskrivelse", - "liability_body": "Brug af appen sker på egen risiko. Vi påtager os intet ansvar for skader, der opstår som følge af brugen af appen - herunder forkerte eller ufuldstændige logbogsindførsler, tab af data eller tekniske fejl.", + "liability_body": "Brugen sker på eget ansvar. Der påtages intet ansvar for skader, der opstår som følge af brugen af appen – herunder fejlbehæftede eller ufuldstændige logbogspostninger, datatab eller tekniske fejl.", "warranty_title": "Ingen garanti", - "warranty_body": "Der gives ingen garanti for tjenestens funktion, korrekthed eller tilgængelighed. Driften kan til enhver tid blive afbrudt, begrænset eller annulleret.", + "warranty_body": "Der gives ingen garanti for tjenestens funktion, nøjagtighed eller tilgængelighed. Driften kan til enhver tid blive afbrudt, begrænset eller indstillet.", "copyright": "© 2026 KnorrLabs, Markus F.J. Busche", "accept": "Accepter og fortsæt", "close": "Luk", - "button_title": "Noter og ansvarsfraskrivelse" + "button_title": "Bemærkninger og ansvarsfraskrivelse" }, "feedback": { "button_title": "Send feedback", "title": "Feedback", - "intro": "Del fejl, ideer eller generel feedback. Din besked vil blive sendt til projektteamet via en sikker meddelelseskanal.", + "intro": "Del fejl, ideer eller generel feedback. Din besked sendes til projektteamet via en sikker kommunikationskanal.", "category_label": "Kategori", "category_general": "Generelt", - "category_bug": "Rapporter fejl", - "category_feature": "Anmodning om funktion", + "category_bug": "Rapporter en fejl", + "category_feature": "Ønsket om en funktion", "category_translation": "Oversættelsesfejl", "contact_label": "E-mail (valgfrit)", "contact_placeholder": "deine@email.beispiel", "message_label": "Besked", - "message_placeholder": "Beskriv din feedback...", + "message_placeholder": "Beskriv din feedback…", "send": "Send", - "sending": "Vil blive sendt...", + "sending": "Sendes…", "cancel": "Annuller", - "success": "Tusind tak skal du have! Din feedback er blevet sendt.", - "error_send": "Feedback kunne ikke sendes. Prøv venligst igen senere.", + "success": "Mange tak! Din feedback er blevet sendt.", + "error_send": "Feedback kunne ikke sendes. Prøv igen senere.", "error_invalid_email": "Indtast venligst en gyldig e-mailadresse.", "error_not_configured": "Feedback er ikke tilgængelig på denne server.", - "error_rate_limited": "For mange tilbagemeldinger på kort tid. Vent venligst et par minutter.", - "error_spam": "Denne besked kunne ikke sendes. Vær venlig at omformulere den." + "error_rate_limited": "Der er modtaget for mange feedback-beskeder på kort tid. Vent venligst et par minutter.", + "error_spam": "Denne besked kunne ikke sendes. Omformuler den venligst." }, "demo": { "logbook_title": "Demo-logbog Østersøen", "badge": "Demo", - "public_banner": "Skrivebeskyttet demo-visning", + "public_banner": "Demo-visning (skrivebeskyttet)", "cta_register": "Opret konto", - "back_to_login": "Til registreringen" + "back_to_login": "Tilmelding" }, "invitation": { - "error_invalid_key": "Invitationslinket er kryptografisk ugyldigt (nøglen er forkert).", - "error_missing_key": "Invitationslinket indeholder ikke en dekrypteringsnøgle (#key=...). Brug venligst det fulde link fra ejeren.", + "error_invalid_key": "Inviteringslinket er kryptografisk ugyldigt (fejl i nøglen).", + "error_missing_key": "Inviteringslinket indeholder ingen dekrypteringsnøgle (#key=...). Brug venligst det fulde link fra ejeren.", "error_expired": "Denne invitation er udløbet (gyldig i 48 timer).", - "error_invalid_token": "Invitationstokenet er ugyldigt.", - "error_load_failed": "Invitationsoplysningerne kunne ikke indlæses.", - "error_incomplete_session": "Session ufuldstændig - log venligst ind igen (bruger-ID mangler).", - "error_accept_failed": "Tiltrædelse mislykkedes.", - "error_login_failed": "Passkey Login mislykkedes.", - "error_username_missing": "Brugernavnet kunne ikke bestemmes - log venligst ind igen.", - "error_register_failed": "Registrering mislykkedes.", - "loading_joining": "At slutte sig til...", - "loading_checking": "Invitation vil blive tjekket...", - "loading_unlocking": "Logbogen er låst op og synkroniseret...", - "loading_retrieving_key": "Download krypteringsnøgle...", - "error_title": "Fejl i invitation", - "back_to_start": "Tilbage til start", - "title": "Invitation til logbog", + "error_invalid_token": "Invitationstoken er ugyldig.", + "error_load_failed": "Det var ikke muligt at indlæse oplysninger om invitationen.", + "error_incomplete_session": "Sessionen er ufuldstændig — log venligst ind igen (bruger-ID mangler).", + "error_accept_failed": "Tilmeldingen mislykkedes.", + "error_login_failed": "Passkey-login mislykkedes.", + "error_username_missing": "Brugernavnet kunne ikke findes — log ind igen.", + "error_register_failed": "Registreringen mislykkedes.", + "loading_joining": "Tilmelding...", + "loading_checking": "Invitationen bliver behandlet...", + "loading_unlocking": "Logbogen aktiveres og synkroniseres...", + "loading_retrieving_key": "Indlæser krypteringsnøgle...", + "error_title": "Indlæsningsfejl", + "back_to_start": "Tilbage til starten", + "title": "Invitation til logbogen", "invited_by": "Invitation fra", "vessel_logbook": "Skib / Logbog", - "signed_in_preparing": "Registreret som {{username}}. Tilslutning er ved at blive forberedt...", - "join_again": "Deltag igen", - "login_or_register_hint": "Log ind eller opret en konto for at deltage i logbogen.", - "or_sign_up": "ELLER REGISTRER DIG IGEN", + "signed_in_preparing": "Logget ind som {{username}}. Tilmelding forberedes...", + "join_again": "Tilmeld dig igen", + "login_or_register_hint": "Log ind eller opret en konto for at få adgang til logbogen.", + "or_sign_up": "ELLER OPRETT EN NY KONTO", "register_crew_account": "Opret en ny crew-konto", "username_label": "Brugernavn", - "create_passkey": "Opret Passkey.", + "create_passkey": "Opret Passkey", "switch_language_en": "Engelsk", "switch_language_de": "Tysk" }, "stats": { "title": "Statistik", - "subtitle": "Overblik over ruter, forbrug og kørselstype", - "scope_label": "Evalueringsområde", + "subtitle": "Rækkevidde, brændstofforbrug og drivform på et øjeblik", + "scope_label": "Analyseområde", "scope_logbook": "Denne logbog", "scope_account": "Alle logbøger", - "loading": "Statistikkerne er beregnet...", - "no_data": "Ingen rejsedage tilgængelige endnu.", - "total_distance": "Samlet afstand", + "loading": "Statistikken beregnes…", + "no_data": "Der er endnu ingen rejsedage.", + "total_distance": "Samlet strækning", "travel_days": "Rejsedage", "sail_distance": "Under sejl", - "motor_distance": "Kørsel med maskine", - "motor_hours_total": "Samlet antal maskintimer", - "daily_motor_hours": "Maskintimer pr. rejsedag", - "avg_motor_hours": "Ø maskintimer pr. rejsedag", + "motor_distance": "Maskinkørsel", + "motor_hours_total": "Samlede maskintimer", + "daily_motor_hours": "Maskin-timer pr. rejsedag", + "avg_motor_hours": "Gennemsnitlige maskintimer pr. rejsedag", "unknown_propulsion": "Ukendt", "fuel_total": "Brændstof i alt", "water_total": "Vand i alt", - "daily_etmal": "Daglige tider", - "daily_consumption": "Dagligt forbrug", + "daily_etmal": "Dagsmål", + "daily_consumption": "Dagsforbrug", "route_overview": "Rute", "route_map_title": "Oversigt over ruter", - "propulsion_title": "Sejl vs. maskine", - "propulsion_hint": "Opdelingen er baseret på logbogshændelser pr. rejsedag, ikke på GPS-segmenter.", - "avg_distance": "Ø pr. rejsedag", + "propulsion_title": "Sejl eller motor", + "propulsion_hint": "Opdelingen er baseret på logbogsbegivenhederne for hver rejsedag, ikke på GPS-segmenter.", + "avg_distance": "Gennemsnit pr. rejsedag", "avg_fuel": "Ø Brændstof", "avg_water": "Ø Vand", - "fuel_per_nm": "Brændstof pr. sm", - "fuel_per_motor_hour": "Brændstof pr. maskintime", - "daily_fuel_per_motor_hour": "Brændstofforbrug pr. maskintime pr. rejsedag", + "fuel_per_nm": "Brændstof pr. sømil", + "fuel_per_motor_hour": "Brændstofforbrug pr. driftstime", + "daily_fuel_per_motor_hour": "Brændstofforbrug pr. driftstime pr. rejsedag", "fuel_legend": "Brændstof", "water_legend": "Vand", "unit_nm": "sm", "unit_h": "h", "unit_l": "L", "day_label": "Dag {{day}}", - "account_logbooks": "Et overblik over logbøger", + "account_logbooks": "Oversigt over logbøger", "col_logbook": "Logbog", "event_series_title": "Hændelsesforløb", "event_series_hint": "Kronologiske værdier fra hændelsesloggen.", "event_series_pressure": "Lufttryk", "event_series_wind": "Vind", "event_series_motor": "Motor", - "event_series_empty": "Ingen indtastninger endnu." + "event_series_empty": "Der er ingen poster." }, "tour": { "skip": "Spring turen over", "back": "Tilbage", - "next": "Yderligere", - "finish": "Klar", - "progress": "Trin {{current}} fra {{total}}.", + "next": "Fortsæt", + "finish": "Færdig", + "progress": "Trin {{current}} af {{total}}", "steps": { "welcome": { "title": "Velkommen om bord!", - "body": "Vi har lavet en demo-logbog med tre dages rejse i Kielerfjorden til dig. Du kan til enhver tid slette prøveposterne, hvis du vil starte din egen logbog. Denne korte rundvisning viser dig de vigtigste funktioner." + "body": "Vi har oprettet en demo-logbog med tre rejsedage i Kieler Fjorden til dig. Du kan til enhver tid slette eksempelindtastningerne, hvis du vil gå i gang med din egen logbog. Denne korte tur viser dig de vigtigste funktioner." }, "welcome_public": { "title": "Velkommen om bord!", - "body": "Udforsk vores demo-logbog med tre dages rejse i Kielerfjorden – uden konto. Turen viser logbogsposter samt valg af skib og besætning for denne logbog. Flåde og stamm-besætning vedligeholder du senere i brugerprofilen." + "body": "Udforsk vores demo-logbog med tre rejsedage i Kieler Fjorden – helt uden at oprette en konto. Turen viser dig logbogsindlæg samt valg af skib og besætning til denne logbog. Du kan senere opdatere flåden og den faste besætning i din brugerprofil." }, "nav_logs": { - "title": "Indlæg i logbogen", - "body": "Det er her, du styrer dine rejsedage - afgang, destination, vejr, brændstofniveau og GPS-spor." + "title": "Logbogsnotater", + "body": "Her kan du administrere dine rejsedage – afgang, destination, vejr, brændstofstand og GPS-ruter." }, "entry_list": { "title": "Dine rejsedage", - "body": "Hvert kort repræsenterer en rejsedag. Tryk på en post for at se eller redigere detaljer." + "body": "Hvert kort repræsenterer en rejsedag. Tryk på en post for at se eller redigere detaljerne." }, "entry_open": { - "title": "Åben rejsedag", - "body": "Sådan ser et udfyldt logbogsnotat ud - med begivenheder, tankniveauer og meget mere." + "title": "Åbn rejsedag", + "body": "Sådan ser en udfyldt logbogsoptegnelse ud – med begivenheder, brændstofstand og mere." }, "entry_track": { - "title": "GPS-spor", - "body": "Upload GPX-filer, eller se allerede gemte ruter på kortet - inklusive afstand og hastighed." + "title": "GPS-rute", + "body": "Upload GPX-filer, eller se allerede gemte ruter på kortet – inklusive afstand og hastighed." }, "nav_vessel": { - "title": "Skib for logbog", - "body": "Vælg skib fra flåden for denne logbog. Administrer skibe i brugerprofilen under Flåde og besætning." + "title": "Skib til logbogen", + "body": "Vælg det skib fra din flåde, der skal bruges til denne logbog. Du kan administrere dine skibe i brugerprofilen under »Flåde & besætning«." }, "profile_vessel_pool": { "title": "Skibsflåde", - "body": "I brugerprofilen opretter du alle dine skibe – charter, eget skib osv. Vælg derefter det rigtige skib per logbog." + "body": "I brugerprofilen opretter du alle dine skibe – charterbåde, egen båd osv. For hver logbog vælger du derefter det relevante skib." }, "profile_crew_pool": { - "title": "Stamm-Crew og skippere", - "body": "I brugerprofilen vedligeholder du en personpulje – flere skippere (f.eks. charter) og crew til alle logbøger." + "title": "Fast besætning & skipper", + "body": "I brugerprofilen administrerer du din personliste – flere skippere (f.eks. til charter) og besætningsmedlemmer til alle logbøger." }, "nav_logbook_crew": { - "title": "Crew per logbog", - "body": "Vælg skipper og crew fra puljen til denne logbog. Rejsedage arver valget som standard." + "title": "Besætning pr. logbog", + "body": "Vælg fra listen, hvem der skal angives som skipper og besætning i denne logbog. Rejsedagene overtager som standard dette valg." }, "nav_stats": { "title": "Statistik-dashboard", - "body": "Her kan du se kørselsafstande, brændstofforbrug, rutekort og kørselsandele - automatisk beregnet ud fra dine logbogsnotater." + "body": "Her kan du se kørte afstande, brændstofforbrug, rutekort og fordelingen af drivkraft – alt sammen beregnet automatisk ud fra dine logbogsnotater." }, "nav_feedback": { "title": "Send feedback", - "body": "Du kan bruge denne formular til at sende fejl, ideer eller generel feedback direkte til projektteamet - også efter rundvisningen, når som helst ved hjælp af ikonet øverst til højre." + "body": "Via denne formular kan du sende fejl, ideer eller generel feedback direkte til projektteamet – også efter turen, når som helst via ikonet øverst til højre." }, "nav_profile": { "title": "Din brugerprofil", - "body": "Du kan få adgang til din personlige profil via skipperknappen øverst - uanset den aktuelle logbog." + "body": "Via Skipper-knappen øverst kan du gå til din personlige profil – uanset hvilket logbog du er i." }, "profile_preferences": { - "title": "Regnskab og præsentation", - "body": "Her kan du administrere din kontoidentitet, tema og lys/mørk tilstand. Du kan til enhver tid genstarte app-turen. Passkeys og sikkerhedsindstillinger findes længere nede i profilen." + "title": "Konto & visning", + "body": "Her kan du administrere din kontoidentitet, dit tema og lys/mørk-tilstand. Du kan når som helst starte app-guiden igen. Passkeys og sikkerhedsindstillinger finder du længere nede i profilen." }, "finish": { - "title": "Okay!", - "body": "Du vil blive ført direkte til statistikdashboardet. Du kan til enhver tid genstarte turen i din brugerprofil. Hav en god tur!" + "title": "Fint!", + "body": "Du kommer straks til statistikoversigten. Du kan når som helst starte rundvisningen igen i din brugerprofil. God tur!" } } }, "seo": { - "title": "Kapteins Daagbok - Gratis digital yachtlogbog (reklamefri)", - "description": "Gratis, reklamefri digital yachtlogbog med end-to-end-kryptering og Passkey-login. Dokumenter sikkert rejsedage, GPS-spor, Crew- og skibsdata - også offline som PWA.", - "keywords": "Yachtlogbog, skibslogbog, logbog om bord, sejlads, Passkey, E2E-kryptering, GPS-spor, maritim logbog, gratis, reklamefri, gratis, uden reklame", + "title": "Kapteins Daagbok – Gratis digitalt logbog til lystbåde (uden reklamer)", + "description": "Gratis, reklamefri digital bådlogbog med ende-til-ende-kryptering og Passkey-login. Dokumenter rejsedage, GPS-ruter, besætning og skibsdata sikkert – også offline som PWA.", + "keywords": "Yachtlogbog, skibsdagbog, skibslogbog, sejlads, Passkey, E2E-kryptering, GPS-spor, maritim logbog, gratis, uden reklamer, gratis, uden reklamer", "ogImageAlt": "Kapteins Daagbok Logo" } } diff --git a/client/src/i18n/locales/de.json b/client/src/i18n/locales/de.json index 96a5c5e..3151a32 100644 --- a/client/src/i18n/locales/de.json +++ b/client/src/i18n/locales/de.json @@ -15,7 +15,9 @@ "en": "English", "da": "Dansk", "sv": "Svenska", - "nb": "Norsk" + "nb": "Norsk", + "fr": "Français", + "es": "Español" }, "dialog": { "ok": "OK", diff --git a/client/src/i18n/locales/en.json b/client/src/i18n/locales/en.json index b84c666..544874b 100644 --- a/client/src/i18n/locales/en.json +++ b/client/src/i18n/locales/en.json @@ -15,7 +15,9 @@ "en": "English", "da": "Dansk", "sv": "Svenska", - "nb": "Norsk" + "nb": "Norsk", + "fr": "French", + "es": "Spanish" }, "dialog": { "ok": "OK", diff --git a/client/src/i18n/locales/es.json b/client/src/i18n/locales/es.json new file mode 100644 index 0000000..9f39f48 --- /dev/null +++ b/client/src/i18n/locales/es.json @@ -0,0 +1,1080 @@ +{ + "translation": { + "app": { + "name": "Kapteins Daagbok", + "tagline": "Diario de navegación de un yate privado", + "beta": "Beta", + "beta_hint": "Versión beta — Las funciones aún pueden sufrir cambios" + }, + "footer": { + "kofi_label": "Ko-fi", + "kofi_title": "Apoya el proyecto, su desarrollo y los gastos de funcionamiento en Ko-fi" + }, + "languages": { + "de": "Deutsch", + "en": "English", + "da": "Dansk", + "sv": "Svenska", + "nb": "Norsk", + "fr": "Français", + "es": "Español" + }, + "dialog": { + "ok": "Vale", + "yes": "Sí", + "no": "No" + }, + "errors": { + "load_failed": "No se han podido cargar los datos.", + "save_failed": "No se han podido guardar los cambios.", + "delete_failed": "Error al borrar.", + "export_failed": "Error al exportar." + }, + "common": { + "unsaved_changes_title": "Cambios no guardados", + "unsaved_changes_message": "Tienes cambios sin guardar. ¿De verdad quieres salir de la página? Se perderán tus cambios.", + "unsaved_changes_stay": "Quedarse", + "unsaved_changes_save_leave": "Guardar y salir", + "unsaved_changes_discard": "Descartar", + "unsaved_changes_leave": "Abandonado" + }, + "nav": { + "dashboard": "Panel de control", + "vessel": "Datos del buque", + "crew": "Tripulación", + "deviation": "Tabla de distracciones", + "logs": "Entradas del diario de a bordo", + "stats": "Estadísticas", + "settings": "Configuración", + "admin": "Admin" + }, + "auth": { + "welcome": "Bienvenido a Kapteins Daagbok", + "tagline": "Tu diario de navegación seguro y cifrado con E2E.", + "register": "Registrarse con Passkey", + "login": "Iniciar sesión con Passkey", + "login_as": "Iniciar sesión como {{name}}", + "quick_login": "Inicio de sesión rápido", + "forget_account": "¿Has olvidado tu cuenta en este dispositivo?", + "not_user": "¿No es {{name}}?", + "recovery_title": "Tu clave de recuperación", + "recovery_warning": "IMPORTANTE: Anota estas 12 palabras. Si pierdes tu Passkey y estas palabras, no se podrán recuperar tus datos.", + "confirm_recovery": "He apuntado las palabras", + "status_logged_in": "Iniciado sesión", + "status_logged_out": "Desconectado", + "copied": "¡Copiado!", + "copy_phrase": "Hacer una copia de la llave", + "enter_recovery": "Introducir la clave de recuperación", + "recovery_fallback_warning": "Tu Passkey se ha autenticado correctamente, pero tu dispositivo no admite la derivación de claves basada en hardware. Introduce tu frase de recuperación de 12 palabras para descifrar tu diario de registro.", + "recovery_placeholder": "Introduce tu clave de recuperación, compuesta por 12 palabras separadas por espacios...", + "back": "Atrás", + "decrypting": "Descifrado...", + "decrypt_logbook": "Descifrar el diario de a bordo", + "error_incorrect_recovery": "Clave de recuperación incorrecta. Fallo en el descifrado.", + "error_decryption_failed": "Error al descifrar. Comprueba tu clave de recuperación.", + "or_register": "o Registrarse", + "explore_demo": "Explora la demo sin necesidad de crear una cuenta", + "username_placeholder": "Nombre de usuario / Nombre de patrón", + "processing": "Procesando...", + "help": "Ayuda", + "setup_pin_title": "Configurar un PIN local (opcional)", + "setup_pin_warning": "Dado que tu dispositivo no admite la derivación directa de claves Passkey, de lo contrario tendrías que introducir tu clave de 12 palabras cada vez que iniciaras sesión en este dispositivo. Configura un PIN local para evitarlo.", + "pin_placeholder": "Por ejemplo, 123456", + "pin_label": "Código PIN local (4-8 dígitos)", + "save_pin": "Guardar PIN y continuar", + "skip_pin": "Saltar y utilizar la función de recuperación", + "enter_pin_title": "Descifrar con el PIN", + "enter_pin_warning": "Introduce tu PIN local para desbloquear la clave de descifrado en este dispositivo.", + "enter_pin_placeholder": "Introduce tu PIN...", + "decrypt_with_pin": "Descifrar", + "use_recovery_instead": "En su lugar, utiliza la clave de recuperación", + "error_incorrect_pin": "PIN incorrecto. Error al descifrar.", + "error_invalid_host": "Passkeys no funciona a través de 127.0.0.1. Abre la aplicación a través de localhost.", + "use_localhost_link": "Cambiar a localhost", + "error_passkey_cancelled": "Passkey: sesión cancelada o caducada. Inténtalo de nuevo.", + "error_invalid_rp_id": "El dominio Passkey no es válido (RP ID). A nivel local, utiliza solo http://localhost:5173 con RP_ID=localhost en el archivo .env.", + "error_session_incomplete": "El registro está incompleto. Vuelve a registrarte con Passkey.", + "restore_checking": "Se está comprobando la sesión…", + "restore_title": "Recuperar sesión", + "restore_subtitle": "Tu cuenta sigue activa. Desbloquea tu diario de a bordo con Passkey o tu PIN.", + "restore_unlocking": "Se está desbloqueando…", + "restore_with_passkey": "Desbloquear con Passkey ({{name}})", + "restore_with_pin": "Desbloquear con el PIN", + "restore_pin_warning": "Introduce tu PIN local para desbloquear tu diario de a bordo tras la recarga.", + "restore_other_account": "Iniciar sesión con otra cuenta" + }, + "pwa": { + "title": "Instalar la aplicación", + "generic_benefit": "Instala Kapteins Daagbok en tu dispositivo para disfrutar de un acceso más rápido, poder utilizarlo sin conexión y guardar los datos de forma permanente.", + "ios_instructions": "En el iPad/iPhone: añade la aplicación al pantalla de inicio para que tus datos del diario de navegación permanezcan protegidos y la aplicación se inicie como una aplicación nativa.", + "ios_step_share": "Toca el icono de compartir en la barra Safari", + "ios_step_add": "Selecciona «Ir a la pantalla de inicio»", + "install_now": "Instalar ahora", + "installing": "Instalación…", + "later": "Más tarde", + "never": "No volver a mostrar", + "platform_ios": "Instalación a través de Safari", + "platform_android": "Instalación a través del navegador", + "platform_desktop": "Instalación como aplicación de escritorio", + "settings_section": "Instalación de la aplicación", + "update_title": "Hay una actualización disponible", + "update_desc": "Ya está disponible una nueva versión de Kapteins Daagbok. Actualiza para obtener los últimos cambios.", + "update_now": "Actualizar ahora", + "update_reloading": "Cargando…", + "storage_persist_hint": "El navegador puede borrar los datos sin conexión. Permite el almacenamiento permanente para que tu diario de navegación permanezca protegido (en la configuración del navegador o la próxima vez que se te avise)." + }, + "sync": { + "status_synced": "Doblada", + "status_syncing": "Sincronizar…", + "status_offline": "Caché sin conexión", + "status_unsynced": "Cambios no sincronizados", + "conflict_title": "Conflicto de sincronización", + "conflict_message": "{{count}} No se han podido sincronizar los cambios (entrada {{id}}…). Elige qué versión quieres aplicar.", + "conflict_use_server": "Aplicar la versión del servidor", + "conflict_keep_local": "Conservar mi versión" + }, + "vessel": { + "title": "Datos maestros de buques", + "name": "Nombre del yate", + "type": "Tipo de yate", + "type_unset": "— no especificado —", + "type_sailing": "velero", + "type_motor": "yate a motor", + "length_m": "Longitud (m)", + "draft_m": "Calado (m)", + "air_draft_m": "Altura (m)", + "invalid_metric": "Valor numérico no válido: introduzca los metros en formato decimal (p. ej., 12,5).", + "port": "puerto de origen", + "owner": "Propietario", + "charter": "Empresa de alquiler de barcos", + "registration": "Matrícula", + "callsign": "Indicativo de llamada por radio", + "atis": "N.º ATIS", + "mmsi": "N.º MMSI", + "save": "Guardar datos del barco", + "saving": "Se está guardando...", + "saved": "¡Datos del barco guardados correctamente!", + "loading": "Se están cargando los datos del barco...", + "sails_list": "Aparejo (velas disponibles)", + "sails_help": "Introduce aquí las velas de las que dispone tu barco (por ejemplo, la vela mayor, el génova, el foque).", + "add_sail": "Añadir vela", + "sail_name_placeholder": "p. ej., la vela mayor", + "no_sails": "No hay velas guardadas.", + "photo_add": "Añadir foto", + "photo_change": "Cambiar foto", + "photo_delete": "Eliminar foto", + "tanks_section": "Depósitos (capacidad)", + "tanks_help": "Opcional en litros: permite utilizar el control deslizante en el diario cuando se conocen las capacidades de los depósitos.", + "freshwater_capacity_l": "Agua potable (litros)", + "fuel_capacity_l": "Combustible (litros)", + "greywater_capacity_l": "Aguas grises (litros)", + "invalid_tank_liters": "Valor numérico no válido: introduce los litros como un número (por ejemplo, 200)." + }, + "logs": { + "title": "Diario de a bordo", + "new_entry": "Nuevo día de viaje", + "travel_details": "Detalles del viaje", + "add_event": "Añadir una nueva entrada al diario de a bordo", + "add_event_btn": "Añadir evento", + "edit_event": "Editar evento", + "save_event_btn": "Guardar cambio", + "cancel_event_edit": "Cancelar", + "delete_event": "Eliminar evento", + "sign_cleared_skipper_re_sign_title": "Se ha eliminado la firma del patrón", + "sign_cleared_skipper_re_sign": "Se ha modificado el registro de eventos. Se ha eliminado la firma del patrón. Por favor, vuelva a aprobarlo.", + "date": "Fecha", + "day_of_travel": "Día del viaje", + "travel_day_number": "Día del viaje {{number}}", + "departure": "Puerto de salida (viaje desde)", + "destination": "Puerto de destino (a)", + "route": "Viaje desde/hacia", + "tanks": "Depósitos", + "customize_columns": "Ajustar columnas", + "column_selector_title": "Columnas que se deben mostrar", + "freshwater": "Agua dulce (litros)", + "fuel": "Combustible (litros)", + "greywater": "Aguas grises (litros)", + "greywater_level": "Nivel", + "tank_slider_of_max": "{{current}} / {{max}} L", + "tank_capacity_tooltip": "Si en los datos del barco se han introducido las capacidades de los depósitos (en litros), puedes introducir aquí los niveles de llenado mediante el control deslizante.", + "morning": "Situación a primera hora de la mañana", + "refilled": "Repuesto", + "evening": "Situación al atardecer", + "consumption": "Consumo diario", + "signatures": "Firmas / Autorización", + "sign_skipper": "Firma del patrón", + "sign_crew": "Firma del equipo", + "sign_hint": "Firmar con el dedo, un bolígrafo o el ratón", + "sign_clear": "Eliminar", + "sign_export_image": "[Firma]", + "sign_with_passkey": "Compartir con Passkey", + "sign_passkey_signing": "Se está solicitando Passkey…", + "sign_passkey_signed": "Publicado por {{username}}", + "sign_passkey_export": "Passkey: {{username}} ({{date}})", + "sign_attribution_export": "{{username}} ({{date}})", + "sign_passkey_clear": "Eliminar la autorización Passkey", + "sign_mode_passkey": "Passkey", + "sign_mode_classic": "Clásico", + "sign_passkey_failed": "Passkey: error en la autorización", + "sign_passkey_cancelled": "Passkey: autorización cancelada", + "sign_invalid": "Firma no válida: el contenido ha sido modificado", + "sign_badge_skipper": "patrón", + "sign_badge_skipper_invalid": "No válido", + "sign_badge_skipper_title_valid": "Skipper lo ha publicado", + "sign_badge_skipper_title_invalid": "Firma del capitán no válida — Se ha modificado el contenido", + "sign_classic_or_passkey": "Opcional: firma clásica o autorización Passkey en la parte superior", + "sign_crew_passkey_hint": "Los miembros del equipo con permisos de escritura pueden compartir mediante Passkey", + "sign_offline_hint": "La autorización Passkey requiere conexión a Internet; la firma clásica se puede realizar sin conexión", + "sign_lock_notice": "Una vez firmada, no se podrán realizar modificaciones en la entrada del diario de a bordo (excepto en las fotos) sin que el patrón y la tripulación tengan que volver a firmar.", + "sign_lock_active": "Esta entrada está firmada. Los cambios en el diario de a bordo (excepto las fotos) eliminan automáticamente las firmas del patrón y de la tripulación.", + "sign_lock_warning_title": "Confirmar la firma", + "sign_lock_warning": "Una vez firmada, no se podrán realizar modificaciones en la entrada del diario de a bordo (excepto en las fotos) sin que el patrón y la tripulación tengan que volver a firmar.\n\n¿Quieres continuar?", + "sign_proceed": "Firmar", + "sign_cancel": "Cancelar", + "sign_cleared_re_sign_title": "Se han eliminado las firmas", + "sign_cleared_re_sign": "Se ha modificado la entrada del diario de a bordo. Se han eliminado las firmas del patrón y de la tripulación. Por favor, vuelva a firmar.", + "no_entries": "No se han encontrado entradas en el diario de navegación de este yate. ¡Crea tu primer día de viaje!", + "back_to_list": "Volver a la lista de revistas", + "save": "Guardar página del diario de a bordo", + "saving": "Se está guardando...", + "saved": "¡Página del diario de a bordo guardada correctamente!", + "loading": "Se está cargando el diario...", + "view_mode_label": "Vista", + "view_list": "Lista", + "live_mode": "En directo", + "live_title": "Diario en vivo", + "live_loading": "Se está cargando Live-Journal...", + "live_retry": "Intentarlo de nuevo", + "live_load_error": "No se ha podido cargar Live-Journal.", + "live_action_error": "No se ha podido guardar la entrada.", + "live_open_editor": "Editor completo", + "live_actions_label": "Ofertas de última hora", + "live_stream_label": "Registro de eventos", + "live_stream_title": "Diario", + "live_no_events": "Aún no hay entradas — selecciona una acción.", + "live_motor_start": "Arranque del motor", + "live_motor_stop": "Parada del motor", + "live_cast_off": "Desplazarse", + "live_moor": "Crear", + "live_sails_btn": "Vela", + "live_sails_pick": "Elegir vela", + "live_sails_pick_hint": "Toca varias velas (vuelve a tocarlas para deseleccionarlas) y, a continuación, introduce los datos.", + "live_sails_selected": "Selección: {{sails}}", + "live_sails_confirm": "Registrarse", + "live_sails_confirm_count": "Registrarse ({{count}})", + "live_sails": "Vela: {{sails}}", + "live_position": "Cargo", + "live_position_coords": "Posición {{lat}}, {{lng}}", + "live_position_manual_hint": "El GPS no está disponible. Introduce manualmente la latitud y la longitud o vuelve a intentarlo pulsando el botón de GPS.", + "live_position_gps_loading": "Se está calculando la posición GPS…", + "live_position_invalid": "Introduzca coordenadas válidas (latitud −90…90, longitud −180…180).", + "live_position_lat_placeholder": "Ancho (Lat)", + "live_position_lng_placeholder": "Longitud (Lng)", + "live_photo_btn": "Foto (cámara)", + "live_photo_capture_btn": "Grabar", + "live_photo_save_btn": "Guardar", + "live_photo_retake_btn": "Volver a grabar", + "live_photo_capture_failed": "Error al grabar. Inténtalo de nuevo.", + "live_photo_open_camera_btn": "Abrir la cámara", + "live_photo_native_hint": "Haz una foto con la cámara del dispositivo y guárdala aquí.", + "live_photo_camera_starting": "Se está encendiendo la cámara…", + "live_photo_camera_denied": "Se ha denegado el acceso a la cámara o no está disponible.", + "live_photo_camera_unavailable": "Este navegador no es compatible con la cámara.", + "live_photo_no_camera": "Este dispositivo no dispone de cámara.", + "live_photo_error": "No se ha podido guardar la foto.", + "live_photo_entry": "Foto: {{caption}}", + "live_photo_entry_plain": "Foto tomada", + "live_undo_photo_hint": "Foto guardada", + "live_voice_btn": "Nota de voz", + "live_voice_hint": "Graba una nota de voz breve (máx. 60 segundos).", + "live_voice_record": "Iniciar grabación", + "live_voice_stop": "Finalizar la grabación", + "live_voice_recording": "Grabación {{time}}", + "live_voice_save": "Guardar", + "live_voice_saving": "Se está guardando…", + "live_voice_retake": "Volver a grabar", + "live_voice_mic_denied": "No se permite el acceso al micrófono o no está disponible.", + "live_voice_record_failed": "Error en la grabación. Inténtalo de nuevo.", + "live_voice_unavailable": "No hay nota de voz disponible", + "live_voice_too_large": "La grabación es demasiado larga. Por favor, graba una más corta.", + "live_voice_error": "No se ha podido guardar la nota de voz.", + "live_voice_entry": "Nota de voz: {{caption}}", + "live_voice_entry_plain": "Nota de voz", + "live_voice_caption_label": "Rotulación (opcional)", + "live_voice_caption_placeholder": "por ejemplo, comunicación por radio con el capitán del puerto", + "live_voice_transcribe_action": "Transcribir", + "live_voice_transcribing": "Transcribe...", + "live_voice_transcribe_failed": "Se ha guardado la nota de voz, pero la transcripción ha fallado.", + "live_undo_voice_hint": "Nota de voz guardada", + "live_comment_btn": "Comentario", + "live_comment_placeholder": "Escribir texto libre…", + "live_comment_confirm": "Registrarse", + "live_gps_error": "No se ha podido determinar la posición GPS.", + "live_gps_start_hint": "Empieza siempre tu recorrido diario por un lugar.", + "live_event_generic": "Evento", + "live_weather_btn": "El tiempo", + "live_weather_owm_btn": "OpenWeatherMap Consultar el tiempo", + "live_weather_owm_loading": "Se está cargando la información meteorológica…", + "live_weather_position_required": "Para el tiempo de OpenWeatherMap, introduce primero una ubicación (botón «Ubicación»). La ubicación no puede tener más de 6 horas de antigüedad.", + "live_weather_position_stale": "La última posición tiene más de 6 horas de antigüedad. Por favor, registra una nueva posición antes de consultar la información meteorológica.", + "live_wind_btn": "Viento", + "live_temp_btn": "T °C", + "live_pressure_btn": "presión atmosférica", + "live_precip_btn": "Precipitaciones", + "live_sea_state_btn": "mar agitado", + "live_visibility_btn": "Visibilidad", + "live_course_btn": "Curso", + "live_fuel_btn": "+ Diésel", + "live_water_btn": "+ Agua", + "live_wind_entry": "Viento {{value}}", + "live_temp_entry": "Temperatura {{temp}} °C", + "live_pressure_entry": "Presión atmosférica {{value}} hPa", + "live_precip_entry": "Precipitaciones {{value}}", + "live_sea_state_entry": "Mar picado {{value}}", + "live_visibility_entry": "Visibilidad {{value}}", + "live_course_entry": "Curso {{course}}", + "live_fuel_entry": "Diésel +{{liters}} L", + "live_water_entry": "Agua +{{liters}} L", + "live_auto_position": "Posición automática", + "live_undo_hint": "Entrada guardada", + "live_undo_btn": "Deshacer", + "live_cancel": "Demolición", + "live_pressure_placeholder": "p. ej., 1013", + "live_temp_placeholder": "p. ej., 18", + "live_precip_placeholder": "por ejemplo, lluvia ligera", + "live_sea_state_placeholder": "p. ej., 3", + "live_visibility_placeholder": "por ejemplo, 10 km", + "live_course_placeholder": "p. ej., 245", + "live_fuel_placeholder": "Litros rellenados", + "live_water_placeholder": "Litros rellenados", + "live_sog_btn": "SOG", + "live_stw_btn": "STW", + "live_sog_entry": "SOG {{speed}} kn", + "live_stw_entry": "STW {{speed}} kn", + "live_sog_placeholder": "p. ej., 5,2", + "live_stw_placeholder": "p. ej., 4,8", + "live_sog_hint": "Distancia recorrida (km) — El valor del GPS se rellena automáticamente si está disponible.", + "delete_entry": "Eliminar etiqueta", + "delete_confirm": "¿Estás seguro de que quieres eliminar definitivamente este día de viaje?", + "carry_over_tanks_title": "¿Importar los datos del día anterior?", + "carry_over_tanks_confirm": "¿Se mantienen los valores iniciales del puerto de salida, el agua dulce, el combustible y las aguas grises del último día del viaje?\n\nPuerto de salida: {{departure}}\nAgua dulce: {{fw}} L\nCombustible: {{fuel}} L\nAguas grises: {{greywater}} L", + "carry_over_tanks_yes": "Aplicar", + "carry_over_tanks_no": "Empezar desde cero", + "event_title": "Registro cronológico de eventos", + "event_creator": "Publicado por", + "no_events": "Aún no se han registrado eventos para este día del viaje.", + "event_time": "Hora", + "event_mgk": "Curso de MgK", + "event_rwk": "Curso RwK", + "event_course_section": "Curso", + "course_dial_hint": "Girar el anillo o introducir el grado", + "course_dial_step_label": "Incremento", + "course_step_fine": "1.º", + "course_step_medium": "5°", + "course_step_coarse": "10°", + "course_tab_mgk": "MgK", + "course_tab_rwk": "rwK", + "course_invalid": "Rango no válido (0–360)", + "course_placeholder_degrees": "p. ej., 180", + "course_placeholder_cardinal": "p. ej., NW", + "compass_n": "N", + "compass_e": "O", + "compass_s": "S", + "compass_w": "W", + "wind_mode_cardinal": "cardenal", + "wind_mode_degrees": "Como grado", + "event_wind_direction": "Dirección del viento", + "event_wind_strength": "intensidad del viento", + "event_sea_state": "mar agitado", + "event_visibility": "Visibilidad", + "event_visibility_placeholder": "por ejemplo, 10 km", + "weather_slider_unset": "—", + "weather_slider_pressure": "{{value}} hPa", + "weather_slider_sea_state": "Nivel {{value}}", + "weather_slider_heel": "{{value}}°", + "event_weather": "El tiempo", + "event_log": "Logge (sm)", + "event_gps": "Coordenadas GPS", + "event_location": "Localidad / Puerto", + "event_location_placeholder": "p. ej., Kiel", + "event_remarks": "Observaciones / Incidentes", + "gps_btn": "Obtener las coordenadas GPS", + "gps_permission_denied": "Se ha denegado el acceso a la ubicación. Permítelo en la configuración del navegador o del dispositivo y vuelve a intentarlo.", + "gps_timeout": "Tiempo de espera del GPS agotado. Inténtalo de nuevo, a ser posible al aire libre, donde haya buena cobertura.", + "gps_position_unavailable": "No hay señal GPS disponible. Por favor, espera o introduce las coordenadas manualmente.", + "gps_unavailable": "Este navegador o dispositivo no es compatible con el GPS.", + "gps_failed": "No se ha podido determinar la posición GPS.", + "gps_fallback_no_location": "Error en el GPS. Introduce una ubicación en «Lugar / Puerto», el puerto de salida o de destino, o introduce las coordenadas manualmente.", + "gps_fallback_success": "Coordenadas de «{{location}}» determinadas a partir del nombre de la localidad (no mediante GPS).", + "gps_fallback_failed": "La búsqueda por GPS y por nombre de lugar ha fallado. Introduzca las coordenadas manualmente.", + "gps_quality_excellent": "Buena recepción GPS (±{{accuracy}} m)", + "gps_quality_good": "Buena recepción GPS (±{{accuracy}} m)", + "gps_quality_fair": "Recepción GPS moderada (±{{accuracy}} m): para mejorar la recepción, sal al aire libre.", + "gps_quality_poor": "Señal GPS débil (±{{accuracy}} m): probablemente haya pocos satélites. Inténtalo de nuevo al aire libre o comprueba la posición.", + "gps_quality_unknown": "Se ha obtenido la posición GPS (el dispositivo no indica la precisión).", + "gps_live_intro_title": "Ubicación del registro en tiempo real", + "gps_live_intro_body": "Para que la aplicación pueda registrar automáticamente tu ubicación y utilizar el botón de GPS, necesita acceder a tu ubicación.\n\nPulsa en «Permitir ubicación» y, en el siguiente cuadro de diálogo, confirma el permiso. Si lo prefieres, puedes introducir la ubicación manualmente en cualquier momento en la sección «Ubicación».", + "gps_live_intro_allow": "Permitir el acceso a la ubicación", + "gps_live_intro_later": "Más tarde", + "gps_enable_in_settings_hint": "El acceso a la ubicación está bloqueado. Puedes autorizarlo posteriormente en la configuración del navegador o del dispositivo (sitio web / aplicación → Ubicación).", + "weather_btn": "OpenWeatherMap Consultar el tiempo", + "weather_offline": "OpenWeatherMap requiere una conexión a Internet. Actualmente estás desconectado.", + "event_wind_pressure": "Presión atmosférica (hPa)", + "event_heel": "Inclinación (°)", + "event_sails": "Navegación a vela / Motor", + "motor_propulsion": "Recorrido en máquina", + "sails_picker_show_more": "Ver todas las velas", + "sails_picker_show_less": "Mostrar menos", + "motor_hours": "Horas de funcionamiento (total)", + "fuel_per_motor_hour": "Consumo por hora de funcionamiento", + "event_distance": "Distancia (m)", + "export_csv": "Descargar CSV", + "share_csv": "CSV compartir", + "export_pdf": "Descargar PDF", + "exporting_pdf": "Se está generando PDF...", + "ai_summary_title": "Resumen generado por IA", + "ai_summary_read_only": "Creado por el patrón — solo visible para la tripulación.", + "ai_summary_empty": "Aún no hay resumen disponible.", + "ai_summary_generate": "Generar resumen", + "ai_summary_regenerate": "Volvér a generar", + "ai_summary_generating": "Se está generando…", + "ai_summary_attempts_remaining": "Quedan {{remaining}} de {{max}} intentos", + "ai_summary_error": "El resumen generado por IA no se ha podido realizar. Inténtalo de nuevo más tarde.", + "ai_summary_error_no_key": "No hay ninguna clave API de OpenRouter configurada en el servidor.", + "ai_summary_error_rate_limited": "Se ha alcanzado el número máximo de generaciones para este día del viaje.", + "ai_summary_error_forbidden": "Solo el capitán puede generar resúmenes de IA.", + "ai_summary_offline": "El resumen generado por IA requiere una conexión a Internet. Actualmente no tienes conexión.", + "photos_title": "Archivos adjuntos con fotos", + "photo_caption_label": "Descripción de la foto / Etiqueta (opcional)", + "photo_caption_placeholder": "p. ej., izar las velas cerca de la entrada del puerto", + "photo_btn": "Hacer una foto / Subir una foto", + "photo_camera_btn": "Hacer una foto", + "photo_gallery_btn": "Seleccionar de la galería", + "photo_processing": "Se está procesando...", + "no_photos": "Aún no se han añadido fotos de este día del viaje.", + "photo_delete_confirm": "¿Estás seguro de que quieres borrar esta foto de forma definitiva?", + "confirm_yes": "Sí", + "confirm_no": "No", + "track_upload_title": "Ruta GPS (archivo)", + "track_upload_points": "Puntos", + "gps_tracking_btn_gpx": "Descargar el archivo de pista", + "gps_track_upload_help": "Arrastra aquí un archivo GPX, KML o GeoJSON, o haz clic para seleccionarlo", + "gps_track_upload_btn": "Subir un registro GPS", + "gps_track_delete": "Eliminar archivo de pista", + "gps_track_delete_confirm": "¿Estás seguro de que quieres eliminar este archivo de pista de forma definitiva?", + "track_distance": "Ruta GPS (sm)", + "track_speed_max": "Velocidad máxima (nudos)", + "track_speed_avg": "Ø Velocidad (nudos)", + "track_map_title": "Ruta GPS en OpenSeaMap", + "track_map_start": "Inicio", + "track_map_end": "Objetivo", + "track_map_speed_slow": "lentamente", + "track_map_speed_fast": "rápido", + "nmea_import_title": "Importar protocolo NMEA", + "nmea_import_intro": "Carga un archivo .nmea desde el registrador de a bordo. La aplicación te sugiere entradas del diario; tú decides qué se importan.", + "nmea_import_btn": "Importar NMEA", + "nmea_file_label": "Archivo NMEA", + "nmea_stats": "{{lines}} frases detectadas · Tipos: {{types}}", + "nmea_warn_no_position": "No se han encontrado registros de posición; los campos de ruta y GPS pueden dejarse en blanco.", + "nmea_warn_duplicate_file": "Este archivo NMEA ya se ha importado. Si se vuelve a importar el mismo archivo, se añadirán entradas duplicadas al diario.", + "nmea_mode_label": "Crear entradas en el diario", + "nmea_mode_interval": "Por intervalos de tiempo", + "nmea_mode_change": "En caso de cambios significativos", + "nmea_mode_both": "Ambas cosas (unir)", + "nmea_interval_label": "Intervalo (minutos)", + "nmea_import_track": "Importar un registro GPS desde NMEA", + "nmea_preview": "Vista previa", + "nmea_preview_hint": "{{count}} Entradas de diario sugeridas", + "nmea_select_all": "Seleccionar todo", + "nmea_select_none": "No seleccionar ninguna", + "nmea_source_interval": "Intervalo", + "nmea_source_change": "Evento", + "nmea_apply": "Incorporar al diario", + "nmea_back": "Atrás", + "nmea_cancel": "Cancelar", + "nmea_archive_question": "¿Archivar el registro sin procesar localmente? (Solo en este dispositivo, sin sincronizar.)", + "nmea_archive_keep": "Archivar", + "nmea_archive_discard": "Descartar", + "nmea_archive_stored": "NMEA archivado: {{name}}", + "nmea_archive_delete_confirm": "¿Desea borrar el registro NMEA archivado de este dispositivo?", + "nmea_error_no_samples": "No hay registros NMEA válidos en el archivo.", + "nmea_error_parse": "No se ha podido leer el archivo NMEA.", + "nmea_error_read": "No se ha podido leer el archivo.", + "nmea_error_no_file": "Selecciona primero un archivo NMEA.", + "nmea_error_no_selection": "Selecciona al menos una entrada del diario.", + "nmea_remark_interval": "Intervalo NMEA", + "nmea_remark_uncertain": "inseguro", + "nmea_remark_depth": "Profundidad {{depth}} m", + "nmea_change_course": "Cambio de rumbo de {{from}}° a {{to}}°", + "nmea_change_wind": "Viento {{from}}° → {{to}}°", + "nmea_change_wind_speed": "Viento {{from}} → {{to}} nudos", + "nmea_change_pressure": "Presión atmosférica {{from}} → {{to}} hPa", + "nmea_change_depth": "Profundidad {{from}} → {{to}} m", + "nmea_change_engine_start": "Motor encendido ({{rpm}} rpm)", + "nmea_change_engine_stop": "Apagar el motor", + "nmea_change_autopilot_on": "Activar el piloto automático", + "nmea_change_autopilot_off": "Desactivar el piloto automático", + "nmea_change_gps_lost": "Se ha perdido la señal del GPS", + "nmea_change_gps_regained": "Posición GPS recuperada", + "nmea_change_water_temp": "Temperatura del agua {{from}} → {{to}} °C", + "nmea_change_departure": "Salida / Inicio del trayecto", + "nmea_change_anchor": "Frenar / Parar", + "nmea_change_speed": "Velocidad {{from}} → {{to}} nudos", + "track_map_error": "No se ha podido cargar el mapa.", + "exporting": "Exportar...", + "share_unsupported": "En este dispositivo no es posible compartir. En su lugar, se ha descargado el archivo.", + "invite_crew": "Invitar a la tripulación", + "invite_link_copied": "¡Enlace de invitación copiado en el portapapeles!", + "invite_link_desc": "Comparte este enlace con los miembros de la tripulación para concederles derechos de escritura en este diario de a bordo.", + "collaborators_list": "Miembros / Equipo", + "revoke": "Eliminar", + "revoke_confirm": "¿Estás seguro de que quieres revocar el acceso a este miembro del equipo?", + "invite_role": "Papel", + "invite_expires": "El enlace es válido durante 48 horas" + }, + "dashboard": { + "title": "Tus diarios de a bordo", + "subtitle": "Elige un diario de viaje o crea uno nuevo para gestionar tus viajes.", + "create_btn": "Crear un diario de a bordo", + "new_logbook_placeholder": "Nombre del diario de navegación o del yate", + "logout": "Cerrar sesión", + "logged_in_as": "Iniciado sesión como {{name}}", + "delete_confirm": "¿Estás seguro de que quieres eliminar este diario de forma definitiva? Se borrarán todos los datos locales y las copias del servidor.\n\nConsejo: si quieres conservar los datos más adelante, crea primero una copia de seguridad (.daagbok) en Ajustes → Copia de seguridad y restauración.", + "no_logbooks": "No se han encontrado diarios. ¡Crea tu primer diario para empezar!", + "loading": "Se están cargando los registros...", + "status_synced": "Doblada", + "status_local": "Solo caché local", + "delete_btn": "Borrar el registro", + "section_owned": "Mis diarios de a bordo", + "section_shared": "Diarios compartidos", + "section_shared_hint": "Te han invitado como miembro de la tripulación. El perfil del patrón y la configuración pertenecen al propietario.", + "role_owner": "Mi propio diario de a bordo", + "role_owner_hint": "Eres el propietario y el patrón de este diario de navegación", + "role_crew": "Acceso para la tripulación", + "role_crew_hint": "Cuaderno de bitácora abierto a todos: puedes colaborar como tripulante y firmarlo", + "role_read": "Solo lectura", + "role_read_hint": "Cuaderno de bitácora compartido: solo lectura, sin posibilidad de editar", + "open_profile": "Abrir el perfil de {{name}}", + "open_logbook": "Abrir el diario de a bordo «{{title}}»", + "edit_title": "Cambiar el nombre del diario de a bordo", + "edit_placeholder": "Nuevo nombre del diario de a bordo", + "edit_success": "El diario de a bordo se ha renombrado correctamente", + "edit_btn": "Renombrar", + "filter_label": "Filtrar registros", + "filter_placeholder": "Nombre, año, fecha, tripulación o barco…", + "filter_clear": "Restablecer filtros", + "filter_results": "{{count}} resultados", + "filter_no_results": "No hay ningún diario de navegación que coincida con tu búsqueda. Prueba con otro nombre o otro año.", + "sort_label": "Ordenar", + "sort_by_label": "Ordenar por", + "sort_by_name": "Nombre", + "sort_by_date": "Fecha", + "sort_dir_label": "Orden", + "sort_asc": "En orden ascendente", + "sort_desc": "En orden descendente", + "sort_name_asc": "Nombres de la A a la Z", + "sort_name_desc": "Nombre de la Z a la A", + "sort_date_asc": "Los más antiguos primero", + "sort_date_desc": "Las más recientes primero" + }, + "profile": { + "title": "Perfil de usuario", + "subtitle": "Cuenta, Passkey y estadísticas de {{name}}", + "back": "Volver al panel de control", + "loading": "Se está cargando el perfil…", + "load_error": "No se ha podido cargar el perfil.", + "copy_failed": "Error al copiar.", + "processing": "Se está procesando…", + "identity_title": "Identidad de la cuenta", + "username": "Nombre de usuario", + "user_id": "ID de usuario", + "copy_user_id": "Copiar el ID de usuario", + "account_since": "Cuenta desde", + "prf_status": "Derivación de claves Passkey (PRF)", + "prf_active": "Activo", + "prf_inactive": "Sin amueblar", + "passkeys_title": "Passkeys", + "passkeys_desc": "Registra un Passkey diferente en cada dispositivo. Así podrás iniciar sesión incluso si cambias de plataforma.", + "passkeys_empty": "No se han encontrado Passkey.", + "add_passkey_btn": "Añadir un nuevo Passkey", + "add_passkey_success": "Passkey añadido correctamente.", + "add_passkey_failed": "No se ha podido añadir Passkey.", + "remove_passkey_btn": "Eliminar Passkey", + "remove_passkey_last_title": "Último Passkey", + "remove_passkey_last_desc": "El único Passkey no se puede eliminar sin perder el acceso a tu cuenta. Para eliminar la cuenta por completo, utiliza el enlace que aparece al final de esta página.", + "remove_passkey_failed": "No se ha podido eliminar Passkey.", + "remove_passkey_confirm_title": "¿Eliminar Passkey?", + "remove_passkey_confirm_desc": "Este dispositivo ya no podrá volver a iniciar sesión con este Passkey.", + "remove_passkey_confirm_yes": "Eliminar", + "remove_passkey_confirm_no": "Cancelar", + "pin_title": "PIN local", + "pin_status": "Estado", + "pin_active": "Activo en este dispositivo", + "pin_inactive": "Sin amueblar", + "pin_confirm_label": "Confirmar el PIN", + "pin_confirm_placeholder": "Introduce el PIN de nuevo", + "pin_set_btn": "Configurar el PIN", + "pin_change_btn": "Cambiar el PIN", + "pin_remove_btn": "Eliminar el PIN", + "pin_saved": "PIN guardado.", + "pin_save_failed": "No se ha podido guardar el PIN.", + "pin_mismatch": "Los códigos PIN introducidos no coinciden.", + "pin_length_error": "El PIN debe tener al menos 4 caracteres.", + "pin_no_session": "La sesión ha caducado; vuelve a iniciar sesión.", + "remove_pin_confirm_title": "¿Eliminar el PIN?", + "remove_pin_confirm_desc": "Tienes que volver a iniciar sesión en este dispositivo con Passkey o con la clave de recuperación.", + "remove_pin_confirm_yes": "Eliminar el PIN", + "remove_pin_confirm_no": "Cancelar", + "security_title": "Lista de comprobación de seguridad", + "security_desc": "Resumen de los principales mecanismos de seguridad de tu cuenta.", + "security_passkeys_ok": "Se ha registrado al menos un Passkey", + "security_passkeys_missing": "No hay ningún Passkey registrado", + "security_prf_ok": "Derivación de claves PRF activa", + "security_prf_missing": "PRF no configurado", + "security_pin_ok": "PIN local en este dispositivo", + "security_pin_missing": "Sin PIN local", + "security_recovery_ok": "Clave de recuperación configurada", + "security_recovery_hint": "Las 12 palabras se mostraron durante el registro. Guárdalas fuera de línea y separadas del dispositivo. Puedes generar una nueva clave más abajo; la antigua dejará de ser válida.", + "recovery_rotate_btn": "Crear una nueva clave de recuperación", + "recovery_rotate_confirm_title": "¿Quieres crear una nueva clave de recuperación?", + "recovery_rotate_confirm_desc": "La clave de 12 palabras anterior deja de ser válida de inmediato. Asegúrate de guardar la nueva clave en un lugar seguro antes de continuar.", + "recovery_rotate_confirm_yes": "Generar una nueva clave", + "recovery_rotate_confirm_no": "Cancelar", + "recovery_rotate_new_warning": "IMPORTANTE: Anota estas 12 palabras y guárdalas en un lugar físico. La clave de recuperación anterior ya no es válida a partir de ahora.", + "recovery_rotate_failed": "No se ha podido crear la clave de recuperación.", + "recovery_rotate_no_session": "La sesión de cifrado ha caducado. Cierra la sesión y vuelve a iniciar sesión, y luego vuelve a intentarlo.", + "device_title": "Este aparato", + "device_desc": "Caché local, estado de sincronización e inicio de sesión rápido en este navegador.", + "device_sync_pending": "{{count}} entradas de sincronización pendientes", + "device_sync_ok": "Todos los cambios locales se sincronizan", + "device_remembered": "Cuenta guardada en este dispositivo para iniciar sesión rápidamente", + "device_not_remembered": "La cuenta no aparece en la lista de inicio de sesión rápido", + "device_forget_btn": "¿Has olvidado tu cuenta en este dispositivo?", + "device_forget_confirm_title": "¿Eliminar el inicio de sesión rápido?", + "device_forget_confirm_desc": "La cuenta desaparecerá de la lista de inicio de sesión rápido en este dispositivo. Tu sesión y tus registros locales se mantendrán.", + "device_forget_confirm_yes": "Eliminar", + "device_forget_confirm_no": "Cancelar", + "passkey_label": "Nombre para el nuevo Passkey (opcional)", + "passkey_label_placeholder": "p. ej., MacBook, iPhone", + "passkey_rename_btn": "Guardar nombre", + "passkey_rename_success": "Passkey: nombre guardado.", + "passkey_rename_failed": "No se ha podido guardar el nombre Passkey.", + "passkey_unnamed": "Anónimo Passkey", + "stats_title": "Estadísticas", + "stats_subtitle": "Acerca de todos tus registros en este dispositivo", + "stats_logbooks": "Diarios de a bordo", + "stats_account_since": "Cuenta desde", + "stats_shared_logbooks": "Diarios compartidos", + "appearance_title": "Aplicación y presentación", + "appearance_desc": "El diseño y la combinación de colores se aplican a toda la aplicación en este dispositivo.", + "theme_label": "Estilo de diseño de la aplicación", + "theme_auto": "Automático (detección del sistema operativo)", + "theme_ocean": "Océano (morfismo del vidrio)", + "theme_material": "Material (Android)", + "theme_cupertino": "Cupertino (iOS)", + "color_scheme_label": "Modo claro o oscuro", + "color_scheme_auto": "Automático (sistema)", + "color_scheme_light": "Claro", + "color_scheme_dark": "Oscuro", + "integrations_title": "Integraciones", + "owm_key": "OpenWeatherMap Clave de API", + "owm_help": "Opcional: clave API OpenWeatherMap propia. Si no se introduce ninguna, se utilizará la clave del servidor que figura en la configuración del operador.", + "ai_title": "Funciones de IA y protección de datos", + "ai_desc": "Autoriza el uso de la inteligencia artificial (integraciones locales o en la nube) para tus registros.", + "ai_help": "La activación permite resumir automáticamente los relatos de viaje y transcribir las notas de voz. Para su procesamiento, las grabaciones de voz y las entradas del diario de a bordo se transmiten de forma cifrada a OpenRouter. Los datos no se almacenan allí de forma permanente.\n\nDado que el funcionamiento de estos recursos en la nube genera costes, agradeceríamos cualquier apoyo voluntario a través del enlace de donaciones de Ko-fi que aparece en el pie de página, para poder seguir ofreciendo estas funciones de forma gratuita para todos de manera permanente.", + "ai_enable_label": "Activar la transcripción y los resúmenes diarios", + "ai_unauthorized_alert_title": "Funciones de IA no autorizadas", + "ai_unauthorized_alert_desc": "Para transcribir notas de voz o resumir relatos de viajes, debes aceptar la transmisión de datos a OpenRouter en tu perfil de usuario, en la sección «Funciones de IA y protección de datos».", + "prefs_save": "Guardar", + "prefs_saving": "Se está guardando…", + "prefs_saved": "Guardado", + "tour_title": "Recorrido por la aplicación", + "tour_desc": "Deja que te guíen de nuevo por las secciones más importantes de la aplicación.", + "tour_restart": "Reiniciar el recorrido", + "push_title": "Notificaciones push", + "push_desc": "Como propietario del diario de navegación, recibirás una notificación cuando los miembros de la tripulación invitados sincronicen los cambios. No se transmite ningún contenido en texto sin cifrar.", + "push_enable": "Notificar los cambios en la tripulación", + "push_active": "Las notificaciones push están activadas en este dispositivo.", + "push_unsupported": "Este navegador no admite notificaciones push.", + "push_denied_hint": "Las notificaciones están bloqueadas. Actívalas en la configuración del navegador o del dispositivo.", + "push_ios_install_hint": "En el iPhone/iPad: añade la app al pantalla de inicio (iOS 16.4 o posterior) para recibir notificaciones push.", + "push_error": "No se han podido activar las notificaciones push.", + "sections": { + "account": "Cuenta y configuración", + "fleet": "Flota y tripulación", + "security": "Seguridad y dispositivo", + "stats": "Estadísticas", + "danger": "Zona de peligro" + } + }, + "vessel_pool": { + "title": "flota", + "section_title": "Tus naves", + "subtitle": "Gestiona aquí todas las naves para tus diarios de a bordo. Para cada diario de a bordo, selecciona la nave activa de esta lista.", + "loading": "Cargando la flota de barcos…", + "add_vessel": "Añadir barco", + "edit_vessel": "Editar barco", + "no_vessels": "Todavía no hay barcos en el grupo.", + "delete_confirm": "¿De verdad quieres eliminar este barco de la flota?", + "max_vessels": "Se ha alcanzado el número máximo de 20 buques en la flota." + }, + "logbook_vessel": { + "title": "Embarcación para este diario de navegación", + "subtitle": "Elige el barco para este diario de navegación. Los días de viaje utilizarán los datos de navegación y de combustible del barco seleccionado.", + "active_vessel": "Embarcación para este diario de navegación", + "no_vessels_in_pool": "No hay ningún barco en la flota: primero hay que añadirlo en el perfil de usuario.", + "no_vessel": "No se ha seleccionado ningún barco", + "unnamed": "Sin título", + "save": "Guardar barco", + "saved": "Barco guardado en el diario de navegación.", + "selection_only_hint": "Puedes ver el barco elegido por el propietario (cuaderno de bitácora compartido).", + "manage_in_profile": "Gestionar barcos en el perfil de usuario" + }, + "person_pool": { + "title": "Tripulación habitual y patrón", + "subtitle": "Crea aquí tu lista de personas: patrones y tripulación para todos los diarios de a bordo. De esta lista, selecciona la tripulación activa para cada diario de a bordo y cada día de viaje.", + "loading": "Se está cargando la lista de personas…", + "skippers_section": "Patrón habitual", + "crew_section": "Equipo habitual", + "add_skipper": "Añadir patrón", + "add_crew": "Añadir un miembro del equipo", + "edit_skipper": "Editar patrón", + "no_skippers": "Todavía no hay ningún patrón en la lista.", + "no_crew": "Todavía no hay miembros de la tripulación en la lista.", + "delete_confirm": "¿De verdad quieres eliminar a esta persona de la lista?" + }, + "logbook_crew": { + "title": "Tripulación de este diario de a bordo", + "subtitle": "Elige el patrón y la tripulación para este diario de a bordo. Los nuevos días de viaje adoptarán esta selección de forma predeterminada.", + "loading": "Se está cargando la tripulación…", + "active_skipper": "Capitán de este diario de navegación", + "active_crew": "Tripulación de este diario de a bordo", + "no_skippers_in_pool": "No hay ningún patrón en la lista: primero hay que añadirlo al perfil de usuario.", + "no_crew_in_pool": "No hay ningún equipo en la piscina: primero hay que crearlo en el perfil de usuario.", + "no_skipper": "No se ha elegido ningún patrón", + "unnamed": "Sin título", + "save": "Guardar equipo", + "saved": "Tripulación guardada en el diario de a bordo.", + "selection_only_hint": "Puedes ver la tripulación designada por el propietario (cuaderno de bitácora compartido)." + }, + "entry_crew": { + "title": "Tripulación de este día de viaje", + "subtitle": "Puede diferir del formato estándar del diario de viaje. Los días siguientes del viaje se copian del día anterior.", + "day_skipper": "Patrón de ese día", + "day_crew": "El equipo de ese día", + "no_skipper": "No se ha elegido ningún patrón", + "no_crew": "No se ha seleccionado ningún equipo" + }, + "crew": { + "title": "Perfiles de los patrones y la tripulación", + "skipper_section": "Perfil del patrón", + "skipper_read_only_hint": "El perfil del patrón solo puede ser editado por el propietario del diario de navegación.", + "crew_section": "Lista de la tripulación", + "add_crew": "Añadir un miembro del equipo", + "edit_crew": "Editar perfil de un miembro del equipo", + "no_crew": "Aún no se ha añadido ningún miembro de la tripulación.", + "max_crew": "Se ha alcanzado el número máximo de 12 miembros de la tripulación en la reserva.", + "name": "Nombre", + "address": "Dirección", + "birthdate": "Cumpleaños", + "phone": "Número de teléfono", + "nationality": "Nacionalidad", + "passport": "Número de pasaporte / documento de identidad", + "bloodtype": "Grupo sanguíneo", + "allergies": "Alergias", + "diseases": "Antecedentes médicos / Enfermedades", + "save": "Guardar datos del patrón", + "save_member": "Guardar miembro", + "saved": "¡Perfil del patrón guardado correctamente!", + "loading": "Se están cargando los archivos de la tripulación...", + "delete_confirm": "¿Estás seguro de que quieres eliminar a este miembro del equipo?" + }, + "deviation": { + "title": "Tabla de desviación de la brújula", + "subtitle": "Introduce la desviación de la brújula magnética (desv.) para los rumbos (MgK) de 000° a 360°, en intervalos de 10°.", + "heading": "MgK", + "deviation": "Distracción", + "save": "Guardar rejilla de calibración", + "saving": "Se está guardando...", + "saved": "¡Rejilla de calibración guardada correctamente!", + "loading": "Se está cargando la tabla de calibración..." + }, + "settings": { + "title": "Configuración del diario de a bordo", + "subtitle": "Compartir, hacer copias de seguridad y colaborar en este diario de a bordo.", + "select_logbook_hint": "Selecciona un diario de a bordo para editar su configuración.", + "no_key": "No hay ninguna clave API OpenWeatherMap disponible. Introduce tu propia clave en el perfil de usuario o ponte en contacto con el administrador.", + "weather_success": "¡Datos meteorológicos recuperados correctamente!", + "weather_error": "No se han podido recuperar los datos meteorológicos. Comprueba la clave API y la conexión.", + "weather_unauthorized": "No se han podido recuperar los datos meteorológicos. La clave API no es válida o no está autorizada.", + "weather_not_found": "No se han podido recuperar los datos meteorológicos. No se ha encontrado la localidad o las coordenadas indicadas.", + "weather_bad_request": "No se han podido recuperar los datos meteorológicos. No se ha especificado ninguna localidad ni posición GPS.", + "weather_date_mismatch": "Solo se pueden consultar los datos meteorológicos correspondientes a la fecha de hoy ({{today}}). Esta entrada del diario de a bordo está fechada el {{date}}.", + "gps_error": "Indica una ubicación o busca las coordenadas GPS.", + "share_title": "Compartir el diario de a bordo (solo lectura)", + "share_desc": "Activa esta opción para crear un enlace público de solo lectura. Cualquier persona que tenga el enlace podrá ver tus viajes, los perfiles de tus yates y la tripulación. Las claves de cifrado nunca se envían al servidor (permanecen en la parte hash de la URL).", + "share_privacy_warning": "Recomendación: comparte este enlace solo en privado (por ejemplo, por correo electrónico o mensajería instantánea), no en las redes sociales.", + "share_enable": "Activar enlace público", + "share_copied": "¡Enlace copiado!", + "share_copy_btn": "Copiar enlace", + "link_qr_hint": "Código QR para escanear con el smartphone", + "link_qr_alt": "Código QR del enlace", + "danger_zone_title": "Zona de peligro", + "danger_zone_desc": "Al eliminar tu cuenta, se borrarán de forma irreversible todos tus Passkey, diarios de a bordo, datos de naves, perfiles de tripulación, entradas de viaje y claves E2E. Esta acción no se puede deshacer.", + "delete_account_btn": "Eliminar la cuenta de forma definitiva", + "delete_account_confirm_title": "¿Eliminar la cuenta?", + "delete_account_confirm_desc": "¿Estás completamente seguro de que quieres eliminar de forma definitiva tu cuenta y todos los registros asociados, así como los datos cifrados con E2E?", + "delete_account_confirm_yes": "Sí, eliminar la cuenta y todos los datos", + "delete_account_confirm_no": "Cancelar", + "delete_account_failed": "No se ha podido eliminar la cuenta. Inténtalo de nuevo.", + "delete_backup_hint": "Consejo: Antes de borrarlos, haz copias de seguridad de tus diarios de a bordo (.daagbok) en la configuración de cada uno de ellos.", + "deleting_account": "Se está eliminando la cuenta…", + "invite_push_prompt_title": "¿Quieres activar las notificaciones push?", + "invite_push_prompt_message": "En cuanto los miembros de la tripulación invitados sincronicen los cambios, podrás recibir una notificación push. El contenido del diario de a bordo no se envía en texto sin cifrar.", + "invite_push_prompt_ios_message": "En cuanto los miembros del equipo sincronicen los cambios, podrás recibir una notificación push. En el iPhone/iPad: añade la aplicación al pantalla de inicio (iOS 16.4+), y luego activa las notificaciones push en el perfil de usuario.", + "invite_push_prompt_enable": "Activar ahora", + "invite_push_prompt_later": "Más tarde", + "invite_push_prompt_success": "Las notificaciones push están activadas en este dispositivo.", + "backup_title": "Copias de seguridad y restauración", + "backup_desc": "Copia de seguridad completa y cifrada de este diario de a bordo (entradas, fotos, notas de voz, rutas GPS, tripulación, barco). Protegida con una contraseña de seguridad, para poder restaurarla en esta cuenta o en una nueva.", + "backup_export_title": "Hacer una copia de seguridad", + "backup_export_desc": "Descarga todos los datos locales en un archivo .daagbok comprimido. Guarda el archivo y la frase de contraseña por separado y en un lugar seguro.", + "backup_restore_title": "Restaurar copia de seguridad", + "backup_restore_desc": "Restaura una copia de seguridad en tu cuenta actual, incluso después de haber creado una nueva cuenta.", + "backup_passphrase": "Contraseña de copia de seguridad", + "backup_passphrase_placeholder": "Mínimo 8 caracteres", + "backup_passphrase_confirm": "Confirmar la frase de contraseña", + "backup_passphrase_short": "La frase de contraseña de copia de seguridad debe tener una longitud mínima de 8 caracteres.", + "backup_passphrase_mismatch": "Las frases de contraseña no coinciden.", + "backup_wrong_passphrase": "La frase de contraseña es incorrecta o la copia de seguridad está dañada.", + "backup_export_btn": "Descargar copia de seguridad", + "backup_exporting": "Se está creando una copia de seguridad…", + "backup_export_success": "Se ha creado una copia de seguridad ({{count}} días de viaje).", + "backup_file_label": "Archivo de copia de seguridad (.daagbok)", + "backup_export_progress": "Archivos comprimidos {{current}} / {{total}}…", + "backup_invalid_archive": "El archivo no es un archivo de copia de seguridad válido.", + "backup_version_unsupported": "Formato de copia de seguridad antiguo (v1). Utiliza una copia de seguridad .daagbok actual.", + "backup_import_size_confirm": "Esta copia de seguridad ocupa aproximadamente {{size}}. La restauración en el dispositivo puede tardar más tiempo y ocupar mucho espacio de almacenamiento. ¿Deseas continuar?", + "backup_stat_voice": "{{count}} Notas de voz", + "backup_stat_size": "Sin comprimir, aprox. {{size}}", + "backup_preview_btn": "Comprobar el contenido", + "backup_previewing": "Comprueba…", + "backup_restore_btn": "Restaurar", + "backup_restoring": "Se está restaurando…", + "backup_restore_success": "Se ha recuperado el diario de a bordo «{{title}}».", + "backup_restore_cancelled": "La recuperación se ha interrumpido.", + "backup_invalid_json": "El archivo no es un archivo JSON válido.", + "backup_invalid_format": "Formato de copia de seguridad desconocido u obsoleto.", + "backup_not_owner": "Solo el propietario del diario de navegación puede crear copias de seguridad.", + "backup_not_authenticated": "Inicia sesión para restaurar una copia de seguridad.", + "backup_id_conflict": "Ya existe un registro con este ID.", + "backup_overwrite_confirm": "Se sustituirá el registro existente con el mismo ID. ¿Desea continuar?", + "backup_new_id_confirm": "¿Importar la copia de seguridad como un nuevo diario con un nuevo ID?", + "backup_stat_entries": "{{count}} Días de viaje", + "backup_stat_photos": "{{count}} Fotos", + "backup_stat_crew": "{{count}} Entradas de la tripulación", + "backup_stat_tracks": "{{count}} Rutas GPS", + "backup_exported_at": "Exportado: {{date}}" + }, + "disclaimer": { + "title": "Notas importantes", + "intro": "Por favor, lee las siguientes indicaciones antes de utilizar Kapteins Daagbok.", + "e2e_title": "Cifrado de extremo a extremo", + "e2e_body": "Los datos de tu diario de a bordo se cifran de extremo a extremo. Solo tú —o las personas que tengan tu clave— podéis leer el contenido. En el servidor solo se almacenan datos cifrados.", + "pwa_title": "Aplicación web progresiva (PWA)", + "pwa_body": "Kapteins Daagbok funciona como una aplicación web progresiva en tu navegador y se puede instalar en tu dispositivo, de forma similar a una aplicación nativa, pero sin necesidad de pasar por una tienda de aplicaciones.", + "storage_title": "Almacenamiento local y sincronización", + "storage_body": "Tus datos se almacenan temporalmente en tu dispositivo (IndexedDB). Cuando hay conexión a Internet, los cambios se sincronizan con el servidor. Si no hay conexión, puedes seguir trabajando; la sincronización se realizará más tarde.", + "free_title": "Gratis y sin publicidad", + "free_body": "Kapteins Daagbok es gratuito y no contiene publicidad.", + "liability_title": "Exención de responsabilidad", + "liability_body": "El uso de la aplicación es bajo su propia responsabilidad. No se asume ninguna responsabilidad por los daños que puedan derivarse del uso de la aplicación, incluyendo entradas erróneas o incompletas en el diario de a bordo, pérdida de datos o fallos técnicos.", + "warranty_title": "Sin garantía", + "warranty_body": "No se ofrece garantía alguna respecto al funcionamiento, la exactitud o la disponibilidad del servicio. El servicio puede interrumpirse, restringirse o suspenderse en cualquier momento.", + "copyright": "© 2026 KnorrLabs, Markus F.J. Busche", + "accept": "Aceptar y continuar", + "close": "Cerrar", + "button_title": "Avisos y exención de responsabilidad" + }, + "feedback": { + "button_title": "Enviar comentarios", + "title": "Comentarios", + "intro": "Comparte errores, ideas o comentarios generales. Tu mensaje se enviará al equipo del proyecto a través de un canal de notificación seguro.", + "category_label": "Categoría", + "category_general": "General", + "category_bug": "Informar de un error", + "category_feature": "Sugerencia de función", + "category_translation": "Error de traducción", + "contact_label": "Correo electrónico (opcional)", + "contact_placeholder": "deine@email.beispiel", + "message_label": "Mensaje", + "message_placeholder": "Describe tus comentarios…", + "send": "Enviar", + "sending": "Se está enviando…", + "cancel": "Cancelar", + "success": "¡Muchas gracias! Se ha enviado tu comentario.", + "error_send": "No se ha podido enviar el comentario. Inténtalo de nuevo más tarde.", + "error_invalid_email": "Introduce una dirección de correo electrónico válida.", + "error_not_configured": "La función de comentarios no está disponible en este servidor.", + "error_rate_limited": "Se han enviado demasiados mensajes de comentarios en poco tiempo. Por favor, espera unos minutos.", + "error_spam": "No se ha podido enviar este mensaje. Por favor, reformúlalo." + }, + "demo": { + "logbook_title": "Cuaderno de bitácora de la demostración en el mar Báltico", + "badge": "Demostración", + "public_banner": "Vista de demostración sin posibilidad de edición", + "cta_register": "Crear cuenta", + "back_to_login": "Inscripción" + }, + "invitation": { + "error_invalid_key": "El enlace de invitación no es válido desde el punto de vista criptográfico (la clave es incorrecta).", + "error_missing_key": "El enlace de invitación no contiene ninguna clave de descifrado (#key=...). Utiliza el enlace completo que te ha facilitado el propietario.", + "error_expired": "Esta invitación ha caducado (válida durante 48 horas).", + "error_invalid_token": "El token de invitación no es válido.", + "error_load_failed": "No se han podido cargar los detalles de la invitación.", + "error_incomplete_session": "Sesión incompleta: vuelve a iniciar sesión (falta el ID de usuario).", + "error_accept_failed": "Error al registrarse.", + "error_login_failed": "Passkey: error al iniciar sesión.", + "error_username_missing": "No se ha podido identificar el nombre de usuario. Vuelve a iniciar sesión.", + "error_register_failed": "El registro ha fallado.", + "loading_joining": "Inscripción...", + "loading_checking": "Se está comprobando la invitación...", + "loading_unlocking": "Se está activando y sincronizando el diario de a bordo...", + "loading_retrieving_key": "Cargando clave de cifrado...", + "error_title": "Error en la invitación", + "back_to_start": "Volver al inicio", + "title": "Invitación al diario de a bordo", + "invited_by": "Invitación de", + "vessel_logbook": "Barco / Diario de navegación", + "signed_in_preparing": "Iniciado sesión como {{username}}. Se está preparando el acceso...", + "join_again": "Volver a unirse", + "login_or_register_hint": "Inicia sesión o crea una cuenta para unirte al diario de a bordo.", + "or_sign_up": "O REGÍSTRATE", + "register_crew_account": "Crear una nueva cuenta de equipo", + "username_label": "Nombre de usuario", + "create_passkey": "Crear Passkey", + "switch_language_en": "Español", + "switch_language_de": "Alemán" + }, + "stats": { + "title": "Estadísticas", + "subtitle": "Autonomía, consumo y tipo de propulsión de un vistazo", + "scope_label": "Ámbito de evaluación", + "scope_logbook": "Este diario de a bordo", + "scope_account": "Todos los diarios de a bordo", + "loading": "Se están calculando las estadísticas…", + "no_data": "Aún no hay días de viaje disponibles.", + "total_distance": "Distancia total", + "travel_days": "Días de viaje", + "sail_distance": "A vela", + "motor_distance": "Recorrido en máquina", + "motor_hours_total": "Total de horas de funcionamiento", + "daily_motor_hours": "Horas de funcionamiento por día de viaje", + "avg_motor_hours": "Ø Horas de máquina por día de viaje", + "unknown_propulsion": "Desconocido", + "fuel_total": "Combustible total", + "water_total": "Agua en total", + "daily_etmal": "Etmal diurnos", + "daily_consumption": "Consumo diario", + "route_overview": "Ruta", + "route_map_title": "Resumen de rutas", + "propulsion_title": "Vela frente a motor", + "propulsion_hint": "La distribución se basa en los eventos del diario de navegación por día de viaje, no en segmentos de GPS.", + "avg_distance": "Ø por día de viaje", + "avg_fuel": "Ø Combustible", + "avg_water": "Ø Agua", + "fuel_per_nm": "Consumo de combustible por kilómetro", + "fuel_per_motor_hour": "Consumo de combustible por hora de funcionamiento", + "daily_fuel_per_motor_hour": "Consumo de combustible por hora de funcionamiento por día de viaje", + "fuel_legend": "Combustible", + "water_legend": "Agua", + "unit_nm": "sm", + "unit_h": "h", + "unit_l": "L", + "day_label": "Día {{day}}", + "account_logbooks": "Resumen de los registros", + "col_logbook": "Diario de a bordo", + "event_series_title": "Historial de eventos", + "event_series_hint": "Valores cronológicos del registro de eventos.", + "event_series_pressure": "presión atmosférica", + "event_series_wind": "Viento", + "event_series_motor": "Motor", + "event_series_empty": "No hay entradas." + }, + "tour": { + "skip": "Saltar el recorrido", + "back": "Atrás", + "next": "Continuar", + "finish": "Listo", + "progress": "Paso {{current}} de {{total}}", + "steps": { + "welcome": { + "title": "¡Bienvenido a bordo!", + "body": "Hemos creado para ti un diario de navegación de demostración con tres días de travesía por la bahía de Kiel. Puedes borrar las entradas de ejemplo en cualquier momento si quieres empezar con tu propio diario de navegación. Este breve recorrido te muestra las funciones más importantes." + }, + "welcome_public": { + "title": "¡Bienvenido a bordo!", + "body": "Explora nuestro diario de navegación de demostración con tres días de travesía por la bahía de Kiel, sin necesidad de crear una cuenta. El recorrido te muestra las entradas del diario, así como la selección de barco y tripulación para este diario. Más adelante podrás gestionar la flota y la tripulación habitual en tu perfil de usuario." + }, + "nav_logs": { + "title": "Entradas del diario de a bordo", + "body": "Aquí puedes gestionar los datos de tu viaje: salida, destino, tiempo, niveles de combustible y rutas GPS." + }, + "entry_list": { + "title": "Tus días de viaje", + "body": "Cada tarjeta representa un día de viaje. Toca una entrada para ver o editar los detalles." + }, + "entry_open": { + "title": "Abrir el día del viaje", + "body": "Así es como se ve una entrada completada en el diario de a bordo: con eventos, niveles de combustible y mucho más." + }, + "entry_track": { + "title": "Ruta GPS", + "body": "Sube archivos GPX o consulta en el mapa las rutas ya guardadas, incluyendo la distancia y la velocidad." + }, + "nav_vessel": { + "title": "Barco para el diario de navegación", + "body": "Elige de tu flota la nave para este diario de a bordo. Puedes gestionar las naves en tu perfil de usuario, en la sección «Flota y tripulación»." + }, + "profile_vessel_pool": { + "title": "flota", + "body": "En el perfil de usuario puedes añadir todas tus embarcaciones: yates de alquiler, tu propio barco, etc. A continuación, selecciona la embarcación correspondiente para cada diario de navegación." + }, + "profile_crew_pool": { + "title": "Tripulación habitual y patrón", + "body": "En el perfil de usuario puedes gestionar tu lista de personas: varios patrones (por ejemplo, para alquileres) y tripulantes para todos los cuadernos de bitácora." + }, + "nav_logbook_crew": { + "title": "Tripulación por diario de navegación", + "body": "Elige de la lista quiénes figuran como patrón y tripulación en este diario de a bordo. Los días de viaje adoptan esta selección de forma predeterminada." + }, + "nav_stats": { + "title": "Panel de estadísticas", + "body": "Aquí puedes ver las distancias recorridas, el consumo, los mapas de ruta y la distribución de la propulsión, todo ello calculado automáticamente a partir de las entradas de tu diario de a bordo." + }, + "nav_feedback": { + "title": "Enviar comentarios", + "body": "A través de este formulario puedes enviar errores, ideas o comentarios generales directamente al equipo del proyecto; también puedes hacerlo en cualquier momento después del recorrido haciendo clic en el icono de la esquina superior derecha." + }, + "nav_profile": { + "title": "Tu perfil de usuario", + "body": "A través del botón «Skipper» de la parte superior puedes acceder a tu perfil personal, independientemente del diario de navegación actual." + }, + "profile_preferences": { + "title": "Cuenta y presentación", + "body": "Aquí puedes gestionar la identidad de tu cuenta, el tema y el modo claro/oscuro. Puedes volver a iniciar el recorrido por la aplicación en cualquier momento. Encontrarás los ajustes de Passkey y de seguridad más abajo, en el perfil." + }, + "finish": { + "title": "¡De acuerdo!", + "body": "Enseguida accederás al panel de estadísticas. Puedes volver a iniciar el recorrido en cualquier momento desde tu perfil de usuario. ¡Buen viaje!" + } + } + }, + "seo": { + "title": "Kapteins Daagbok – Diario de navegación digital gratuito (sin publicidad)", + "description": "Diario de navegación digital gratuito y sin publicidad, con cifrado de extremo a extremo e inicio de sesión mediante Passkey. Documenta de forma segura los días de viaje, los rastros GPS, la tripulación y los datos del barco, incluso sin conexión como PWA.", + "keywords": "Diario de a bordo de yates, diario de navegación, diario de a bordo, navegación a vela, Passkey, cifrado E2E, ruta GPS, diario de navegación marítima, gratuito, sin publicidad, gratis, sin anuncios", + "ogImageAlt": "Kapteins Daagbok Logotipo" + } + } +} diff --git a/client/src/i18n/locales/fr.json b/client/src/i18n/locales/fr.json new file mode 100644 index 0000000..d4a79b4 --- /dev/null +++ b/client/src/i18n/locales/fr.json @@ -0,0 +1,1080 @@ +{ + "translation": { + "app": { + "name": "Kapteins Daagbok", + "tagline": "Journal de bord privé d'un yacht", + "beta": "Bêta", + "beta_hint": "Version bêta — Les fonctionnalités sont susceptibles d'évoluer" + }, + "footer": { + "kofi_label": "Ko-fi", + "kofi_title": "Soutenez le projet, son développement et ses coûts d'exploitation sur Ko-fi" + }, + "languages": { + "de": "Deutsch", + "en": "English", + "da": "Dansk", + "sv": "Svenska", + "nb": "Norsk", + "fr": "Français", + "es": "Español" + }, + "dialog": { + "ok": "OK", + "yes": "Oui", + "no": "Non" + }, + "errors": { + "load_failed": "Les données n'ont pas pu être chargées.", + "save_failed": "Les modifications n'ont pas pu être enregistrées.", + "delete_failed": "Échec de la suppression.", + "export_failed": "Échec de l'exportation." + }, + "common": { + "unsaved_changes_title": "Modifications non enregistrées", + "unsaved_changes_message": "Tu as des modifications non enregistrées. Veux-tu vraiment quitter cette page ? Tes modifications seront perdues.", + "unsaved_changes_stay": "Rester", + "unsaved_changes_save_leave": "Enregistrer et quitter", + "unsaved_changes_discard": "Rejeter", + "unsaved_changes_leave": "Quitter" + }, + "nav": { + "dashboard": "Tableau de bord", + "vessel": "Données relatives au navire", + "crew": "Équipage", + "deviation": "Tableau des déviations", + "logs": "Entrées du journal de bord", + "stats": "Statistiques", + "settings": "Paramètres", + "admin": "Admin" + }, + "auth": { + "welcome": "Bienvenue chez Kapteins Daagbok", + "tagline": "Ton journal de bord maritime sécurisé et crypté avec le protocole E2E.", + "register": "S'inscrire avec Passkey", + "login": "Se connecter avec Passkey", + "login_as": "Se connecter en tant que {{name}}", + "quick_login": "Connexion rapide", + "forget_account": "Compte oublié sur cet appareil", + "not_user": "Pas {{name}} ?", + "recovery_title": "Ta clé de récupération", + "recovery_warning": "IMPORTANT : Note ces 12 mots. Si tu perds ton Passkey et ces mots, tes données ne pourront pas être récupérées.", + "confirm_recovery": "J'ai noté ces mots", + "status_logged_in": "Connecté", + "status_logged_out": "Déconnecté", + "copied": "Copié !", + "copy_phrase": "Faire faire un double de la clé", + "enter_recovery": "Saisir la clé de récupération", + "recovery_fallback_warning": "Ton Passkey a été authentifié avec succès, mais ton appareil ne prend pas en charge la dérivation de clé matérielle. Saisis ta phrase de récupération de 12 mots pour déchiffrer ton journal.", + "recovery_placeholder": "Saisis ta phrase de récupération composée de 12 mots, séparés par des espaces...", + "back": "Retour", + "decrypting": "Décryptage...", + "decrypt_logbook": "Décrypter le journal de bord", + "error_incorrect_recovery": "Clé de restauration incorrecte. Échec du déchiffrement.", + "error_decryption_failed": "Échec du déchiffrement. Vérifie ta clé de récupération.", + "or_register": "ou S'inscrire", + "explore_demo": "Découvrir la démo sans créer de compte", + "username_placeholder": "Nom d'utilisateur / Nom de skipper", + "processing": "Traitement en cours...", + "help": "Aide", + "setup_pin_title": "Configurer un code PIN local (facultatif)", + "setup_pin_warning": "Comme ton appareil ne prend pas en charge la dérivation directe de la clé Passkey, tu devrais sinon saisir ta clé de 12 mots à chaque connexion sur cet appareil. Configure un code PIN local pour éviter cela.", + "pin_placeholder": "Par exemple : 123456", + "pin_label": "Code PIN local (4 à 8 chiffres)", + "save_pin": "Enregistrer le code PIN et continuer", + "skip_pin": "Passer et utiliser la fonction de récupération", + "enter_pin_title": "Décrypter avec un code PIN", + "enter_pin_warning": "Saisis ton code PIN local pour déverrouiller la clé de déchiffrement sur cet appareil.", + "enter_pin_placeholder": "Saisis ton code PIN...", + "decrypt_with_pin": "Décrypter", + "use_recovery_instead": "Utiliser plutôt la clé de récupération", + "error_incorrect_pin": "Code PIN incorrect. Échec du décryptage.", + "error_invalid_host": "Passkey ne fonctionne pas via 127.0.0.1. Veuillez ouvrir l'application via localhost.", + "use_localhost_link": "Passer à localhost", + "error_passkey_cancelled": "Passkey - Connexion interrompue ou expirée. Veuillez réessayer.", + "error_invalid_rp_id": "Le domaine Passkey ne correspond pas (RP ID). En local, utilisez uniquement http://localhost:5173 avec RP_ID=localhost dans le fichier .env.", + "error_session_incomplete": "Inscription incomplète. Veuillez vous reconnecter avec Passkey.", + "restore_checking": "La session est en cours de vérification…", + "restore_title": "Restaurer la session", + "restore_subtitle": "Ton inscription est toujours active. Déverrouille ton journal de bord avec Passkey ou ton code PIN.", + "restore_unlocking": "Déverrouillage en cours…", + "restore_with_passkey": "Déverrouiller avec Passkey ({{name}})", + "restore_with_pin": "Déverrouiller avec le code PIN", + "restore_pin_warning": "Saisis ton code PIN local pour déverrouiller ton journal de bord après le redémarrage.", + "restore_other_account": "Se connecter avec un autre compte" + }, + "pwa": { + "title": "Installer l'application", + "generic_benefit": "Installez Kapteins Daagbok sur votre appareil pour bénéficier d'un accès plus rapide, d'une utilisation hors ligne et d'un stockage permanent des données.", + "ios_instructions": "Sur le iPad/iPhone : ajoute l'application à l'écran d'accueil afin que tes données de journal de bord restent protégées et que l'application se lance comme une application native.", + "ios_step_share": "Appuyez sur l'icône de partage dans la barre Safari", + "ios_step_add": "Sélectionner « Retour à l'écran d'accueil »", + "install_now": "Installer maintenant", + "installing": "Installation…", + "later": "Plus tard", + "never": "Ne plus afficher", + "platform_ios": "Installation via Safari", + "platform_android": "Installation via le navigateur", + "platform_desktop": "Installation en tant qu'application de bureau", + "settings_section": "Installation de l'application", + "update_title": "Mise à jour disponible", + "update_desc": "Une nouvelle version de Kapteins Daagbok est disponible. Veuillez effectuer la mise à jour pour bénéficier des dernières modifications.", + "update_now": "Mettre à jour maintenant", + "update_reloading": "Chargement en cours…", + "storage_persist_hint": "Le navigateur peut supprimer les données hors ligne. Autorise le stockage permanent afin que ton journal de bord reste protégé (dans les paramètres du navigateur ou lors de la prochaine notification)." + }, + "sync": { + "status_synced": "Doublé", + "status_syncing": "Synchroniser…", + "status_offline": "Cache hors ligne", + "status_unsynced": "Modifications non synchronisées", + "conflict_title": "Conflit de synchronisation", + "conflict_message": "{{count}} La ou les modifications n'ont pas pu être synchronisées (entrée {{id}}…). Veuillez choisir la version à appliquer.", + "conflict_use_server": "Appliquer la version du serveur", + "conflict_keep_local": "Conserver ma version" + }, + "vessel": { + "title": "Données de base du navire", + "name": "Nom du yacht", + "type": "Type de yacht", + "type_unset": "— non spécifié —", + "type_sailing": "voilier", + "type_motor": "yacht à moteur", + "length_m": "Longueur (m)", + "draft_m": "Tirant d'eau (m)", + "air_draft_m": "Altitude (m)", + "invalid_metric": "Valeur numérique non valide — veuillez saisir la mesure sous forme de nombre décimal (par exemple 12,5).", + "port": "port d'attache", + "owner": "propriétaire", + "charter": "société de location de bateaux", + "registration": "Numéro d'immatriculation", + "callsign": "Indicatif d'appel radio", + "atis": "N° ATIS", + "mmsi": "Numéro MMSI", + "save": "Enregistrer les données du navire", + "saving": "En cours d'enregistrement...", + "saved": "Les données du navire ont été enregistrées avec succès !", + "loading": "Chargement des données du navire...", + "sails_list": "Gréement (voiles disponibles)", + "sails_help": "Indique ici les voiles dont dispose ton bateau (par exemple : grand-voile, génois, foc).", + "add_sail": "Ajouter une voile", + "sail_name_placeholder": "par exemple, la grand-voile", + "no_sails": "Aucune voile n'est stockée.", + "photo_add": "Ajouter une photo", + "photo_change": "Changer de photo", + "photo_delete": "Supprimer la photo", + "tanks_section": "Réservoirs (capacité)", + "tanks_help": "En option en litres — permet d'afficher un curseur dans le journal lorsque la capacité du réservoir est connue.", + "freshwater_capacity_l": "Eau potable (litres)", + "fuel_capacity_l": "Carburant (litres)", + "greywater_capacity_l": "Eaux grises (litres)", + "invalid_tank_liters": "Valeur numérique non valide — veuillez saisir le nombre de litres sous forme de chiffre (par exemple, 200)." + }, + "logs": { + "title": "Journal de bord", + "new_entry": "Nouveau jour de voyage", + "travel_details": "Détails du voyage", + "add_event": "Ajouter une nouvelle entrée au journal de bord", + "add_event_btn": "Ajouter un événement", + "edit_event": "Modifier l'événement", + "save_event_btn": "Enregistrer la modification", + "cancel_event_edit": "Annuler", + "delete_event": "Supprimer l'événement", + "sign_cleared_skipper_re_sign_title": "Signature du skipper supprimée", + "sign_cleared_skipper_re_sign": "Le journal des événements a été modifié. La signature du skipper a été supprimée. Veuillez le valider à nouveau.", + "date": "Date", + "day_of_travel": "Jour de voyage", + "travel_day_number": "Jour de voyage {{number}}", + "departure": "Port de départ (départ de)", + "destination": "Port de destination (vers)", + "route": "Voyage depuis/vers", + "tanks": "Réservoirs", + "customize_columns": "Ajuster les colonnes", + "column_selector_title": "Colonnes à afficher", + "freshwater": "Eau douce (litres)", + "fuel": "Carburant (litres)", + "greywater": "Eaux grises (litres)", + "greywater_level": "niveau de remplissage", + "tank_slider_of_max": "{{current}} / {{max}} L", + "tank_capacity_tooltip": "Si les capacités des réservoirs (en litres) sont indiquées dans les données du bateau, tu peux saisir ici les niveaux de remplissage à l'aide du curseur.", + "morning": "Situation ce matin", + "refilled": "Réapprovisionné", + "evening": "Situation en fin de journée", + "consumption": "consommation quotidienne", + "signatures": "Signatures / Validation", + "sign_skipper": "Signature du skipper", + "sign_crew": "Signature de l'équipe", + "sign_hint": "Signer avec le doigt, un stylo ou la souris", + "sign_clear": "Supprimer", + "sign_export_image": "[Signature]", + "sign_with_passkey": "Partager avec Passkey", + "sign_passkey_signing": "Passkey est demandé…", + "sign_passkey_signed": "Publié par {{username}}", + "sign_passkey_export": "Passkey : {{username}} ({{date}})", + "sign_attribution_export": "{{username}} ({{date}})", + "sign_passkey_clear": "Supprimer l'autorisation Passkey", + "sign_mode_passkey": "Passkey", + "sign_mode_classic": "Classique", + "sign_passkey_failed": "Échec de la validation Passkey", + "sign_passkey_cancelled": "Passkey - Validation interrompue", + "sign_invalid": "Signature non valide — Le contenu a été modifié", + "sign_badge_skipper": "skipper", + "sign_badge_skipper_invalid": "Non valide", + "sign_badge_skipper_title_valid": "Skipper a validé", + "sign_badge_skipper_title_invalid": "Signature du skipper non valide — Le contenu a été modifié", + "sign_classic_or_passkey": "En option : signature classique ou validation Passkey en haut", + "sign_crew_passkey_hint": "Les membres de l'équipe disposant d'un accès en écriture peuvent partager via Passkey", + "sign_offline_hint": "La validation Passkey nécessite une connexion Internet — la signature classique est possible hors ligne", + "sign_lock_notice": "Une fois le document signé, aucune modification ne peut être apportée à l'inscription dans le journal de bord (à l'exception des photos) sans que le skipper et l'équipage ne doivent à nouveau signer.", + "sign_lock_active": "Cette entrée est signée. Toute modification apportée au journal de bord (à l'exception des photos) supprime automatiquement les signatures du skipper et de l'équipage.", + "sign_lock_warning_title": "Confirmer la signature", + "sign_lock_warning": "Une fois la signature apposée, aucune modification ne peut être apportée à l'entrée du journal de bord (à l'exception des photos) sans que le skipper et l'équipage ne doivent à nouveau signer.\n\nSouhaites-tu continuer ?", + "sign_proceed": "Signer", + "sign_cancel": "Annuler", + "sign_cleared_re_sign_title": "Signatures supprimées", + "sign_cleared_re_sign": "L'entrée du journal de bord a été modifiée. Les signatures du skipper et de l'équipage ont été supprimées. Veuillez signer à nouveau.", + "no_entries": "Aucune entrée de journal de bord n'a été trouvée pour ce yacht. Créez votre premier journal de bord !", + "back_to_list": "Retour à la liste des articles", + "save": "Enregistrer la page du journal de bord", + "saving": "En cours d'enregistrement...", + "saved": "La page du journal de bord a été enregistrée avec succès !", + "loading": "Le journal est en cours de chargement...", + "view_mode_label": "Vue", + "view_list": "Liste", + "live_mode": "En direct", + "live_title": "Journal en direct", + "live_loading": "LiveJournal est en cours de chargement...", + "live_retry": "Réessayer", + "live_load_error": "Impossible de charger Live-Journal.", + "live_action_error": "L'enregistrement n'a pas pu être sauvegardé.", + "live_open_editor": "Éditeur complet", + "live_actions_label": "Offres flash", + "live_stream_label": "Journal des événements", + "live_stream_title": "Journal", + "live_no_events": "Pas encore d'entrées — clique sur une action.", + "live_motor_start": "Démarrage du moteur", + "live_motor_stop": "Arrêt du moteur", + "live_cast_off": "Déposer", + "live_moor": "Créer", + "live_sails_btn": "voile", + "live_sails_pick": "Choisir une voile", + "live_sails_pick_hint": "Appuyez sur plusieurs voiles (appuyez à nouveau pour les désélectionner), puis enregistrez.", + "live_sails_selected": "Sélection : {{sails}}", + "live_sails_confirm": "S'inscrire", + "live_sails_confirm_count": "S'inscrire ({{count}})", + "live_sails": "Voile : {{sails}}", + "live_position": "Position", + "live_position_coords": "Position {{lat}}, {{lng}}", + "live_position_manual_hint": "GPS indisponible. Saisissez manuellement la latitude et la longitude ou réessayez en appuyant sur le bouton GPS.", + "live_position_gps_loading": "La position GPS est en cours de calcul…", + "live_position_invalid": "Veuillez saisir des coordonnées valides (latitude −90…90, longitude −180…180).", + "live_position_lat_placeholder": "Largeur (Lat)", + "live_position_lng_placeholder": "Longueur (Lng)", + "live_photo_btn": "Photo (appareil photo)", + "live_photo_capture_btn": "Enregistrer", + "live_photo_save_btn": "Enregistrer", + "live_photo_retake_btn": "Réenregistrer", + "live_photo_capture_failed": "Échec de l'enregistrement. Veuillez réessayer.", + "live_photo_open_camera_btn": "Ouvrir l'appareil photo", + "live_photo_native_hint": "Prenez une photo avec l'appareil photo de l'appareil, puis enregistrez-la ici.", + "live_photo_camera_starting": "La caméra démarre…", + "live_photo_camera_denied": "Accès à la caméra refusé ou indisponible.", + "live_photo_camera_unavailable": "Ce navigateur ne prend pas en charge la caméra.", + "live_photo_no_camera": "Cet appareil n'est pas équipé d'un appareil photo.", + "live_photo_error": "Impossible d'enregistrer la photo.", + "live_photo_entry": "Photo : {{caption}}", + "live_photo_entry_plain": "Photo prise", + "live_undo_photo_hint": "Photo enregistrée", + "live_voice_btn": "message vocal", + "live_voice_hint": "Enregistrer un court message vocal (60 secondes maximum).", + "live_voice_record": "Lancer l'enregistrement", + "live_voice_stop": "Terminer l'enregistrement", + "live_voice_recording": "Enregistrement {{time}}", + "live_voice_save": "Enregistrer", + "live_voice_saving": "En cours d'enregistrement…", + "live_voice_retake": "Réenregistrer", + "live_voice_mic_denied": "Accès au microphone refusé ou indisponible.", + "live_voice_record_failed": "Échec de l'enregistrement. Veuillez réessayer.", + "live_voice_unavailable": "Mémorandum vocal indisponible", + "live_voice_too_large": "L'enregistrement est trop long. Veuillez raccourcir l'enregistrement.", + "live_voice_error": "Impossible d'enregistrer le message vocal.", + "live_voice_entry": "Note vocale : {{caption}}", + "live_voice_entry_plain": "message vocal", + "live_voice_caption_label": "Inscription (facultative)", + "live_voice_caption_placeholder": "par exemple, communications radio avec le capitaine du port", + "live_voice_transcribe_action": "Transcrire", + "live_voice_transcribing": "Transcris...", + "live_voice_transcribe_failed": "Le mémo vocal a été enregistré, mais la transcription a échoué.", + "live_undo_voice_hint": "Note vocale enregistrée", + "live_comment_btn": "Commentaire", + "live_comment_placeholder": "Saisir du texte libre…", + "live_comment_confirm": "S'inscrire", + "live_gps_error": "Impossible de déterminer la position GPS.", + "live_gps_start_hint": "Commence toujours ton parcours quotidien par une position.", + "live_event_generic": "Événement", + "live_weather_btn": "Météo", + "live_weather_owm_btn": "OpenWeatherMap Consulter la météo", + "live_weather_owm_loading": "Chargement de la météo…", + "live_weather_position_required": "Pour les conditions météo de OpenWeatherMap, commencez par saisir une position (bouton « Position »). La position ne doit pas dater de plus de 6 heures.", + "live_weather_position_stale": "La dernière position date de plus de 6 heures. Veuillez enregistrer une nouvelle position avant de consulter la météo.", + "live_wind_btn": "Vent", + "live_temp_btn": "T °C", + "live_pressure_btn": "pression atmosphérique", + "live_precip_btn": "Précipitations", + "live_sea_state_btn": "état de la mer", + "live_visibility_btn": "visibilité", + "live_course_btn": "Cours", + "live_fuel_btn": "+ Diesel", + "live_water_btn": "+ Eau", + "live_wind_entry": "Vent {{value}}", + "live_temp_entry": "Température {{temp}} °C", + "live_pressure_entry": "Pression atmosphérique {{value}} hPa", + "live_precip_entry": "Précipitations {{value}}", + "live_sea_state_entry": "État de la mer {{value}}", + "live_visibility_entry": "Portée visuelle {{value}}", + "live_course_entry": "Cours {{course}}", + "live_fuel_entry": "Diesel +{{liters}} L", + "live_water_entry": "Eau +{{liters}} L", + "live_auto_position": "Position automatique", + "live_undo_hint": "Entrée enregistrée", + "live_undo_btn": "Annuler", + "live_cancel": "Interruption", + "live_pressure_placeholder": "par exemple 1013", + "live_temp_placeholder": "par exemple 18", + "live_precip_placeholder": "par exemple, une pluie légère", + "live_sea_state_placeholder": "par exemple 3", + "live_visibility_placeholder": "par exemple 10 km", + "live_course_placeholder": "par exemple 245", + "live_fuel_placeholder": "Litres rechargés", + "live_water_placeholder": "Litres rechargés", + "live_sog_btn": "SOG", + "live_stw_btn": "STW", + "live_sog_entry": "SOG {{speed}} kn", + "live_stw_entry": "STW {{speed}} kn", + "live_sog_placeholder": "par exemple 5,2", + "live_stw_placeholder": "par exemple 4,8", + "live_sog_hint": "Vitesse par rapport au sol (kn) — La valeur GPS est préremplie si elle est disponible.", + "delete_entry": "Supprimer la balise", + "delete_confirm": "Es-tu sûr de vouloir supprimer définitivement cette date de voyage ?", + "carry_over_tanks_title": "Reprendre les données de la veille ?", + "carry_over_tanks_confirm": "Reprendre les valeurs de départ du port de départ, d'eau douce, de carburant et d'eaux usées du dernier jour du voyage ?\n\nPort de départ : {{departure}}\nEau douce : {{fw}} L\nCarburant : {{fuel}} L\nEaux usées : {{greywater}} L", + "carry_over_tanks_yes": "Appliquer", + "carry_over_tanks_no": "Commencer à zéro", + "event_title": "Journal chronologique des événements", + "event_creator": "Publié par", + "no_events": "Aucun événement n'a encore été enregistré pour cette journée de voyage.", + "event_time": "Heure", + "event_mgk": "Cours MgK", + "event_rwk": "Cours RwK", + "event_course_section": "Cours", + "course_dial_hint": "Faire tourner l'anneau ou saisir un angle", + "course_dial_step_label": "Incrément", + "course_step_fine": "1°", + "course_step_medium": "5°", + "course_step_coarse": "10°", + "course_tab_mgk": "MgK", + "course_tab_rwk": "rwK", + "course_invalid": "Valeur non valide (0–360)", + "course_placeholder_degrees": "par exemple 180", + "course_placeholder_cardinal": "par exemple NW", + "compass_n": "N", + "compass_e": "O", + "compass_s": "S", + "compass_w": "W", + "wind_mode_cardinal": "cardinal", + "wind_mode_degrees": "En degrés", + "event_wind_direction": "Direction du vent", + "event_wind_strength": "force du vent", + "event_sea_state": "état de la mer", + "event_visibility": "visibilité", + "event_visibility_placeholder": "par exemple 10 km", + "weather_slider_unset": "—", + "weather_slider_pressure": "{{value}} hPa", + "weather_slider_sea_state": "Niveau {{value}}", + "weather_slider_heel": "{{value}}°", + "event_weather": "Météo", + "event_log": "Logge (sm)", + "event_gps": "Coordonnées GPS", + "event_location": "Lieu / Port", + "event_location_placeholder": "par exemple, Kiel", + "event_remarks": "Remarques / Évènements", + "gps_btn": "Obtenir les coordonnées GPS", + "gps_permission_denied": "L'accès à la localisation a été refusé. Veuillez l'autoriser dans les paramètres de votre navigateur ou de votre appareil, puis réessayez.", + "gps_timeout": "Délai d'attente GPS. Veuillez réessayer, de préférence à l'extérieur, dans un endroit où la réception est bonne.", + "gps_position_unavailable": "Aucun signal GPS disponible. Veuillez patienter ou saisir les coordonnées manuellement.", + "gps_unavailable": "Le GPS n'est pas pris en charge par ce navigateur ou cet appareil.", + "gps_failed": "Impossible de déterminer la position GPS.", + "gps_fallback_no_location": "Échec de la localisation GPS. Veuillez saisir un lieu dans la rubrique « Lieu / Port », indiquer le port de départ ou d'arrivée, ou saisir les coordonnées manuellement.", + "gps_fallback_success": "Coordonnées de « {{location}} » déterminées à partir du nom de la localité (et non par GPS).", + "gps_fallback_failed": "La recherche par GPS et par nom de lieu a échoué. Veuillez saisir les coordonnées manuellement.", + "gps_quality_excellent": "Réception GPS puissante (±{{accuracy}} m)", + "gps_quality_good": "Bonne réception GPS (±{{accuracy}} m)", + "gps_quality_fair": "Réception GPS moyenne (±{{accuracy}} m) – pour une meilleure réception, sortez à l'extérieur.", + "gps_quality_poor": "Réception GPS faible (±{{accuracy}} m) – probablement peu de satellites. Réessayez à l'extérieur ou vérifiez votre position.", + "gps_quality_unknown": "Position GPS enregistrée (précision non indiquée par l'appareil).", + "gps_live_intro_title": "Emplacement du journal en temps réel", + "gps_live_intro_body": "Pour enregistrer automatiquement ta position et utiliser le bouton GPS, l'application doit pouvoir accéder à ta localisation.\n\nAppuie sur « Autoriser l'accès à la localisation » ; dans la fenêtre suivante, confirme l'autorisation. Tu peux à tout moment saisir manuellement ta position dans la rubrique « Position ».", + "gps_live_intro_allow": "Autoriser l'accès à la localisation", + "gps_live_intro_later": "Plus tard", + "gps_enable_in_settings_hint": "L'accès à la localisation est bloqué. Tu peux autoriser l'accès ultérieurement dans les paramètres du navigateur ou de l'appareil (site web / application → Localisation).", + "weather_btn": "OpenWeatherMap Consulter la météo", + "weather_offline": "OpenWeatherMap nécessite une connexion Internet. Tu es actuellement hors ligne.", + "event_wind_pressure": "Pression atmosphérique (hPa)", + "event_heel": "Gîte (°)", + "event_sails": "Voile / Moteur", + "motor_propulsion": "déplacement de la machine", + "sails_picker_show_more": "Afficher toutes les voiles", + "sails_picker_show_less": "Afficher moins", + "motor_hours": "Heures-machine (total)", + "fuel_per_motor_hour": "Consommation par heure de fonctionnement", + "event_distance": "Distance (m)", + "export_csv": "Télécharger CSV", + "share_csv": "Partager CSV", + "export_pdf": "Télécharger PDF", + "exporting_pdf": "PDF est généré...", + "ai_summary_title": "Résumé généré par l'IA", + "ai_summary_read_only": "Créé par le skipper — accessible uniquement à l'équipage.", + "ai_summary_empty": "Il n'y a pas encore de résumé.", + "ai_summary_generate": "Générer un résumé", + "ai_summary_regenerate": "Regénérer", + "ai_summary_generating": "En cours de génération…", + "ai_summary_attempts_remaining": "Il reste encore {{remaining}} essais sur {{max}}", + "ai_summary_error": "Échec du résumé généré par l'IA. Veuillez réessayer plus tard.", + "ai_summary_error_no_key": "Aucune clé API OpenRouter n'est configurée sur le serveur.", + "ai_summary_error_rate_limited": "Le nombre maximal de générations pour cette journée de voyage a été atteint.", + "ai_summary_error_forbidden": "Seul le skipper est autorisé à générer des résumés basés sur l'IA.", + "ai_summary_offline": "Le résumé généré par l'IA nécessite une connexion Internet. Tu es actuellement hors ligne.", + "photos_title": "Pièces jointes (photos)", + "photo_caption_label": "Description de la photo / Étiquette (facultatif)", + "photo_caption_placeholder": "par exemple, hisser les voiles près de l'entrée du port", + "photo_btn": "Prendre une photo / Télécharger une photo", + "photo_camera_btn": "Prendre une photo", + "photo_gallery_btn": "Sélectionner dans la galerie", + "photo_processing": "En cours de traitement...", + "no_photos": "Aucune photo n'a encore été ajoutée pour cette journée de voyage.", + "photo_delete_confirm": "Es-tu sûr de vouloir supprimer définitivement cette photo ?", + "confirm_yes": "Oui", + "confirm_no": "Non", + "track_upload_title": "Tracé GPS (fichier)", + "track_upload_points": "Points", + "gps_tracking_btn_gpx": "Télécharger le fichier de piste", + "gps_track_upload_help": "Faites glisser un fichier GPX, KML ou GeoJSON ici ou cliquez pour sélectionner", + "gps_track_upload_btn": "Télécharger un tracé GPS", + "gps_track_delete": "Supprimer le fichier de piste", + "gps_track_delete_confirm": "Es-tu sûr de vouloir supprimer définitivement ce fichier audio ?", + "track_distance": "Parcours GPS (sm)", + "track_speed_max": "Vitesse maximale (nœuds)", + "track_speed_avg": "Vitesse moyenne (nœuds)", + "track_map_title": "Tracé GPS sur OpenSeaMap", + "track_map_start": "Accueil", + "track_map_end": "Objectif", + "track_map_speed_slow": "lentement", + "track_map_speed_fast": "rapidement", + "nmea_import_title": "Importer un fichier au format NMEA", + "nmea_import_intro": "Importe un fichier .nmea depuis l'enregistreur de bord. L'application te propose des entrées de journal — c'est toi qui décides lesquelles sont reprises.", + "nmea_import_btn": "Importer des données NMEA", + "nmea_file_label": "Fichier NMEA", + "nmea_stats": "{{lines}} phrases détectées · Types : {{types}}", + "nmea_warn_no_position": "Aucune donnée de position trouvée — les champs « Track » et « GPS » peuvent rester vides.", + "nmea_warn_duplicate_file": "Ce fichier NMEA a déjà été importé. Une nouvelle importation du même fichier entraînerait la création d'entrées en double dans le journal.", + "nmea_mode_label": "Créer des entrées de journal", + "nmea_mode_interval": "Par intervalle de temps", + "nmea_mode_change": "En cas de modification importante", + "nmea_mode_both": "Les deux (fusionner)", + "nmea_interval_label": "Intervalle (minutes)", + "nmea_import_track": "Importer un tracé GPS au format NMEA", + "nmea_preview": "Aperçu", + "nmea_preview_hint": "{{count}} Entrées de journal suggérées", + "nmea_select_all": "Tout sélectionner", + "nmea_select_none": "Ne rien sélectionner", + "nmea_source_interval": "Intervalle", + "nmea_source_change": "Événement", + "nmea_apply": "Enregistrer dans le journal", + "nmea_back": "Retour", + "nmea_cancel": "Annuler", + "nmea_archive_question": "Archiver le journal brut localement ? (Uniquement sur cet appareil, sans synchronisation.)", + "nmea_archive_keep": "Archiver", + "nmea_archive_discard": "Rejeter", + "nmea_archive_stored": "NMEA archivé : {{name}}", + "nmea_archive_delete_confirm": "Supprimer le journal NMEA archivé de cet appareil ?", + "nmea_error_no_samples": "Le fichier ne contient aucun enregistrement NMEA exploitable.", + "nmea_error_parse": "Impossible de lire le fichier NMEA.", + "nmea_error_read": "Impossible de lire le fichier.", + "nmea_error_no_file": "Veuillez d'abord sélectionner un fichier NMEA.", + "nmea_error_no_selection": "Veuillez sélectionner au moins une entrée du journal.", + "nmea_remark_interval": "Intervalle NMEA", + "nmea_remark_uncertain": "incertain", + "nmea_remark_depth": "Profondeur {{depth}} m", + "nmea_change_course": "Changement de cap {{from}}° → {{to}}°", + "nmea_change_wind": "Vent {{from}}° → {{to}}°", + "nmea_change_wind_speed": "Vent {{from}} → {{to}} nœuds", + "nmea_change_pressure": "Pression atmosphérique {{from}} → {{to}} hPa", + "nmea_change_depth": "Profondeur {{from}} → {{to}} m", + "nmea_change_engine_start": "Moteur en marche ({{rpm}} tr/min)", + "nmea_change_engine_stop": "Moteur éteint", + "nmea_change_autopilot_on": "Pilote automatique activé", + "nmea_change_autopilot_off": "Pilote automatique désactivé", + "nmea_change_gps_lost": "Perte de la position GPS", + "nmea_change_gps_regained": "Position GPS rétablie", + "nmea_change_water_temp": "Température de l'eau {{from}} → {{to}} °C", + "nmea_change_departure": "Départ / Début du trajet", + "nmea_change_anchor": "Ancrage / Arrêt", + "nmea_change_speed": "Vitesse {{from}} → {{to}} nœuds", + "track_map_error": "Impossible de charger la carte.", + "exporting": "Exporter...", + "share_unsupported": "Le partage n'est pas pris en charge sur cet appareil. Le fichier a été téléchargé à la place.", + "invite_crew": "Inviter l'équipe", + "invite_link_copied": "Le lien d'invitation a été copié dans le presse-papiers !", + "invite_link_desc": "Partage ce lien avec les membres de l'équipage pour leur accorder des droits d'écriture sur ce journal de bord.", + "collaborators_list": "Membres / Équipe", + "revoke": "Supprimer", + "revoke_confirm": "Es-tu sûr de vouloir retirer l'accès à ce membre de l'équipe ?", + "invite_role": "rôle", + "invite_expires": "Le lien est valable pendant 48 heures" + }, + "dashboard": { + "title": "Tes carnets de bord", + "subtitle": "Choisis un carnet de voyage ou crée-en un nouveau pour gérer tes voyages.", + "create_btn": "Créer un journal de bord", + "new_logbook_placeholder": "Nom du journal de bord ou du yacht", + "logout": "Se déconnecter", + "logged_in_as": "Connecté en tant que {{name}}", + "delete_confirm": "Es-tu sûr de vouloir supprimer définitivement ce journal ? Toutes les données locales et les copies sur le serveur seront effacées.\n\nConseil : si tu souhaites conserver ces données ultérieurement, pense à créer au préalable une copie de sauvegarde (.daagbok) dans Réglages → Sauvegarde et restauration.", + "no_logbooks": "Aucun journal de bord trouvé. Crée ton premier journal de bord pour commencer !", + "loading": "Chargement des journaux de bord...", + "status_synced": "Doublé", + "status_local": "Cache local uniquement", + "delete_btn": "Effacer le journal de bord", + "section_owned": "Mes carnets de bord", + "section_shared": "Journaux de bord partagés", + "section_shared_hint": "Tu as été invité en tant que membre d'équipage. Le profil du skipper et les paramètres lui appartiennent.", + "role_owner": "Son propre journal de bord", + "role_owner_hint": "Tu es le propriétaire et le skipper de ce journal de bord", + "role_crew": "Accès à l'équipe", + "role_crew_hint": "Journal de bord ouvert à tous — tu peux y contribuer en tant que membre d'équipage et y apposer ta signature", + "role_read": "Lecture seule", + "role_read_hint": "Journal partagé — consultation uniquement, pas de modification", + "open_profile": "Ouvrir le profil de {{name}}", + "open_logbook": "Ouvrir le journal de bord « {{title}} »", + "edit_title": "Renommer le journal de bord", + "edit_placeholder": "Nouveau nom du journal de bord", + "edit_success": "Le journal de bord a été renommé avec succès", + "edit_btn": "Renommer", + "filter_label": "Filtrer les journaux de bord", + "filter_placeholder": "Nom, année, date, équipage ou navire…", + "filter_clear": "Réinitialiser les filtres", + "filter_results": "{{count}} résultats", + "filter_no_results": "Aucun journal de bord ne correspond à ta recherche. Essaie un autre nom ou une autre année.", + "sort_label": "Trier", + "sort_by_label": "Trier par", + "sort_by_name": "Nom", + "sort_by_date": "Date", + "sort_dir_label": "Ordre", + "sort_asc": "Par ordre croissant", + "sort_desc": "Par ordre décroissant", + "sort_name_asc": "Nom de A à Z", + "sort_name_desc": "Nom de Z à A", + "sort_date_asc": "Les plus anciens en premier", + "sort_date_desc": "Les plus récents en premier" + }, + "profile": { + "title": "Profil utilisateur", + "subtitle": "Compte, Passkeys et statistiques pour {{name}}", + "back": "Retour au tableau de bord", + "loading": "Chargement du profil…", + "load_error": "Impossible de charger le profil.", + "copy_failed": "Échec de la copie.", + "processing": "En cours de traitement…", + "identity_title": "Identifiant du compte", + "username": "Nom d'utilisateur", + "user_id": "Identifiant utilisateur", + "copy_user_id": "Copier l'identifiant utilisateur", + "account_since": "Compte depuis", + "prf_status": "Dérivation de clé Passkey (PRF)", + "prf_active": "Actif", + "prf_inactive": "Non aménagé", + "passkeys_title": "Passkeys", + "passkeys_desc": "Enregistre un identifiant Passkey distinct sur chaque appareil. Tu pourras ainsi te connecter même après avoir changé de plateforme.", + "passkeys_empty": "Aucun Passkey trouvé.", + "add_passkey_btn": "Ajouter un nouveau Passkey", + "add_passkey_success": "Passkey a été ajouté avec succès.", + "add_passkey_failed": "Passkey n'a pas pu être ajouté.", + "remove_passkey_btn": "Supprimer Passkey", + "remove_passkey_last_title": "Dernier Passkey", + "remove_passkey_last_desc": "Le seul Passkey ne peut pas être supprimé sans perdre l'accès à ton compte. Pour supprimer complètement le compte, utilise la zone de suppression située en bas de cette page.", + "remove_passkey_failed": "Passkey n'a pas pu être supprimé.", + "remove_passkey_confirm_title": "Supprimer Passkey ?", + "remove_passkey_confirm_desc": "Cet appareil ne pourra plus se connecter à ce Passkey par la suite.", + "remove_passkey_confirm_yes": "Supprimer", + "remove_passkey_confirm_no": "Annuler", + "pin_title": "Code PIN local", + "pin_status": "Statut", + "pin_active": "Actif sur cet appareil", + "pin_inactive": "Non aménagé", + "pin_confirm_label": "Confirmer le code PIN", + "pin_confirm_placeholder": "Entrez à nouveau votre code PIN", + "pin_set_btn": "Configurer le code PIN", + "pin_change_btn": "Modifier le code PIN", + "pin_remove_btn": "Supprimer le code PIN", + "pin_saved": "Code PIN enregistré.", + "pin_save_failed": "Le code PIN n'a pas pu être enregistré.", + "pin_mismatch": "Les codes PIN saisis ne correspondent pas.", + "pin_length_error": "Le code PIN doit comporter au moins 4 caractères.", + "pin_no_session": "La session a expiré — veuillez vous reconnecter.", + "remove_pin_confirm_title": "Supprimer le code PIN ?", + "remove_pin_confirm_desc": "Tu dois te reconnecter sur cet appareil à l'aide de Passkey ou de la clé de récupération.", + "remove_pin_confirm_yes": "Supprimer le code PIN", + "remove_pin_confirm_no": "Annuler", + "security_title": "Liste de contrôle de sécurité", + "security_desc": "Aperçu des principaux mécanismes de sécurité de ton compte.", + "security_passkeys_ok": "Au moins un Passkey enregistré", + "security_passkeys_missing": "Aucun Passkey enregistré", + "security_prf_ok": "Génération de clé PRF activée", + "security_prf_missing": "PRF non configuré", + "security_pin_ok": "Code PIN local sur cet appareil", + "security_pin_missing": "Pas de code PIN local", + "security_recovery_ok": "Clé de récupération configurée", + "security_recovery_hint": "Les 12 mots ont été affichés lors de l'inscription. Conserve-les hors ligne et séparément de l'appareil. Tu peux générer une nouvelle clé ci-dessous — l'ancienne sera alors invalidée.", + "recovery_rotate_btn": "Créer une nouvelle clé de récupération", + "recovery_rotate_confirm_title": "Créer une nouvelle clé de récupération ?", + "recovery_rotate_confirm_desc": "L'ancienne clé de 12 mots n'est plus valable à compter de maintenant. Assure-toi de conserver la nouvelle clé en lieu sûr avant de continuer.", + "recovery_rotate_confirm_yes": "Créer une nouvelle clé", + "recovery_rotate_confirm_no": "Annuler", + "recovery_rotate_new_warning": "IMPORTANT : note ces 12 mots et conserve-les hors ligne. L'ancienne clé de récupération n'est plus valable à compter de maintenant.", + "recovery_rotate_failed": "Impossible de créer la clé de récupération.", + "recovery_rotate_no_session": "La session de chiffrement a expiré — veuillez vous déconnecter puis vous reconnecter, puis réessayer.", + "device_title": "Cet appareil", + "device_desc": "Cache local, état de la synchronisation et connexion rapide sur ce navigateur.", + "device_sync_pending": "{{count}} entrées de synchronisation en attente", + "device_sync_ok": "Toutes les modifications locales sont synchronisées", + "device_remembered": "Compte enregistré sur cet appareil pour une connexion rapide", + "device_not_remembered": "Compte absent de la liste de connexion rapide", + "device_forget_btn": "Compte oublié sur cet appareil", + "device_forget_confirm_title": "Supprimer la connexion rapide ?", + "device_forget_confirm_desc": "Le compte disparaîtra de la liste de connexion rapide sur cet appareil. Ta session et tes journaux locaux seront conservés.", + "device_forget_confirm_yes": "Supprimer", + "device_forget_confirm_no": "Annuler", + "passkey_label": "Nom du nouveau Passkey (facultatif)", + "passkey_label_placeholder": "par exemple, MacBook, iPhone", + "passkey_rename_btn": "Enregistrer le nom", + "passkey_rename_success": "Nom Passkey enregistré.", + "passkey_rename_failed": "Impossible d'enregistrer le nom Passkey.", + "passkey_unnamed": "Anonyme Passkey", + "stats_title": "Statistiques", + "stats_subtitle": "Tous tes journaux de bord sur cet appareil", + "stats_logbooks": "Journaux de bord", + "stats_account_since": "Compte depuis", + "stats_shared_logbooks": "Journaux de bord partagés", + "appearance_title": "Application et présentation", + "appearance_desc": "Le design et la palette de couleurs s'appliquent à l'ensemble de l'application sur cet appareil.", + "theme_label": "Style graphique de l'application", + "theme_auto": "Automatique (détection du système d'exploitation)", + "theme_ocean": "Océan (morphisme du verre)", + "theme_material": "Matériau (Android)", + "theme_cupertino": "Cupertino (iOS)", + "color_scheme_label": "Mode clair ou mode sombre", + "color_scheme_auto": "Automatique (système)", + "color_scheme_light": "Clair", + "color_scheme_dark": "Sombre", + "integrations_title": "Intégrations", + "owm_key": "OpenWeatherMap Clé API", + "owm_help": "Facultatif : clé API OpenWeatherMap personnalisée. En l'absence de cette entrée, la clé côté serveur issue de la configuration de l'opérateur est utilisée.", + "ai_title": "Fonctionnalités IA et protection des données", + "ai_desc": "Autorise l'utilisation de l'intelligence artificielle (intégrations locales/cloud) pour tes journaux de bord.", + "ai_help": "Cette fonctionnalité permet de résumer automatiquement les récits de voyage et de transcrire les notes vocales. Pour le traitement, les enregistrements vocaux et les entrées du journal de bord sont transmis de manière cryptée à OpenRouter. Les données n'y sont pas stockées de manière permanente.\n\nL'exploitation de ces ressources cloud engendrant des coûts, nous vous serions reconnaissants de bien vouloir nous soutenir volontairement via le lien de don Ko-fi situé en bas de page, afin que nous puissions continuer à offrir ces fonctionnalités gratuitement à tous.", + "ai_enable_label": "Activer la transcription et les résumés quotidiens", + "ai_unauthorized_alert_title": "Fonctions d'IA non autorisées", + "ai_unauthorized_alert_desc": "Pour transcrire des notes vocales ou résumer des récits de voyage, tu dois accepter le transfert de données vers OpenRouter dans ton profil utilisateur, sous « Fonctions IA et protection des données ».", + "prefs_save": "Enregistrer", + "prefs_saving": "En cours d'enregistrement…", + "prefs_saved": "Enregistré", + "tour_title": "Présentation de l'application", + "tour_desc": "Laisse-toi guider à nouveau à travers les principales sections de l'application.", + "tour_restart": "Recommencer le circuit", + "push_title": "Notifications push", + "push_desc": "En tant que propriétaire du journal de bord, tu seras averti lorsque les membres d'équipage invités synchroniseront des modifications. Aucun contenu n'est transmis en clair.", + "push_enable": "M'avertir en cas de changement au sein de l'équipe", + "push_active": "Les notifications push sont activées sur cet appareil.", + "push_unsupported": "Les notifications push ne sont pas prises en charge par ce navigateur.", + "push_denied_hint": "Les notifications sont désactivées. Activez-les dans les paramètres de votre navigateur ou de votre appareil.", + "push_ios_install_hint": "Sur le iPhone/iPad : ajoutez l'application à l'écran d'accueil (iOS 16.4 et versions ultérieures) pour recevoir des notifications push.", + "push_error": "Les notifications push n'ont pas pu être activées.", + "sections": { + "account": "Compte et paramètres", + "fleet": "Flotte et équipage", + "security": "Sécurité et appareil", + "stats": "Statistiques", + "danger": "Zone dangereuse" + } + }, + "vessel_pool": { + "title": "flotte de navires", + "section_title": "Tes vaisseaux", + "subtitle": "Gère ici tous les navires pour tes journaux de bord. Pour chaque journal de bord, sélectionne le navire actif dans cette liste.", + "loading": "Chargement de la flotte en cours…", + "add_vessel": "Ajouter un navire", + "edit_vessel": "Modifier le navire", + "no_vessels": "Il n'y a pas encore de navires dans le pool.", + "delete_confirm": "Voulez-vous vraiment retirer ce navire de la flotte ?", + "max_vessels": "Le nombre maximal de 20 navires dans la flotte a été atteint." + }, + "logbook_vessel": { + "title": "Navire concerné par ce journal de bord", + "subtitle": "Sélectionne le bateau pour ce journal de bord. Les jours de voyage utilisent les données de navigation et de ravitaillement du bateau sélectionné.", + "active_vessel": "Navire concerné par ce journal de bord", + "no_vessels_in_pool": "Aucun navire dans la flotte – veuillez d'abord en créer un dans votre profil utilisateur.", + "no_vessel": "Aucun navire sélectionné", + "unnamed": "Sans titre", + "save": "Enregistrer le navire", + "saved": "Navire enregistré dans le journal de bord.", + "selection_only_hint": "Tu vois le bateau choisi par le propriétaire (journal de bord partagé).", + "manage_in_profile": "Gérer les navires dans le profil utilisateur" + }, + "person_pool": { + "title": "Équipage habituel et skipper", + "subtitle": "Crée ici ton vivier de personnel – skippers et équipage pour tous les carnets de bord. C'est dans ce vivier que tu sélectionneras l'équipage actif pour chaque carnet de bord et chaque jour de voyage.", + "loading": "Chargement de la liste des personnes…", + "skippers_section": "Skipper attitré", + "crew_section": "équipe de base", + "add_skipper": "Ajouter un skipper", + "add_crew": "Ajouter un membre de l'équipe", + "edit_skipper": "Modifier le skipper", + "no_skippers": "Il n'y a pas encore de skipper dans la liste.", + "no_crew": "Il n'y a encore aucun membre d'équipage dans la liste.", + "delete_confirm": "Voulez-vous vraiment supprimer cette personne de la liste ?" + }, + "logbook_crew": { + "title": "Équipage de ce journal de bord", + "subtitle": "Choisis le skipper et l'équipage pour ce journal de bord. Les nouveaux jours de voyage reprendront automatiquement cette sélection.", + "loading": "Chargement de l'équipage en cours…", + "active_skipper": "Skipper pour ce journal de bord", + "active_crew": "Équipage de ce journal de bord", + "no_skippers_in_pool": "Il n'y a pas de skipper dans la liste – veuillez d'abord le créer dans le profil utilisateur.", + "no_crew_in_pool": "Aucun équipage dans la liste – veuillez d'abord le créer dans le profil utilisateur.", + "no_skipper": "Aucun skipper n'a été choisi", + "unnamed": "Sans titre", + "save": "Enregistrer l'équipe", + "saved": "Équipage enregistré dans le journal de bord.", + "selection_only_hint": "Tu peux voir l'équipage désigné par le propriétaire (journal de bord partagé)." + }, + "entry_crew": { + "title": "L'équipe pour cette journée de voyage", + "subtitle": "Peut différer du format standard du journal de bord. Les jours de voyage suivants reprennent les données de la veille.", + "day_skipper": "Skipper ce jour-là", + "day_crew": "L'équipe ce jour-là", + "no_skipper": "Aucun skipper n'a été choisi", + "no_crew": "Aucun équipage sélectionné" + }, + "crew": { + "title": "Profils des skippers et des équipiers", + "skipper_section": "Profil du skipper", + "skipper_read_only_hint": "Seul le propriétaire du journal de bord peut modifier le profil du skipper.", + "crew_section": "Liste de l'équipe", + "add_crew": "Ajouter un membre de l'équipe", + "edit_crew": "Modifier les informations d'un membre de l'équipe", + "no_crew": "Aucun membre d'équipage n'a encore été ajouté.", + "max_crew": "Le nombre maximal de 12 membres d'équipage dans le pool a été atteint.", + "name": "Nom", + "address": "Adresse", + "birthdate": "Anniversaire", + "phone": "Numéro de téléphone", + "nationality": "Nationalité", + "passport": "Numéro de passeport / de carte d'identité", + "bloodtype": "groupe sanguin", + "allergies": "Allergies", + "diseases": "Antécédents médicaux / Maladies", + "save": "Enregistrer les données du skipper", + "save_member": "Enregistrer le membre", + "saved": "Le profil du skipper a été enregistré avec succès !", + "loading": "Chargement des fichiers de l'équipage...", + "delete_confirm": "Es-tu sûr de vouloir supprimer ce membre de l'équipe ?" + }, + "deviation": { + "title": "Tableau des déviations (Compass Deviation)", + "subtitle": "Indique la déclinaison magnétique (déc.) pour les caps (MgK) de 000° à 360°, par incréments de 10°.", + "heading": "MgK", + "deviation": "distraction", + "save": "Enregistrer la grille d'étalonnage", + "saving": "En cours d'enregistrement...", + "saved": "La grille d'étalonnage a été enregistrée avec succès !", + "loading": "Chargement du tableau d'étalonnage..." + }, + "settings": { + "title": "Paramètres du journal de bord", + "subtitle": "Partage, sauvegarde et collaboration pour ce journal de bord.", + "select_logbook_hint": "Sélectionne un journal de bord pour modifier ses paramètres.", + "no_key": "Aucune clé API OpenWeatherMap n'est disponible. Enregistre ta propre clé dans ton profil utilisateur ou contacte l'administrateur.", + "weather_success": "Les données météorologiques ont été récupérées avec succès !", + "weather_error": "Échec de la récupération des données météorologiques. Vérifie la clé API et la connexion.", + "weather_unauthorized": "Échec de la récupération des données météorologiques. La clé API n'est pas valide ou n'est pas autorisée.", + "weather_not_found": "Échec de la récupération des données météorologiques. La localité ou les coordonnées indiquées n'ont pas été trouvées.", + "weather_bad_request": "Échec de la récupération des données météorologiques. Aucun lieu ni aucune position GPS n'ont été indiqués.", + "weather_date_mismatch": "Les données météorologiques ne peuvent être consultées que pour la journée d'aujourd'hui ({{today}}). Cette entrée du journal de bord est datée du {{date}}.", + "gps_error": "Veuillez indiquer un lieu ou déterminer les coordonnées GPS.", + "share_title": "Partager le journal de bord (en lecture seule)", + "share_desc": "Coche cette case pour créer un lien public en lecture seule. Toute personne disposant de ce lien pourra consulter tes voyages, tes profils de yacht et ton équipage. Les clés de chiffrement ne sont jamais transmises au serveur (elles restent dans la partie hachée de l'URL).", + "share_privacy_warning": "Recommandation : partage ce lien uniquement en privé (par exemple par e-mail ou via une messagerie instantanée), et non sur les réseaux sociaux.", + "share_enable": "Activer le lien public", + "share_copied": "Lien copié !", + "share_copy_btn": "Copier le lien", + "link_qr_hint": "Code QR à scanner avec un smartphone", + "link_qr_alt": "Code QR pour le lien", + "danger_zone_title": "Zone dangereuse", + "danger_zone_desc": "La suppression de ton compte entraînera la suppression définitive de tous tes Passkey, journaux de bord, données de vaisseau, profils d'équipage, entrées de voyage et clés E2E. Cette action est irréversible.", + "delete_account_btn": "Supprimer définitivement le compte", + "delete_account_confirm_title": "Supprimer le compte ?", + "delete_account_confirm_desc": "Es-tu absolument certain de vouloir supprimer définitivement ton compte ainsi que tous les journaux de bord associés et les données cryptées E2E ?", + "delete_account_confirm_yes": "Oui, supprimer le compte et toutes les données", + "delete_account_confirm_no": "Annuler", + "delete_account_failed": "Impossible de supprimer le compte. Veuillez réessayer.", + "delete_backup_hint": "Conseil : avant de les supprimer, effectue des sauvegardes de tes journaux (.daagbok) dans les paramètres de chaque journal.", + "deleting_account": "Le compte est en cours de suppression…", + "invite_push_prompt_title": "Activer les notifications push ?", + "invite_push_prompt_message": "Dès que les membres d'équipage invités synchronisent leurs modifications, tu peux être informé par notification push. Aucun contenu du journal de bord n'est envoyé en clair.", + "invite_push_prompt_ios_message": "Dès que les membres de l'équipe synchronisent des modifications, tu peux recevoir une notification push. Sur le iPhone/iPad : ajoute l'application à l'écran d'accueil (iOS 16.4+), puis active les notifications push dans ton profil utilisateur.", + "invite_push_prompt_enable": "Activer maintenant", + "invite_push_prompt_later": "Plus tard", + "invite_push_prompt_success": "Les notifications push sont activées sur cet appareil.", + "backup_title": "Sauvegarde et restauration", + "backup_desc": "Sauvegarde complète et cryptée de ce journal de bord (entrées, photos, notes vocales, traces GPS, équipage, navire). Protégée par un mot de passe de sauvegarde — pour une restauration sur ce compte ou sur un nouveau compte.", + "backup_export_title": "Effectuer une sauvegarde", + "backup_export_desc": "Télécharge toutes les données locales sous la forme d'un fichier .daagbok compressé. Conservez le fichier et la phrase de passe séparément et en lieu sûr.", + "backup_restore_title": "Restaurer une sauvegarde", + "backup_restore_desc": "Restaure une sauvegarde dans ton compte actuel, même après la création d'un nouveau compte.", + "backup_passphrase": "Phrase secrète de sauvegarde", + "backup_passphrase_placeholder": "Au moins 8 caractères", + "backup_passphrase_confirm": "Confirmer la phrase secrète", + "backup_passphrase_short": "La phrase de passe de sauvegarde doit comporter au moins 8 caractères.", + "backup_passphrase_mismatch": "Les phrases de passe ne correspondent pas.", + "backup_wrong_passphrase": "Mot de passe incorrect ou sauvegarde endommagée.", + "backup_export_btn": "Télécharger la sauvegarde", + "backup_exporting": "Sauvegarde en cours…", + "backup_export_success": "Sauvegarde effectuée ({{count}} jours de voyage).", + "backup_file_label": "Fichier de sauvegarde (.daagbok)", + "backup_export_progress": "Compresser les fichiers {{current}} / {{total}}…", + "backup_invalid_archive": "Ce fichier n'est pas une archive de sauvegarde valide.", + "backup_version_unsupported": "Ancien format de sauvegarde (v1). Veuillez utiliser une sauvegarde .daagbok récente.", + "backup_import_size_confirm": "Cette sauvegarde pèse environ {{size}}. La restauration sur l'appareil peut prendre plus de temps et occuper beaucoup d'espace de stockage. Continuer ?", + "backup_stat_voice": "{{count}} Notes vocales", + "backup_stat_size": "Non compressé : environ {{size}}", + "backup_preview_btn": "Vérifier le contenu", + "backup_previewing": "Vérifie…", + "backup_restore_btn": "Restaurer", + "backup_restoring": "En cours de restauration…", + "backup_restore_success": "Le journal de bord « {{title}} » a été restauré.", + "backup_restore_cancelled": "Restauration interrompue.", + "backup_invalid_json": "Ce fichier n'est pas un fichier JSON valide.", + "backup_invalid_format": "Format de sauvegarde inconnu ou obsolète.", + "backup_not_owner": "Seul le propriétaire du journal de bord peut créer des sauvegardes.", + "backup_not_authenticated": "Veuillez vous connecter pour restaurer une sauvegarde.", + "backup_id_conflict": "Un journal de bord portant cet identifiant existe déjà.", + "backup_overwrite_confirm": "Le journal existant portant le même identifiant sera remplacé. Voulez-vous continuer ?", + "backup_new_id_confirm": "Importer la sauvegarde en tant que nouveau journal avec un nouvel identifiant ?", + "backup_stat_entries": "{{count}} Jours de voyage", + "backup_stat_photos": "{{count}} Photos", + "backup_stat_crew": "{{count}} Entrées de l'équipe", + "backup_stat_tracks": "{{count}} Traces GPS", + "backup_exported_at": "Exporté : {{date}}" + }, + "disclaimer": { + "title": "Remarques importantes", + "intro": "Veuillez lire les remarques suivantes avant d'utiliser Kapteins Daagbok.", + "e2e_title": "Chiffrement de bout en bout", + "e2e_body": "Les données de ton journal de bord sont chiffrées de bout en bout. Seul toi – ou les personnes disposant de ta clé – pouvez en lire le contenu. Seules des données chiffrées sont stockées sur le serveur.", + "pwa_title": "Application web progressive (PWA)", + "pwa_body": "Kapteins Daagbok fonctionne comme une application web progressive dans ton navigateur et peut être installée sur ton appareil, un peu comme une application native, mais sans passer par l'App Store.", + "storage_title": "Stockage local et synchronisation", + "storage_body": "Tes données sont temporairement enregistrées localement sur ton appareil (IndexedDB). Lorsque tu es connecté à Internet, les modifications sont synchronisées avec le serveur. Tu peux continuer à travailler même sans connexion ; la synchronisation s'effectuera plus tard.", + "free_title": "Gratuit et sans publicité", + "free_body": "Kapteins Daagbok est gratuit et ne contient aucune publicité.", + "liability_title": "Clause de non-responsabilité", + "liability_body": "L'utilisation se fait sous votre propre responsabilité. Nous déclinons toute responsabilité pour les dommages résultant de l'utilisation de l'application, y compris les entrées de journal de bord erronées ou incomplètes, la perte de données ou les dysfonctionnements techniques.", + "warranty_title": "Aucune garantie", + "warranty_body": "Nous ne garantissons ni le bon fonctionnement, ni l'exactitude, ni la disponibilité du service. Son fonctionnement peut être interrompu, limité ou suspendu à tout moment.", + "copyright": "© 2026 KnorrLabs, Markus F.J. Busche", + "accept": "Accepter et continuer", + "close": "Fermer", + "button_title": "Remarques et clause de non-responsabilité" + }, + "feedback": { + "button_title": "Envoyer un commentaire", + "title": "Commentaires", + "intro": "Signale-nous des bugs, des idées ou donne-nous ton avis. Ton message sera transmis à l'équipe du projet via un canal de communication sécurisé.", + "category_label": "Catégorie", + "category_general": "Généralités", + "category_bug": "Signaler une erreur", + "category_feature": "Demande de fonctionnalité", + "category_translation": "erreur de traduction", + "contact_label": "E-mail (facultatif)", + "contact_placeholder": "deine@email.beispiel", + "message_label": "Message", + "message_placeholder": "Décris ton avis…", + "send": "Envoyer", + "sending": "Envoi en cours…", + "cancel": "Annuler", + "success": "Merci beaucoup ! Ton avis a été envoyé.", + "error_send": "Impossible d'envoyer vos commentaires. Veuillez réessayer plus tard.", + "error_invalid_email": "Veuillez saisir une adresse e-mail valide.", + "error_not_configured": "La fonctionnalité de commentaires n'est pas disponible sur ce serveur.", + "error_rate_limited": "Il y a trop de messages de commentaires en peu de temps. Veuillez patienter quelques minutes.", + "error_spam": "Ce message n'a pas pu être envoyé. Veuillez le reformuler." + }, + "demo": { + "logbook_title": "Journal de bord de la manifestation en mer Baltique", + "badge": "Démonstration", + "public_banner": "Mode démo en lecture seule", + "cta_register": "Créer un compte", + "back_to_login": "Pour s'inscrire" + }, + "invitation": { + "error_invalid_key": "Le lien d'invitation n'est pas valide d'un point de vue cryptographique (clé incorrecte).", + "error_missing_key": "Le lien d'invitation ne contient pas de clé de déchiffrement (#key=...). Veuillez utiliser le lien complet fourni par le propriétaire.", + "error_expired": "Cette invitation a expiré (valable 48 heures).", + "error_invalid_token": "Jeton d'invitation non valide.", + "error_load_failed": "Les détails de l'invitation n'ont pas pu être chargés.", + "error_incomplete_session": "Session incomplète — veuillez vous reconnecter (identifiant utilisateur manquant).", + "error_accept_failed": "Échec de l'inscription.", + "error_login_failed": "Échec de la connexion à Passkey.", + "error_username_missing": "Impossible de retrouver votre nom d'utilisateur — veuillez vous reconnecter.", + "error_register_failed": "Échec de l'enregistrement.", + "loading_joining": "Adhésion...", + "loading_checking": "L'invitation est en cours de vérification...", + "loading_unlocking": "Le journal de bord est en cours d'activation et de synchronisation...", + "loading_retrieving_key": "Chargement de la clé de chiffrement...", + "error_title": "Erreur d'invitation", + "back_to_start": "Retour à la page d'accueil", + "title": "Invitation au journal de bord", + "invited_by": "Invitation de", + "vessel_logbook": "Navire / Journal de bord", + "signed_in_preparing": "Connecté en tant que {{username}}. Connexion en cours...", + "join_again": "Se réinscrire", + "login_or_register_hint": "Connecte-toi ou crée un compte pour rejoindre le journal de bord.", + "or_sign_up": "OU S'INSCRIRE", + "register_crew_account": "Créer un nouveau compte d'équipe", + "username_label": "Nom d'utilisateur", + "create_passkey": "Créer Passkey", + "switch_language_en": "Anglais", + "switch_language_de": "Allemand" + }, + "stats": { + "title": "Statistiques", + "subtitle": "Autonomie, consommation et type de motorisation en un coup d'œil", + "scope_label": "Domaine d'analyse", + "scope_logbook": "Ce journal de bord", + "scope_account": "Tous les journaux de bord", + "loading": "Les statistiques sont en cours de calcul…", + "no_data": "Il n'y a pas encore de jours de voyage.", + "total_distance": "Distance totale", + "travel_days": "Jours de voyage", + "sail_distance": "À la voile", + "motor_distance": "déplacement de la machine", + "motor_hours_total": "Nombre total d'heures de fonctionnement", + "daily_motor_hours": "Heures-machine par jour de déplacement", + "avg_motor_hours": "Ø Heures-machine par jour de déplacement", + "unknown_propulsion": "Inconnu", + "fuel_total": "Consommation totale", + "water_total": "Eau (total)", + "daily_etmal": "Données journalières", + "daily_consumption": "consommation quotidienne", + "route_overview": "Itinéraire", + "route_map_title": "Aperçu des itinéraires", + "propulsion_title": "Voile ou moteur", + "propulsion_hint": "La répartition est basée sur les événements du journal de bord pour chaque jour de voyage, et non sur les segments GPS.", + "avg_distance": "Ø par jour de voyage", + "avg_fuel": "Ø Carburant", + "avg_water": "Ø Eau", + "fuel_per_nm": "Consommation de carburant par km", + "fuel_per_motor_hour": "Consommation de carburant par heure de fonctionnement", + "daily_fuel_per_motor_hour": "Consommation de carburant par heure de fonctionnement et par jour de voyage", + "fuel_legend": "carburant", + "water_legend": "Eau", + "unit_nm": "sm", + "unit_h": "h", + "unit_l": "L", + "day_label": "Jour {{day}}", + "account_logbooks": "Aperçu des journaux de bord", + "col_logbook": "Journal de bord", + "event_series_title": "Historique des événements", + "event_series_hint": "Valeurs chronologiques issues du journal des événements.", + "event_series_pressure": "pression atmosphérique", + "event_series_wind": "Vent", + "event_series_motor": "Moteur", + "event_series_empty": "Aucune entrée disponible." + }, + "tour": { + "skip": "Passer la visite", + "back": "Retour", + "next": "Continuer", + "finish": "C'est prêt", + "progress": "Étape {{current}} sur {{total}}", + "steps": { + "welcome": { + "title": "Bienvenue à bord !", + "body": "Nous avons créé pour toi un journal de bord de démonstration comprenant trois jours de voyage dans la baie de Kiel. Tu peux supprimer les entrées d'exemple à tout moment si tu souhaites commencer à utiliser ton propre journal de bord. Ce petit parcours te présente les principales fonctionnalités." + }, + "welcome_public": { + "title": "Bienvenue à bord !", + "body": "Découvrez notre journal de bord de démonstration, qui retrace trois jours de voyage dans la baie de Kiel, sans avoir besoin de créer de compte. Ce parcours vous présente les entrées du journal de bord ainsi que le choix du bateau et de l'équipage pour ce journal. Vous pourrez gérer votre flotte et votre équipage habituel ultérieurement dans votre profil utilisateur." + }, + "nav_logs": { + "title": "Entrées du journal de bord", + "body": "C'est ici que tu gères tes journées de voyage : départ, destination, météo, niveaux de carburant et traces GPS." + }, + "entry_list": { + "title": "Tes jours de voyage", + "body": "Chaque carte correspond à une journée de voyage. Appuie sur une entrée pour afficher ou modifier les détails." + }, + "entry_open": { + "title": "Afficher le jour du voyage", + "body": "Voici à quoi ressemble une entrée de journal de bord dûment remplie – avec les événements, les niveaux de carburant et bien plus encore." + }, + "entry_track": { + "title": "Tracé GPS", + "body": "Télécharge des fichiers GPX ou consulte les itinéraires déjà enregistrés sur la carte, avec la distance et la vitesse." + }, + "nav_vessel": { + "title": "Navire à inscrire dans le journal de bord", + "body": "Choisis dans ta flotte le vaisseau pour ce journal de bord. Tu peux gérer tes vaisseaux dans ton profil utilisateur, sous « Flotte et équipage »." + }, + "profile_vessel_pool": { + "title": "flotte de navires", + "body": "Dans ton profil utilisateur, tu enregistres tous tes bateaux : yachts de location, bateau personnel, etc. Pour chaque journal de bord, tu sélectionnes ensuite le bateau correspondant." + }, + "profile_crew_pool": { + "title": "Équipage habituel et skipper", + "body": "Dans ton profil utilisateur, tu gères ton vivier de personnes : plusieurs skippers (par exemple pour la location de bateaux) et membres d'équipage pour tous les journaux de bord." + }, + "nav_logbook_crew": { + "title": "Équipage par journal de bord", + "body": "Choisis parmi les membres de l'équipage ceux qui figureront dans ce journal de bord en tant que skipper et équipage. Les jours de voyage reprennent cette sélection par défaut." + }, + "nav_stats": { + "title": "Tableau de bord statistique", + "body": "Tu trouveras ici les distances parcourues, la consommation, les cartes d'itinéraire et la répartition des modes de propulsion – calculés automatiquement à partir des données de ton journal de bord." + }, + "nav_feedback": { + "title": "Envoyer un commentaire", + "body": "Ce formulaire te permet d'envoyer directement des remarques, des suggestions ou des commentaires généraux à l'équipe du projet – même après la visite, à tout moment, en cliquant sur l'icône en haut à droite." + }, + "nav_profile": { + "title": "Ton profil utilisateur", + "body": "En cliquant sur le bouton « Skipper » en haut de la page, tu accèdes à ton profil personnel, quel que soit le journal de bord en cours." + }, + "profile_preferences": { + "title": "Compte et présentation", + "body": "C'est ici que tu peux gérer ton identifiant de compte, ton thème et le mode clair/foncé. Tu peux relancer la visite guidée de l'application à tout moment. Tu trouveras les paramètres de confidentialité et de sécurité plus bas dans ton profil." + }, + "finish": { + "title": "D'accord !", + "body": "Tu vas être redirigé vers le tableau de bord des statistiques. Tu peux relancer la visite à tout moment depuis ton profil utilisateur. Bonne visite !" + } + } + }, + "seo": { + "title": "Kapteins Daagbok – Journal de bord numérique gratuit pour yacht (sans publicité)", + "description": "Journal de bord numérique gratuit et sans publicité pour les yachts, avec cryptage de bout en bout et connexion via Passkey. Consignez en toute sécurité vos dates de voyage, vos tracés GPS, les informations sur l'équipage et le navire – même hors ligne en tant que PWA.", + "keywords": "Journal de bord de yacht, journal de bord de navire, journal de bord, voile, Passkey, cryptage E2E, trace GPS, journal de bord maritime, gratuit, sans publicité, sans frais, sans pub", + "ogImageAlt": "Logo Kapteins Daagbok" + } + } +} diff --git a/client/src/i18n/locales/nb.json b/client/src/i18n/locales/nb.json index d8c8e33..e774b1b 100644 --- a/client/src/i18n/locales/nb.json +++ b/client/src/i18n/locales/nb.json @@ -2,20 +2,22 @@ "translation": { "app": { "name": "Kapteins Daagbok", - "tagline": "Loggbok for private båter", + "tagline": "Privat yachtloggbok", "beta": "Beta", - "beta_hint": "Betaversjon - funksjoner kan fortsatt endres" + "beta_hint": "Betaversjon — Funksjonene kan fortsatt endres" }, "footer": { "kofi_label": "Ko-fi", - "kofi_title": "Støtt prosjektet, videreutvikling og driftskostnader på Ko-fi" + "kofi_title": "Støtt prosjektet, videreutviklingen og driftskostnadene på Ko-fi" }, "languages": { "de": "Deutsch", "en": "English", "da": "Dansk", "sv": "Svenska", - "nb": "Norsk" + "nb": "Norsk", + "fr": "Français", + "es": "Español" }, "dialog": { "ok": "OK", @@ -23,24 +25,24 @@ "no": "Nei" }, "errors": { - "load_failed": "Data kunne ikke lastes.", - "save_failed": "Endringer kunne ikke lagres.", - "delete_failed": "Sletting mislyktes.", - "export_failed": "Eksport mislyktes." + "load_failed": "Dataene kunne ikke lastes inn.", + "save_failed": "Endringene kunne ikke lagres.", + "delete_failed": "Slettingen mislyktes.", + "export_failed": "Eksporten mislyktes." }, "common": { - "unsaved_changes_title": "Ikke-lagrede endringer", + "unsaved_changes_title": "Ulagrede endringer", "unsaved_changes_message": "Du har endringer som ikke er lagret. Vil du virkelig forlate siden? Endringene dine vil gå tapt.", "unsaved_changes_stay": "Bli", - "unsaved_changes_save_leave": "Lagre og forlat", - "unsaved_changes_discard": "Forkast", - "unsaved_changes_leave": "Oppgivelse" + "unsaved_changes_save_leave": "Lagre og avslutt", + "unsaved_changes_discard": "Avvis", + "unsaved_changes_leave": "Forlatt" }, "nav": { "dashboard": "Dashbord", "vessel": "Skipsdata", - "crew": "Crew", - "deviation": "Tabell over distraksjoner", + "crew": "Mannskap", + "deviation": "Avledningstabell", "logs": "Loggbokoppføringer", "stats": "Statistikk", "settings": "Innstillinger", @@ -52,269 +54,269 @@ "register": "Registrer deg med Passkey", "login": "Logg inn med Passkey", "login_as": "Logg inn som {{name}}", - "quick_login": "Rask innlogging", - "forget_account": "Glemt konto på denne enheten", + "quick_login": "Hurtiginnlogging", + "forget_account": "Glemt kontoen på denne enheten", "not_user": "Ikke {{name}}?", "recovery_title": "Gjenopprettingsnøkkelen din", - "recovery_warning": "VIKTIG: Skriv ned disse 12 ordene. Hvis du mister Passkey og disse ordene, kan du ikke gjenopprette dataene dine.", + "recovery_warning": "VIKTIG: Skriv ned disse 12 ordene. Hvis du mister din Passkey og disse ordene, kan ikke dataene dine gjenopprettes.", "confirm_recovery": "Jeg har skrevet ned ordene", - "status_logged_in": "Innlogget", - "status_logged_out": "Avlyst", - "copied": "Oppfattet!", - "copy_phrase": "Kopieringstast", - "enter_recovery": "Skriv inn gjenopprettingsnøkkel", - "recovery_fallback_warning": "Din Passkey har blitt autentisert, men enheten din støtter ikke maskinvarebasert nøkkelderivering. Skriv inn gjenopprettingsnøkkelen på 12 ord for å dekryptere loggboken.", - "recovery_placeholder": "Skriv inn gjenopprettingsnøkkelen din, som består av 12 ord atskilt med mellomrom...", + "status_logged_in": "Logg inn", + "status_logged_out": "Logg av", + "copied": "Kopiert!", + "copy_phrase": "Kopiere nøkkel", + "enter_recovery": "Skriv inn gjenopprettingsnøkkelen", + "recovery_fallback_warning": "Din Passkey er godkjent, men enheten din støtter ikke maskinvarebasert nøkkelgenerering. Skriv inn gjenopprettingsnøkkelen på 12 ord for å dekryptere loggboken din.", + "recovery_placeholder": "Skriv inn gjenopprettingsnøkkelen din, som består av 12 ord, atskilt med mellomrom...", "back": "Tilbake", "decrypting": "Dekryptering...", - "decrypt_logbook": "Dekryptere loggbok", + "decrypt_logbook": "Dechiffrere loggboken", "error_incorrect_recovery": "Feil gjenopprettingsnøkkel. Dekryptering mislyktes.", "error_decryption_failed": "Dekryptering mislyktes. Vennligst sjekk gjenopprettingsnøkkelen din.", - "or_register": "eller registrer deg", - "explore_demo": "Utforsk demoen uten konto", + "or_register": "eller Registrer deg", + "explore_demo": "Utforsk demoen uten å opprette konto", "username_placeholder": "Brukernavn / Skippernavn", - "processing": "Behandling...", + "processing": "Behandler...", "help": "Hjelp", - "setup_pin_title": "Konfigurer lokal PIN-kode (valgfritt)", - "setup_pin_warning": "Siden enheten din ikke støtter direkte Passkey-nøkkelavledning, må du ellers skrive inn 12-ordsnøkkelen hver gang du logger deg på denne enheten. Konfigurer en lokal PIN-kode for å unngå dette.", - "pin_placeholder": "E.G. 123456", - "pin_label": "Lokal PIN-kode (4-8 sifre)", + "setup_pin_title": "Konfigurere lokal PIN-kode (valgfritt)", + "setup_pin_warning": "Siden enheten din ikke støtter direkte Passkey-nøkkelgenerering, må du ellers oppgi din 12-ords nøkkel hver gang du logger inn på denne enheten. Opprett en lokal PIN-kode for å unngå dette.", + "pin_placeholder": "F.eks. 123456", + "pin_label": "Lokal PIN-kode (4–8 siffer)", "save_pin": "Lagre PIN-kode og fortsett", "skip_pin": "Hopp over og bruk gjenoppretting", "enter_pin_title": "Dekrypter med PIN-kode", - "enter_pin_warning": "Skriv inn din lokale PIN-kode for å låse opp dekrypteringsnøkkelen på denne enheten.", - "enter_pin_placeholder": "Tast inn PIN-koden din...", + "enter_pin_warning": "Skriv inn din lokale PIN-kode for å aktivere dekrypteringsnøkkelen på denne enheten.", + "enter_pin_placeholder": "Skriv inn PIN-koden din...", "decrypt_with_pin": "Dekryptere", - "use_recovery_instead": "Bruk gjenopprettingsnøkler i stedet", + "use_recovery_instead": "Bruk gjenopprettingsnøkkelen i stedet", "error_incorrect_pin": "Feil PIN-kode. Dekryptering mislyktes.", - "error_invalid_host": "Passkeys fungerer ikke via 127.0.0.1. Åpne appen via localhost.", + "error_invalid_host": "Passkey fungerer ikke via 127.0.0.1. Vennligst åpne appen via localhost.", "use_localhost_link": "Bytt til localhost", - "error_passkey_cancelled": "Passkey-innlogging ble avbrutt eller utløp. Prøv igjen.", - "error_invalid_rp_id": "Passkey-domene stemmer ikke (RP ID). Bruk http://localhost:5173 med RP_ID=localhost i .env for lokal utvikling.", - "error_session_incomplete": "Innlogging ufullstendig. Logg inn med passkey igjen.", - "restore_checking": "Sjekker økt…", + "error_passkey_cancelled": "Passkey-påloggingen ble avbrutt eller har utløpt. Prøv på nytt.", + "error_invalid_rp_id": "Passkey-domenet stemmer ikke (RP-ID). Bruk kun http://localhost:5173 lokalt med RP_ID=localhost i .env.", + "error_session_incomplete": "Påloggingen er ufullstendig. Vennligst logg inn på nytt med Passkey.", + "restore_checking": "Økten blir sjekket…", "restore_title": "Gjenopprett økt", - "restore_subtitle": "Du er fortsatt innlogget. Lås opp loggboken med passkey eller PIN.", - "restore_unlocking": "Låser opp…", - "restore_with_passkey": "Lås opp med passkey ({{name}})", - "restore_with_pin": "Lås opp med PIN", - "restore_pin_warning": "Skriv inn din lokale PIN for å låse opp loggboken etter omlasting.", + "restore_subtitle": "Påloggingen din er fortsatt aktiv. Lås opp loggboken din med Passkey eller PIN-koden.", + "restore_unlocking": "Låses opp…", + "restore_with_passkey": "Lås opp med Passkey ({{name}})", + "restore_with_pin": "Lås opp med PIN-kode", + "restore_pin_warning": "Skriv inn din lokale PIN-kode for å låse opp loggboken etter at den er lastet inn på nytt.", "restore_other_account": "Logg inn med en annen konto" }, "pwa": { - "title": "Installer app", - "generic_benefit": "Installer Kapteins Daagbok på enheten din for raskere tilgang, frakoblet bruk og permanent lagring av data.", - "ios_instructions": "På iPad/iPhone: Legg til appen på startskjermen, slik at loggbokdataene dine forblir beskyttet og appen starter som en vanlig app.", - "ios_step_share": "Trykk på aksjesymbolet i Safari-linjen", - "ios_step_add": "Velg \"Gå til startskjermen\"", + "title": "Installer appen", + "generic_benefit": "Installer Kapteins Daagbok på enheten din for raskere tilgang, bruk uten nettilgang og permanent datalagring.", + "ios_instructions": "På iPad/iPhone: Legg til appen på startskjermen, slik at loggdataene dine forblir beskyttet og appen starter som en innebygd app.", + "ios_step_share": "Trykk på del-ikonet i Safari-linjen", + "ios_step_add": "Velg «Til startskjermen»", "install_now": "Installer nå", - "installing": "Installasjon...", + "installing": "Installasjon…", "later": "Senere", "never": "Ikke vis mer", "platform_ios": "Installasjon via Safari", "platform_android": "Installasjon via nettleseren", - "platform_desktop": "Installasjon som en desktop-app", - "settings_section": "Installasjon av app", + "platform_desktop": "Installasjon som skrivebordsapp", + "settings_section": "App-installasjon", "update_title": "Oppdatering tilgjengelig", - "update_desc": "En ny versjon av Kapteins Daagbok er klar. Oppdater for å få med de siste endringene.", + "update_desc": "En ny versjon av Kapteins Daagbok er klar. Oppdater for å få de siste endringene.", "update_now": "Oppdater nå", "update_reloading": "Laster...", - "storage_persist_hint": "Nettleseren kan slette offlinedata. Tillat permanent lagring slik at loggboken din forblir beskyttet." + "storage_persist_hint": "Nettleseren kan slette data som er lagret offline. Tillat permanent lagring for å sikre at loggen din forblir beskyttet (i nettleserinnstillingene eller når du blir spurt neste gang)." }, "sync": { "status_synced": "Synkronisert", - "status_syncing": "Synkroniser...", - "status_offline": "Frakoblet hurtigbuffer", - "status_unsynced": "Usynkroniserte endringer", + "status_syncing": "Synkroniser…", + "status_offline": "Offline-buffer", + "status_unsynced": "Endringer som ikke er synkronisert", "conflict_title": "Synkroniseringskonflikt", - "conflict_message": "{{count}} endring(er) kunne ikke synkroniseres (post {{id}}…). Velg hvilken versjon som skal gjelde.", - "conflict_use_server": "Bruk serverversjon", + "conflict_message": "{{count}} Endringene kunne ikke synkroniseres (oppføring {{id}}…). Vennligst velg hvilken versjon som skal gjelde.", + "conflict_use_server": "Bruk serverversjonen", "conflict_keep_local": "Behold min versjon" }, "vessel": { - "title": "Stamdata for skip", - "name": "Båtens navn", + "title": "Skipsstamdata", + "name": "Yachtnavn", "type": "Båttype", - "type_unset": "- ikke spesifisert -", + "type_unset": "— ikke oppgitt —", "type_sailing": "Seilbåt", - "type_motor": "Motorbåt", + "type_motor": "Motoryacht", "length_m": "Lengde (m)", - "draft_m": "Trekkraft (m)", + "draft_m": "Dypgang (m)", "air_draft_m": "Høyde (m)", - "invalid_metric": "Ugyldig tallverdi - angi meter som desimaltall (f.eks. 12,5).", + "invalid_metric": "Ugyldig tallverdi — vennligst skriv inn måleenheten som et desimaltall (f.eks. 12,5).", "port": "Hjemmehavn", "owner": "Eier", - "charter": "Charterselskap", - "registration": "Nummerskilt/registreringsnummer", + "charter": "Charterfirma", + "registration": "Registreringsnummer", "callsign": "Radiokallesignal", - "atis": "ATIS nr.", - "mmsi": "MMSI-nr.", - "save": "Lagre skipsdata", - "saving": "...vil bli reddet...", - "saved": "Skipsdata vellykket lagret!", - "loading": "Skipsdata er lastet inn...", - "sails_list": "Seil (eksisterende seil)", - "sails_help": "Skriv inn seilene som er tilgjengelige på båten din her (f.eks. storseil, genua, fokk).", + "atis": "ATIS-nr.", + "mmsi": "MMSI-nummer", + "save": "Lagre skipets data", + "saving": "Lagrer...", + "saved": "Skipsdataene er lagret!", + "loading": "Skipsdata lastes inn...", + "sails_list": "Seilutrustning (eksisterende seil)", + "sails_help": "Fyll inn seilene som er tilgjengelige på båten din (f.eks. storseil, genua, fokk).", "add_sail": "Legg til seil", - "sail_name_placeholder": "z. f.eks. storseil", - "no_sails": "Ingen seil lagret.", + "sail_name_placeholder": "f.eks. storseil", + "no_sails": "Ingen seil er registrert.", "photo_add": "Legg til bilde", - "photo_change": "Endre bilde", + "photo_change": "Bytt bilde", "photo_delete": "Slett bilde", "tanks_section": "Tanker (kapasitet)", - "tanks_help": "Valgfritt i liter - muliggjør glidebryter i tidsskriftet for kjente tankstørrelser.", + "tanks_help": "Valgfritt i liter — muliggjør glidebryter i journalen ved kjente tankstørrelser.", "freshwater_capacity_l": "Drikkevann (liter)", "fuel_capacity_l": "Drivstoff (liter)", "greywater_capacity_l": "Gråvann (liter)", - "invalid_tank_liters": "Ugyldig tallverdi - skriv inn liter som et tall (f.eks. 200)." + "invalid_tank_liters": "Ugyldig tallverdi — vennligst skriv inn liter som et tall (f.eks. 200)." }, "logs": { - "title": "Loggbokdagbok", + "title": "Loggbok", "new_entry": "Ny reisedag", - "travel_details": "Detaljer om reisen", - "add_event": "Legg til ny loggbokoppføring", + "travel_details": "Reisedetaljer", + "add_event": "Legg til ny loggoppføring", "add_event_btn": "Legg til hendelse", "edit_event": "Rediger hendelse", "save_event_btn": "Lagre endring", "cancel_event_edit": "Avbryt", "delete_event": "Slett hendelse", - "sign_cleared_skipper_re_sign_title": "Skippers signatur fjernet", - "sign_cleared_skipper_re_sign": "Hendelsesloggen har blitt endret. Skipperens signatur er fjernet. Vennligst godkjenn på nytt.", - "date": "dato", + "sign_cleared_skipper_re_sign_title": "Skipperens signatur fjernet", + "sign_cleared_skipper_re_sign": "Hendelsesloggen er endret. Skipperens signatur er fjernet. Vennligst godkjenn på nytt.", + "date": "Dato", "day_of_travel": "Reisedag", "travel_day_number": "Reisedag {{number}}", - "departure": "Starthavn (reise fra)", - "destination": "Destinasjonsport (til)", + "departure": "Avreisehavn (reise fra)", + "destination": "Ankomsthavn (til)", "route": "Reise fra/til", "tanks": "Tanker", - "customize_columns": "Tilpass kolonner", - "column_selector_title": "Kolonner å vise", + "customize_columns": "Juster kolonner", + "column_selector_title": "Kolonner som skal vises", "freshwater": "Ferskvann (liter)", - "fuel": "Drivstoff / Drivstoff (liter)", + "fuel": "Drivstoff (liter)", "greywater": "Gråvann (liter)", "greywater_level": "Fyllingsnivå", "tank_slider_of_max": "{{current}} / {{max}} L", - "tank_capacity_tooltip": "Hvis tankkapasiteten (liter) er lagret i skipsdataene, kan du angi fyllingsnivåene her ved hjelp av glidebryteren.", - "morning": "Stå opp om morgenen", + "tank_capacity_tooltip": "Hvis tankkapasiteten (i liter) er angitt i skipets data, kan du legge inn fyllingsnivåene her ved hjelp av glidebryteren.", + "morning": "Situasjonen om morgenen", "refilled": "Påfyllt", - "evening": "Kveldsstand", - "consumption": "Daglig forbruk", - "signatures": "Underskrifter / frigivelse", - "sign_skipper": "Skippers signatur", - "sign_crew": "Crews signatur", - "sign_hint": "Signer med finger, penn eller mus", + "evening": "Situasjonen om kvelden", + "consumption": "Dagsforbruk", + "signatures": "Signaturer / Godkjenning", + "sign_skipper": "Skipperens underskrift", + "sign_crew": "Signatur fra mannskapet", + "sign_hint": "Skriv under med fingeren, en penn eller musen", "sign_clear": "Slett", "sign_export_image": "[Signatur]", - "sign_with_passkey": "Utgivelse med Passkey", - "sign_passkey_signing": "Passkey er forespurt...", - "sign_passkey_signed": "Utgitt av {{username}}", + "sign_with_passkey": "Del med Passkey", + "sign_passkey_signing": "Passkey blir hentet…", + "sign_passkey_signed": "Godkjent av {{username}}", "sign_passkey_export": "Passkey: {{username}} ({{date}})", "sign_attribution_export": "{{username}} ({{date}})", - "sign_passkey_clear": "Fjern Passkey utgivelse", + "sign_passkey_clear": "Fjern Passkey-godkjenning", "sign_mode_passkey": "Passkey", "sign_mode_classic": "Klassisk", - "sign_passkey_failed": "Passkey Utgivelsen mislyktes", - "sign_passkey_cancelled": "Passkey Utgivelse kansellert", - "sign_invalid": "Signaturen er ugyldig - innholdet har blitt endret", + "sign_passkey_failed": "Passkey-delingen mislyktes", + "sign_passkey_cancelled": "Passkey-godkjenning avbrutt", + "sign_invalid": "Signaturen er ugyldig — innholdet er endret", "sign_badge_skipper": "Skipper", "sign_badge_skipper_invalid": "Ugyldig", - "sign_badge_skipper_title_valid": "Skipper har gitt ut", - "sign_badge_skipper_title_invalid": "Skippersignaturen er ugyldig - innholdet har blitt endret", - "sign_classic_or_passkey": "Valgfritt: klassisk signatur eller Passkey utgivelse ovenfor", - "sign_crew_passkey_hint": "Crew-medlemmer med skrivetilgang kan frigjøre via Passkey.", - "sign_offline_hint": "Passkey-Godkjenning krever Internett - klassisk signatur mulig offline", - "sign_lock_notice": "Etter signering er det ikke mulig å gjøre endringer i loggbokoppføringen (unntatt bilder) uten at skipper og crew må signere på nytt.", - "sign_lock_active": "Denne oppføringen er signert. Endringer i loggboken (unntatt bilder) fjerner automatisk skipperens og crews signaturer.", - "sign_lock_warning_title": "Bekreft signatur", - "sign_lock_warning": "Etter signering er det ikke lenger mulig å gjøre endringer i loggbokoppføringen (unntatt bilder) uten at skipper og crew må signere på nytt.\n\nØnsker du å fortsette?", - "sign_proceed": "Skilt", + "sign_badge_skipper_title_valid": "Skipper har godkjent", + "sign_badge_skipper_title_invalid": "Skipper-signaturen er ugyldig — innholdet er endret", + "sign_classic_or_passkey": "Valgfritt: klassisk signatur eller Passkey-godkjenning øverst", + "sign_crew_passkey_hint": "Medarbeidere med skriveadgang kan dele via Passkey", + "sign_offline_hint": "Passkey-godkjenning krever internett — klassisk signatur er mulig uten nett", + "sign_lock_notice": "Etter at loggbokoppføringen er signert, kan den ikke endres (med unntak av bilder) uten at skipperen og mannskapet må signere på nytt.", + "sign_lock_active": "Denne oppføringen er signert. Endringer i loggboken (unntatt bilder) fjerner automatisk skipperens og mannskapets signaturer.", + "sign_lock_warning_title": "Bekreft signaturen", + "sign_lock_warning": "Etter at loggbokoppføringen er signert, kan den ikke lenger endres (med unntak av bilder) uten at skipperen og mannskapet må signere på nytt.\n\nVil du fortsette?", + "sign_proceed": "Skriv under", "sign_cancel": "Avbryt", "sign_cleared_re_sign_title": "Signaturer fjernet", - "sign_cleared_re_sign": "Loggbokoppføringen har blitt endret. Skipperens og crews signaturer er fjernet. Vennligst signer på nytt.", - "no_entries": "Ingen loggbokoppføringer funnet for denne båten. Lag din første seilasdag!", - "back_to_list": "Tilbake til tidsskriftlisten", - "save": "Lagre loggbokside", - "saving": "...vil bli reddet...", - "saved": "Loggboksiden er vellykket lagret!", - "loading": "Tidsskriftet lastes inn...", + "sign_cleared_re_sign": "Loggboksoppføringen er endret. Skipperens og mannskapets underskrifter er fjernet. Vennligst skriv under på nytt.", + "no_entries": "Det ble ikke funnet noen loggbokoppføringer for denne båten. Opprett din første reisedag!", + "back_to_list": "Tilbake til journaloversikten", + "save": "Lagre loggsiden", + "saving": "Lagrer...", + "saved": "Loggboksiden er lagret!", + "loading": "Loggboken lastes inn...", "view_mode_label": "Visning", "view_list": "Liste", - "live_mode": "Live", - "live_title": "Live-journal", - "live_loading": "Live-journal lastes inn...", - "live_retry": "Prøv igjen", - "live_load_error": "Live-journal kunne ikke lastes inn.", + "live_mode": "Direkte", + "live_title": "Live-Journal", + "live_loading": "Live-Journal lastes inn...", + "live_retry": "Prøv på nytt", + "live_load_error": "Live-Journal kunne ikke lastes inn.", "live_action_error": "Oppføringen kunne ikke lagres.", - "live_open_editor": "Full editor", - "live_actions_label": "Hurtighandlinger", + "live_open_editor": "Fullverdig redigeringsprogram", + "live_actions_label": "Hurtigkampanjer", "live_stream_label": "Hendelseslogg", - "live_stream_title": "Journal", - "live_no_events": "Ingen oppføringer ennå — trykk på en handling.", - "live_motor_start": "Motor Start", - "live_motor_stop": "Motor Stopp", - "live_cast_off": "Avreise", - "live_moor": "Anløp", + "live_stream_title": "Tidsskrift", + "live_no_events": "Ingen oppføringer ennå — trykk på en aktivitet.", + "live_motor_start": "Motorstart", + "live_motor_stop": "Motorstopp", + "live_cast_off": "Legge fra land", + "live_moor": "Opprett", "live_sails_btn": "Seil", "live_sails_pick": "Velg seil", - "live_sails_pick_hint": "Trykk flere seil (trykk igjen for å fjerne), deretter loggfør.", - "live_sails_selected": "Valgt: {{sails}}", - "live_sails_confirm": "Loggfør", - "live_sails_confirm_count": "Loggfør ({{count}})", + "live_sails_pick_hint": "Trykk på flere seil (trykk på nytt for å fjerne markeringen), og skriv deretter inn.", + "live_sails_selected": "Valg: {{sails}}", + "live_sails_confirm": "Registrer deg", + "live_sails_confirm_count": "Registrer ({{count}})", "live_sails": "Seil: {{sails}}", - "live_position": "Posisjon", + "live_position": "Stillingen", "live_position_coords": "Posisjon {{lat}}, {{lng}}", - "live_position_manual_hint": "GPS ikke tilgjengelig. Skriv inn bredde- og lengdegrad manuelt, eller prøv igjen med GPS-knappen.", - "live_position_gps_loading": "Henter GPS-posisjon…", - "live_position_invalid": "Skriv inn gyldige koordinater (bredde −90…90, lengde −180…180).", + "live_position_manual_hint": "GPS er ikke tilgjengelig. Angi breddegrad og lengdegrad manuelt, eller prøv på nytt ved å trykke på GPS-knappen.", + "live_position_gps_loading": "GPS-posisjonen blir beregnet…", + "live_position_invalid": "Vennligst oppgi gyldige koordinater (breddegrad −90…90, lengdegrad −180…180).", "live_position_lat_placeholder": "Bredde (Lat)", "live_position_lng_placeholder": "Lengde (Lng)", "live_photo_btn": "Foto (kamera)", - "live_photo_capture_btn": "Ta bilde", + "live_photo_capture_btn": "Ta opp", "live_photo_save_btn": "Lagre", - "live_photo_retake_btn": "Ta på nytt", - "live_photo_capture_failed": "Opptak mislyktes. Prøv igjen.", - "live_photo_open_camera_btn": "Åpne kamera", - "live_photo_native_hint": "Ta et bilde med enhetskameraet og lagre det her etterpå.", - "live_photo_camera_starting": "Starter kamera…", + "live_photo_retake_btn": "Ta opp på nytt", + "live_photo_capture_failed": "Opptaket mislyktes. Prøv på nytt.", + "live_photo_open_camera_btn": "Åpne kameraet", + "live_photo_native_hint": "Ta et bilde med enhetens kamera og lagre det deretter her.", + "live_photo_camera_starting": "Kameraet startes…", "live_photo_camera_denied": "Kameratilgang nektet eller utilgjengelig.", - "live_photo_camera_unavailable": "Kamera støttes ikke i denne nettleseren.", - "live_photo_no_camera": "Ingen kamera er tilgjengelig på denne enheten.", - "live_photo_error": "Kunne ikke lagre foto.", + "live_photo_camera_unavailable": "Denne nettleseren støtter ikke kameraet.", + "live_photo_no_camera": "Denne enheten har ikke kamera.", + "live_photo_error": "Bildet kunne ikke lagres.", "live_photo_entry": "Foto: {{caption}}", "live_photo_entry_plain": "Foto tatt", - "live_undo_photo_hint": "Foto lagret", + "live_undo_photo_hint": "Bildet er lagret", "live_voice_btn": "Talemelding", "live_voice_hint": "Ta opp en kort talemelding (maks. 60 sekunder).", "live_voice_record": "Start opptak", - "live_voice_stop": "Stopp opptak", - "live_voice_recording": "Tar opp {{time}}", + "live_voice_stop": "Avslutt opptak", + "live_voice_recording": "Opptak {{time}}", "live_voice_save": "Lagre", - "live_voice_saving": "Lagrer…", + "live_voice_saving": "Lagrer...", "live_voice_retake": "Ta opp på nytt", - "live_voice_mic_denied": "Mikrofontilgang nektet eller utilgjengelig.", - "live_voice_record_failed": "Opptak mislyktes. Prøv igjen.", - "live_voice_unavailable": "Talemelding utilgjengelig", - "live_voice_too_large": "Opptaket er for stort. Ta et kortere opptak.", - "live_voice_error": "Kunne ikke lagre talemelding.", + "live_voice_mic_denied": "Mikrofonen er blokkert eller utilgjengelig.", + "live_voice_record_failed": "Opptaket mislyktes. Prøv på nytt.", + "live_voice_unavailable": "Talemelding ikke tilgjengelig", + "live_voice_too_large": "Opptaket er for langt. Vennligst ta et kortere opptak.", + "live_voice_error": "Det var ikke mulig å lagre talemeldingen.", "live_voice_entry": "Talemelding: {{caption}}", "live_voice_entry_plain": "Talemelding", - "live_voice_caption_label": "Bildetekst (valgfritt)", - "live_voice_caption_placeholder": "f.eks. radiokontakt med havnesjef", + "live_voice_caption_label": "Tekst (valgfritt)", + "live_voice_caption_placeholder": "f.eks. radiokommunikasjon med havnesjefen", "live_voice_transcribe_action": "Transkribere", - "live_voice_transcribing": "Transkriberer…", - "live_voice_transcribe_failed": "Taleopptak lagret, men transkribering mislyktes.", + "live_voice_transcribing": "Transkriber...", + "live_voice_transcribe_failed": "Talememoet er lagret, men transkripsjonen mislyktes.", "live_undo_voice_hint": "Talemelding lagret", "live_comment_btn": "Kommentar", - "live_comment_placeholder": "Skriv inn tekst…", - "live_comment_confirm": "Loggfør", - "live_gps_error": "GPS-posisjon kunne ikke bestemmes.", - "live_gps_start_hint": "Start alltid dagsreisen med en posisjon.", + "live_comment_placeholder": "Skriv inn fri tekst…", + "live_comment_confirm": "Registrer deg", + "live_gps_error": "GPS-posisjonen kunne ikke fastslås.", + "live_gps_start_hint": "Start alltid dagsturen med å finne en posisjon.", "live_event_generic": "Hendelse", "live_weather_btn": "Vær", - "live_weather_owm_btn": "Hent OpenWeatherMap-vær", - "live_weather_owm_loading": "Henter vær…", - "live_weather_position_required": "Logg først en posisjon (Posisjon-knapp) for å hente OpenWeatherMap-vær. Posisjonen må være maks 6 timer gammel.", - "live_weather_position_stale": "Siste posisjon er eldre enn 6 timer. Logg en ny posisjon før du henter vær.", + "live_weather_owm_btn": "OpenWeatherMap Hent værmelding", + "live_weather_owm_loading": "Været lastes inn…", + "live_weather_position_required": "For vær fra OpenWeatherMap må du først legge inn en posisjon (knappen «Posisjon»). Posisjonen må ikke være eldre enn 6 timer.", + "live_weather_position_stale": "Den siste posisjonen er eldre enn 6 timer. Vennligst registrer en ny posisjon før du henter værmeldingen.", "live_wind_btn": "Vind", "live_temp_btn": "T °C", "live_pressure_btn": "Lufttrykk", @@ -333,10 +335,10 @@ "live_course_entry": "Kurs {{course}}", "live_fuel_entry": "Diesel +{{liters}} L", "live_water_entry": "Vann +{{liters}} L", - "live_auto_position": "Auto-posisjon", - "live_undo_hint": "Oppføring lagret", - "live_undo_btn": "Angre", - "live_cancel": "Avbryt", + "live_auto_position": "Automatisk posisjon", + "live_undo_hint": "Oppføringen er lagret", + "live_undo_btn": "Tilbakekall", + "live_cancel": "Avbrudd", "live_pressure_placeholder": "f.eks. 1013", "live_temp_placeholder": "f.eks. 18", "live_precip_placeholder": "f.eks. lett regn", @@ -351,30 +353,30 @@ "live_stw_entry": "STW {{speed}} kn", "live_sog_placeholder": "f.eks. 5,2", "live_stw_placeholder": "f.eks. 4,8", - "live_sog_hint": "Fart over grunn (kn) — GPS-verdi fylles inn hvis tilgjengelig.", - "delete_entry": "Slett tagg", - "delete_confirm": "Er du sikker på at du vil slette denne reisedagen permanent?", - "carry_over_tanks_title": "Overføre data fra dagen før?", - "carry_over_tanks_confirm": "Overta starthavn, ferskvann, drivstoff og gråvann fra startnivåene fra siste dag på turen?\n\nStart havn: {{departure}}\nFerskvann: {{fw}} L\nDrivstoff: {{fuel}} L\nGråvann: {{greywater}} L", - "carry_over_tanks_yes": "Ta over", - "carry_over_tanks_no": "Begynn med 0", + "live_sog_hint": "Fart over grunn (kn) — GPS-verdien fylles inn automatisk hvis den er tilgjengelig.", + "delete_entry": "Slett dag", + "delete_confirm": "Er du sikker på at du vil slette denne reisedagen uten mulighet for å angre?", + "carry_over_tanks_title": "Skal data fra i går overføres?", + "carry_over_tanks_confirm": "Skal starthavn, ferskvann, drivstoff og gråvann ved avreise overføres fra den siste reisedagen?\n\nStarthavn: {{departure}}\nFerskvann: {{fw}} l\nDrivstoff: {{fuel}} l\nGråvann: {{greywater}} l", + "carry_over_tanks_yes": "Bruk", + "carry_over_tanks_no": "Starte fra 0", "event_title": "Kronologisk hendelseslogg", "event_creator": "Registrert av", - "no_events": "Ingen arrangementer lagt inn for denne reisedagen ennå.", - "event_time": "Tid på døgnet", + "no_events": "Det er ennå ikke lagt inn noen hendelser for denne reisedagen.", + "event_time": "Klokkeslett", "event_mgk": "MgK-kurs", "event_rwk": "RwK-kurs", "event_course_section": "Kurs", - "course_dial_hint": "Vri ringen eller angi grader", + "course_dial_hint": "Drei på ringen eller angi vinkel", "course_dial_step_label": "Trinnstørrelse", "course_step_fine": "1°", "course_step_medium": "5°", "course_step_coarse": "10°", "course_tab_mgk": "MgK", "course_tab_rwk": "rwK", - "course_invalid": "Ugyldig kurs (0-360)", - "course_placeholder_degrees": "z. B. 180", - "course_placeholder_cardinal": "z. E.G. NW", + "course_invalid": "Ugyldig kurs (0–360)", + "course_placeholder_degrees": "f.eks. 180", + "course_placeholder_cardinal": "f.eks. NW", "compass_n": "N", "compass_e": "O", "compass_s": "S", @@ -383,512 +385,512 @@ "wind_mode_degrees": "Som grad", "event_wind_direction": "Vindretning", "event_wind_strength": "Vindstyrke", - "event_sea_state": "Havets tilstand", + "event_sea_state": "Sjøgang", "event_visibility": "Sikt", "event_visibility_placeholder": "f.eks. 10 km", "weather_slider_unset": "—", "weather_slider_pressure": "{{value}} hPa", - "weather_slider_sea_state": "Grad {{value}}", + "weather_slider_sea_state": "Nivå {{value}}", "weather_slider_heel": "{{value}}°", - "event_weather": "Været", - "event_log": "Logg (sm)", + "event_weather": "Vær", + "event_log": "Logge (sm)", "event_gps": "GPS-posisjon", - "event_location": "Sted / havn", - "event_location_placeholder": "z. f.eks. Kiel", - "event_remarks": "Merknader / hendelser", - "gps_btn": "Hent GPS-koordinater", - "gps_permission_denied": "Tilgang til posisjon ble nektet. Tillat det i nettleser- eller enhetsinnstillinger og prøv igjen.", - "gps_timeout": "GPS fikk tidsavbrudd. Prøv igjen utendørs med fri sikt mot himmelen.", - "gps_position_unavailable": "Ingen GPS-signal tilgjengelig. Vent og prøv igjen, eller skriv inn koordinater manuelt.", + "event_location": "Sted / Havn", + "event_location_placeholder": "f.eks. Kiel", + "event_remarks": "Merknader / Hendelser", + "gps_btn": "Hente GPS-koordinater", + "gps_permission_denied": "Tilgang til posisjonsdata ble nektet. Vennligst tillat dette i nettleser- eller enhetsinnstillingene og prøv på nytt.", + "gps_timeout": "GPS-tidsavbrudd. Prøv på nytt – helst utendørs der det er god dekning.", + "gps_position_unavailable": "Det er ikke noe GPS-signal. Vennligst vent, eller skriv inn koordinatene manuelt.", "gps_unavailable": "GPS støttes ikke av denne nettleseren eller enheten.", - "gps_failed": "GPS-posisjon kunne ikke bestemmes.", - "gps_fallback_no_location": "GPS mislyktes. Skriv inn et sted under sted/havn, avreise eller destinasjon, eller koordinater manuelt.", - "gps_fallback_success": "Koordinater for «{{location}}» funnet via stedsnavn (ikke GPS).", - "gps_fallback_failed": "GPS og stedsnavnssøk mislyktes. Skriv inn koordinater manuelt.", + "gps_failed": "GPS-posisjonen kunne ikke fastslås.", + "gps_fallback_no_location": "GPS-funksjonen mislyktes. Vennligst oppgi et sted under «Sted/havn», start- eller målhavn, eller skriv inn koordinatene manuelt.", + "gps_fallback_success": "Koordinatene for «{{location}}» er fastsatt ut fra stedsnavnet (ikke via GPS).", + "gps_fallback_failed": "GPS- og stedsnavnsøk mislyktes. Vennligst skriv inn koordinatene manuelt.", "gps_quality_excellent": "Sterk GPS-mottak (±{{accuracy}} m)", "gps_quality_good": "God GPS-mottak (±{{accuracy}} m)", - "gps_quality_fair": "Middels GPS-mottak (±{{accuracy}} m) – gå utendørs for bedre signal.", - "gps_quality_poor": "Svakt GPS-mottak (±{{accuracy}} m) – sannsynligvis få satellitter. Prøv utendørs igjen eller kontroller posisjonen.", - "gps_quality_unknown": "GPS-posisjon tatt i bruk (nøyaktighet ikke rapportert av enheten).", - "gps_live_intro_title": "Posisjon for live-logg", - "gps_live_intro_body": "Appen trenger posisjonen din for automatiske posisjonsregistreringer og GPS-knappen.\n\nTrykk «Tillat posisjon» og bekreft i neste dialog. Du kan alltid legge inn posisjon manuelt via «Posisjon».", - "gps_live_intro_allow": "Tillat posisjon", + "gps_quality_fair": "Middels GPS-mottak (±{{accuracy}} m) – gå utendørs for bedre mottak.", + "gps_quality_poor": "Svakt GPS-signal (±{{accuracy}} m) – sannsynligvis få satellitter. Prøv på nytt utendørs eller sjekk posisjonen.", + "gps_quality_unknown": "GPS-posisjon hentet (nøyaktighet ikke oppgitt av enheten).", + "gps_live_intro_title": "Plassering for Live-Log", + "gps_live_intro_body": "For automatiske posisjonsoppføringer og GPS-knappen trenger appen tilgang til posisjonen din.\n\nTrykk på «Tillat posisjon» – bekreft tillatelsen i den neste dialogboksen. Du kan når som helst legge inn posisjonen manuelt under «Posisjon».", + "gps_live_intro_allow": "Tillat bruk av posisjonsdata", "gps_live_intro_later": "Senere", - "gps_enable_in_settings_hint": "Posisjonstilgang er blokkert. Du kan tillate det senere i nettleser- eller enhetsinnstillinger (nettsted / app → Posisjon).", - "weather_btn": "OpenWeatherMap Ring opp været", - "weather_offline": "OpenWeatherMap krever internettforbindelse. Du er frakoblet.", + "gps_enable_in_settings_hint": "Tilgang til posisjonsdata er blokkert. Du kan senere gi tillatelse til dette i nettleser- eller enhetsinnstillingene (Nettsted / App → Posisjon).", + "weather_btn": "OpenWeatherMap Hent værmelding", + "weather_offline": "OpenWeatherMap krever en internettforbindelse. Du er for øyeblikket frakoblet.", "event_wind_pressure": "Lufttrykk (hPa)", - "event_heel": "Helning (°)", - "event_sails": "Seilhåndtering / motor", - "motor_propulsion": "Maskinreise", + "event_heel": "Krengning (°)", + "event_sails": "Seilbåt / Motor", + "motor_propulsion": "Maskinkjøring", "sails_picker_show_more": "Vis alle seil", - "sails_picker_show_less": "Vis mindre", - "motor_hours": "Maskintimer (totalt)", + "sails_picker_show_less": "Vis færre", + "motor_hours": "Maskin timer (totalt)", "fuel_per_motor_hour": "Forbruk per maskintime", "event_distance": "Avstand (sm)", "export_csv": "Last ned CSV", - "share_csv": "CSV andel", + "share_csv": "CSV del", "export_pdf": "Last ned PDF", "exporting_pdf": "PDF genereres...", - "ai_summary_title": "AI-sammendrag", - "ai_summary_read_only": "Opprettet av skipperen — kun lesbar for mannskapet.", - "ai_summary_empty": "Ingen sammendrag ennå.", + "ai_summary_title": "Sammendrag av AI", + "ai_summary_read_only": "Opprettet av skipperen — kun synlig for mannskapet.", + "ai_summary_empty": "Det finnes ikke noe sammendrag ennå.", "ai_summary_generate": "Generer sammendrag", "ai_summary_regenerate": "Generer på nytt", - "ai_summary_generating": "Genererer…", - "ai_summary_attempts_remaining": "{{remaining}} av {{max}} forsøk igjen", - "ai_summary_error": "AI-sammendrag mislyktes. Prøv igjen senere.", - "ai_summary_error_no_key": "Ingen OpenRouter API-nøkkel konfigurert på serveren.", - "ai_summary_error_rate_limited": "Maksimalt antall genereringer nådd for denne reisedagen.", - "ai_summary_error_forbidden": "Kun skipperen kan generere AI-sammendrag.", - "ai_summary_offline": "AI-sammendrag krever internettforbindelse. Du er frakoblet.", + "ai_summary_generating": "Genereres…", + "ai_summary_attempts_remaining": "Fortsatt {{remaining}} av {{max}} forsøk", + "ai_summary_error": "Sammendraget av AI mislyktes. Prøv igjen senere.", + "ai_summary_error_no_key": "Det er ikke konfigurert noen OpenRouter-API-nøkkel på serveren.", + "ai_summary_error_rate_limited": "Maksimalt antall genereringer for denne reisedagen er nådd.", + "ai_summary_error_forbidden": "Bare skipperen har lov til å generere AI-sammendrag.", + "ai_summary_offline": "AI-sammendraget krever en internettforbindelse. Du er for øyeblikket frakoblet.", "photos_title": "Bildevedlegg", - "photo_caption_label": "Fotobeskrivelse/etikett (valgfritt)", - "photo_caption_placeholder": "f.eks. å sette seil nær innseilingen til havnen", - "photo_btn": "Ta bilde / last opp", - "photo_camera_btn": "Ta bilde", - "photo_gallery_btn": "Velg fra galleri", - "photo_processing": "...blir behandlet...", - "no_photos": "Ingen bilder knyttet til denne reisedagen ennå.", + "photo_caption_label": "Bildetekst / Etikett (valgfritt)", + "photo_caption_placeholder": "f.eks. sette seil nær havneinnseilingen", + "photo_btn": "Ta bilde / Last opp", + "photo_camera_btn": "Ta et bilde", + "photo_gallery_btn": "Velg fra galleriet", + "photo_processing": "Behandles...", + "no_photos": "Det er ikke lagt ved noen bilder fra denne reisedagen ennå.", "photo_delete_confirm": "Er du sikker på at du vil slette dette bildet permanent?", "confirm_yes": "Ja", "confirm_no": "Nei", - "track_upload_title": "GPS-sporing (fil)", + "track_upload_title": "GPS-spor (fil)", "track_upload_points": "Poeng", "gps_tracking_btn_gpx": "Last ned sporfil", "gps_track_upload_help": "Dra en GPX-, KML- eller GeoJSON-fil hit, eller klikk for å velge", "gps_track_upload_btn": "Last opp GPS-spor", "gps_track_delete": "Slett sporfil", - "gps_track_delete_confirm": "Er du sikker på at du vil slette denne sporfilen permanent?", + "gps_track_delete_confirm": "Er du sikker på at du vil slette denne sporingsfilen permanent?", "track_distance": "GPS-rute (sm)", - "track_speed_max": "Maks. Hastighet (kn)", + "track_speed_max": "Maks. hastighet (kn)", "track_speed_avg": "Ø Hastighet (kn)", "track_map_title": "GPS-spor på OpenSeaMap", "track_map_start": "Start", "track_map_end": "Mål", - "track_map_speed_slow": "langsomt", + "track_map_speed_slow": "sakte", "track_map_speed_fast": "raskt", - "track_map_error": "Kartet kunne ikke lastes inn.", - "exporting": "Eksport...", - "share_unsupported": "Deling støttes ikke på denne enheten. Filen har blitt lastet ned i stedet.", - "invite_crew": "Inviter crewet", - "invite_link_copied": "Invitasjonslenke kopiert til utklippstavlen!", - "invite_link_desc": "Del denne lenken med Crew-medlemmene for å gi dem skrivetilgang til loggboken.", - "collaborators_list": "Medlemmer / Crew", - "revoke": "Fjern", - "revoke_confirm": "Er du sikker på at du vil oppheve dette Crew-medlemmets tilgang?", - "invite_role": "Rolle", - "invite_expires": "Lenken er gyldig i 48 timer", - "nmea_import_title": "Import NMEA log", - "nmea_import_intro": "Upload a .nmea file from your onboard logger. The app suggests journal entries — you choose what to import.", - "nmea_import_btn": "Import NMEA", - "nmea_file_label": "NMEA file", - "nmea_stats": "{{lines}} sentences parsed · types: {{types}}", - "nmea_warn_no_position": "No position sentences found — track and GPS fields may stay empty.", - "nmea_mode_label": "Generate journal entries", - "nmea_mode_interval": "By time interval", - "nmea_mode_change": "On significant change", - "nmea_mode_both": "Both (merge)", - "nmea_interval_label": "Interval (minutes)", - "nmea_import_track": "Import GPS track from NMEA", - "nmea_preview": "Preview", - "nmea_preview_hint": "{{count}} suggested journal entries", - "nmea_select_all": "Select all", - "nmea_select_none": "Select none", - "nmea_source_interval": "Interval", - "nmea_source_change": "Event", - "nmea_apply": "Apply to journal", - "nmea_back": "Back", - "nmea_cancel": "Cancel", - "nmea_archive_question": "Archive raw log locally? (This device only, not synced.)", - "nmea_archive_keep": "Archive", - "nmea_archive_discard": "Discard", - "nmea_archive_stored": "NMEA archived: {{name}}", - "nmea_archive_delete_confirm": "Delete archived NMEA log from this device?", - "nmea_error_no_samples": "No usable NMEA sentences in the file.", - "nmea_error_parse": "Could not read NMEA file.", - "nmea_error_read": "Could not read file.", - "nmea_error_no_file": "Please choose an NMEA file first.", - "nmea_error_no_selection": "Please select at least one journal entry.", - "nmea_remark_interval": "NMEA interval", - "nmea_remark_uncertain": "uncertain", - "nmea_remark_depth": "Depth {{depth}} m", - "nmea_change_course": "Course change {{from}}° → {{to}}°", - "nmea_change_wind": "Wind {{from}}° → {{to}}°", - "nmea_change_wind_speed": "Wind {{from}} → {{to}} kn", - "nmea_change_pressure": "Pressure {{from}} → {{to}} hPa", - "nmea_change_depth": "Depth {{from}} → {{to}} m", - "nmea_change_engine_start": "Engine on ({{rpm}} rpm)", - "nmea_change_engine_stop": "Engine off", - "nmea_change_autopilot_on": "Autopilot on", - "nmea_change_autopilot_off": "Autopilot off", - "nmea_change_gps_lost": "GPS-posisjon tapt", + "nmea_import_title": "Importer NMEA-protokoll", + "nmea_import_intro": "Last inn en .nmea-fil fra loggeren om bord. Appen foreslår loggoppføringer – du bestemmer selv hva som skal importeres.", + "nmea_import_btn": "Importer NMEA", + "nmea_file_label": "NMEA-fil", + "nmea_stats": "{{lines}} setninger gjenkjent · Typer: {{types}}", + "nmea_warn_no_position": "Ingen posisjonssetter funnet — spor- og GPS-feltene kan stå tomme.", + "nmea_warn_duplicate_file": "Denne NMEA-filen er allerede importert. Hvis du importerer den samme filen på nytt, vil det føre til dupliserte loggoppføringer.", + "nmea_mode_label": "Opprette journaloppføringer", + "nmea_mode_interval": "Etter tidsintervall", + "nmea_mode_change": "Ved vesentlige endringer", + "nmea_mode_both": "Begge deler (slå sammen)", + "nmea_interval_label": "Intervall (minutter)", + "nmea_import_track": "Importer GPS-spor fra NMEA", + "nmea_preview": "Forhåndsvisning", + "nmea_preview_hint": "{{count}} foreslåtte journaloppføringer", + "nmea_select_all": "Velg alle", + "nmea_select_none": "Ikke velg noen", + "nmea_source_interval": "Intervall", + "nmea_source_change": "Hendelse", + "nmea_apply": "Overfør til journalen", + "nmea_back": "Tilbake", + "nmea_cancel": "Avbryt", + "nmea_archive_question": "Skal råloggen arkiveres lokalt? (Bare på denne enheten, ikke synkronisert.)", + "nmea_archive_keep": "Arkivere", + "nmea_archive_discard": "Avvis", + "nmea_archive_stored": "NMEA-logg: {{name}}", + "nmea_archive_delete_confirm": "Vil du slette arkivert NMEA-logg fra denne enheten?", + "nmea_error_no_samples": "Ingen brukbare NMEA-setninger i filen.", + "nmea_error_parse": "NMEA-filen kunne ikke leses.", + "nmea_error_read": "Filen kunne ikke leses.", + "nmea_error_no_file": "Velg først en NMEA-fil.", + "nmea_error_no_selection": "Velg minst én journaloppføring.", + "nmea_remark_interval": "NMEA-intervall", + "nmea_remark_uncertain": "usikker", + "nmea_remark_depth": "Dybde {{depth}} m", + "nmea_change_course": "Kursendring {{from}}° → {{to}}°", + "nmea_change_wind": "Vind {{from}}° → {{to}}°", + "nmea_change_wind_speed": "Vind {{from}} → {{to}} kn", + "nmea_change_pressure": "Lufttrykk {{from}} → {{to}} hPa", + "nmea_change_depth": "Dybde {{from}} → {{to}} m", + "nmea_change_engine_start": "Motor på ({{rpm}} o/min)", + "nmea_change_engine_stop": "Motor av", + "nmea_change_autopilot_on": "Autopilot på", + "nmea_change_autopilot_off": "Autopilot av", + "nmea_change_gps_lost": "GPS-posisjonen er tapt", "nmea_change_gps_regained": "GPS-posisjon gjenopprettet", - "nmea_change_water_temp": "Water temp. {{from}} → {{to}} °C", - "nmea_change_departure": "Departure / underway", - "nmea_change_anchor": "Anchored / stop", - "nmea_change_speed": "Speed {{from}} → {{to}} kn", - "nmea_warn_duplicate_file": "This NMEA file has already been imported. Importing the same file again will add duplicate journal entries." + "nmea_change_water_temp": "Vanntemperatur {{from}} → {{to}} °C", + "nmea_change_departure": "Avgang / Start", + "nmea_change_anchor": "Anker / Stopp", + "nmea_change_speed": "Hastighet {{from}} → {{to}} kn", + "track_map_error": "Kartet kunne ikke lastes inn.", + "exporting": "Eksporter...", + "share_unsupported": "Deling støttes ikke på denne enheten. Filen ble i stedet lastet ned.", + "invite_crew": "Inviter mannskapet", + "invite_link_copied": "Invitasjonslenken er kopiert til utklippstavlen!", + "invite_link_desc": "Del denne lenken med besetningsmedlemmer for å gi dem skriverettigheter til denne loggboken.", + "collaborators_list": "Medlemmer / Mannskap", + "revoke": "Fjern", + "revoke_confirm": "Er du sikker på at du vil fjerne tilgangen til dette besetningsmedlemmet?", + "invite_role": "Rolle", + "invite_expires": "Koblingen er gyldig i 48 timer" }, "dashboard": { "title": "Loggbøkene dine", - "subtitle": "Velg en loggbok eller opprett en ny for å administrere reisene dine.", + "subtitle": "Velg en loggbok eller opprett en ny for å holde oversikt over reisene dine.", "create_btn": "Opprett loggbok", - "new_logbook_placeholder": "Navn på loggboken eller båten", + "new_logbook_placeholder": "Navnet på loggboken eller båten", "logout": "Logg ut", - "logged_in_as": "Innlogget som {{name}}", - "delete_confirm": "Er du sikker på at du vil slette denne loggboken permanent? Alle lokale data og serverkopier vil bli ødelagt.\n\nTips: Lag en sikkerhetskopi (.daagbok) på forhånd under Innstillinger → Sikkerhetskopiering og gjenoppretting hvis du ønsker å beholde dataene senere.", + "logged_in_as": "Logg inn som {{name}}", + "delete_confirm": "Er du sikker på at du vil slette denne loggboken permanent? Alle lokale data og serverkopier vil bli slettet.\n\nTips: Lag først en sikkerhetskopi (.daagbok) under Innstillinger → Sikkerhetskopiering og gjenoppretting, hvis du ønsker å beholde dataene senere.", "no_logbooks": "Ingen loggbøker funnet. Opprett din første loggbok for å komme i gang!", - "loading": "Loggbøker er lastet...", + "loading": "Loggbøkene lastes inn...", "status_synced": "Synkronisert", - "status_local": "Kun lokal hurtigbuffer", - "delete_btn": "Slett loggbok", + "status_local": "Kun lokal cache", + "delete_btn": "Slett loggboken", "section_owned": "Loggbøkene mine", - "section_shared": "Felles loggbøker", - "section_shared_hint": "Du er invitert som Crew-medlem. Skipperprofil og innstillinger tilhører eieren.", + "section_shared": "Delte loggbøker", + "section_shared_hint": "Du er invitert som besetningsmedlem. Skipperprofilen og innstillingene tilhører eieren.", "role_owner": "Egen loggbok", "role_owner_hint": "Du er eier og skipper av denne loggboken", - "role_crew": "Tilgang for crewet", - "role_crew_hint": "Loggbok med invitasjon - du kan jobbe som crew og signere den", - "role_read": "Bare les", - "role_read_hint": "Delt loggbok - kun visning, ingen redigering", + "role_crew": "Tilgang for mannskapet", + "role_crew_hint": "Inviterte loggbok — du kan bidra som besetningsmedlem og skrive under", + "role_read": "Bare lesing", + "role_read_hint": "Delt loggbok — kun visning, ingen redigering", "open_profile": "Åpne profilen til {{name}}", - "open_logbook": "Åpne loggbok «{{title}}»", - "edit_title": "Endre navn på loggbok", + "open_logbook": "Åpne loggboken «{{title}}»", + "edit_title": "Endre navn på loggboken", "edit_placeholder": "Nytt navn på loggboken", - "edit_success": "Loggboken har fått nytt navn", - "edit_btn": "Gi nytt navn", + "edit_success": "Loggboken er nå omdøpt", + "edit_btn": "Endre navn", "filter_label": "Filtrer loggbøker", - "filter_placeholder": "Navn, årstall, dato, crew eller skip …", + "filter_placeholder": "Navn, år, dato, mannskap eller skip …", "filter_clear": "Tilbakestill filter", "filter_results": "{{count}} Treff", - "filter_no_results": "Ingen loggbøker samsvarer med søket ditt. Prøv et annet navn eller et annet år.", - "sort_label": "Sortere", + "filter_no_results": "Det finnes ingen loggbøker som samsvarer med søket ditt. Prøv et annet navn eller et annet år.", + "sort_label": "Sorter", "sort_by_label": "Sorter etter", "sort_by_name": "Navn", - "sort_by_date": "dato", - "sort_dir_label": "Sekvens", + "sort_by_date": "Dato", + "sort_dir_label": "Rekkefølge", "sort_asc": "Stigende", - "sort_desc": "Synkende", - "sort_name_asc": "Navn A til Å", - "sort_name_desc": "Navn Z til A", - "sort_date_asc": "Eldst først", + "sort_desc": "I synkende rekkefølge", + "sort_name_asc": "Navn fra A til Å", + "sort_name_desc": "Navn fra Z til A", + "sort_date_asc": "Eldste først", "sort_date_desc": "Nyeste først" }, "profile": { "title": "Brukerprofil", - "subtitle": "Regnskap, Passkeys og statistikk for {{name}}.", - "back": "Tilbake til dashbordet", - "loading": "Profilen lastes inn...", + "subtitle": "Konto, Passkeys og statistikk for {{name}}", + "back": "Tilbake til oversikten", + "loading": "Profilen lastes inn…", "load_error": "Profilen kunne ikke lastes inn.", - "copy_failed": "Kopien mislyktes.", - "processing": "Blir behandlet...", + "copy_failed": "Kopieringen mislyktes.", + "processing": "Behandles…", "identity_title": "Kontoidentitet", "username": "Brukernavn", "user_id": "Bruker-ID", "copy_user_id": "Kopier bruker-ID", "account_since": "Konto siden", - "prf_status": "Passkey nøkkelavledning (PRF)", + "prf_status": "Passkey-nøkkelgenerering (PRF)", "prf_active": "Aktiv", - "prf_inactive": "Ikke satt opp", + "prf_inactive": "Ikke innredet", "passkeys_title": "Passkeys", - "passkeys_desc": "Registrer en separat Passkey på hver enhet. Dette gjør at du kan logge på selv etter at du har byttet plattform.", - "passkeys_empty": "Ingen Passkeyer funnet.", + "passkeys_desc": "Registrer en egen Passkey på hver enhet. På den måten kan du logge inn selv etter at du har byttet plattform.", + "passkeys_empty": "Ingen Passkey-er funnet.", "add_passkey_btn": "Legg til ny Passkey", - "add_passkey_success": "Passkey vellykket lagt til.", + "add_passkey_success": "Passkey er lagt til.", "add_passkey_failed": "Passkey kunne ikke legges til.", "remove_passkey_btn": "Fjern Passkey", - "remove_passkey_last_title": "Sist Passkey", - "remove_passkey_last_desc": "Den eneste Passkey kan ikke fjernes uten at du mister tilgangen til kontoen din. For å slette kontoen helt, bruk faresonen nederst på denne siden.", + "remove_passkey_last_title": "Siste Passkey", + "remove_passkey_last_desc": "Den eneste Passkey kan ikke fjernes uten at du mister tilgangen til kontoen din. For å slette kontoen fullstendig, bruk sikkerhetssonen nederst på denne siden.", "remove_passkey_failed": "Passkey kunne ikke fjernes.", - "remove_passkey_confirm_title": "Fjern Passkey?", - "remove_passkey_confirm_desc": "Denne enheten kan da ikke lenger logge inn med denne Passkey.", + "remove_passkey_confirm_title": "Passkey fjerne?", + "remove_passkey_confirm_desc": "Denne enheten kan ikke lenger logge seg på med denne Passkey etter dette.", "remove_passkey_confirm_yes": "Fjern", "remove_passkey_confirm_no": "Avbryt", "pin_title": "Lokal PIN-kode", "pin_status": "Status", "pin_active": "Aktiv på denne enheten", - "pin_inactive": "Ikke satt opp", - "pin_confirm_label": "Bekreft PIN-kode", - "pin_confirm_placeholder": "Tast inn PIN-koden på nytt", - "pin_set_btn": "Konfigurer PIN-kode", + "pin_inactive": "Ikke innredet", + "pin_confirm_label": "Bekreft PIN-koden", + "pin_confirm_placeholder": "Skriv inn PIN-koden på nytt", + "pin_set_btn": "Opprette PIN-kode", "pin_change_btn": "Endre PIN-kode", "pin_remove_btn": "Fjern PIN-kode", - "pin_saved": "PIN-kode lagret.", + "pin_saved": "PIN-koden er lagret.", "pin_save_failed": "PIN-koden kunne ikke lagres.", "pin_mismatch": "PIN-kodene stemmer ikke overens.", "pin_length_error": "PIN-koden må bestå av minst 4 tegn.", - "pin_no_session": "Økten er utløpt - vennligst registrer deg på nytt.", - "remove_pin_confirm_title": "Fjerne PIN-kode?", - "remove_pin_confirm_desc": "Du må logge på igjen på denne enheten med Passkey eller gjenopprettingsnøkkel.", + "pin_no_session": "Økten har utløpt — vennligst logg inn på nytt.", + "remove_pin_confirm_title": "Fjerne PIN-koden?", + "remove_pin_confirm_desc": "Du må logge på denne enheten igjen med Passkey eller gjenopprettingsnøkkelen.", "remove_pin_confirm_yes": "Fjern PIN-kode", "remove_pin_confirm_no": "Avbryt", - "security_title": "Sjekkliste for sikkerhet", - "security_desc": "Oversikt over de viktigste beskyttelsesmekanismene for kontoen din.", + "security_title": "Sikkerhetssjekkliste", + "security_desc": "Oversikt over de viktigste sikkerhetsfunksjonene for kontoen din.", "security_passkeys_ok": "Minst én Passkey registrert", - "security_passkeys_missing": "Nei Passkey registrert", - "security_prf_ok": "PRF-nøkkelavledning aktiv", - "security_prf_missing": "PRF ikke satt opp", + "security_passkeys_missing": "Ingen Passkey registrert", + "security_prf_ok": "PRF-nøkkelgenerering aktiv", + "security_prf_missing": "PRF er ikke konfigurert", "security_pin_ok": "Lokal PIN-kode på denne enheten", "security_pin_missing": "Ingen lokal PIN-kode", - "security_recovery_ok": "Oppsett av gjenopprettingsnøkkel", - "security_recovery_hint": "De 12 ordene ble vist under registreringen. Oppbevar dem frakoblet og adskilt fra enheten. Du kan opprette en ny nøkkel nedenfor - den gamle blir da ugyldig.", - "recovery_rotate_btn": "Opprett en ny gjenopprettingsnøkkel", - "recovery_rotate_confirm_title": "Opprette en ny gjenopprettingsnøkkel?", - "recovery_rotate_confirm_desc": "Den forrige 12-ordsnøkkelen blir ugyldig umiddelbart. Sørg for at du oppbevarer den nye nøkkelen trygt før du fortsetter.", + "security_recovery_ok": "Gjenopprettingsnøkkel opprettet", + "security_recovery_hint": "De 12 ordene ble vist under registreringen. Oppbevar dem offline og adskilt fra enheten. Du kan opprette en ny nøkkel nedenfor – den gamle blir da ugyldig.", + "recovery_rotate_btn": "Opprett ny gjenopprettingsnøkkel", + "recovery_rotate_confirm_title": "Vil du opprette en ny gjenopprettingsnøkkel?", + "recovery_rotate_confirm_desc": "Den tidligere 12-ordsnøkkelen blir umiddelbart ugyldig. Sørg for å oppbevare den nye nøkkelen på et sikkert sted før du fortsetter.", "recovery_rotate_confirm_yes": "Opprett ny nøkkel", "recovery_rotate_confirm_no": "Avbryt", - "recovery_rotate_new_warning": "VIKTIG: Skriv ned disse 12 ordene og oppbevar dem offline. Den forrige gjenopprettingsnøkkelen er nå ugyldig.", - "recovery_rotate_failed": "Gjenopprettingsnøkkel kunne ikke opprettes.", - "recovery_rotate_no_session": "Krypteringsøkten er utløpt - logg ut og logg inn igjen, og prøv deretter på nytt.", + "recovery_rotate_new_warning": "VIKTIG: Skriv ned disse 12 ordene og oppbevar dem uten nettilgang. Den tidligere gjenopprettingsnøkkelen er fra og med nå ugyldig.", + "recovery_rotate_failed": "Det var ikke mulig å opprette gjenopprettingsnøkkelen.", + "recovery_rotate_no_session": "Krypteringsøkten har utløpt — vennligst logg ut og logg inn på nytt, og prøv igjen.", "device_title": "Denne enheten", - "device_desc": "Lokal hurtigbuffer, synkroniseringsstatus og hurtigpålogging i denne nettleseren.", - "device_sync_pending": "{{count}} ventende synkroniseringsoppføringer", - "device_sync_ok": "Alle lokale endringer synkroniseres", - "device_remembered": "Konto for hurtiginnlogging lagret på denne enheten", - "device_not_remembered": "Kontoen er ikke i hurtiginnloggingslisten", - "device_forget_btn": "Glemt konto på denne enheten", + "device_desc": "Lokal cache, synkroniseringsstatus og hurtiginnlogging i denne nettleseren.", + "device_sync_pending": "{{count}} utestående synkroniseringsoppføringer", + "device_sync_ok": "Alle lokale endringer er synkronisert", + "device_remembered": "Kontoen er lagret på denne enheten for hurtiginnlogging", + "device_not_remembered": "Kontoen er ikke på listen over hurtiginnlogginger", + "device_forget_btn": "Glemt kontoen på denne enheten", "device_forget_confirm_title": "Fjerne hurtiginnlogging?", - "device_forget_confirm_desc": "Kontoen forsvinner fra hurtiginnloggingslisten på denne enheten. Økten og de lokale loggbøkene beholdes.", + "device_forget_confirm_desc": "Kontoen fjernes fra listen over hurtiginnlogginger på denne enheten. Sesjonen din og de lokale loggene dine beholdes.", "device_forget_confirm_yes": "Fjern", "device_forget_confirm_no": "Avbryt", "passkey_label": "Navn på ny Passkey (valgfritt)", - "passkey_label_placeholder": "z. f.eks. MacBook, iPhone", + "passkey_label_placeholder": "f.eks. MacBook, iPhone", "passkey_rename_btn": "Lagre navn", - "passkey_rename_success": "Passkey navn lagret.", - "passkey_rename_failed": "Passkey-Navn kunne ikke lagres.", - "passkey_unnamed": "Uten tittel Passkey", + "passkey_rename_success": "Passkey-navnet er lagret.", + "passkey_rename_failed": "Passkey-navnet kunne ikke lagres.", + "passkey_unnamed": "Ukjent Passkey", "stats_title": "Statistikk", "stats_subtitle": "Om alle loggbøkene dine på denne enheten", "stats_logbooks": "Loggbøker", "stats_account_since": "Konto siden", - "stats_shared_logbooks": "Felles loggbøker", - "appearance_title": "App og visualisering", + "stats_shared_logbooks": "Delte loggbøker", + "appearance_title": "App og visning", "appearance_desc": "Designet og fargevalget gjelder for hele appen på denne enheten.", "theme_label": "Appens designstil", - "theme_auto": "Automatisk (OS-deteksjon)", + "theme_auto": "Automatisk (OS-gjenkjenning)", "theme_ocean": "Ocean (glassmorfisme)", "theme_material": "Materiale (Android)", "theme_cupertino": "Cupertino (iOS)", "color_scheme_label": "Lys eller mørk modus", "color_scheme_auto": "Automatisk (system)", "color_scheme_light": "Lys", - "color_scheme_dark": "Mørk", + "color_scheme_dark": "Mørkt", "integrations_title": "Integrasjoner", "owm_key": "OpenWeatherMap API-nøkkel", - "owm_help": "Valgfritt: egen OpenWeatherMap API-nøkkel. Hvis ingen oppføring er gjort, brukes serverside-nøkkelen fra operatørkonfigurasjonen.", - "ai_title": "KI-funksjoner og personvern", - "ai_desc": "Autoriser integrasjoner av kunstig intelligens for loggbøkene dine.", - "ai_help": "Aktivering av KI-funksjoner gjør det mulig for appen å oppsummere reisedagene dine og transkribere innspilte talememoer. For å behandle disse forespørslene sendes rå stemmedata og reiselogger sikkert løpende til OpenRouter. Ingen data lagres permanent av KI-modellen.\n\nDisse nettskyressursene koster penger å drifte. Hvis du har glede av å bruke dem, kan du vurdere å støtte prosjektet frivillig med en donasjon via Ko-fi-lenken i bunnteksten for å holde dem gratis og bærekraftige for alle.", - "ai_enable_label": "Aktiver transkribering og oppsummeringer av reisedager", - "ai_unauthorized_alert_title": "KI-funktionen er ikke autorisert", - "ai_unauthorized_alert_desc": "For å bruke transkribering eller reisedagsoppsummeringer, må du autorisere dataoverføringen til OpenRouter i brukerprofilen din under 'KI-funksjoner og personvern'.", - "prefs_save": "Spar", - "prefs_saving": "...vil bli reddet...", - "prefs_saved": "Reddet", - "tour_title": "App-tur", - "tour_desc": "La deg veilede gjennom de viktigste områdene i appen på nytt.", + "owm_help": "Valgfritt: egen OpenWeatherMap-API-nøkkel. Hvis dette feltet ikke fylles ut, brukes nøkkelen på serversiden fra operatørkonfigurasjonen.", + "ai_title": "AI-funksjoner og personvern", + "ai_desc": "Godkjenn bruk av kunstig intelligens (lokale/skybaserte integrasjoner) for loggbøkene dine.", + "ai_help": "Aktivering gjør det mulig å oppsummere reiserapporter automatisk og transkribere talemeldinger. For behandling overføres lydopptak og loggbokoppføringer i kryptert form til OpenRouter. Dataene lagres ikke permanent der.\n\nSiden driften av disse skyressursene medfører kostnader, setter vi pris på frivillig støtte via Ko-fi-donasjonslenken i bunnteksten, slik at vi kan tilby disse funksjonene gratis for alle på lang sikt.", + "ai_enable_label": "Aktiver transkripsjon og daglige sammendrag", + "ai_unauthorized_alert_title": "AI-funksjoner ikke godkjent", + "ai_unauthorized_alert_desc": "For å transkribere talemeldinger eller oppsummere reiseberetninger må du samtykke til dataoverføring til OpenRouter i brukerprofilen din under «AI-funksjoner og personvern».", + "prefs_save": "Lagre", + "prefs_saving": "Lagrer...", + "prefs_saved": "Lagret", + "tour_title": "Omvisning i appen", + "tour_desc": "La deg igjen bli guidet gjennom de viktigste delene av appen.", "tour_restart": "Start turen på nytt", "push_title": "Push-varsler", - "push_desc": "Som loggbokseier vil du bli varslet når inviterte Crew-medlemmer synkroniserer endringer. Ingen innhold overføres i ren tekst.", - "push_enable": "Gi oss beskjed om endringer i crewet", - "push_active": "Push-varsler er aktive på denne enheten.", + "push_desc": "Som loggbokseier får du beskjed når inviterte besetningsmedlemmer synkroniserer endringer. Det overføres ikke noe innhold i klartekst.", + "push_enable": "Gi beskjed ved endringer i besetningen", + "push_active": "Push-varsler er aktivert på denne enheten.", "push_unsupported": "Push-varsler støttes ikke i denne nettleseren.", - "push_denied_hint": "Varsler er blokkert. Tillat dem i innstillingene i nettleseren eller på enheten.", - "push_ios_install_hint": "På iPhone/iPad: Legg til app på startskjermen (iOS 16.4+) for å bruke push.", - "push_error": "Push-varsler kunne ikke aktiveres.", + "push_denied_hint": "Varslinger er blokkert. Tillat dem i nettleser- eller enhetsinnstillingene.", + "push_ios_install_hint": "På iPhone/iPad: Legg til appen på startskjermen (iOS 16.4+), for å kunne motta push-varsler.", + "push_error": "Det var ikke mulig å aktivere push-varsler.", "sections": { "account": "Konto og innstillinger", - "fleet": "Flåte og crew", - "security": "Sikkerhet og enhet", + "fleet": "Flåte og mannskap", + "security": "Sikkerhet og utstyr", "stats": "Statistikk", - "danger": "Faresone" + "danger": "Fareområde" } }, "vessel_pool": { "title": "Skipsflåte", "section_title": "Dine skip", - "subtitle": "Hold alle skip for loggbøkene dine her. Velg aktivt skip per loggbok fra listen.", - "loading": "Laster skipsflåte…", + "subtitle": "Her kan du administrere alle skipene i loggbøkene dine. For hver loggbok velger du det aktive skipet fra denne listen.", + "loading": "Skipsflåten lastes inn…", "add_vessel": "Legg til skip", "edit_vessel": "Rediger skip", - "no_vessels": "Ingen skip i poolen ennå.", - "delete_confirm": "Fjerne dette skipet fra flåten?", - "max_vessels": "Maksimalt 20 skip i poolen." + "no_vessels": "Ingen skip i flåten ennå.", + "delete_confirm": "Vil du virkelig fjerne dette skipet fra flåten?", + "max_vessels": "Maksimalt antall på 20 skip i flåten er nådd." }, "logbook_vessel": { - "title": "Skip for denne loggboken", - "subtitle": "Velg skip for denne loggboken. Reisedager bruker seil- og tankdata fra valgt skip.", - "active_vessel": "Skip for denne loggboken", - "no_vessels_in_pool": "Ingen skip i flåten – legg til i brukerprofilen først.", - "no_vessel": "Ingen skip valgt", + "title": "Fartøy for denne loggboken", + "subtitle": "Velg skipet for denne loggboken. Reisedagene bruker seil- og drivstoffdataene for det valgte skipet.", + "active_vessel": "Fartøy for denne loggboken", + "no_vessels_in_pool": "Ingen skip i flåten – opprett først i brukerprofilen.", + "no_vessel": "Ingen båt valgt", "unnamed": "Uten navn", "save": "Lagre skip", - "saved": "Loggbok-skip lagret.", - "selection_only_hint": "Du ser skipet eieren har valgt (delt loggbok).", + "saved": "Skipet er lagret i loggboken.", + "selection_only_hint": "Du ser båten som eieren har valgt (delt loggbok).", "manage_in_profile": "Administrer skip i brukerprofilen" }, "person_pool": { - "title": "Stamm-Crew og skippere", - "subtitle": "Hold personpoolen din her – skippere og crew for alle loggbøker. Velg aktivt crew per loggbok og reisedag fra poolen.", - "loading": "Laster personpool…", - "skippers_section": "Skippere", - "crew_section": "Stamm-Crew", + "title": "Fast mannskap og skipper", + "subtitle": "Opprett din personellpool her – skippere og mannskap for alle loggbøker. Fra denne poolen velger du det aktive mannskapet for hver loggbok og hver reisedag.", + "loading": "Brukerpoolen lastes inn…", + "skippers_section": "Faste skippere", + "crew_section": "Fast mannskap", "add_skipper": "Legg til skipper", - "add_crew": "Legg til Crew-medlem", + "add_crew": "Legg til et besetningsmedlem", "edit_skipper": "Rediger skipper", - "no_skippers": "Ingen skipper i poolen ennå.", - "no_crew": "Ingen Crew-medlemmer i poolen ennå.", - "delete_confirm": "Fjerne denne personen fra poolen?" + "no_skippers": "Det er ingen skipper i puljen ennå.", + "no_crew": "Det er ingen besetningsmedlemmer i puljen ennå.", + "delete_confirm": "Vil du virkelig fjerne denne personen fra gruppen?" }, "logbook_crew": { - "title": "Crew for denne loggboken", - "subtitle": "Velg skipper og crew for denne loggboken. Nye reisedager arver valget som standard.", - "loading": "Laster crew…", + "title": "Mannskapet for denne loggboken", + "subtitle": "Velg skipper og mannskap for denne loggboken. Nye reisedager overtar dette valget som standard.", + "loading": "Mannskapet lastes inn…", "active_skipper": "Skipper for denne loggboken", - "active_crew": "Crew for denne loggboken", - "no_skippers_in_pool": "Ingen skipper i poolen – legg til i brukerprofilen først.", - "no_crew_in_pool": "Ingen crew i poolen – legg til i brukerprofilen først.", - "no_skipper": "Ingen skipper valgt", + "active_crew": "Mannskapet for denne loggboken", + "no_skippers_in_pool": "Ingen skipper i databasen – opprett først i brukerprofilen.", + "no_crew_in_pool": "Ingen mannskap i bassenget – opprett først i brukerprofilen.", + "no_skipper": "Ingen skipper er valgt", "unnamed": "Uten navn", - "save": "Lagre crew", - "saved": "Loggbok-Crew lagret.", - "selection_only_hint": "Du ser crewet eieren har valgt (delt loggbok)." + "save": "Lagre mannskap", + "saved": "Mannskapet er lagret i loggboken.", + "selection_only_hint": "Du ser besetningen som eieren har fastsatt (delt loggbok)." }, "entry_crew": { - "title": "Crew på denne reisedagen", - "subtitle": "Kan avvike fra loggbokstandard. Følgende dager arver fra forrige dag.", + "title": "Mannskapet på denne reisedagen", + "subtitle": "Kan avvike fra standarden i loggboken. De påfølgende reisedagene overtar dataene fra dagen før.", "day_skipper": "Skipper denne dagen", - "day_crew": "Crew denne dagen", - "no_skipper": "Ingen skipper valgt", - "no_crew": "Ingen crew valgt" + "day_crew": "Mannskapet denne dagen", + "no_skipper": "Ingen skipper er valgt", + "no_crew": "Ingen mannskap valgt" }, "crew": { - "title": "Skipper- og Crew-profiler", + "title": "Skipper- og mannskapsprofiler", "skipper_section": "Skipperprofil", - "skipper_read_only_hint": "Skipperprofilen kan bare redigeres av eieren av loggboken.", - "crew_section": "Crew-liste", - "add_crew": "Legg til Crew-medlem", - "edit_crew": "Rediger Crew-medlem", - "no_crew": "Ingen Crew-medlemmer er lagt til ennå.", - "max_crew": "Maksimalt antall på 12 Crew-medlemmer i poolen er nådd.", + "skipper_read_only_hint": "Skipperprofilen kan kun redigeres av loggbokens eier.", + "crew_section": "Mannskapsliste", + "add_crew": "Legg til et besetningsmedlem", + "edit_crew": "Rediger besetningsmedlem", + "no_crew": "Det er ikke lagt til noen besetningsmedlemmer ennå.", + "max_crew": "Det maksimale antallet på 12 besetningsmedlemmer i gruppen er nådd.", "name": "Navn", - "address": "adresse", + "address": "Adresse", "birthdate": "Bursdag", "phone": "Telefonnummer", "nationality": "Nasjonalitet", "passport": "Pass-/ID-nummer", - "bloodtype": "Blodgruppe", + "bloodtype": "Blodtype", "allergies": "Allergier", - "diseases": "Eksisterende tilstander/sykdommer", - "save": "Lagre skipperdata", + "diseases": "Tidligere sykdommer / sykdommer", + "save": "Lagre skipperopplysninger", "save_member": "Lagre medlem", - "saved": "Skipperprofilen er vellykket lagret!", - "loading": "Crew-filene er lastet inn...", - "delete_confirm": "Er du sikker på at du vil fjerne dette Crew-medlemmet?" + "saved": "Skipper-profilen er lagret!", + "loading": "Crew-filer lastes inn...", + "delete_confirm": "Er du sikker på at du vil fjerne dette crew-medlemmet?" }, "deviation": { - "title": "Tabell over kompassavvik", - "subtitle": "Angi den magnetiske kompassavbøyningen (avbøyning) for kurser (MgK) fra 000° til 360° i trinn på 10°.", + "title": "Avvikstabell (kompassavvik)", + "subtitle": "Fyll inn magnetkompassavviket (Abl.) for kurser (MgK) fra 000° til 360° i trinn på 10°.", "heading": "MgK", "deviation": "Distraksjon", - "save": "Lagre kalibreringsrutenettet", - "saving": "...vil bli reddet...", - "saved": "Kalibreringsrutenettet er vellykket lagret!", - "loading": "Kalibreringstabellen er lastet inn..." + "save": "Lagre kalibreringsrutenett", + "saving": "Lagrer...", + "saved": "Kalibreringsrutenettet er lagret!", + "loading": "Kalibreringstabellen lastes inn..." }, "settings": { "title": "Innstillinger for loggbok", - "subtitle": "Del, sikkerhetskopier og samarbeid for denne loggboken.", + "subtitle": "Deling, sikkerhetskopiering og samarbeid for denne loggboken.", "select_logbook_hint": "Velg en loggbok for å redigere innstillingene.", - "no_key": "Ingen OpenWeatherMap API-nøkkel tilgjengelig. Lagre din egen nøkkel i brukerprofilen, eller kontakt operatøren.", - "weather_success": "Værdata vellykket hentet!", + "no_key": "Ingen OpenWeatherMap-API-nøkkel tilgjengelig. Legg inn en egen nøkkel i brukerprofilen, eller kontakt operatøren.", + "weather_success": "Værdataene er hentet!", "weather_error": "Henting av værdata mislyktes. Kontroller API-nøkkelen og tilkoblingen.", "weather_unauthorized": "Henting av værdata mislyktes. API-nøkkelen er ugyldig eller ikke autorisert.", - "weather_not_found": "Henting av værdata mislyktes. Den angitte posisjonen eller koordinatene ble ikke funnet.", - "weather_bad_request": "Henting av værdata mislyktes. Ingen posisjon eller GPS-koordinater ble angitt.", - "weather_date_mismatch": "Værdata kan bare hentes ut for i dag ({{today}}). Denne loggbokoppføringen er datert {{date}}.", - "gps_error": "Vennligst skriv inn en posisjon eller finn GPS-koordinatene.", + "weather_not_found": "Henting av værdata mislyktes. Det angitte stedet eller koordinatene ble ikke funnet.", + "weather_bad_request": "Henting av værdata mislyktes. Det ble ikke angitt noe sted eller noen GPS-posisjon.", + "weather_date_mismatch": "Værdata kan kun hentes for dagens dato ({{today}}). Denne loggoppføringen er datert {{date}}.", + "gps_error": "Oppgi et sted eller finn GPS-koordinatene.", "share_title": "Del loggbok (skrivebeskyttet)", - "share_desc": "Aktiver dette alternativet for å opprette en offentlig, skrivebeskyttet lenke. Alle som har denne lenken, kan se seilasene, båtprofilene og crewet ditt. Krypteringsnøklene overføres aldri til serveren (de forblir i hash-delen av URL-en).", - "share_privacy_warning": "Anbefaling: Del denne lenken kun privat (f.eks. via e-post eller messenger), ikke på sosiale medier.", + "share_desc": "Aktiver dette alternativet for å opprette en offentlig, skrivebeskyttet lenke. Alle som har lenken, kan se dine reiser, yachtprofiler og mannskap. Krypteringsnøklene overføres aldri til serveren (de forblir i hash-delen av URL-en).", + "share_privacy_warning": "Anbefaling: Del denne lenken kun privat (f.eks. via e-post eller meldingstjenester), ikke på sosiale medier.", "share_enable": "Aktiver offentlig lenke", - "share_copied": "Linken er kopiert!", - "share_copy_btn": "Kopier lenke", - "link_qr_hint": "Skann QR-koden med telefonen", + "share_copied": "Koblingen er kopiert!", + "share_copy_btn": "Kopier lenken", + "link_qr_hint": "QR-kode som kan skannes med smarttelefonen", "link_qr_alt": "QR-kode for lenken", - "danger_zone_title": "Faresone", - "danger_zone_desc": "Hvis du sletter kontoen din, slettes alle dine Passkeys, loggbøker, skipsdata, Crew-profiler, reiseoppføringer og E2E-nøkler ugjenkallelig. Denne handlingen kan ikke angres.", - "delete_account_btn": "Slett konto ugjenkallelig", - "delete_account_confirm_title": "Slett konto?", - "delete_account_confirm_desc": "Er du helt sikker på at du vil slette kontoen din og alle tilknyttede loggbøker og E2E-krypterte data ugjenkallelig?", - "delete_account_confirm_yes": "Ja, slett konto og alle data", + "danger_zone_title": "Fareområde", + "danger_zone_desc": "Når du sletter kontoen din, blir alle dine Passkey-er, loggbøker, skipdata, mannskapsprofiler, reiseoppføringer og E2E-nøkler slettet permanent. Denne handlingen kan ikke angres.", + "delete_account_btn": "Slette kontoen permanent", + "delete_account_confirm_title": "Slette kontoen?", + "delete_account_confirm_desc": "Er du helt sikker på at du vil slette kontoen din og alle tilhørende loggbøker og E2E-krypterte data permanent?", + "delete_account_confirm_yes": "Ja, slett kontoen og alle opplysningene", "delete_account_confirm_no": "Avbryt", - "delete_account_failed": "Kontoen kunne ikke slettes. Vennligst prøv igjen.", + "delete_account_failed": "Kontoen kunne ikke slettes. Prøv på nytt.", "delete_backup_hint": "Tips: Lag sikkerhetskopier av loggbøkene dine (.daagbok) i innstillingene for hver loggbok før du sletter dem.", - "deleting_account": "Kontoen vil bli slettet...", - "invite_push_prompt_title": "Aktivere push-varsler?", - "invite_push_prompt_message": "Så snart inviterte Crew-medlemmer synkroniserer endringer, kan du bli informert via push. Ingen loggbokinnhold sendes i ren tekst.", - "invite_push_prompt_ios_message": "Så snart Crew-medlemmene synkroniserer endringer, kan du bli informert via push. På iPhone/iPad: Legg til appen på startskjermen (iOS 16.4+), og aktiver deretter push i brukerprofilen.", + "deleting_account": "Kontoen blir slettet…", + "invite_push_prompt_title": "Vil du aktivere push-varsler?", + "invite_push_prompt_message": "Så snart inviterte besetningsmedlemmer synkroniserer endringer, kan du få beskjed via push-varsel. Innholdet i loggboken sendes ikke i klartekst.", + "invite_push_prompt_ios_message": "Så snart teammedlemmer synkroniserer endringer, kan du få beskjed via push-varsel. På iPhone/iPad: Legg til appen på startskjermen (iOS 16.4+), og aktiver deretter push-varsler i brukerprofilen.", "invite_push_prompt_enable": "Aktiver nå", "invite_push_prompt_later": "Senere", - "invite_push_prompt_success": "Push-varsler er aktive på denne enheten.", + "invite_push_prompt_success": "Push-varsler er aktivert på denne enheten.", "backup_title": "Sikkerhetskopiering og gjenoppretting", - "backup_desc": "Fullstendig kryptert sikkerhetskopi av denne loggboken (oppføringer, bilder, GPS-spor, crew, skip). Beskyttet med sikkerhetskopieringspassord - for gjenoppretting til denne eller en ny konto.", - "backup_export_title": "Opprett sikkerhetskopi", - "backup_export_desc": "Laster ned alle lokale data som et komprimert .daagbok-arkiv. Hold filen og passordfrasen adskilt og sikker.", + "backup_desc": "Fullstendig kryptert sikkerhetskopi av denne loggboken (oppføringer, bilder, talemeldinger, GPS-spor, mannskap, skip). Beskyttet med sikkerhetskopipassord — for gjenoppretting på denne eller en ny konto.", + "backup_export_title": "Ta sikkerhetskopi", + "backup_export_desc": "Laster ned alle lokale data som en komprimert .daagbok-fil. Oppbevar filen og passordfrasen separat og på et sikkert sted.", "backup_restore_title": "Gjenopprett sikkerhetskopi", - "backup_restore_desc": "Gjenoppretter en sikkerhetskopi til din nåværende konto - selv etter at du har registrert en ny konto.", - "backup_passphrase": "Passord for sikkerhetskopiering", + "backup_restore_desc": "Gjenopprett en sikkerhetskopi i din nåværende konto — selv etter at du har opprettet en ny konto.", + "backup_passphrase": "Sikkerhetskode for sikkerhetskopi", "backup_passphrase_placeholder": "Minst 8 tegn", "backup_passphrase_confirm": "Bekreft passordfrasen", - "backup_passphrase_short": "Passordfrasen for sikkerhetskopiering må være på minst 8 tegn.", - "backup_passphrase_mismatch": "Passordfraser stemmer ikke overens.", - "backup_wrong_passphrase": "Passordfrasen er feil eller sikkerhetskopien er ødelagt.", + "backup_passphrase_short": "Sikkerhetsfrasen må bestå av minst 8 tegn.", + "backup_passphrase_mismatch": "Passordsetningene stemmer ikke overens.", + "backup_wrong_passphrase": "Feil passordfrase eller ødelagt sikkerhetskopi.", "backup_export_btn": "Last ned sikkerhetskopi", - "backup_exporting": "Sikkerhetskopien er opprettet...", + "backup_exporting": "Sikkerhetskopiering pågår…", "backup_export_success": "Sikkerhetskopi opprettet ({{count}} reisedager).", "backup_file_label": "Sikkerhetskopifil (.daagbok)", - "backup_export_progress": "Pakker filer {{current}} / {{total}}…", - "backup_invalid_archive": "Filen er ikke et gyldig backup-arkiv.", - "backup_version_unsupported": "Gammelt backup-format (v1). Bruk en aktuell .daagbok-sikkerhetskopi.", - "backup_import_size_confirm": "Denne sikkerhetskopien er ca. {{size}} ukomprimert. Gjenoppretting kan ta lengre tid. Fortsette?", - "backup_stat_voice": "{{count}} talemeldinger", - "backup_stat_size": "Ca. {{size}} ukomprimert", - "backup_preview_btn": "Sjekk innhold", - "backup_previewing": "Sjekk...", + "backup_export_progress": "Pakke filer {{current}} / {{total}}…", + "backup_invalid_archive": "Filen er ikke et gyldig sikkerhetskopiarkiv.", + "backup_version_unsupported": "Gammelt sikkerhetskopiformat (v1). Bruk en oppdatert .daagbok-sikkerhetskopi.", + "backup_import_size_confirm": "Denne sikkerhetskopien er omtrent {{size}} stor. Gjenoppretting på enheten kan ta lengre tid og bruke mye lagringsplass. Vil du fortsette?", + "backup_stat_voice": "{{count}} Talemeldinger", + "backup_stat_size": "Ukomprimert ca. {{size}}", + "backup_preview_btn": "Kontroller innholdet", + "backup_previewing": "Sjekk…", "backup_restore_btn": "Gjenopprett", - "backup_restoring": "Vil bli restaurert...", - "backup_restore_success": "Loggbok \"{{title}}\" er gjenopprettet.", - "backup_restore_cancelled": "Gjenoppretting avlyst.", + "backup_restoring": "Gjenopprettes…", + "backup_restore_success": "Loggboken «{{title}}» er gjenopprettet.", + "backup_restore_cancelled": "Gjenopprettingen ble avbrutt.", "backup_invalid_json": "Filen er ikke en gyldig JSON-fil.", "backup_invalid_format": "Ukjent eller utdatert sikkerhetskopiformat.", - "backup_not_owner": "Det er bare eieren av loggboken som kan opprette sikkerhetskopier.", + "backup_not_owner": "Bare loggbokens eier kan ta sikkerhetskopier.", "backup_not_authenticated": "Vennligst logg inn for å gjenopprette en sikkerhetskopi.", "backup_id_conflict": "Det finnes allerede en loggbok med denne ID-en.", - "backup_overwrite_confirm": "Den eksisterende loggboken med samme ID erstattes. Fortsette?", - "backup_new_id_confirm": "Importere sikkerhetskopien som en ny loggbok med ny ID?", + "backup_overwrite_confirm": "Den eksisterende loggboken med samme ID vil bli erstattet. Vil du fortsette?", + "backup_new_id_confirm": "Skal sikkerhetskopien importeres som en ny logg med ny ID?", "backup_stat_entries": "{{count}} Reisedager", "backup_stat_photos": "{{count}} Bilder", - "backup_stat_crew": "{{count}} Crew-poster", - "backup_stat_tracks": "{{count}} GPS-spor", + "backup_stat_crew": "{{count}} Crew-oppføringer", + "backup_stat_tracks": "{{count}} GPS-ruter", "backup_exported_at": "Eksportert: {{date}}" }, "disclaimer": { - "title": "Viktige merknader", - "intro": "Vennligst les følgende instruksjoner før du bruker Kapteins Daagbok.", - "e2e_title": "Ende-til-ende-kryptering", - "e2e_body": "Loggbokdataene dine er kryptert fra ende til ende. Bare du - eller personer med din nøkkel - kan lese innholdet. Kun krypterte data lagres på serveren.", - "pwa_title": "Progressiv webapp (PWA)", - "pwa_body": "Kapteins Daagbok kjører som en progressiv webapp i nettleseren din og kan installeres på enheten din - på samme måte som en native-app, men uten en appbutikk.", + "title": "Viktige opplysninger", + "intro": "Les følgende opplysninger før du bruker Kapteins Daagbok.", + "e2e_title": "End-til-ende-kryptering", + "e2e_body": "Loggboksdataene dine krypteres fra ende til ende. Bare du – eller personer som har nøkkelen din – kan lese innholdet. Det lagres utelukkende krypterte data på serveren.", + "pwa_title": "Progressiv nettapp (PWA)", + "pwa_body": "Kapteins Daagbok kjører som en progressiv nettapp i nettleseren din og kan installeres på enheten din – på samme måte som en innfødt app, men uten appbutikk.", "storage_title": "Lokal lagring og synkronisering", - "storage_body": "Dataene dine lagres lokalt på enheten din (IndexedDB). Endringer synkroniseres med serveren når en Internett-tilkobling er aktiv. Du kan fortsette å jobbe uten tilkobling, synkroniseringen skjer senere.", - "free_title": "Gratis og reklamefri", + "storage_body": "Dataene dine lagres midlertidig lokalt på enheten din (IndexedDB). Når du har en aktiv internettforbindelse, synkroniseres endringene med serveren. Du kan fortsette å jobbe uten nettilgang; synkroniseringen skjer senere.", + "free_title": "Gratis og uten reklame", "free_body": "Kapteins Daagbok er gratis og inneholder ingen reklame.", "liability_title": "Ansvarsfraskrivelse", - "liability_body": "Bruk av appen skjer på eget ansvar. Vi fraskriver oss ethvert ansvar for skader som oppstår som følge av bruk av appen - inkludert feilaktige eller ufullstendige loggbokoppføringer, tap av data eller tekniske feil.", + "liability_body": "Bruken skjer på eget ansvar. Vi påtar oss ikke noe ansvar for skader som oppstår som følge av bruken av appen – herunder feilaktige eller ufullstendige loggoppføringer, tap av data eller tekniske feil.", "warranty_title": "Ingen garanti", - "warranty_body": "Det gis ingen garanti for tjenestens funksjon, korrekthet eller tilgjengelighet. Driften kan når som helst bli avbrutt, begrenset eller kansellert.", + "warranty_body": "Det gis ingen garanti for tjenestens funksjon, nøyaktighet eller tilgjengelighet. Driften kan når som helst bli avbrutt, begrenset eller innstilt.", "copyright": "© 2026 KnorrLabs, Markus F.J. Busche", "accept": "Godta og fortsett", "close": "Lukk", @@ -896,59 +898,59 @@ }, "feedback": { "button_title": "Send tilbakemelding", - "title": "Tilbakemeldinger", - "intro": "Del feil, ideer eller generelle tilbakemeldinger. Meldingen din vil bli sendt til prosjektteamet via en sikker varslingskanal.", + "title": "Tilbakemelding", + "intro": "Del feil, ideer eller generelle tilbakemeldinger. Meldingen din blir sendt til prosjektteamet via en sikker meldingskanal.", "category_label": "Kategori", "category_general": "Generelt", "category_bug": "Rapporter feil", - "category_feature": "Forespørsel om funksjonalitet", + "category_feature": "Ønsket funksjon", "category_translation": "Oversettelsesfeil", "contact_label": "E-post (valgfritt)", "contact_placeholder": "deine@email.beispiel", "message_label": "Melding", - "message_placeholder": "Beskriv tilbakemeldingene dine...", + "message_placeholder": "Beskriv tilbakemeldingen din…", "send": "Send", - "sending": "Vil bli sendt...", + "sending": "Sendes…", "cancel": "Avbryt", - "success": "Tusen takk skal du ha! Tilbakemeldingen din er sendt.", - "error_send": "Tilbakemelding kunne ikke sendes. Vennligst prøv igjen senere.", - "error_invalid_email": "Vennligst skriv inn en gyldig e-postadresse.", + "success": "Tusen takk! Tilbakemeldingen din er sendt.", + "error_send": "Tilbakemeldingen kunne ikke sendes. Prøv igjen senere.", + "error_invalid_email": "Vennligst oppgi en gyldig e-postadresse.", "error_not_configured": "Tilbakemelding er ikke tilgjengelig på denne serveren.", - "error_rate_limited": "For mange tilbakemeldinger på kort tid. Vennligst vent noen minutter.", + "error_rate_limited": "Det er for mange tilbakemeldinger på kort tid. Vennligst vent noen minutter.", "error_spam": "Denne meldingen kunne ikke sendes. Vennligst omformuler den." }, "demo": { - "logbook_title": "Demologgbok Østersjøen", + "logbook_title": "Demologg for Østersjøen", "badge": "Demo", "public_banner": "Skrivebeskyttet demovisning", "cta_register": "Opprett konto", - "back_to_login": "Til registreringen" + "back_to_login": "Til påmelding" }, "invitation": { "error_invalid_key": "Invitasjonslenken er kryptografisk ugyldig (feil nøkkel).", - "error_missing_key": "Invitasjonslenken inneholder ikke en dekrypteringsnøkkel (#key=...). Vennligst bruk den fullstendige lenken fra eieren.", + "error_missing_key": "Invitasjonslenken inneholder ingen dekrypteringsnøkkel (#key=...). Bruk den fullstendige lenken fra eieren.", "error_expired": "Denne invitasjonen har utløpt (gyldig i 48 timer).", "error_invalid_token": "Invitasjonstokenet er ugyldig.", - "error_load_failed": "Invitasjonsdetaljer kunne ikke lastes inn.", - "error_incomplete_session": "Økten er ufullstendig - vennligst logg inn på nytt (bruker-ID mangler).", - "error_accept_failed": "Tiltredelse mislyktes.", - "error_login_failed": "Passkey Innlogging mislyktes.", - "error_username_missing": "Brukernavnet ble ikke funnet - vennligst logg inn på nytt.", - "error_register_failed": "Registrering mislyktes.", - "loading_joining": "Bli med...", - "loading_checking": "Invitasjonen vil bli sjekket...", - "loading_unlocking": "Loggboken er låst opp og synkronisert...", - "loading_retrieving_key": "Last ned krypteringsnøkkelen...", - "error_title": "Feil i invitasjonen", - "back_to_start": "Tilbake til start", + "error_load_failed": "Det var ikke mulig å laste inn invitasjonsdetaljene.", + "error_incomplete_session": "Påloggingen er ikke fullført — vennligst logg inn på nytt (bruker-ID mangler).", + "error_accept_failed": "Registreringen mislyktes.", + "error_login_failed": "Passkey-påloggingen mislyktes.", + "error_username_missing": "Brukernavnet kunne ikke identifiseres — vennligst logg inn på nytt.", + "error_register_failed": "Registreringen mislyktes.", + "loading_joining": "Bli medlem...", + "loading_checking": "Invitasjonen blir sjekket...", + "loading_unlocking": "Loggboken aktiveres og synkroniseres...", + "loading_retrieving_key": "Laster krypteringsnøkkel...", + "error_title": "Invitasjonsfeil", + "back_to_start": "Tilbake til starten", "title": "Invitasjon til loggbok", "invited_by": "Invitasjon fra", "vessel_logbook": "Skip / Loggbok", - "signed_in_preparing": "Registrert som {{username}}. Tilslutning er under forberedelse...", - "join_again": "Bli med igjen", - "login_or_register_hint": "Logg inn eller registrer en konto for å bli med i loggboken.", - "or_sign_up": "ELLER REGISTRER DEG PÅ NYTT", - "register_crew_account": "Opprett en ny crew-konto", + "signed_in_preparing": "Logg inn som {{username}}. Opprettelse av konto pågår...", + "join_again": "Bli medlem igjen", + "login_or_register_hint": "Logg inn eller opprett en konto for å bli med i loggboken.", + "or_sign_up": "ELLER REGISTRER DEG", + "register_crew_account": "Opprett ny mannskapskonto", "username_label": "Brukernavn", "create_passkey": "Opprett Passkey", "switch_language_en": "Engelsk", @@ -956,34 +958,34 @@ }, "stats": { "title": "Statistikk", - "subtitle": "Oversikt over ruter, forbruk og kjøretype", - "scope_label": "Evalueringsområde", + "subtitle": "Rangering, forbruk og drivtype på et øyeblikk", + "scope_label": "Analyseområde", "scope_logbook": "Denne loggboken", "scope_account": "Alle loggbøker", - "loading": "Statistikken er beregnet...", - "no_data": "Ingen reisedager tilgjengelig ennå.", - "total_distance": "Total avstand", + "loading": "Statistikken beregnes…", + "no_data": "Det er ingen reisedager ennå.", + "total_distance": "Total lengde", "travel_days": "Reisedager", "sail_distance": "Under seil", - "motor_distance": "Maskinreise", - "motor_hours_total": "Totalt antall maskintimer", - "daily_motor_hours": "Maskintimer per reisedøgn", - "avg_motor_hours": "Ø maskintimer per reisedøgn", + "motor_distance": "Maskinkjøring", + "motor_hours_total": "Totalt antall driftstimer", + "daily_motor_hours": "Maskin timer per reisedag", + "avg_motor_hours": "Ø Maskin timer per reisedag", "unknown_propulsion": "Ukjent", "fuel_total": "Totalt drivstoff", - "water_total": "Totalt vann", - "daily_etmal": "Daglige tider", - "daily_consumption": "Daglig forbruk", + "water_total": "Vann totalt", + "daily_etmal": "Daglige etmaler", + "daily_consumption": "Dagsforbruk", "route_overview": "Rute", - "route_map_title": "Oversikt over ruten", - "propulsion_title": "Seil vs. maskin", - "propulsion_hint": "Fordelingen er basert på loggbokhendelser per reisedag, ikke på GPS-segmenter.", - "avg_distance": "Ø per reisedag", + "route_map_title": "Oversikt over ruter", + "propulsion_title": "Seil vs. motor", + "propulsion_hint": "Inndelingen er basert på loggbokhendelser per reisedag, ikke på GPS-segmenter.", + "avg_distance": "Gjennomsnitt per reisedag", "avg_fuel": "Ø Drivstoff", "avg_water": "Ø Vann", - "fuel_per_nm": "Drivstoff per sm", - "fuel_per_motor_hour": "Drivstoff per maskintime", - "daily_fuel_per_motor_hour": "Drivstofforbruk per maskintime per kjøredag", + "fuel_per_nm": "Drivstoff per nautisk mil", + "fuel_per_motor_hour": "Drivstoff per driftstime", + "daily_fuel_per_motor_hour": "Drivstoffforbruk per maskintime per reisedag", "fuel_legend": "Drivstoff", "water_legend": "Vann", "unit_nm": "sm", @@ -997,81 +999,81 @@ "event_series_pressure": "Lufttrykk", "event_series_wind": "Vind", "event_series_motor": "Motor", - "event_series_empty": "Ingen oppføringer ennå." + "event_series_empty": "Ingen oppføringer." }, "tour": { - "skip": "Hopp over turen", + "skip": "Hopp over omvisningen", "back": "Tilbake", "next": "Videre", "finish": "Ferdig", - "progress": "Trinn {{current}} fra {{total}}", + "progress": "Trinn {{current}} av {{total}}", "steps": { "welcome": { "title": "Velkommen om bord!", - "body": "Vi har laget en demo-loggbok med tre dagers reise i Kielfjorden for deg. Du kan når som helst slette eksempeloppføringene hvis du vil starte din egen loggbok. Denne korte omvisningen viser deg de viktigste funksjonene." + "body": "Vi har opprettet en demo-loggbok for deg med tre reisedager i Kielerfjorden. Du kan når som helst slette eksemplene på oppføringene hvis du ønsker å begynne med din egen loggbok. Denne korte turen viser deg de viktigste funksjonene." }, "welcome_public": { "title": "Velkommen om bord!", - "body": "Utforsk vår demologgbok med tre dagers reise i Kielfjorden – uten konto. Omvisningen viser loggbokoppføringer og valg av skip og crew for denne loggboken. Flåte og stamm-crew legger du inn senere i brukerprofilen." + "body": "Utforsk vårt demo-loggbok med tre reisedager i Kielerfjorden – helt uten å opprette en konto. Turen viser deg loggbokoppføringer samt valg av skip og mannskap for denne loggboken. Du kan oppdatere flåten og fast mannskap senere i brukerprofilen." }, "nav_logs": { "title": "Loggbokoppføringer", - "body": "Her administrerer du reisedagene dine - avreise, destinasjon, vær, drivstoffnivå og GPS-spor." + "body": "Her kan du administrere reisedagene dine – avreise, destinasjon, vær, drivstoffnivåer og GPS-spor." }, "entry_list": { - "title": "Dine reisedager", - "body": "Hvert kort representerer en reisedag. Trykk på en oppføring for å vise eller redigere detaljer." + "title": "Reisedagene dine", + "body": "Hvert kort representerer en reisedag. Trykk på en oppføring for å se eller redigere detaljene." }, "entry_open": { - "title": "Åpen reisedag", - "body": "Slik ser en fullført loggbok ut - med hendelser, tanknivåer og mer." + "title": "Åpne reisedag", + "body": "Slik ser en utfylt loggoppføring ut – med hendelser, drivstoffnivåer og mer." }, "entry_track": { - "title": "GPS-sporing", - "body": "Last opp GPX-filer eller se allerede lagrede ruter på kartet - inkludert avstand og hastighet." + "title": "GPS-spor", + "body": "Last opp GPX-filer eller se allerede lagrede ruter på kartet – inkludert avstand og hastighet." }, "nav_vessel": { - "title": "Skip for loggbok", - "body": "Velg skip fra flåten for denne loggboken. Administrer skip i brukerprofilen under Flåte og crew." + "title": "Skip til loggboken", + "body": "Velg hvilket skip fra flåten din som skal brukes i denne loggboken. Du kan administrere skipene dine i brukerprofilen under «Flåte og mannskap»." }, "profile_vessel_pool": { "title": "Skipsflåte", - "body": "I brukerprofilen legger du inn alle skip – charter, eget båt osv. Velg deretter riktig skip per loggbok." + "body": "I brukerprofilen oppretter du alle båtene dine – leiebåter, egen båt osv. For hver loggbok velger du deretter den aktuelle båten." }, "profile_crew_pool": { - "title": "Stamm-Crew og skippere", - "body": "I brukerprofilen vedlikeholder du en personpool – flere skippere (f.eks. charter) og crew for alle loggbøker." + "title": "Fast mannskap og skipper", + "body": "I brukerprofilen din administrerer du din personpool – flere skippere (f.eks. ved charter) og besetningsmedlemmer for alle loggbøker." }, "nav_logbook_crew": { - "title": "Crew per loggbok", - "body": "Velg skipper og crew fra poolen for denne loggboken. Reisedager arver valget som standard." + "title": "Mannskap per loggbok", + "body": "Velg fra listen hvem som skal regnes som skipper og mannskap i denne loggboken. Reisedagene overtar dette valget som standard." }, "nav_stats": { - "title": "Dashbord for statistikk", - "body": "Her kan du se kjørelengder, drivstofforbruk, rutekart og kjøreandeler - automatisk beregnet ut fra loggbokoppføringene dine." + "title": "Statistikk-oversikt", + "body": "Her ser du kjørelengde, drivstoffforbruk, rutekart og drivstofffordeling – beregnet automatisk ut fra oppføringene i loggboken din." }, "nav_feedback": { "title": "Send tilbakemelding", - "body": "Du kan bruke dette skjemaet til å sende feil, ideer eller generelle tilbakemeldinger direkte til prosjektteamet - også etter omvisningen, når som helst ved hjelp av ikonet øverst til høyre." + "body": "Gjennom dette skjemaet kan du sende feilmeldinger, forslag eller generell tilbakemelding direkte til prosjektteamet – også etter turen, når som helst via ikonet øverst til høyre." }, "nav_profile": { - "title": "Din brukerprofil", - "body": "Du får tilgang til din personlige profil via skipperknappen øverst - uavhengig av hvilken loggbok du bruker." + "title": "Brukerprofilen din", + "body": "Ved å klikke på Skipper-knappen øverst kommer du til din personlige profil – uavhengig av den aktuelle loggboken." }, "profile_preferences": { - "title": "Regnskap og presentasjon", - "body": "Her kan du administrere kontoidentitet, tema og lys/mørk modus. Du kan når som helst starte appturen på nytt. Passkeys og sikkerhetsinnstillinger finner du lenger ned i profilen." + "title": "Konto og visning", + "body": "Her kan du administrere kontoidentiteten din, temaet og lys/mørk-modus. Du kan starte app-omvisningen på nytt når som helst. Passkeys og sikkerhetsinnstillinger finner du lenger ned i profilen." }, "finish": { "title": "Greit!", - "body": "Du kommer rett til statistikkoversikten. Du kan når som helst starte turen på nytt i brukerprofilen din. Ha en riktig god tur!" + "body": "Du kommer straks til statistikkpanelet. Du kan når som helst starte omvisningen på nytt i brukerprofilen. God tur!" } } }, "seo": { - "title": "Kapteins Daagbok - Gratis digital loggbok for fritidsbåter (uten reklame)", - "description": "Gratis, annonsefri digital loggbok med ende-til-ende-kryptering og Passkey-pålogging. Dokumenter seilingsdager, GPS-spor, Crew- og skipsdata på en sikker måte - også offline som PWA.", - "keywords": "Yachtloggbok, skipsloggbok, loggbok om bord, seiling, Passkey, E2E-kryptering, GPS-sporing, maritim loggbok, gratis, reklamefri, gratis, uten reklame", + "title": "Kapteins Daagbok – Gratis digitalt loggbok for yachter (uten reklame)", + "description": "Gratis, reklamefritt digitalt båtlogg med ende-til-ende-kryptering og Passkey-pålogging. Dokumenter reisedager, GPS-spor, mannskap og båtdata på en sikker måte – også offline som PWA.", + "keywords": "Yachtlogg, skipslogg, bordlogg, seiling, Passkey, E2E-kryptering, GPS-spor, maritim logg, gratis, uten reklame, gratis, uten annonser", "ogImageAlt": "Kapteins Daagbok Logo" } } diff --git a/client/src/i18n/locales/sv.json b/client/src/i18n/locales/sv.json index 5967f07..51dbebd 100644 --- a/client/src/i18n/locales/sv.json +++ b/client/src/i18n/locales/sv.json @@ -2,20 +2,22 @@ "translation": { "app": { "name": "Kapteins Daagbok", - "tagline": "Loggbok för privat yacht", + "tagline": "Privat båtlogg", "beta": "Beta", - "beta_hint": "Betaversion - funktioner kan fortfarande ändras" + "beta_hint": "Betaversion — Funktionerna kan komma att ändras" }, "footer": { "kofi_label": "Ko-fi", - "kofi_title": "Stöd projektet, vidareutveckling och driftskostnader på Ko-fi" + "kofi_title": "Stöd projektet, vidareutvecklingen och driftskostnaderna på Ko-fi" }, "languages": { "de": "Deutsch", "en": "English", "da": "Dansk", "sv": "Svenska", - "nb": "Norsk" + "nb": "Norsk", + "fr": "Français", + "es": "Español" }, "dialog": { "ok": "OK", @@ -23,24 +25,24 @@ "no": "Nej" }, "errors": { - "load_failed": "Data kunde inte laddas.", - "save_failed": "Ändringar kunde inte sparas.", - "delete_failed": "Radering misslyckades.", - "export_failed": "Export misslyckades." + "load_failed": "Det gick inte att ladda data.", + "save_failed": "Ändringarna kunde inte sparas.", + "delete_failed": "Raderingen misslyckades.", + "export_failed": "Exporten misslyckades." }, "common": { "unsaved_changes_title": "Osparade ändringar", - "unsaved_changes_message": "Du har ändringar som inte sparats. Vill du verkligen lämna sidan? Dina ändringar kommer att gå förlorade.", + "unsaved_changes_message": "Du har ändringar som inte har sparats. Vill du verkligen lämna sidan? Dina ändringar kommer att gå förlorade.", "unsaved_changes_stay": "Stanna kvar", - "unsaved_changes_save_leave": "Spara och lämna", - "unsaved_changes_discard": "Kasta", - "unsaved_changes_leave": "Övergivande" + "unsaved_changes_save_leave": "Spara och avsluta", + "unsaved_changes_discard": "Avvisa", + "unsaved_changes_leave": "Lämna" }, "nav": { - "dashboard": "Instrumentpanel", + "dashboard": "Instrumentpanelen", "vessel": "Fartygsdata", - "crew": "Crew", - "deviation": "Distraktionsbord", + "crew": "Besättning", + "deviation": "Avledningstabell", "logs": "Loggboksanteckningar", "stats": "Statistik", "settings": "Inställningar", @@ -48,279 +50,279 @@ }, "auth": { "welcome": "Välkommen till Kapteins Daagbok", - "tagline": "Din säkra, E2Ekrypterade loggbok för sjöfarten.", + "tagline": "Din säkra, E2E-krypterade sjöfartsloggbok.", "register": "Registrera dig med Passkey", "login": "Logga in med Passkey", "login_as": "Logga in som {{name}}", - "quick_login": "Snabb inloggning", - "forget_account": "Glömt konto på den här enheten", + "quick_login": "Snabbinloggning", + "forget_account": "Glömt ditt konto på den här enheten", "not_user": "Inte {{name}}?", "recovery_title": "Din återställningsnyckel", - "recovery_warning": "VIKTIGT: Skriv ner dessa 12 ord. Om du förlorar din Passkey och dessa ord kan dina data inte återställas.", + "recovery_warning": "VIKTIGT: Skriv ner dessa 12 ord. Om du tappar bort din Passkey och dessa ord går det inte att återställa dina data.", "confirm_recovery": "Jag har skrivit ner orden", "status_logged_in": "Inloggad", - "status_logged_out": "Avbruten", + "status_logged_out": "Utloggad", "copied": "Kopierat!", - "copy_phrase": "Kopiera tangent", + "copy_phrase": "Kopiera nyckel", "enter_recovery": "Ange återställningsnyckel", - "recovery_fallback_warning": "Din Passkey har autentiserats, men din enhet stöder inte maskinvarubaserad nyckelavledning. Ange din återställningsnyckel på 12 ord för att dekryptera din loggbok.", - "recovery_placeholder": "Ange din återställningsnyckel som består av 12 ord åtskilda av mellanslag...", + "recovery_fallback_warning": "Din Passkey har autentiserats, men din enhet stöder inte hårdvarubaserad nyckelgenerering. Ange din återställningsnyckel på 12 ord för att dekryptera din loggbok.", + "recovery_placeholder": "Ange din återställningsnyckel bestående av 12 ord, åtskilda med mellanslag...", "back": "Tillbaka", - "decrypting": "Dekryptering...", - "decrypt_logbook": "Dekryptera loggbok", - "error_incorrect_recovery": "Felaktig återställningsnyckel. Dekryptering misslyckades.", - "error_decryption_failed": "Dekrypteringen misslyckades. Vänligen kontrollera din återställningsnyckel.", - "or_register": "eller registrera dig", - "explore_demo": "Utforska demoversionen utan konto", - "username_placeholder": "Användarnamn / Skepparnamn", - "processing": "Bearbetning...", + "decrypting": "Avkodning...", + "decrypt_logbook": "Tolka loggboken", + "error_incorrect_recovery": "Felaktig återställningsnyckel. Dekrypteringen misslyckades.", + "error_decryption_failed": "Dekrypteringen misslyckades. Kontrollera din återställningsnyckel.", + "or_register": "eller Registrera dig", + "explore_demo": "Utforska demoversionen utan att skapa ett konto", + "username_placeholder": "Användarnamn / Skippernamn", + "processing": "Bearbetar...", "help": "Hjälp", - "setup_pin_title": "Ange lokal PIN-kod (tillval)", - "setup_pin_warning": "Eftersom din enhet inte stöder direkt härledning av Passkey-nycklar måste du annars ange din nyckel på 12 ord varje gång du loggar in på den här enheten. Konfigurera en lokal PIN-kod för att undvika detta.", - "pin_placeholder": "E.G. 123456", - "pin_label": "Lokal PIN-kod (4-8 siffror)", - "save_pin": "Spara PIN-kod och fortsätt", - "skip_pin": "Skip & använd återvinning", + "setup_pin_title": "Ställa in lokal PIN-kod (valfritt)", + "setup_pin_warning": "Eftersom din enhet inte stöder direkt Passkey-nyckelgenerering skulle du annars behöva ange din 12-ordsnyckel varje gång du loggar in på den här enheten. Ställ in en lokal PIN-kod för att undvika detta.", + "pin_placeholder": "T.ex. 123456", + "pin_label": "Lokal PIN-kod (4–8 siffror)", + "save_pin": "Spara PIN-kod & Fortsätt", + "skip_pin": "Hoppa över och använd återställning", "enter_pin_title": "Dekryptera med PIN-kod", - "enter_pin_warning": "Ange din lokala PIN-kod för att låsa upp dekrypteringsnyckeln på den här enheten.", + "enter_pin_warning": "Ange din lokala PIN-kod för att aktivera dekrypteringsnyckeln på den här enheten.", "enter_pin_placeholder": "Ange din PIN-kod...", - "decrypt_with_pin": "Dekryptera", - "use_recovery_instead": "Använd återställningsnycklar istället", - "error_incorrect_pin": "Felaktig PIN-kod. Dekryptering misslyckades.", - "error_invalid_host": "Passkeys fungerar inte via 127.0.0.1. Öppna appen via localhost.", + "decrypt_with_pin": "Avkoda", + "use_recovery_instead": "Använd istället återställningsnyckeln", + "error_incorrect_pin": "Felaktig PIN-kod. Dekrypteringen misslyckades.", + "error_invalid_host": "Passkey fungerar inte via 127.0.0.1. Öppna appen via localhost.", "use_localhost_link": "Byt till localhost", - "error_passkey_cancelled": "Passkey-inloggning avbröts eller gick ut. Försök igen.", - "error_invalid_rp_id": "Passkey-domänen matchar inte (RP ID). Använd http://localhost:5173 med RP_ID=localhost i .env för lokal utveckling.", - "error_session_incomplete": "Inloggning ofullständig. Logga in med passkey igen.", - "restore_checking": "Kontrollerar session…", + "error_passkey_cancelled": "Passkey-inloggningen avbröts eller har gått ut. Försök igen.", + "error_invalid_rp_id": "Passkey-domänen stämmer inte (RP-ID). Använd endast http://localhost:5173 med RP_ID=localhost i .env lokalt.", + "error_session_incomplete": "Inloggningen är ofullständig. Logga in igen med Passkey.", + "restore_checking": "Sessionen kontrolleras…", "restore_title": "Återställ session", - "restore_subtitle": "Du är fortfarande inloggad. Lås upp din loggbok med passkey eller PIN.", - "restore_unlocking": "Låser upp…", - "restore_with_passkey": "Lås upp med passkey ({{name}})", - "restore_with_pin": "Lås upp med PIN", - "restore_pin_warning": "Ange din lokala PIN för att låsa upp loggboken efter omladdning.", + "restore_subtitle": "Din registrering är fortfarande aktiv. Lås upp din loggbok med Passkey eller din PIN-kod.", + "restore_unlocking": "Låses upp…", + "restore_with_passkey": "Lås upp med Passkey ({{name}})", + "restore_with_pin": "Lås upp med PIN-kod", + "restore_pin_warning": "Ange din lokala PIN-kod för att låsa upp din loggbok efter omstarten.", "restore_other_account": "Logga in med ett annat konto" }, "pwa": { - "title": "Installera app", - "generic_benefit": "Installera Kapteins Daagbok på din enhet för snabbare åtkomst, offline-användning och permanent datalagring.", - "ios_instructions": "På iPad/iPhone: Lägg till appen på startskärmen så att dina loggboksdata förblir skyddade och appen startar som en inbyggd app.", - "ios_step_share": "Tryck på aktiesymbolen i fältet Safari.", - "ios_step_add": "Välj \"Gå till startskärmen\"", + "title": "Installera appen", + "generic_benefit": "Installera Kapteins Daagbok på din enhet för snabbare åtkomst, användning offline och permanent datalagring.", + "ios_instructions": "På iPad/iPhone: Lägg till appen på hemskärmen så att dina loggdata förblir skyddade och appen startar som en inbyggd app.", + "ios_step_share": "Tryck på delningsikonen i Safari-fältet", + "ios_step_add": "Välj ”Till startskärmen”", "install_now": "Installera nu", - "installing": "Installation...", + "installing": "Installation…", "later": "Senare", - "never": "Visa inte mer", - "platform_ios": "Installation via Safari.", + "never": "Visa inte längre", + "platform_ios": "Installation via Safari", "platform_android": "Installation via webbläsaren", - "platform_desktop": "Installation som en skrivbordsapp", - "settings_section": "Installation av app", + "platform_desktop": "Installation som skrivbordsapp", + "settings_section": "Appinstallation", "update_title": "Uppdatering tillgänglig", - "update_desc": "En ny version av Kapteins Daagbok är klar. Uppdatera för att få de senaste ändringarna.", - "update_now": "Uppdatering nu", - "update_reloading": "Laddar...", - "storage_persist_hint": "Webbläsaren kan radera offlinedata. Tillåt permanent lagring så att din loggbok förblir skyddad." + "update_desc": "En ny version av Kapteins Daagbok är tillgänglig. Uppdatera gärna för att få tillgång till de senaste ändringarna.", + "update_now": "Uppdatera nu", + "update_reloading": "Laddar…", + "storage_persist_hint": "Webbläsaren kan radera offline-data. Tillåt permanent lagring så att din logg förblir skyddad (i webbläsarinställningarna eller vid nästa meddelande)." }, "sync": { "status_synced": "Synkroniserad", - "status_syncing": "Synkronisera...", + "status_syncing": "Synkronisera…", "status_offline": "Offline-cache", - "status_unsynced": "Osynkroniserade förändringar", + "status_unsynced": "Icke-synkroniserade ändringar", "conflict_title": "Synkroniseringskonflikt", - "conflict_message": "{{count}} ändring(ar) kunde inte synkas (post {{id}}…). Välj vilken version som ska gälla.", - "conflict_use_server": "Använd serverversion", + "conflict_message": "{{count}} Ändringarna kunde inte synkroniseras (post {{id}}…). Välj vilken version som ska gälla.", + "conflict_use_server": "Överför serverversionen", "conflict_keep_local": "Behåll min version" }, "vessel": { - "title": "Masterdata för fartyg", - "name": "Yacht namn", - "type": "Typ av båt", - "type_unset": "- inte specificerad -", - "type_sailing": "Segelyacht", + "title": "Fartygsstamdata", + "name": "Båtens namn", + "type": "Båttyp", + "type_unset": "— ej angivet —", + "type_sailing": "Segelbåt", "type_motor": "Motorbåt", "length_m": "Längd (m)", - "draft_m": "Djupgående (m)", + "draft_m": "Djup (m)", "air_draft_m": "Höjd (m)", - "invalid_metric": "Ogiltigt numeriskt värde - ange meter som ett decimaltal (t.ex. 12,5).", - "port": "Hem hamn", + "invalid_metric": "Ogiltigt talvärde — ange längden som ett decimaltal (t.ex. 12,5).", + "port": "Hemhamn", "owner": "Ägare", - "charter": "Charterbolag", - "registration": "Registreringsnummer/registreringsskylt", - "callsign": "Radioanropssignal", - "atis": "ATIS nr.", - "mmsi": "MMSI nr.", + "charter": "Charterföretag", + "registration": "Registreringsnummer", + "callsign": "Anropssignal", + "atis": "ATIS-nr", + "mmsi": "MMSI-nummer", "save": "Spara fartygsdata", - "saving": "Kommer att sparas...", - "saved": "Fartygsdata har sparats framgångsrikt!", - "loading": "Fartygsdata är inlästa...", - "sails_list": "Segel (befintliga segel)", - "sails_help": "Ange här de segel som finns tillgängliga på din båt (t.ex. storsegel, genua, fock).", + "saving": "Sparas...", + "saved": "Fartygsdata har sparats!", + "loading": "Fartygsdata laddas...", + "sails_list": "Segelutrustning (befintliga segel)", + "sails_help": "Ange här vilka segel som finns tillgängliga på ditt fartyg (t.ex. storsegel, genua, fock).", "add_sail": "Lägg till segel", - "sail_name_placeholder": "z. t.ex. storsegel", - "no_sails": "Inga segel lagrade.", + "sail_name_placeholder": "t.ex. storsegel", + "no_sails": "Inga segel har lagts in.", "photo_add": "Lägg till foto", - "photo_change": "Ändra foto", + "photo_change": "Byt foto", "photo_delete": "Ta bort foto", - "tanks_section": "Tankar (kapacitet)", - "tanks_help": "Valfritt i liter - möjliggör slider i journalen för kända tankstorlekar.", + "tanks_section": "Tankar (volym)", + "tanks_help": "Valfritt i liter — möjliggör en skjutreglage i dagboken för kända tankvolymer.", "freshwater_capacity_l": "Dricksvatten (liter)", "fuel_capacity_l": "Bränsle (liter)", "greywater_capacity_l": "Gråvatten (liter)", - "invalid_tank_liters": "Ogiltigt numeriskt värde - ange liter som ett tal (t.ex. 200)." + "invalid_tank_liters": "Ogiltigt talvärde — ange liter som ett tal (t.ex. 200)." }, "logs": { - "title": "Loggboksjournal", - "new_entry": "Ny resdag", - "travel_details": "Detaljer om resan", - "add_event": "Lägg till ny loggbokspost", + "title": "Loggbok", + "new_entry": "En ny resedag", + "travel_details": "Resedetaljer", + "add_event": "Lägg till en ny loggboksanteckning", "add_event_btn": "Lägg till händelse", "edit_event": "Redigera händelse", "save_event_btn": "Spara ändring", "cancel_event_edit": "Avbryt", "delete_event": "Ta bort händelse", - "sign_cleared_skipper_re_sign_title": "Skippers signatur borttagen", - "sign_cleared_skipper_re_sign": "Händelseloggen har ändrats. Skepparens signatur har tagits bort. Vänligen godkänn igen.", - "date": "datum", + "sign_cleared_skipper_re_sign_title": "Skaparens signatur har tagits bort", + "sign_cleared_skipper_re_sign": "Händelseprotokollet har ändrats. Skipperns underskrift har tagits bort. Vänligen godkänn det på nytt.", + "date": "Datum", "day_of_travel": "Resedag", "travel_day_number": "Resedag {{number}}", - "departure": "Starthamn (resa från)", - "destination": "Destinationsport (till)", + "departure": "Avgångshamn (avresa från)", + "destination": "Ankomsthamn (till)", "route": "Resa från/till", "tanks": "Tankar", - "customize_columns": "Anpassa kolumner", - "column_selector_title": "Kolumner att visa", + "customize_columns": "Anpassa kolumnerna", + "column_selector_title": "Kolumner som ska visas", "freshwater": "Färskvatten (liter)", - "fuel": "Treibstoff / Bränsle (liter)", + "fuel": "Bränsle (liter)", "greywater": "Gråvatten (liter)", "greywater_level": "Fyllnadsnivå", "tank_slider_of_max": "{{current}} / {{max}} L", - "tank_capacity_tooltip": "Om tankens kapacitet (liter) finns lagrad i fartygets data kan du ange fyllnadsnivåerna här med hjälp av skjutreglaget.", - "morning": "Stå på morgonen", - "refilled": "Påfylld", - "evening": "Kvällsställ", - "consumption": "Daglig konsumtion", - "signatures": "Underskrifter / frisläppande", - "sign_skipper": "Skepparens signatur", - "sign_crew": "Crews signatur", - "sign_hint": "Signera med finger, penna eller mus", + "tank_capacity_tooltip": "Om tankarnas kapacitet (i liter) finns angiven i fartygsdata kan du ange fyllnadsnivåerna här med hjälp av skjutreglaget.", + "morning": "Läget på morgonen", + "refilled": "Påfyllt", + "evening": "Läget på kvällen", + "consumption": "Dagsförbrukning", + "signatures": "Underskrifter / Godkännande", + "sign_skipper": "Skipperns underskrift", + "sign_crew": "Besättningens signatur", + "sign_hint": "Underteckna med fingret, en penna eller musen", "sign_clear": "Radera", - "sign_export_image": "[Signatur]", - "sign_with_passkey": "Frigör med Passkey", - "sign_passkey_signing": "Passkey begärs...", - "sign_passkey_signed": "Utgiven av {{username}}", + "sign_export_image": "[Underskrift]", + "sign_with_passkey": "Dela med Passkey", + "sign_passkey_signing": "Passkey begärs…", + "sign_passkey_signed": "Godkänt av {{username}}", "sign_passkey_export": "Passkey: {{username}} ({{date}})", "sign_attribution_export": "{{username}} ({{date}})", - "sign_passkey_clear": "Ta bort Passkey release", + "sign_passkey_clear": "Ta bort Passkey-behörigheten", "sign_mode_passkey": "Passkey", "sign_mode_classic": "Klassisk", - "sign_passkey_failed": "Passkey Frigöring misslyckades", - "sign_passkey_cancelled": "Passkey Frigörandet inställt", - "sign_invalid": "Signaturen är ogiltig - innehållet har ändrats", - "sign_badge_skipper": "Skeppare", - "sign_badge_skipper_invalid": "Ogiltig", - "sign_badge_skipper_title_valid": "Skepparen har släppt", - "sign_badge_skipper_title_invalid": "Skippers signatur ogiltig - innehållet har ändrats", - "sign_classic_or_passkey": "Valfritt: klassisk signatur eller Passkey release ovan", - "sign_crew_passkey_hint": "Crew-medlemmar med skrivbehörighet kan frigöra via Passkey.", - "sign_offline_hint": "Passkey-Godkännande kräver Internet - klassisk signatur möjlig offline", - "sign_lock_notice": "Efter undertecknandet är det inte möjligt att göra ändringar i loggboksanteckningen (utom foton) utan att skepparen och crewen måste underteckna på nytt.", - "sign_lock_active": "Denna post är signerad. Ändringar i loggboken (utom foton) tar automatiskt bort skepparens och crews signaturer.", - "sign_lock_warning_title": "Bekräfta underskrift", - "sign_lock_warning": "Efter undertecknandet är det inte längre möjligt att göra ändringar i loggboksanteckningen (utom foton) utan att skepparen och crewen måste underteckna på nytt.\n\nVill du fortsätta?", - "sign_proceed": "Teckna", + "sign_passkey_failed": "Passkey-godkännandet misslyckades", + "sign_passkey_cancelled": "Passkey-godkännandet avbrutet", + "sign_invalid": "Signaturen är ogiltig — innehållet har ändrats", + "sign_badge_skipper": "skeppare", + "sign_badge_skipper_invalid": "Ogiltigt", + "sign_badge_skipper_title_valid": "Skipper har godkänt", + "sign_badge_skipper_title_invalid": "Skipper-signaturen är ogiltig — innehållet har ändrats", + "sign_classic_or_passkey": "Alternativ: klassisk signatur eller Passkey-godkännande högst upp", + "sign_crew_passkey_hint": "Besättningsmedlemmar med skrivbehörighet kan dela via Passkey", + "sign_offline_hint": "Passkey-godkännande kräver internetuppkoppling — traditionell underskrift är möjlig offline", + "sign_lock_notice": "Efter att loggboksanteckningen har undertecknats kan inga ändringar göras (förutom i bilderna) utan att skepparen och besättningen måste underteckna på nytt.", + "sign_lock_active": "Denna anteckning är undertecknad. Ändringar i loggboken (förutom foton) raderar automatiskt skepparens och besättningens underskrifter.", + "sign_lock_warning_title": "Bekräfta signaturen", + "sign_lock_warning": "Efter att loggboksanteckningen har undertecknats går det inte längre att göra ändringar (förutom i bilderna) utan att skepparen och besättningen måste underteckna den på nytt.\n\nVill du fortsätta?", + "sign_proceed": "Underteckna", "sign_cancel": "Avbryt", - "sign_cleared_re_sign_title": "Underskrifter borttagna", - "sign_cleared_re_sign": "Loggboksanteckningen har ändrats. Skepparens och crews namnteckningar har tagits bort. Vänligen underteckna igen.", - "no_entries": "Inga loggboksposter hittade för denna yacht. Skapa din första resedag!", + "sign_cleared_re_sign_title": "Underskrifter har tagits bort", + "sign_cleared_re_sign": "Loggboksanteckningen har ändrats. Skepparens och besättningens underskrifter har tagits bort. Vänligen skriv under på nytt.", + "no_entries": "Inga loggboksanteckningar hittades för denna båt. Skapa din första resedag!", "back_to_list": "Tillbaka till tidskriftslistan", - "save": "Spara loggbokssida", - "saving": "Kommer att sparas...", - "saved": "Loggbokssidan har sparats framgångsrikt!", + "save": "Spara loggsidan", + "saving": "Sparas...", + "saved": "Loggboksidan har sparats!", "loading": "Journalen laddas...", "view_mode_label": "Vy", "view_list": "Lista", "live_mode": "Live", - "live_title": "Live-journal", - "live_loading": "Live-journal laddas...", + "live_title": "Live-Journal", + "live_loading": "Live-Journal laddas...", "live_retry": "Försök igen", - "live_load_error": "Live-journal kunde inte laddas.", - "live_action_error": "Posten kunde inte sparas.", - "live_open_editor": "Fullständig editor", - "live_actions_label": "Snabbåtgärder", + "live_load_error": "Live-Journal kunde inte laddas.", + "live_action_error": "Det gick inte att spara inlägget.", + "live_open_editor": "Fullständig redigerare", + "live_actions_label": "Snabba erbjudanden", "live_stream_label": "Händelselogg", - "live_stream_title": "Journal", - "live_no_events": "Inga poster ännu — tryck på en åtgärd.", - "live_motor_start": "Motor Start", - "live_motor_stop": "Motor Stopp", - "live_cast_off": "Avgång", - "live_moor": "Anlöp", + "live_stream_title": "Tidskrift", + "live_no_events": "Inga inlägg ännu — klicka på en aktivitet.", + "live_motor_start": "Motorstart", + "live_motor_stop": "Motorstopp", + "live_cast_off": "Lägga undan", + "live_moor": "Skapa", "live_sails_btn": "Segel", "live_sails_pick": "Välj segel", - "live_sails_pick_hint": "Tryck på flera segel (tryck igen för att avmarkera), logga sedan.", - "live_sails_selected": "Valt: {{sails}}", - "live_sails_confirm": "Logga", - "live_sails_confirm_count": "Logga ({{count}})", + "live_sails_pick_hint": "Tryck på flera segel (tryck igen för att avmarkera), och ange sedan.", + "live_sails_selected": "Val: {{sails}}", + "live_sails_confirm": "Registrera dig", + "live_sails_confirm_count": "Registrera ({{count}})", "live_sails": "Segel: {{sails}}", "live_position": "Position", "live_position_coords": "Position {{lat}}, {{lng}}", - "live_position_manual_hint": "GPS ej tillgänglig. Ange latitud och longitud manuellt, eller försök igen med GPS-knappen.", - "live_position_gps_loading": "Hämtar GPS-position…", + "live_position_manual_hint": "GPS är inte tillgänglig. Ange latitud och longitud manuellt eller försök igen genom att trycka på GPS-knappen.", + "live_position_gps_loading": "GPS-positionen hämtas…", "live_position_invalid": "Ange giltiga koordinater (latitud −90…90, longitud −180…180).", - "live_position_lat_placeholder": "Latitud (Lat)", - "live_position_lng_placeholder": "Longitud (Lng)", + "live_position_lat_placeholder": "Bredd (Lat)", + "live_position_lng_placeholder": "Längd (Lng)", "live_photo_btn": "Foto (kamera)", - "live_photo_capture_btn": "Ta foto", + "live_photo_capture_btn": "Spela in", "live_photo_save_btn": "Spara", - "live_photo_retake_btn": "Ta om", - "live_photo_capture_failed": "Bildtagning misslyckades. Försök igen.", - "live_photo_open_camera_btn": "Öppna kamera", - "live_photo_native_hint": "Ta ett foto med enhetens kamera och spara det här efteråt.", - "live_photo_camera_starting": "Startar kamera…", - "live_photo_camera_denied": "Kameraåtkomst nekad eller ej tillgänglig.", - "live_photo_camera_unavailable": "Kameran stöds inte i den här webbläsaren.", - "live_photo_no_camera": "Ingen kamera finns på den här enheten.", - "live_photo_error": "Foto kunde inte sparas.", + "live_photo_retake_btn": "Spela in på nytt", + "live_photo_capture_failed": "Inspelningen misslyckades. Försök igen.", + "live_photo_open_camera_btn": "Öppna kameran", + "live_photo_native_hint": "Ta en bild med enhetens kamera och spara den sedan här.", + "live_photo_camera_starting": "Kameran startas…", + "live_photo_camera_denied": "Kameratillgång nekas eller är inte tillgänglig.", + "live_photo_camera_unavailable": "Den här webbläsaren stöder inte kameran.", + "live_photo_no_camera": "Den här enheten har ingen kamera.", + "live_photo_error": "Bilden kunde inte sparas.", "live_photo_entry": "Foto: {{caption}}", "live_photo_entry_plain": "Foto taget", "live_undo_photo_hint": "Foto sparat", - "live_voice_btn": "Röstanteckning", - "live_voice_hint": "Spela in en kort röstanteckning (max 60 sekunder).", - "live_voice_record": "Starta inspelning", - "live_voice_stop": "Stoppa inspelning", - "live_voice_recording": "Spelar in {{time}}", + "live_voice_btn": "Röstmeddelande", + "live_voice_hint": "Spela in ett kort röstmeddelande (max. 60 sekunder).", + "live_voice_record": "Starta inspelningen", + "live_voice_stop": "Avsluta inspelningen", + "live_voice_recording": "Inspelning {{time}}", "live_voice_save": "Spara", - "live_voice_saving": "Sparar…", - "live_voice_retake": "Spela in igen", - "live_voice_mic_denied": "Mikrofonåtkomst nekad eller ej tillgänglig.", - "live_voice_record_failed": "Inspelning misslyckades. Försök igen.", - "live_voice_unavailable": "Röstanteckning ej tillgänglig", - "live_voice_too_large": "Inspelningen är för stor. Spela in kortare.", - "live_voice_error": "Kunde inte spara röstanteckning.", - "live_voice_entry": "Röstanteckning: {{caption}}", - "live_voice_entry_plain": "Röstanteckning", - "live_voice_caption_label": "Bildtext (valfritt)", - "live_voice_caption_placeholder": "t.ex. radiokontakt med hamnmästare", + "live_voice_saving": "Sparas…", + "live_voice_retake": "Spela in på nytt", + "live_voice_mic_denied": "Mikrofonåtkomst nekas eller är inte tillgänglig.", + "live_voice_record_failed": "Inspelningen misslyckades. Försök igen.", + "live_voice_unavailable": "Röstmeddelande finns inte tillgängligt", + "live_voice_too_large": "Inspelningen är för lång. Spela in en kortare version.", + "live_voice_error": "Röstmeddelandet kunde inte sparas.", + "live_voice_entry": "Röstmeddelande: {{caption}}", + "live_voice_entry_plain": "Röstmeddelande", + "live_voice_caption_label": "Text (valfritt)", + "live_voice_caption_placeholder": "t.ex. radiokommunikation med hamnkaptenen", "live_voice_transcribe_action": "Transkribera", - "live_voice_transcribing": "Transkriberar…", - "live_voice_transcribe_failed": "Röstanteckning sparad, men transkribering misslyckades.", - "live_undo_voice_hint": "Röstanteckning sparad", + "live_voice_transcribing": "Transkribera...", + "live_voice_transcribe_failed": "Röstmemo sparat, men transkriberingen misslyckades.", + "live_undo_voice_hint": "Röstmeddelande sparat", "live_comment_btn": "Kommentar", - "live_comment_placeholder": "Ange text…", - "live_comment_confirm": "Logga", - "live_gps_error": "GPS-position kunde inte bestämmas.", - "live_gps_start_hint": "Börja alltid dagsresan med en position.", + "live_comment_placeholder": "Skriv in fritext…", + "live_comment_confirm": "Registrera dig", + "live_gps_error": "GPS-positionen kunde inte fastställas.", + "live_gps_start_hint": "Börja alltid din dagliga resa med en position.", "live_event_generic": "Händelse", "live_weather_btn": "Väder", - "live_weather_owm_btn": "Hämta OpenWeatherMap-väder", - "live_weather_owm_loading": "Hämtar väder…", - "live_weather_position_required": "Logga först en position (Position-knappen) för att hämta OpenWeatherMap-väder. Positionen får högst vara 6 timmar gammal.", - "live_weather_position_stale": "Senaste positionen är äldre än 6 timmar. Logga en ny position innan du hämtar väder.", + "live_weather_owm_btn": "OpenWeatherMap Hämta väderinformation", + "live_weather_owm_loading": "Väder hämtas…", + "live_weather_position_required": "För väder från OpenWeatherMap, ange först en position (knappen ”Position”). Positionen får inte vara äldre än 6 timmar.", + "live_weather_position_stale": "Den senaste positionen är äldre än 6 timmar. Logga in en ny position innan du hämtar väderinformation.", "live_wind_btn": "Vind", "live_temp_btn": "T °C", "live_pressure_btn": "Lufttryck", "live_precip_btn": "Nederbörd", - "live_sea_state_btn": "Sjögang", - "live_visibility_btn": "Sikt", + "live_sea_state_btn": "sjögång", + "live_visibility_btn": "Siktavstånd", "live_course_btn": "Kurs", "live_fuel_btn": "+ Diesel", "live_water_btn": "+ Vatten", @@ -328,13 +330,13 @@ "live_temp_entry": "Temperatur {{temp}} °C", "live_pressure_entry": "Lufttryck {{value}} hPa", "live_precip_entry": "Nederbörd {{value}}", - "live_sea_state_entry": "Sjögang {{value}}", + "live_sea_state_entry": "Sjögång {{value}}", "live_visibility_entry": "Sikt {{value}}", "live_course_entry": "Kurs {{course}}", "live_fuel_entry": "Diesel +{{liters}} L", "live_water_entry": "Vatten +{{liters}} L", - "live_auto_position": "Auto-position", - "live_undo_hint": "Post sparad", + "live_auto_position": "Automatisk positionering", + "live_undo_hint": "Inlägget har sparats", "live_undo_btn": "Ångra", "live_cancel": "Avbryt", "live_pressure_placeholder": "t.ex. 1013", @@ -351,184 +353,184 @@ "live_stw_entry": "STW {{speed}} kn", "live_sog_placeholder": "t.ex. 5,2", "live_stw_placeholder": "t.ex. 4,8", - "live_sog_hint": "Fart över grund (kn) — GPS-värde fylls i om tillgängligt.", - "delete_entry": "Ta bort tagg", - "delete_confirm": "Är du säker på att du vill radera den här resedagen permanent?", + "live_sog_hint": "Avstånd över marken (kn) — GPS-värdet fylls i automatiskt om det finns tillgängligt.", + "delete_entry": "Ta bort dag", + "delete_confirm": "Är du säker på att du vill radera den här resedagen utan möjlighet att ångra dig?", "carry_over_tanks_title": "Överföra data från föregående dag?", - "carry_over_tanks_confirm": "Ta över starthamn, färskvatten, bränsle och gråvatten från startnivåerna från resans sista dag?\n\nStarthamn: {{departure}}\nFärskvatten: {{fw}} L\nBränsle: {{fuel}} L\nGråvatten: {{greywater}} L", - "carry_over_tanks_yes": "Ta över", - "carry_over_tanks_no": "Börja med 0", + "carry_over_tanks_confirm": "Ska utgångsvärdena för avgångshamn, färskvatten, bränsle och gråvatten från den sista resedagen användas?\n\nAvgångshamn: {{departure}}\nFärskvatten: {{fw}} l\nBränsle: {{fuel}} l\nGråvatten: {{greywater}} l", + "carry_over_tanks_yes": "Bekräfta", + "carry_over_tanks_no": "Börja från noll", "event_title": "Kronologisk händelselogg", - "event_creator": "Registrerad av", - "no_events": "Inga händelser inlagda för denna resdag ännu.", - "event_time": "Tid på dygnet", + "event_creator": "Inlagd av", + "no_events": "Inga händelser har ännu lagts in för denna resedag.", + "event_time": "Tid", "event_mgk": "MgK-kurs", "event_rwk": "RwK-kurs", "event_course_section": "Kurs", - "course_dial_hint": "Vrid ringen eller gå in i grader", + "course_dial_hint": "Vrid på ringen eller ange vinkel", "course_dial_step_label": "Stegstorlek", "course_step_fine": "1°", "course_step_medium": "5°", "course_step_coarse": "10°", "course_tab_mgk": "MgK", "course_tab_rwk": "rwK", - "course_invalid": "Ogiltig kurs (0-360)", - "course_placeholder_degrees": "z. B. 180", - "course_placeholder_cardinal": "z. E.G. NW", + "course_invalid": "Ogiltig kurs (0–360)", + "course_placeholder_degrees": "t.ex. 180", + "course_placeholder_cardinal": "t.ex. NW", "compass_n": "N", "compass_e": "O", "compass_s": "S", "compass_w": "W", "wind_mode_cardinal": "Kardinal", - "wind_mode_degrees": "Som examen", + "wind_mode_degrees": "Som grad", "event_wind_direction": "Vindriktning", "event_wind_strength": "Vindstyrka", - "event_sea_state": "Havets tillstånd", - "event_visibility": "Sikt", + "event_sea_state": "sjögång", + "event_visibility": "Siktavstånd", "event_visibility_placeholder": "t.ex. 10 km", "weather_slider_unset": "—", "weather_slider_pressure": "{{value}} hPa", - "weather_slider_sea_state": "Grad {{value}}", + "weather_slider_sea_state": "Nivå {{value}}", "weather_slider_heel": "{{value}}°", "event_weather": "Väder", - "event_log": "Log (sm)", + "event_log": "Logge (sm)", "event_gps": "GPS-position", - "event_location": "Plats / hamn", - "event_location_placeholder": "z. t.ex. Kiel", - "event_remarks": "Anmärkningar / incidenter", + "event_location": "Ort / Hamn", + "event_location_placeholder": "t.ex. Kiel", + "event_remarks": "Anmärkningar / Händelser", "gps_btn": "Hämta GPS-koordinater", - "gps_permission_denied": "Platstillgång nekades. Tillåt det i webbläsar- eller enhetsinställningar och försök igen.", - "gps_timeout": "GPS fick tidsgräns. Försök igen utomhus med fri sikt mot himlen.", - "gps_position_unavailable": "Ingen GPS-signal tillgänglig. Vänta och försök igen, eller ange koordinater manuellt.", - "gps_unavailable": "GPS stöds inte av denna webbläsare eller enhet.", - "gps_failed": "GPS-position kunde inte bestämmas.", - "gps_fallback_no_location": "GPS misslyckades. Ange en plats under ort/hamn, avresa eller destination, eller skriv koordinater manuellt.", - "gps_fallback_success": "Koordinater för \"{{location}}\" hittades via ortsnamn (inte GPS).", - "gps_fallback_failed": "GPS och ortnamnssökning misslyckades. Ange koordinater manuellt.", + "gps_permission_denied": "Åtkomst till platsinformationen nekades. Tillåt detta i webbläsarens eller enhetens inställningar och försök igen.", + "gps_timeout": "GPS-tidsöverskridning. Försök igen – helst utomhus där mottagningen är god.", + "gps_position_unavailable": "Ingen GPS-signal tillgänglig. Vänta eller ange koordinaterna manuellt.", + "gps_unavailable": "GPS stöds inte av den här webbläsaren eller enheten.", + "gps_failed": "GPS-positionen kunde inte fastställas.", + "gps_fallback_no_location": "GPS-anslutningen misslyckades. Ange en plats under ”Plats/hamn”, start- eller målhamn, eller mata in koordinaterna manuellt.", + "gps_fallback_success": "Koordinaterna för ”{{location}}” har fastställts utifrån ortnamnet (inte via GPS).", + "gps_fallback_failed": "GPS-sökningen och sökningen efter ortnamn misslyckades. Ange koordinaterna manuellt.", "gps_quality_excellent": "Stark GPS-mottagning (±{{accuracy}} m)", "gps_quality_good": "Bra GPS-mottagning (±{{accuracy}} m)", - "gps_quality_fair": "Måttlig GPS-mottagning (±{{accuracy}} m) – gå utomhus för bättre signal.", - "gps_quality_poor": "Svag GPS-mottagning (±{{accuracy}} m) – troligen få satelliter. Försök utomhus igen eller kontrollera positionen.", - "gps_quality_unknown": "GPS-position övertagen (noggrannhet ej rapporterad av enheten).", - "gps_live_intro_title": "Plats för live-logg", - "gps_live_intro_body": "Appen behöver din plats för automatiska positionsregistreringar och GPS-knappen.\n\nTryck på „Tillåt plats“ och bekräfta i nästa dialog. Du kan alltid ange position manuellt via „Position“.", - "gps_live_intro_allow": "Tillåt plats", + "gps_quality_fair": "Måttlig GPS-mottagning (±{{accuracy}} m) – gå utomhus för bättre mottagning.", + "gps_quality_poor": "Svag GPS-mottagning (±{{accuracy}} m) – troligen få satelliter. Försök igen utomhus eller kontrollera positionen.", + "gps_quality_unknown": "GPS-positionen har hämtats (enheten rapporterar ingen noggrannhet).", + "gps_live_intro_title": "Plats för Live-Log", + "gps_live_intro_body": "För automatiska positionsinmatningar och GPS-knappen behöver appen tillgång till din position.\n\nTryck på ”Tillåt position” – bekräfta godkännandet i nästa dialogruta. Du kan när som helst ange positionen manuellt under ”Position”.", + "gps_live_intro_allow": "Tillåt platsåtkomst", "gps_live_intro_later": "Senare", - "gps_enable_in_settings_hint": "Platstillgång är blockerad. Du kan tillåta det senare i webbläsar- eller enhetsinställningar (webbplats / app → Plats).", - "weather_btn": "OpenWeatherMap Ring upp väder", - "weather_offline": "OpenWeatherMap kräver internetanslutning. Du är offline.", + "gps_enable_in_settings_hint": "Åtkomst till platsuppgifter är blockerad. Du kan aktivera åtkomsten i webbläsarens eller enhetens inställningar (webbplats/app → plats).", + "weather_btn": "OpenWeatherMap Hämta väderinformation", + "weather_offline": "OpenWeatherMap kräver en internetanslutning. Du är för närvarande offline.", "event_wind_pressure": "Lufttryck (hPa)", "event_heel": "Krängning (°)", - "event_sails": "Segelhantering / motor", - "motor_propulsion": "Maskinens resa", + "event_sails": "Segling / Motor", + "motor_propulsion": "Maskinrutt", "sails_picker_show_more": "Visa alla segel", - "sails_picker_show_less": "Visa mindre", - "motor_hours": "Maskintimmar (totalt)", + "sails_picker_show_less": "Visa färre", + "motor_hours": "Maskinstimmar (totalt)", "fuel_per_motor_hour": "Förbrukning per maskintimme", "event_distance": "Avstånd (sm)", - "export_csv": "Hämta CSV.", - "share_csv": "Aktie", - "export_pdf": "Hämta PDF.", + "export_csv": "Ladda ner CSV", + "share_csv": "CSV dela", + "export_pdf": "Ladda ner PDF", "exporting_pdf": "PDF genereras...", - "ai_summary_title": "AI-sammanfattning", - "ai_summary_read_only": "Skapad av skepparen — endast läsning för besättningen.", - "ai_summary_empty": "Ingen sammanfattning ännu.", - "ai_summary_generate": "Generera sammanfattning", - "ai_summary_regenerate": "Generera igen", - "ai_summary_generating": "Genererar…", - "ai_summary_attempts_remaining": "{{remaining}} av {{max}} försök kvar", - "ai_summary_error": "AI-sammanfattning misslyckades. Försök igen senare.", - "ai_summary_error_no_key": "Ingen OpenRouter API-nyckel konfigurerad på servern.", - "ai_summary_error_rate_limited": "Maximalt antal genereringar nått för denna resedag.", - "ai_summary_error_forbidden": "Endast skepparen får generera AI-sammanfattningar.", - "ai_summary_offline": "AI-sammanfattning kräver internetanslutning. Du är offline.", - "photos_title": "Fotobilagor", - "photo_caption_label": "Fotobeskrivning/etikett (valfritt)", + "ai_summary_title": "Sammanfattning med AI", + "ai_summary_read_only": "Skapad av skepparen — endast läsbar för besättningen.", + "ai_summary_empty": "Det finns ännu ingen sammanfattning.", + "ai_summary_generate": "Skapa en sammanfattning", + "ai_summary_regenerate": "Skapa på nytt", + "ai_summary_generating": "Genereras…", + "ai_summary_attempts_remaining": "Fortfarande {{remaining}} av {{max}} försök", + "ai_summary_error": "Sammanfattningen med AI misslyckades. Försök igen senare.", + "ai_summary_error_no_key": "Ingen OpenRouter-API-nyckel har konfigurerats på servern.", + "ai_summary_error_rate_limited": "Det maximala antalet genereringar för denna resedag har uppnåtts.", + "ai_summary_error_forbidden": "Endast skepparen får skapa AI-sammanfattningar.", + "ai_summary_offline": "AI-sammanfattningen kräver en internetanslutning. Du är för närvarande offline.", + "photos_title": "Bilagor med bilder", + "photo_caption_label": "Bildbeskrivning / Etikett (valfritt)", "photo_caption_placeholder": "t.ex. sätta segel nära hamninloppet", - "photo_btn": "Ta foto / ladda upp", - "photo_camera_btn": "Ta foto", - "photo_gallery_btn": "Välj från galleri", - "photo_processing": "Håller på att bearbetas...", - "no_photos": "Inga foton kopplade till denna resdag ännu.", - "photo_delete_confirm": "Är du säker på att du vill radera det här fotot permanent?", + "photo_btn": "Ta en bild / Ladda upp", + "photo_camera_btn": "Ta en bild", + "photo_gallery_btn": "Välj från galleriet", + "photo_processing": "Bearbetas...", + "no_photos": "Inga bilder har lagts till för denna resedag ännu.", + "photo_delete_confirm": "Är du säker på att du vill radera den här bilden utan möjlighet att återställa den?", "confirm_yes": "Ja", "confirm_no": "Nej", - "track_upload_title": "GPS-spårning (fil)", + "track_upload_title": "GPS-spår (fil)", "track_upload_points": "Poäng", - "gps_tracking_btn_gpx": "Ladda ner spårfil", + "gps_tracking_btn_gpx": "Ladda ner spårfilen", "gps_track_upload_help": "Dra en GPX-, KML- eller GeoJSON-fil hit eller klicka för att välja", "gps_track_upload_btn": "Ladda upp GPS-spår", "gps_track_delete": "Ta bort spårfil", "gps_track_delete_confirm": "Är du säker på att du vill radera den här spårfilen permanent?", "track_distance": "GPS-rutt (sm)", - "track_speed_max": "Max. hastighet Hastighet (kn)", + "track_speed_max": "Max. hastighet (kn)", "track_speed_avg": "Ø Hastighet (kn)", "track_map_title": "GPS-spår på OpenSeaMap", "track_map_start": "Start", "track_map_end": "Mål", "track_map_speed_slow": "långsamt", - "track_map_speed_fast": "snabb", - "track_map_error": "Kartan kunde inte läsas in.", - "exporting": "Export...", - "share_unsupported": "Delning stöds inte på den här enheten. Filen har laddats ner istället.", - "invite_crew": "Bjud in crewen", - "invite_link_copied": "Länk till inbjudan kopierad till urklipp!", - "invite_link_desc": "Dela den här länken med Crew-medlemmar för att ge dem skrivrättigheter till loggboken.", - "collaborators_list": "Medlemmar / Crew", - "revoke": "Ta bort", - "revoke_confirm": "Är du säker på att du vill återkalla den här Crew-medlemmens åtkomst?", - "invite_role": "Roll", - "invite_expires": "Länken är giltig i 48 timmar", - "nmea_import_title": "Import NMEA log", - "nmea_import_intro": "Upload a .nmea file from your onboard logger. The app suggests journal entries — you choose what to import.", - "nmea_import_btn": "Import NMEA", - "nmea_file_label": "NMEA file", - "nmea_stats": "{{lines}} sentences parsed · types: {{types}}", - "nmea_warn_no_position": "No position sentences found — track and GPS fields may stay empty.", - "nmea_mode_label": "Generate journal entries", - "nmea_mode_interval": "By time interval", - "nmea_mode_change": "On significant change", - "nmea_mode_both": "Both (merge)", - "nmea_interval_label": "Interval (minutes)", - "nmea_import_track": "Import GPS track from NMEA", - "nmea_preview": "Preview", - "nmea_preview_hint": "{{count}} suggested journal entries", - "nmea_select_all": "Select all", - "nmea_select_none": "Select none", - "nmea_source_interval": "Interval", - "nmea_source_change": "Event", - "nmea_apply": "Apply to journal", - "nmea_back": "Back", - "nmea_cancel": "Cancel", - "nmea_archive_question": "Archive raw log locally? (This device only, not synced.)", - "nmea_archive_keep": "Archive", - "nmea_archive_discard": "Discard", - "nmea_archive_stored": "NMEA archived: {{name}}", - "nmea_archive_delete_confirm": "Delete archived NMEA log from this device?", - "nmea_error_no_samples": "No usable NMEA sentences in the file.", - "nmea_error_parse": "Could not read NMEA file.", - "nmea_error_read": "Could not read file.", - "nmea_error_no_file": "Please choose an NMEA file first.", - "nmea_error_no_selection": "Please select at least one journal entry.", - "nmea_remark_interval": "NMEA interval", - "nmea_remark_uncertain": "uncertain", - "nmea_remark_depth": "Depth {{depth}} m", - "nmea_change_course": "Course change {{from}}° → {{to}}°", - "nmea_change_wind": "Wind {{from}}° → {{to}}°", - "nmea_change_wind_speed": "Wind {{from}} → {{to}} kn", - "nmea_change_pressure": "Pressure {{from}} → {{to}} hPa", - "nmea_change_depth": "Depth {{from}} → {{to}} m", - "nmea_change_engine_start": "Engine on ({{rpm}} rpm)", - "nmea_change_engine_stop": "Engine off", - "nmea_change_autopilot_on": "Autopilot on", - "nmea_change_autopilot_off": "Autopilot off", - "nmea_change_gps_lost": "GPS-position förlorad", + "track_map_speed_fast": "snabbt", + "nmea_import_title": "Importera NMEA-protokoll", + "nmea_import_intro": "Ladda ner en .nmea-fil från loggaren ombord. Appen föreslår loggposter – du bestämmer själv vilka som ska importeras.", + "nmea_import_btn": "Importera NMEA", + "nmea_file_label": "NMEA-fil", + "nmea_stats": "{{lines}} fraser identifierade · Typer: {{types}}", + "nmea_warn_no_position": "Inga positionsuppsättningar hittades — fälten för spårning och GPS kan lämnas tomma.", + "nmea_warn_duplicate_file": "Denna NMEA-fil har redan importerats. Om du importerar samma fil igen läggs dubbla loggposter till.", + "nmea_mode_label": "Skapa journalposter", + "nmea_mode_interval": "Efter tidsintervall", + "nmea_mode_change": "Vid väsentliga förändringar", + "nmea_mode_both": "Båda (slå samman)", + "nmea_interval_label": "Intervall (minuter)", + "nmea_import_track": "Importera GPS-spår från NMEA", + "nmea_preview": "Förhandsgranskning", + "nmea_preview_hint": "{{count}} föreslagna dagboksanteckningar", + "nmea_select_all": "Välj alla", + "nmea_select_none": "Välj ingen", + "nmea_source_interval": "Intervall", + "nmea_source_change": "Händelse", + "nmea_apply": "Överför till journalen", + "nmea_back": "Tillbaka", + "nmea_cancel": "Avbryt", + "nmea_archive_question": "Ska råprotokollet arkiveras lokalt? (Endast på den här enheten, synkroniseras inte.)", + "nmea_archive_keep": "Arkivera", + "nmea_archive_discard": "Avvisa", + "nmea_archive_stored": "NMEA-arkiv: {{name}}", + "nmea_archive_delete_confirm": "Vill du radera arkiverade NMEA-loggar från den här enheten?", + "nmea_error_no_samples": "Inga användbara NMEA-poster i filen.", + "nmea_error_parse": "NMEA-filen kunde inte läsas.", + "nmea_error_read": "Filen kunde inte läsas.", + "nmea_error_no_file": "Välj först en NMEA-fil.", + "nmea_error_no_selection": "Välj minst en dagboksanteckning.", + "nmea_remark_interval": "NMEA-intervall", + "nmea_remark_uncertain": "osäker", + "nmea_remark_depth": "Djup {{depth}} m", + "nmea_change_course": "Kursändring {{from}}° → {{to}}°", + "nmea_change_wind": "Vind {{from}}° → {{to}}°", + "nmea_change_wind_speed": "Vind {{from}} → {{to}} kn", + "nmea_change_pressure": "Lufttryck {{from}} → {{to}} hPa", + "nmea_change_depth": "Djup {{from}} → {{to}} m", + "nmea_change_engine_start": "Motorn är igång ({{rpm}} varv/min)", + "nmea_change_engine_stop": "Motorn avstängd", + "nmea_change_autopilot_on": "Aktivera autopiloten", + "nmea_change_autopilot_off": "Autopilot avstängd", + "nmea_change_gps_lost": "GPS-positionen har gått förlorad", "nmea_change_gps_regained": "GPS-position återställd", - "nmea_change_water_temp": "Water temp. {{from}} → {{to}} °C", - "nmea_change_departure": "Departure / underway", - "nmea_change_anchor": "Anchored / stop", - "nmea_change_speed": "Speed {{from}} → {{to}} kn", - "nmea_warn_duplicate_file": "This NMEA file has already been imported. Importing the same file again will add duplicate journal entries." + "nmea_change_water_temp": "Vattentemperatur {{from}} → {{to}} °C", + "nmea_change_departure": "Avgång / Resans början", + "nmea_change_anchor": "Ankare / Stopp", + "nmea_change_speed": "Hastighet {{from}} → {{to}} kn", + "track_map_error": "Kartan kunde inte laddas.", + "exporting": "Exportera...", + "share_unsupported": "Delning stöds inte på den här enheten. Filen har istället laddats ner.", + "invite_crew": "Bjud in besättningen", + "invite_link_copied": "Inbjudningslänken har kopierats till urklipp!", + "invite_link_desc": "Dela den här länken med besättningsmedlemmarna för att ge dem skrivbehörighet till den här loggboken.", + "collaborators_list": "Medlemmar / Besättning", + "revoke": "Ta bort", + "revoke_confirm": "Är du säker på att du vill ta bort åtkomsten för den här medarbetaren?", + "invite_role": "Roll", + "invite_expires": "Länken är giltig i 48 timmar" }, "dashboard": { "title": "Dina loggböcker", @@ -537,541 +539,541 @@ "new_logbook_placeholder": "Loggbokens eller båtens namn", "logout": "Logga ut", "logged_in_as": "Inloggad som {{name}}", - "delete_confirm": "Är du säker på att du vill radera den här loggboken permanent? Alla lokala data och serverkopior kommer att förstöras.\n\nTips: Skapa en säkerhetskopia (.daagbok) i förväg under Inställningar → Säkerhetskopiering och återställning om du vill behålla data senare.", + "delete_confirm": "Är du säker på att du vill radera den här loggboken utan möjlighet till återställning? Alla lokala data och serverkopior kommer att raderas.\n\nTips: Skapa först en säkerhetskopia (.daagbok) under Inställningar → Säkerhetskopiering och återställning om du vill behålla uppgifterna senare.", "no_logbooks": "Inga loggböcker hittades. Skapa din första loggbok för att komma igång!", - "loading": "Loggböckerna är fulla...", + "loading": "Loggböckerna laddas...", "status_synced": "Synkroniserad", "status_local": "Endast lokal cache", - "delete_btn": "Radera loggbok", + "delete_btn": "Radera loggboken", "section_owned": "Mina loggböcker", "section_shared": "Delade loggböcker", - "section_shared_hint": "Du har blivit inbjuden som Crew-medlem. Skepparens profil och inställningar tillhör ägaren.", + "section_shared_hint": "Du har blivit inbjuden som besättningsmedlem. Skepparens profil och inställningar tillhör båtägaren.", "role_owner": "Egen loggbok", - "role_owner_hint": "Du är ägare och skeppare till denna loggbok", - "role_crew": "Tillträde för crewen", - "role_crew_hint": "Inbjuden loggbok - du kan arbeta som crew och underteckna den", + "role_owner_hint": "Du är ägare och skeppare för denna loggbok", + "role_crew": "Tillgång för besättningen", + "role_crew_hint": "Inbjudningsloggbok – du kan delta som besättningsmedlem och skriva under", "role_read": "Endast läsning", - "role_read_hint": "Delad loggbok - endast visning, ingen redigering", - "open_profile": "Öppna profil för {{name}}", - "open_logbook": "Öppna loggbok ”{{title}}”", - "edit_title": "Byt namn på loggbok", - "edit_placeholder": "Nytt namn på loggboken", - "edit_success": "Loggboken har framgångsrikt bytt namn", - "edit_btn": "Byt namn på", + "role_read_hint": "Delad loggbok – endast läsbehörighet, ingen redigeringsbehörighet", + "open_profile": "Öppna profilen för {{name}}", + "open_logbook": "Öppna loggboken ”{{title}}”", + "edit_title": "Byt namn på loggboken", + "edit_placeholder": "Loggbokens nya namn", + "edit_success": "Loggboken har bytt namn", + "edit_btn": "Byt namn", "filter_label": "Filtrera loggböcker", - "filter_placeholder": "Namn, årtal, datum, crew eller fartyg …", + "filter_placeholder": "Namn, år, datum, besättning eller fartyg …", "filter_clear": "Återställ filter", - "filter_results": "{{count}} Träffar", - "filter_no_results": "Inga loggböcker matchar din sökning. Försök med ett annat namn eller ett annat år.", + "filter_results": "{{count}} träffar", + "filter_no_results": "Inga loggböcker matchar din sökning. Prova med ett annat namn eller ett annat år.", "sort_label": "Sortera", "sort_by_label": "Sortera efter", "sort_by_name": "Namn", - "sort_by_date": "datum", - "sort_dir_label": "Sekvens", + "sort_by_date": "Datum", + "sort_dir_label": "Ordning", "sort_asc": "Stigande", - "sort_desc": "Nedåtgående", - "sort_name_asc": "Namn A till Ö", - "sort_name_desc": "Namn Z till A", - "sort_date_asc": "Äldst först", - "sort_date_desc": "Nyast först" + "sort_desc": "I fallande ordning", + "sort_name_asc": "Namn A–Ö", + "sort_name_desc": "Namn från Z till A", + "sort_date_asc": "Äldsta först", + "sort_date_desc": "Senaste först" }, "profile": { "title": "Användarprofil", - "subtitle": "Konto, Passkeys och statistik för {{name}}", + "subtitle": "Konto, Passkey och statistik för {{name}}", "back": "Tillbaka till instrumentpanelen", - "loading": "Profilen håller på att laddas...", + "loading": "Profilen laddas…", "load_error": "Profilen kunde inte laddas.", - "copy_failed": "Kopiering misslyckades.", - "processing": "Håller på att bearbetas...", - "identity_title": "Kontots identitet", - "username": "Användarens namn", + "copy_failed": "Kopieringen misslyckades.", + "processing": "Bearbetas…", + "identity_title": "Kontoidentitet", + "username": "Användarnamn", "user_id": "Användar-ID", "copy_user_id": "Kopiera användar-ID", "account_since": "Konto sedan", - "prf_status": "Passkey härledning av nyckel (PRF)", + "prf_status": "Passkey-nyckelgenerering (PRF)", "prf_active": "Aktiv", - "prf_inactive": "Inte konfigurerad", + "prf_inactive": "Ej inrett", "passkeys_title": "Passkeys", - "passkeys_desc": "Registrera en separat Passkey på varje enhet. Detta gör att du kan logga in även efter att du bytt plattform.", - "passkeys_empty": "Inga Passkeys hittades.", + "passkeys_desc": "Registrera ett eget Passkey på varje enhet. På så sätt kan du logga in även efter ett byte av plattform.", + "passkeys_empty": "Inga Passkey hittades.", "add_passkey_btn": "Lägg till ny Passkey", "add_passkey_success": "Passkey har lagts till.", "add_passkey_failed": "Passkey kunde inte läggas till.", - "remove_passkey_btn": "Ta bort Passkey.", - "remove_passkey_last_title": "Senaste Passkey.", - "remove_passkey_last_desc": "Den enda Passkey kan inte tas bort utan att du förlorar åtkomsten till ditt konto. Om du vill radera kontot helt använder du riskzonen längst ner på den här sidan.", + "remove_passkey_btn": "Ta bort Passkey", + "remove_passkey_last_title": "Senaste Passkey", + "remove_passkey_last_desc": "Det enda Passkey kan inte tas bort utan att du förlorar åtkomsten till ditt konto. För att radera kontot helt, använd länken längst ner på denna sida.", "remove_passkey_failed": "Passkey kunde inte tas bort.", - "remove_passkey_confirm_title": "Ta bort Passkey?", - "remove_passkey_confirm_desc": "Denna enhet kan sedan inte längre logga in med denna Passkey.", + "remove_passkey_confirm_title": "Passkey ta bort?", + "remove_passkey_confirm_desc": "Enheten kan därefter inte längre logga in med denna Passkey.", "remove_passkey_confirm_yes": "Ta bort", "remove_passkey_confirm_no": "Avbryt", "pin_title": "Lokal PIN-kod", "pin_status": "Status", "pin_active": "Aktiv på den här enheten", - "pin_inactive": "Inte konfigurerad", - "pin_confirm_label": "Bekräfta PIN-kod", + "pin_inactive": "Ej inrett", + "pin_confirm_label": "Bekräfta PIN-koden", "pin_confirm_placeholder": "Ange PIN-koden igen", - "pin_set_btn": "Ange PIN-kod", + "pin_set_btn": "Ställa in PIN-kod", "pin_change_btn": "Ändra PIN-kod", "pin_remove_btn": "Ta bort PIN-koden", - "pin_saved": "PIN-koden sparad.", - "pin_save_failed": "PIN-koden kunde inte räddas.", + "pin_saved": "PIN-koden har sparats.", + "pin_save_failed": "PIN-koden kunde inte sparas.", "pin_mismatch": "PIN-koderna stämmer inte överens.", - "pin_length_error": "PIN-koden måste innehålla minst 4 tecken.", - "pin_no_session": "Sessionen har löpt ut - vänligen registrera dig igen.", + "pin_length_error": "PIN-koden måste bestå av minst 4 tecken.", + "pin_no_session": "Sessionen har löpt ut — logga in igen.", "remove_pin_confirm_title": "Ta bort PIN-koden?", - "remove_pin_confirm_desc": "Du måste logga in igen på den här enheten med Passkey eller återställningsnyckel.", + "remove_pin_confirm_desc": "Du måste logga in på den här enheten igen med Passkey eller återställningsnyckeln.", "remove_pin_confirm_yes": "Ta bort PIN-koden", "remove_pin_confirm_no": "Avbryt", - "security_title": "Checklista för säkerhet", - "security_desc": "Översikt över de viktigaste skyddsmekanismerna för ditt konto.", + "security_title": "Säkerhetslista", + "security_desc": "En översikt över de viktigaste säkerhetsfunktionerna för ditt konto.", "security_passkeys_ok": "Minst en Passkey registrerad", - "security_passkeys_missing": "Nej Passkey registrerad", - "security_prf_ok": "Avledning av PRF-nyckel aktiv", - "security_prf_missing": "PRF inte upprättad", + "security_passkeys_missing": "Ingen Passkey registrerad", + "security_prf_ok": "PRF-nyckelgenerering aktiverad", + "security_prf_missing": "PRF har inte konfigurerats", "security_pin_ok": "Lokal PIN-kod på den här enheten", "security_pin_missing": "Ingen lokal PIN-kod", - "security_recovery_ok": "Uppsättning av återställningsnyckel", - "security_recovery_hint": "De 12 orden visades under registreringen. Håll dem offline och åtskilda från enheten. Du kan skapa en ny nyckel nedan - den gamla kommer då att bli ogiltig.", + "security_recovery_ok": "Återställningsnyckel har konfigurerats", + "security_recovery_hint": "De 12 orden visades vid registreringen. Förvara dem offline och separat från enheten. Du kan skapa en ny nyckel nedan – den gamla blir då ogiltig.", "recovery_rotate_btn": "Skapa en ny återställningsnyckel", "recovery_rotate_confirm_title": "Skapa en ny återställningsnyckel?", - "recovery_rotate_confirm_desc": "Den tidigare nyckeln på 12 ord blir ogiltig omedelbart. Se till att du förvarar den nya nyckeln säkert innan du fortsätter.", - "recovery_rotate_confirm_yes": "Skapa ny nyckel", + "recovery_rotate_confirm_desc": "Den tidigare 12-ordskoden upphör att gälla omedelbart. Se till att du förvarar den nya koden på ett säkert sätt innan du fortsätter.", + "recovery_rotate_confirm_yes": "Skapa en ny nyckel", "recovery_rotate_confirm_no": "Avbryt", - "recovery_rotate_new_warning": "VIKTIGT: Skriv ner dessa 12 ord och förvara dem offline. Den tidigare återställningsnyckeln är nu ogiltig.", - "recovery_rotate_failed": "Återställningsnyckel kunde inte skapas.", - "recovery_rotate_no_session": "Krypteringssessionen har löpt ut - logga ut och logga in igen och försök sedan igen.", - "device_title": "Denna enhet", - "device_desc": "Lokal cache, synkroniseringsstatus och snabb inloggning i den här webbläsaren.", - "device_sync_pending": "{{count}} väntande synkroniseringsposter", + "recovery_rotate_new_warning": "VIKTIGT: Skriv ner dessa 12 ord och förvara dem offline. Den tidigare återställningsnyckeln är från och med nu ogiltig.", + "recovery_rotate_failed": "Återställningsnyckeln kunde inte skapas.", + "recovery_rotate_no_session": "Krypteringssessionen har löpt ut — logga ut och logga in igen, och försök sedan på nytt.", + "device_title": "Denna apparat", + "device_desc": "Lokal cache, synkroniseringsstatus och snabbinloggning i den här webbläsaren.", + "device_sync_pending": "{{count}} utestående synkroniseringsposter", "device_sync_ok": "Alla lokala ändringar synkroniseras", - "device_remembered": "Konto för snabb inloggning sparat på den här enheten", - "device_not_remembered": "Kontot finns inte med i listan för snabb inloggning", - "device_forget_btn": "Glömt konto på den här enheten", - "device_forget_confirm_title": "Ta bort snabb inloggning?", - "device_forget_confirm_desc": "Kontot försvinner från snabbinloggningslistan på den här enheten. Din session och dina lokala loggböcker behålls.", + "device_remembered": "Ett konto för snabbinloggning har sparats på den här enheten", + "device_not_remembered": "Kontot finns inte med i listan för snabbinloggning", + "device_forget_btn": "Glömt ditt konto på den här enheten", + "device_forget_confirm_title": "Ta bort snabbinloggning?", + "device_forget_confirm_desc": "Kontot försvinner från listan över snabbinloggningar på den här enheten. Din session och dina lokala loggar sparas.", "device_forget_confirm_yes": "Ta bort", "device_forget_confirm_no": "Avbryt", - "passkey_label": "Namn för ny Passkey (valfritt)", - "passkey_label_placeholder": "z. t.ex. MacBook, iPhone", + "passkey_label": "Namn på nya Passkey (valfritt)", + "passkey_label_placeholder": "t.ex. MacBook, iPhone", "passkey_rename_btn": "Spara namn", - "passkey_rename_success": "Passkey namn sparat.", - "passkey_rename_failed": "Passkey-Namnet kunde inte sparas.", - "passkey_unnamed": "Utan titel Passkey", + "passkey_rename_success": "Passkey-namn sparat.", + "passkey_rename_failed": "Passkey-namnet kunde inte sparas.", + "passkey_unnamed": "Anonym Passkey", "stats_title": "Statistik", "stats_subtitle": "Om alla dina loggböcker på den här enheten", "stats_logbooks": "Loggböcker", "stats_account_since": "Konto sedan", "stats_shared_logbooks": "Delade loggböcker", - "appearance_title": "App & visualisering", + "appearance_title": "App & presentation", "appearance_desc": "Designen och färgschemat gäller för hela appen på den här enheten.", "theme_label": "Appens designstil", - "theme_auto": "Automatisk (OS-detektering)", + "theme_auto": "Automatiskt (OS-igenkänning)", "theme_ocean": "Ocean (glasmorfism)", "theme_material": "Material (Android)", "theme_cupertino": "Cupertino (iOS)", - "color_scheme_label": "Ljust eller mörkt läge", - "color_scheme_auto": "Automatisk (system)", - "color_scheme_light": "Ljus", - "color_scheme_dark": "Mörk", + "color_scheme_label": "Ljus- eller mörkläge", + "color_scheme_auto": "Automatiskt (system)", + "color_scheme_light": "Ljust", + "color_scheme_dark": "Mörkt", "integrations_title": "Integrationer", "owm_key": "OpenWeatherMap API-nyckel", - "owm_help": "Valfritt: egen OpenWeatherMap API-nyckel. Om inget anges används nyckeln på serversidan från operatörskonfigurationen.", - "ai_title": "AI-funktioner och integritet", - "ai_desc": "Auktorisera integrationer av artificiell intelligens för dina loggböcker.", - "ai_help": "Genom at aktivera AI-funktioner kan appen sammanfatta dina rejsdagar och transkribera röstmemon. För att bearbeta dessa förfrågningar skickas röstdata och rejsloggar säkert och tillfälligt till OpenRouter. Inga data sparas permanent av AI-modellen.\n\nDessa molnresurser kostar pengar att driva. Om du gillar att använda dem, överväg att frivilligt stödja projektet med en donation via Ko-fi-länken i sidfoten för att hålla dem gratis och hållbara för alla.", - "ai_enable_label": "Aktivera transkribering och sammanfattningar av rejsdagar", - "ai_unauthorized_alert_title": "AI-funktioner är inte auktoriserade", - "ai_unauthorized_alert_desc": "För att använda transkribering eller rejsdagsöversikter måste du auktorisera dataöverföringen till OpenRouter i din användarprofil under 'AI-funktioner och integritet'.", + "owm_help": "Valfritt: egen OpenWeatherMap-API-nyckel. Om inget anges används den serverbaserade nyckeln från operatörskonfigurationen.", + "ai_title": "AI-funktioner och dataskydd", + "ai_desc": "Godkänn användningen av artificiell intelligens (lokala/molnbaserade integrationer) för dina loggböcker.", + "ai_help": "När funktionen är aktiverad kan reserapporter sammanfattas automatiskt och röstmeddelanden transkriberas. För bearbetning överförs röstinspelningar och loggboksanteckningar i krypterad form till OpenRouter. Uppgifterna sparas inte permanent där.\n\nEftersom driften av dessa molnresurser medför kostnader uppskattar vi frivilligt stöd via Ko-fi-donationslänken i sidfoten, så att vi kan erbjuda dessa funktioner gratis för alla på lång sikt.", + "ai_enable_label": "Aktivera transkribering och dagliga sammanfattningar", + "ai_unauthorized_alert_title": "AI-funktioner är inte tillåtna", + "ai_unauthorized_alert_desc": "För att transkribera röstmemon eller sammanfatta reseskildringar måste du godkänna dataöverföringen till OpenRouter i din användarprofil under ”AI-funktioner & integritet”.", "prefs_save": "Spara", - "prefs_saving": "Kommer att sparas...", - "prefs_saved": "Sparade", - "tour_title": "App-turné", - "tour_desc": "Låt dig vägledas genom de viktigaste områdena i appen igen.", - "tour_restart": "Starta resan igen", + "prefs_saving": "Sparas…", + "prefs_saved": "Sparat", + "tour_title": "App-rundtur", + "tour_desc": "Låt dig återigen guidas genom appens viktigaste funktioner.", + "tour_restart": "Starta om turen", "push_title": "Push-meddelanden", - "push_desc": "Som loggboksägare får du ett meddelande när inbjudna Crew-medlemmar synkroniserar ändringar. Inget innehåll överförs i klartext.", - "push_enable": "Meddela oss om förändringar i crewen", - "push_active": "Push-meddelanden är aktiva på den här enheten.", + "push_desc": "Som loggboksägare får du ett meddelande när inbjudna besättningsmedlemmar synkroniserar ändringar. Inget innehåll överförs i klartext.", + "push_enable": "Meddela vid förändringar i besättningen", + "push_active": "Push-meddelanden är aktiverade på den här enheten.", "push_unsupported": "Push-meddelanden stöds inte i den här webbläsaren.", "push_denied_hint": "Meddelanden är blockerade. Tillåt dem i webbläsarens eller enhetens inställningar.", - "push_ios_install_hint": "På iPhone/iPad: Lägg till app på startskärmen (iOS 16.4+) för att använda push.", - "push_error": "Push-meddelanden kunde inte aktiveras.", + "push_ios_install_hint": "På iPhone/iPad: Lägg till appen på hemskärmen (iOS 16.4+) för att kunna använda push-meddelanden.", + "push_error": "Det gick inte att aktivera push-meddelanden.", "sections": { "account": "Konto och inställningar", - "fleet": "Flotta och besättning", - "security": "Säkerhet och enhet", + "fleet": "Flotta & besättning", + "security": "Säkerhet & utrustning", "stats": "Statistik", - "danger": "Riskzon" + "danger": "Farlig zon" } }, "vessel_pool": { - "title": "Skipsflotta", + "title": "Fartygsflotta", "section_title": "Dina fartyg", - "subtitle": "Underhåll alla fartyg för dina loggböcker här. Välj aktivt fartyg per loggbok från listan.", - "loading": "Laddar fartygsflotta…", + "subtitle": "Här hanterar du alla fartyg för dina loggböcker. För varje loggbok väljer du det aktiva fartyget från den här listan.", + "loading": "Fartygsflottan laddas…", "add_vessel": "Lägg till fartyg", "edit_vessel": "Redigera fartyg", - "no_vessels": "Inga fartyg i poolen ännu.", - "delete_confirm": "Ta bort detta fartyg från flottan?", - "max_vessels": "Högst 20 fartyg i poolen." + "no_vessels": "Inga fartyg i flottan ännu.", + "delete_confirm": "Vill du verkligen ta bort det här fartyget från flottan?", + "max_vessels": "Det maximala antalet på 20 fartyg i flottan har uppnåtts." }, "logbook_vessel": { "title": "Fartyg för denna loggbok", - "subtitle": "Välj fartyg för denna loggbok. Resdagar använder segel- och tankdata från valt fartyg.", + "subtitle": "Välj fartyg för denna loggbok. Resdagarna baseras på seglings- och bränsleuppgifter för det valda fartyget.", "active_vessel": "Fartyg för denna loggbok", - "no_vessels_in_pool": "Inget fartyg i flottan – lägg till i användarprofilen först.", + "no_vessels_in_pool": "Inget fartyg i flottan – lägg först till det i användarprofilen.", "no_vessel": "Inget fartyg valt", "unnamed": "Namnlös", "save": "Spara fartyg", - "saved": "Loggbok-fartyg sparat.", - "selection_only_hint": "Du ser fartyget ägaren valt (delad loggbok).", + "saved": "Fartyget har sparats i loggboken.", + "selection_only_hint": "Du ser det fartyg som ägaren har valt (delad loggbok).", "manage_in_profile": "Hantera fartyg i användarprofilen" }, "person_pool": { - "title": "Stamm-Crew och skeppare", - "subtitle": "Underhåll din personpool här – skeppare och crew för alla loggböcker. Välj aktiv crew per loggbok och resdag från poolen.", - "loading": "Laddar personpool…", - "skippers_section": "Skeppare", - "crew_section": "Stamm-Crew", + "title": "Fast besättning & skeppare", + "subtitle": "Skapa din personalpool här – skeppare och besättning för alla loggböcker. Ur denna pool väljer du den aktiva besättningen för varje loggbok och resedag.", + "loading": "Personpoolen laddas…", + "skippers_section": "Stamskipper", + "crew_section": "Stamteamet", "add_skipper": "Lägg till skeppare", - "add_crew": "Lägg till Crew-medlem", + "add_crew": "Lägg till en besättningsmedlem", "edit_skipper": "Redigera skeppare", "no_skippers": "Ingen skeppare i poolen ännu.", - "no_crew": "Inga Crew-medlemmar i poolen ännu.", - "delete_confirm": "Ta bort denna person från poolen?" + "no_crew": "Det finns ännu inga besättningsmedlemmar i poolen.", + "delete_confirm": "Vill du verkligen ta bort den här personen från gruppen?" }, "logbook_crew": { - "title": "Crew för denna loggbok", - "subtitle": "Välj skeppare och crew för denna loggbok. Nya resdagar ärver valet som standard.", - "loading": "Laddar crew…", + "title": "Besättning för denna loggbok", + "subtitle": "Välj skeppare och besättning för denna loggbok. Dessa val överförs automatiskt till nya resdagar.", + "loading": "Besättningen laddas…", "active_skipper": "Skeppare för denna loggbok", - "active_crew": "Crew för denna loggbok", - "no_skippers_in_pool": "Ingen skeppare i poolen – lägg till i användarprofilen först.", - "no_crew_in_pool": "Ingen crew i poolen – lägg till i användarprofilen först.", - "no_skipper": "Ingen skeppare vald", + "active_crew": "Besättning för denna loggbok", + "no_skippers_in_pool": "Ingen skeppare i poolen – lägg först till en i användarprofilen.", + "no_crew_in_pool": "Ingen besättning i poolen – lägg först till den i användarprofilen.", + "no_skipper": "Ingen skeppare har valts", "unnamed": "Namnlös", - "save": "Spara crew", - "saved": "Loggbok-Crew sparad.", - "selection_only_hint": "Du ser den crew ägaren valt (delad loggbok)." + "save": "Spara besättning", + "saved": "Besättningen har sparats i loggboken.", + "selection_only_hint": "Du ser den besättning som ägaren har angett (delad loggbok)." }, "entry_crew": { - "title": "Crew denna resdag", - "subtitle": "Kan skilja sig från loggboksstandard. Följande dagar ärver från föregående dag.", - "day_skipper": "Skeppare denna dag", - "day_crew": "Crew denna dag", - "no_skipper": "Ingen skeppare vald", - "no_crew": "Ingen crew vald" + "title": "Besättningen denna resedag", + "subtitle": "Kan avvika från loggbokens standard. Följande resdagar övertar föregående dag.", + "day_skipper": "Dagens skeppare", + "day_crew": "Besättningen den dagen", + "no_skipper": "Ingen skeppare har valts", + "no_crew": "Ingen besättning vald" }, "crew": { - "title": "Profiler för skeppare och crew", - "skipper_section": "Skepparens profil", - "skipper_read_only_hint": "Skepparens profil kan endast redigeras av loggbokens ägare.", - "crew_section": "Crew-lista", - "add_crew": "Lägg till Crew-medlem", - "edit_crew": "Redigera Crew-medlem", - "no_crew": "Inga Crew-medlemmar har lagts till ännu.", - "max_crew": "Maximalt antal på 12 Crew-medlemmar i poolen uppnått.", + "title": "Skeppar- och besättningsprofiler", + "skipper_section": "Skipperprofil", + "skipper_read_only_hint": "Skipperprofilen kan endast redigeras av loggbokens ägare.", + "crew_section": "Besättningslista", + "add_crew": "Lägg till en besättningsmedlem", + "edit_crew": "Redigera besättningsmedlem", + "no_crew": "Inga besättningsmedlemmar har lagts till ännu.", + "max_crew": "Det maximala antalet på 12 besättningsmedlemmar i poolen har uppnåtts.", "name": "Namn", - "address": "adress", + "address": "Adress", "birthdate": "Födelsedag", "phone": "Telefonnummer", "nationality": "Nationalitet", - "passport": "Pass/ID-nummer", + "passport": "Pass-/ID-nummer", "bloodtype": "Blodgrupp", "allergies": "Allergier", - "diseases": "Redan existerande tillstånd/sjukdomar", - "save": "Spara skeppardata", + "diseases": "Tidigare sjukdomar / sjukdomar", + "save": "Spara skepparuppgifter", "save_member": "Spara medlem", - "saved": "Skepparens profil har sparats!", - "loading": "Crew-filerna är laddade...", - "delete_confirm": "Är du säker på att du vill ta bort den här Crew-medlemmen?" + "saved": "Skipperprofilen har sparats!", + "loading": "Besättningsfiler laddas...", + "delete_confirm": "Är du säker på att du vill ta bort den här medlemmen ur gruppen?" }, "deviation": { - "title": "Tabell för kompassavvikelse", - "subtitle": "Ange den magnetiska kompassdeflektionen (deflektion) för kurser (MgK) från 000° till 360° i steg om 10°.", + "title": "Avvikelse-tabell (kompassavvikelse)", + "subtitle": "Ange magnetkompassens avvikelse (Abl.) för kurser (MgK) från 000° till 360° i steg om 10°.", "heading": "MgK", "deviation": "Distraktion", - "save": "Spara kalibreringsrutan", - "saving": "Kommer att sparas...", - "saved": "Kalibreringsnätet har sparats framgångsrikt!", - "loading": "Kalibreringsbordet är laddat..." + "save": "Spara kalibreringsrutnät", + "saving": "Sparas...", + "saved": "Kalibreringsrutnätet har sparats!", + "loading": "Kalibreringstabellen laddas..." }, "settings": { - "title": "Inställningar för loggbok", - "subtitle": "Dela, säkerhetskopiera och samarbeta för den här loggboken.", + "title": "Inställningar för loggboken", + "subtitle": "Dela, säkerhetskopiera och samarbeta kring denna loggbok.", "select_logbook_hint": "Välj en loggbok för att redigera dess inställningar.", - "no_key": "Ingen OpenWeatherMap API-nyckel tillgänglig. Spara din egen nyckel i användarprofilen eller kontakta operatören.", - "weather_success": "Väderdata har hämtats framgångsrikt!", - "weather_error": "Hämtning av väderdata misslyckades. Kontrollera API-nyckeln och anslutningen.", - "weather_unauthorized": "Hämtning av väderdata misslyckades. API-nyckeln är ogiltig eller inte auktoriserad.", - "weather_not_found": "Hämtning av väderdata misslyckades. Den angivna platsen eller koordinaterna hittades inte.", - "weather_bad_request": "Hämtning av väderdata misslyckades. Ingen plats eller GPS-position angavs.", - "weather_date_mismatch": "Väderdata kan endast hämtas för idag ({{today}}). Denna loggbokspost är daterad {{date}}.", - "gps_error": "Ange en plats eller bestäm GPS-koordinaterna.", - "share_title": "Aktieloggbok (skrivskyddad)", - "share_desc": "Aktivera det här alternativet för att skapa en publik, skrivskyddad länk. Alla som har länken kan se dina resor, båtprofiler och crew. Krypteringsnycklarna överförs aldrig till servern (de finns kvar i hashdelen av URL:en).", - "share_privacy_warning": "Rekommendation: Dela endast den här länken privat (t.ex. via e-post eller messenger), inte på sociala medier.", + "no_key": "Ingen OpenWeatherMap-API-nyckel tillgänglig. Lägg in en egen nyckel i användarprofilen eller kontakta operatören.", + "weather_success": "Väderdata har hämtats!", + "weather_error": "Hämtningen av väderdata misslyckades. Kontrollera API-nyckeln och anslutningen.", + "weather_unauthorized": "Hämtningen av väderdata misslyckades. API-nyckeln är ogiltig eller inte auktoriserad.", + "weather_not_found": "Det gick inte att hämta väderdata. Den angivna orten eller koordinaterna hittades inte.", + "weather_bad_request": "Hämtningen av väderdata misslyckades. Ingen ort eller GPS-position har angetts.", + "weather_date_mismatch": "Väderdata kan endast hämtas för dagens datum ({{today}}). Denna loggboksanteckning är daterad den {{date}}.", + "gps_error": "Ange en plats eller ta reda på GPS-koordinaterna.", + "share_title": "Dela loggboken (skrivskyddad)", + "share_desc": "Aktivera det här alternativet för att skapa en offentlig, skrivskyddad länk. Alla som har länken kan se dina resor, båtprofiler och besättning. Krypteringsnycklarna överförs aldrig till servern (de förblir i hash-delen av URL:en).", + "share_privacy_warning": "Rekommendation: Dela den här länken endast privat (t.ex. via e-post eller meddelandetjänster), inte på sociala medier.", "share_enable": "Aktivera offentlig länk", - "share_copied": "Länk kopierad!", - "share_copy_btn": "Kopiera länk", - "link_qr_hint": "Skanna QR-koden med mobilen", + "share_copied": "Länken har kopierats!", + "share_copy_btn": "Kopiera länken", + "link_qr_hint": "QR-kod att skanna med smarttelefonen", "link_qr_alt": "QR-kod för länken", "danger_zone_title": "Farlig zon", - "danger_zone_desc": "Om du raderar ditt konto raderas oåterkalleligen alla dina Passkey, loggböcker, fartygsdata, Crew-profiler, reseanteckningar och E2E-nycklar. Denna åtgärd kan inte ångras.", - "delete_account_btn": "Ta bort konto oåterkalleligt", - "delete_account_confirm_title": "Radera konto?", - "delete_account_confirm_desc": "Är du helt säker på att du oåterkalleligen vill radera ditt konto och alla tillhörande loggböcker och E2E-krypterade data?", - "delete_account_confirm_yes": "Ja, radera konto och all data", + "danger_zone_desc": "Om du raderar ditt konto kommer alla dina Passkey, loggböcker, fartygsdata, besättningsprofiler, reseinlägg och E2E-nycklar att raderas permanent. Denna åtgärd kan inte ångras.", + "delete_account_btn": "Radera kontot permanent", + "delete_account_confirm_title": "Vill du radera kontot?", + "delete_account_confirm_desc": "Är du helt säker på att du vill radera ditt konto och alla tillhörande loggböcker samt E2E-krypterade data utan möjlighet till återställning?", + "delete_account_confirm_yes": "Ja, radera kontot och alla uppgifter", "delete_account_confirm_no": "Avbryt", - "delete_account_failed": "Kontot kunde inte raderas. Vänligen försök igen.", - "delete_backup_hint": "Tips: Skapa säkerhetskopior av dina loggböcker (.daagbok) i inställningarna för varje loggbok innan du raderar dem.", - "deleting_account": "Kontot kommer att raderas...", - "invite_push_prompt_title": "Aktivera push-meddelanden?", - "invite_push_prompt_message": "Så snart inbjudna Crew-medlemmar synkroniserar ändringar kan du bli informerad via push. Inget loggboksinnehåll skickas i klartext.", - "invite_push_prompt_ios_message": "Så snart Crew-medlemmar synkroniserar ändringar kan du bli informerad via push. På iPhone/iPad: Lägg till appen på startskärmen (iOS 16.4+) och aktivera sedan push i användarprofilen.", + "delete_account_failed": "Kontot kunde inte raderas. Försök igen.", + "delete_backup_hint": "Tips: Gör säkerhetskopior av dina loggböcker (.daagbok) i inställningarna för varje loggbok innan du raderar dem.", + "deleting_account": "Kontot raderas…", + "invite_push_prompt_title": "Vill du aktivera push-meddelanden?", + "invite_push_prompt_message": "Så snart inbjudna besättningsmedlemmar synkroniserar ändringar kan du få ett push-meddelande. Inget innehåll från loggboken skickas i klartext.", + "invite_push_prompt_ios_message": "Så snart teammedlemmarna synkroniserar ändringar kan du få ett push-meddelande. På iPhone/iPad: Lägg till appen på hemskärmen (iOS 16.4+), och aktivera sedan push-meddelanden i användarprofilen.", "invite_push_prompt_enable": "Aktivera nu", "invite_push_prompt_later": "Senare", - "invite_push_prompt_success": "Push-meddelanden är aktiva på den här enheten.", + "invite_push_prompt_success": "Push-meddelanden är aktiverade på den här enheten.", "backup_title": "Säkerhetskopiering och återställning", - "backup_desc": "Komplett krypterad säkerhetskopia av denna loggbok (poster, foton, GPS-spår, crew, fartyg). Skyddad med lösenfras för säkerhetskopian - för återställning till detta eller ett nytt konto.", - "backup_export_title": "Skapa säkerhetskopia", - "backup_export_desc": "Laddar ner alla lokala data som ett komprimerat .daagbok-arkiv. Förvara filen och lösenfrasen separat och säkert.", - "backup_restore_title": "Återställ säkerhetskopian", - "backup_restore_desc": "Återställer en säkerhetskopia till ditt nuvarande konto - även efter att du har registrerat ett nytt konto.", - "backup_passphrase": "Lösenord för säkerhetskopiering", + "backup_desc": "Fullständig krypterad säkerhetskopia av denna loggbok (inlägg, foton, röstmeddelanden, GPS-spår, besättning, fartyg). Skyddad med säkerhetskopieringslösenord – för återställning på detta eller ett nytt konto.", + "backup_export_title": "Skapa en säkerhetskopia", + "backup_export_desc": "Ladda ner alla lokala data som en komprimerad .daagbok-fil. Förvara filen och lösenordet separat och på ett säkert ställe.", + "backup_restore_title": "Återställ säkerhetskopia", + "backup_restore_desc": "Återställer en säkerhetskopia i ditt nuvarande konto — även efter att du har registrerat ett nytt konto.", + "backup_passphrase": "Säkerhetsfras", "backup_passphrase_placeholder": "Minst 8 tecken", - "backup_passphrase_confirm": "Bekräfta lösenfras", - "backup_passphrase_short": "Säkerhetskopians lösenfras måste vara minst 8 tecken lång.", - "backup_passphrase_mismatch": "Lösenfraserna stämmer inte överens.", - "backup_wrong_passphrase": "Lösenordet är felaktigt eller säkerhetskopian är skadad.", - "backup_export_btn": "Ladda ner backup", - "backup_exporting": "Säkerhetskopian skapas...", + "backup_passphrase_confirm": "Bekräfta lösenordsfrasen", + "backup_passphrase_short": "Säkerhetsfrasen måste bestå av minst 8 tecken.", + "backup_passphrase_mismatch": "Lösenordssatserna stämmer inte överens.", + "backup_wrong_passphrase": "Felaktig lösenfras eller skadad säkerhetskopia.", + "backup_export_btn": "Ladda ner säkerhetskopian", + "backup_exporting": "Säkerhetskopiering pågår…", "backup_export_success": "Säkerhetskopia skapad ({{count}} resdagar).", - "backup_file_label": "Säkerhetskopieringsfil (.daagbok)", - "backup_export_progress": "Packar filer {{current}} / {{total}}…", - "backup_invalid_archive": "Filen är inte ett giltigt backup-arkiv.", - "backup_version_unsupported": "Gammalt backup-format (v1). Använd en aktuell .daagbok-säkerhetskopia.", - "backup_import_size_confirm": "Denna säkerhetskopia är ca. {{size}} okomprimerad. Återställning kan ta längre tid. Fortsätta?", - "backup_stat_voice": "{{count}} röstanteckningar", - "backup_stat_size": "Ca. {{size}} okomprimerat", - "backup_preview_btn": "Kontrollera innehåll", - "backup_previewing": "Check...", + "backup_file_label": "Säkerhetskopia (.daagbok)", + "backup_export_progress": "Packa filerna {{current}} / {{total}}…", + "backup_invalid_archive": "Filen är inte ett giltigt säkerhetskopieringsarkiv.", + "backup_version_unsupported": "Gammalt säkerhetskopieringsformat (v1). Använd en aktuell .daagbok-säkerhetskopia.", + "backup_import_size_confirm": "Denna säkerhetskopia är ungefär {{size}} stor. Återställningen kan ta längre tid på enheten och ta upp mycket lagringsutrymme. Vill du fortsätta?", + "backup_stat_voice": "{{count}} Röstmemonter", + "backup_stat_size": "Okomprimerad ca. {{size}}", + "backup_preview_btn": "Kontrollera innehållet", + "backup_previewing": "Kontrollera…", "backup_restore_btn": "Återställ", - "backup_restoring": "Kommer att återställas...", - "backup_restore_success": "Loggbok \"{{title}}\" har återställts.", - "backup_restore_cancelled": "Återhämtning avbruten.", + "backup_restoring": "Återställs…", + "backup_restore_success": "Loggboken ”{{title}}” har återställts.", + "backup_restore_cancelled": "Återställningen avbröts.", "backup_invalid_json": "Filen är inte en giltig JSON-fil.", - "backup_invalid_format": "Okänt eller föråldrat backupformat.", + "backup_invalid_format": "Okänt eller föråldrat säkerhetskopieringsformat.", "backup_not_owner": "Endast loggbokens ägare kan skapa säkerhetskopior.", "backup_not_authenticated": "Logga in för att återställa en säkerhetskopia.", - "backup_id_conflict": "En loggbok med detta ID finns redan.", - "backup_overwrite_confirm": "Den befintliga loggboken med samma ID ersätts. Fortsätter du?", - "backup_new_id_confirm": "Importera säkerhetskopian som en ny loggbok med ett nytt ID?", + "backup_id_conflict": "Det finns redan en loggbok med det här ID-numret.", + "backup_overwrite_confirm": "Den befintliga loggboken med samma ID kommer att ersättas. Vill du fortsätta?", + "backup_new_id_confirm": "Ska säkerhetskopian importeras som en ny logg med ett nytt ID?", "backup_stat_entries": "{{count}} Resdagar", "backup_stat_photos": "{{count}} Foton", - "backup_stat_crew": "{{count}} Crew-poster", + "backup_stat_crew": "{{count}} Besättningsmedlemmar", "backup_stat_tracks": "{{count}} GPS-spår", - "backup_exported_at": "Exporterad: {{date}}" + "backup_exported_at": "Exporterat: {{date}}" }, "disclaimer": { - "title": "Viktiga anmärkningar", - "intro": "Läs följande anvisningar innan du använder Kapteins Daagbok.", + "title": "Viktig information", + "intro": "Läs följande information innan du använder Kapteins Daagbok.", "e2e_title": "End-to-end-kryptering", - "e2e_body": "Dina loggboksdata är krypterade från början till slut. Endast du - eller personer med din nyckel - kan läsa innehållet. Endast krypterade data lagras på servern.", - "pwa_title": "Progressiv webbapplikation (PWA)", - "pwa_body": "Kapteins Daagbok körs som en progressiv webbapp i din webbläsare och kan installeras på din enhet - på samma sätt som en native-app, utan en appbutik.", + "e2e_body": "Uppgifterna i din loggbok krypteras från ändpunkt till ändpunkt. Endast du – eller personer som har din nyckel – kan läsa innehållet. Endast krypterade data lagras på servern.", + "pwa_title": "Progressiv webbapp (PWA)", + "pwa_body": "Kapteins Daagbok körs som en progressiv webbapp i din webbläsare och kan installeras på din enhet – ungefär som en inbyggd app, men utan appbutik.", "storage_title": "Lokal lagring och synkronisering", - "storage_body": "Dina data lagras lokalt på din enhet (IndexedDB). Ändringar synkroniseras med servern när en internetanslutning är aktiv. Du kan fortsätta att arbeta utan anslutning, synkroniseringen sker senare.", - "free_title": "Kostnadsfritt och reklamfritt", - "free_body": "Kapteins Daagbok är kostnadsfritt och innehåller ingen reklam.", + "storage_body": "Dina data sparas tillfälligt lokalt på din enhet (IndexedDB). När du är ansluten till internet synkroniseras ändringarna med servern. Du kan fortsätta arbeta även utan internetuppkoppling; synkroniseringen sker senare.", + "free_title": "Gratis och utan reklam", + "free_body": "Kapteins Daagbok är gratis och innehåller inga annonser.", "liability_title": "Ansvarsfriskrivning", - "liability_body": "Användningen av appen sker på egen risk. Inget ansvar accepteras för skador som uppstår till följd av användningen av appen - inklusive felaktiga eller ofullständiga loggboksanteckningar, förlust av data eller tekniska fel.", + "liability_body": "Användningen sker på eget ansvar. Vi tar inget ansvar för skador som uppstår till följd av användningen av appen – inklusive felaktiga eller ofullständiga loggboksanteckningar, dataförlust eller tekniska störningar.", "warranty_title": "Ingen garanti", - "warranty_body": "Ingen garanti ges för tjänstens funktion, korrekthet eller tillgänglighet. Driften kan när som helst avbrytas, begränsas eller ställas in.", + "warranty_body": "Ingen garanti ges för tjänstens funktion, korrekthet eller tillgänglighet. Driften kan när som helst avbrytas, begränsas eller upphöra.", "copyright": "© 2026 KnorrLabs, Markus F.J. Busche", - "accept": "Acceptera och fortsätt", - "close": "Nära", - "button_title": "Anmärkningar och ansvarsfriskrivning" + "accept": "Godkänn och fortsätt", + "close": "Stäng", + "button_title": "Information och ansvarsfriskrivning" }, "feedback": { "button_title": "Skicka feedback", - "title": "Återkoppling", - "intro": "Dela med dig av buggar, idéer eller allmän feedback. Ditt meddelande kommer att skickas till projektgruppen via en säker meddelandekanal.", + "title": "Feedback", + "intro": "Dela med dig av fel, idéer eller allmän feedback. Ditt meddelande skickas till projektteamet via en säker meddelandekanal.", "category_label": "Kategori", "category_general": "Allmänt", "category_bug": "Rapportera fel", - "category_feature": "Begäran om funktion", + "category_feature": "Önskemål om funktion", "category_translation": "Översättningsfel", "contact_label": "E-post (valfritt)", "contact_placeholder": "deine@email.beispiel", "message_label": "Meddelande", - "message_placeholder": "Beskriv din feedback...", + "message_placeholder": "Beskriv din feedback…", "send": "Skicka", - "sending": "Kommer att skickas...", + "sending": "Sänds nu…", "cancel": "Avbryt", "success": "Tack så mycket! Din feedback har skickats.", - "error_send": "Feedback kunde inte skickas. Vänligen försök igen senare.", - "error_invalid_email": "Vänligen ange en giltig e-postadress.", + "error_send": "Det gick inte att skicka feedbacken. Försök igen senare.", + "error_invalid_email": "Ange en giltig e-postadress.", "error_not_configured": "Feedback är inte tillgängligt på den här servern.", - "error_rate_limited": "För många feedbackmeddelanden på kort tid. Vänligen vänta några minuter.", - "error_spam": "Det här meddelandet kunde inte skickas. Vänligen omformulera det." + "error_rate_limited": "För många feedbackmeddelanden på kort tid. Vänta några minuter.", + "error_spam": "Det gick inte att skicka detta meddelande. Formulera det på ett annat sätt." }, "demo": { - "logbook_title": "Demo loggbok Östersjön", - "badge": "Demo", - "public_banner": "Skrivskyddad demovy", + "logbook_title": "Demologgbok Östersjön", + "badge": "Demoversion", + "public_banner": "Skrivskyddad demoversion", "cta_register": "Skapa konto", - "back_to_login": "Till registreringen" + "back_to_login": "Gå till registreringen" }, "invitation": { - "error_invalid_key": "Länken till inbjudan är kryptografiskt ogiltig (nyckeln är felaktig).", - "error_missing_key": "Länken till inbjudan innehåller ingen dekrypteringsnyckel (#key=...). Vänligen använd den fullständiga länken från ägaren.", - "error_expired": "Denna inbjudan har löpt ut (giltig i 48 timmar).", - "error_invalid_token": "Inbjudan ogiltig.", - "error_load_failed": "Inbjudan kunde inte läsas in.", - "error_incomplete_session": "Sessionen är ofullständig - logga in igen (användar-ID saknas).", - "error_accept_failed": "Anslutningen misslyckades.", - "error_login_failed": "Passkey Inloggningen misslyckades.", - "error_username_missing": "Användarnamnet kunde inte fastställas - vänligen logga in igen.", + "error_invalid_key": "Inbjudningslänken är kryptografiskt ogiltig (felaktig nyckel).", + "error_missing_key": "Inbjudningslänken innehåller ingen dekrypteringsnyckel (#key=...). Använd den fullständiga länken från ägaren.", + "error_expired": "Denna inbjudan har gått ut (giltig i 48 timmar).", + "error_invalid_token": "Inbjudningstokenet är ogiltigt.", + "error_load_failed": "Det gick inte att hämta informationen om inbjudan.", + "error_incomplete_session": "Inloggningen är ofullständig – logga in igen (användar-ID saknas).", + "error_accept_failed": "Registreringen misslyckades.", + "error_login_failed": "Passkey-Inloggningen misslyckades.", + "error_username_missing": "Användarnamnet kunde inte hittas – logga in igen.", "error_register_failed": "Registreringen misslyckades.", - "loading_joining": "Ansluter sig...", - "loading_checking": "Inbjudan kommer att kontrolleras...", - "loading_unlocking": "Loggboken är upplåst och synkroniserad...", - "loading_retrieving_key": "Ladda ner krypteringsnyckel...", - "error_title": "Fel i inbjudan", + "loading_joining": "Anslutning...", + "loading_checking": "Inbjudan granskas...", + "loading_unlocking": "Loggboken aktiveras och synkroniseras...", + "loading_retrieving_key": "Laddar krypteringsnyckel...", + "error_title": "Inbjudningsfel", "back_to_start": "Tillbaka till början", - "title": "Inbjudan till loggbok", + "title": "Inbjudan till loggboken", "invited_by": "Inbjudan från", "vessel_logbook": "Fartyg / Loggbok", - "signed_in_preparing": "Registrerad som {{username}}. Anslutning förbereds...", + "signed_in_preparing": "Inloggad som {{username}}. Anslutning förbereds...", "join_again": "Gå med igen", - "login_or_register_hint": "Logga in eller registrera ett konto för att gå med i loggboken.", - "or_sign_up": "ELLER REGISTRERA DIG IGEN", - "register_crew_account": "Skapa ett nytt konto för crewen", - "username_label": "Användarens namn", - "create_passkey": "Skapa Passkey.", + "login_or_register_hint": "Logga in eller skapa ett konto för att gå med i loggboken.", + "or_sign_up": "ELLER REGISTRERA DIG", + "register_crew_account": "Skapa ett nytt teamkonto", + "username_label": "Användarnamn", + "create_passkey": "Skapa Passkey", "switch_language_en": "Engelska", - "switch_language_de": "Tysk" + "switch_language_de": "Tyska" }, "stats": { "title": "Statistik", - "subtitle": "Översikt över rutter, förbrukning och typ av körning", - "scope_label": "Utvärderingsområde", + "subtitle": "Räckvidd, bränsleförbrukning och drivsystem i korthet", + "scope_label": "Analysområde", "scope_logbook": "Denna loggbok", "scope_account": "Alla loggböcker", - "loading": "Statistiken är beräknad...", - "no_data": "Inga resdagar tillgängliga ännu.", - "total_distance": "Totalt avstånd", - "travel_days": "Resdagar", + "loading": "Statistiken beräknas…", + "no_data": "Inga resedagar ännu.", + "total_distance": "Total sträcka", + "travel_days": "Resedagar", "sail_distance": "Under segel", - "motor_distance": "Maskinens resa", - "motor_hours_total": "Totalt antal maskintimmar", - "daily_motor_hours": "Maskintimmar per resdag", - "avg_motor_hours": "Ø maskintimmar per resdag", + "motor_distance": "Maskinrutt", + "motor_hours_total": "Totalt antal driftstimmar", + "daily_motor_hours": "Maskinstimmar per resdag", + "avg_motor_hours": "Genomsnittligt antal maskintimmar per resdag", "unknown_propulsion": "Okänd", - "fuel_total": "Totalt bränsle", - "water_total": "Totalt vatten", - "daily_etmal": "Dagliga tider", - "daily_consumption": "Daglig konsumtion", - "route_overview": "Vägbeskrivning", - "route_map_title": "Översikt över rutten", - "propulsion_title": "Segel vs. maskin", - "propulsion_hint": "Fördelningen baseras på loggbokshändelser per resdag, inte på GPS-segment.", - "avg_distance": "Ø per resdag", + "fuel_total": "Bränsle totalt", + "water_total": "Vatten totalt", + "daily_etmal": "Dagsmål", + "daily_consumption": "Dagsförbrukning", + "route_overview": "Rutt", + "route_map_title": "Översikt över sträckorna", + "propulsion_title": "Segel mot motor", + "propulsion_hint": "Indelningen baseras på loggbokshändelserna per resedag, inte på GPS-segment.", + "avg_distance": "i genomsnitt per resdag", "avg_fuel": "Ø Bränsle", "avg_water": "Ø Vatten", - "fuel_per_nm": "Bränsle per sm", - "fuel_per_motor_hour": "Bränsle per maskintimme", - "daily_fuel_per_motor_hour": "Bränsleförbrukning per maskintimme och resdag", + "fuel_per_nm": "Bränsle per sjömil", + "fuel_per_motor_hour": "Bränsle per driftstimme", + "daily_fuel_per_motor_hour": "Bränsleförbrukning per maskintimme per resdag", "fuel_legend": "Bränsle", "water_legend": "Vatten", "unit_nm": "sm", "unit_h": "h", "unit_l": "L", - "day_label": "Dag {{day}}__.", - "account_logbooks": "Loggböcker i en överblick", + "day_label": "Dag {{day}}", + "account_logbooks": "Översikt över loggböcker", "col_logbook": "Loggbok", "event_series_title": "Händelseförlopp", "event_series_hint": "Kronologiska värden från händelseloggen.", "event_series_pressure": "Lufttryck", "event_series_wind": "Vind", "event_series_motor": "Motor", - "event_series_empty": "Inga poster ännu." + "event_series_empty": "Inga poster finns." }, "tour": { - "skip": "Hoppa över turen", + "skip": "Hoppa över rundturen", "back": "Tillbaka", - "next": "Ytterligare", - "finish": "Färdig", - "progress": "Steg {{current}} från {{total}}.", + "next": "Fortsätt", + "finish": "Klar", + "progress": "Steg {{current}} av {{total}}", "steps": { "welcome": { "title": "Välkommen ombord!", - "body": "Vi har skapat en demo-loggbok med tre dagars resa i Kielfjorden åt dig. Du kan när som helst radera exempelposterna om du vill starta din egen loggbok. Den här korta rundturen visar dig de viktigaste funktionerna." + "body": "Vi har skapat en demologgbok åt dig med tre dagars segling i Kielerförden. Du kan när som helst radera exempelposterna om du vill börja med din egen loggbok. Denna korta tur visar dig de viktigaste funktionerna." }, "welcome_public": { "title": "Välkommen ombord!", - "body": "Utforska vår demologgbok med tre dagars resor i Kielfjorden – utan konto. Rundturen visar loggboksanteckningar samt val av fartyg och besättning för denna loggbok. Flotta och stamm-besättning hanterar du senare i användarprofilen." + "body": "Utforska vårt demologgbok med tre resdagar i Kielerförden – helt utan att behöva skapa ett konto. Turen visar dig loggboksposter samt valet av fartyg och besättning för denna loggbok. Du kan senare lägga till flottan och stambesättningen i din användarprofil." }, "nav_logs": { - "title": "Loggboksanteckningar", - "body": "Det är här du hanterar dina resdagar - avresa, destination, väder, bränslenivåer och GPS-spår." + "title": "Loggposter", + "body": "Här hanterar du dina resedagar – avfärd, destination, väder, bränslenivåer och GPS-spår." }, "entry_list": { "title": "Dina resdagar", - "body": "Varje kort representerar en resdag. Tryck på en post för att visa eller redigera detaljer." + "body": "Varje kort representerar en resedag. Tryck på en post för att se eller redigera detaljerna." }, "entry_open": { - "title": "Öppen resdag", - "body": "Så här ser en komplett loggboksanteckning ut - med händelser, tanknivåer och mycket mer." + "title": "Öppna resedag", + "body": "Så här ser en ifylld loggboksanteckning ut – med händelser, bränslenivåer och annat." }, "entry_track": { - "title": "GPS-spårning", - "body": "Ladda upp GPX-filer eller visa redan sparade rutter på kartan - inklusive avstånd och hastighet." + "title": "GPS-spår", + "body": "Ladda upp GPX-filer eller visa redan sparade rutter på kartan – inklusive sträcka och hastighet." }, "nav_vessel": { - "title": "Fartyg för loggbok", - "body": "Välj fartyg från flottan för denna loggbok. Hantera fartyg i användarprofilen under Flotta och besättning." + "title": "Fartyg för loggboken", + "body": "Välj vilket fartyg i din flotta som ska ingå i denna loggbok. Du hanterar dina fartyg i användarprofilen under Flotta & besättning." }, "profile_vessel_pool": { "title": "Fartygsflotta", - "body": "I användarprofilen lägger du in alla fartyg – charter, egen båt m.m. Välj sedan rätt fartyg per loggbok." + "body": "I användarprofilen lägger du in alla dina båtar – charterbåtar, egen båt osv. För varje loggbok väljer du sedan rätt båt." }, "profile_crew_pool": { - "title": "Stamm-Crew och skeppare", - "body": "I användarprofilen underhåller du en personpool – flera skeppare (t.ex. charter) och crew för alla loggböcker." + "title": "Fast besättning & skeppare", + "body": "I användarprofilen hanterar du din personalpool – flera skeppare (t.ex. för charter) och besättningsmedlemmar för alla loggböcker." }, "nav_logbook_crew": { - "title": "Crew per loggbok", - "body": "Välj skeppare och crew från poolen för denna loggbok. Resdagar ärver valet som standard." + "title": "Besättning per loggbok", + "body": "Välj från listan vem som ska anges som skeppare och besättning i denna loggbok. Resedagarna övertar detta val som standard." }, "nav_stats": { - "title": "Kontrollpanel för statistik", - "body": "Här kan du se körsträckor, bränsleförbrukning, ruttkartor och körandelar - automatiskt beräknade från dina loggboksanteckningar." + "title": "Statistikpanel", + "body": "Här kan du se körsträckor, bränsleförbrukning, rutkartor och drivkraftsfördelning – automatiskt beräknat utifrån dina loggboksanteckningar." }, "nav_feedback": { "title": "Skicka feedback", - "body": "Du kan använda det här formuläret för att skicka fel, idéer eller allmän feedback direkt till projektgruppen - även efter rundturen när som helst med hjälp av ikonen längst upp till höger." + "body": "Via det här formuläret kan du skicka felrapporter, förslag eller allmän feedback direkt till projektteamet – även efter turen, när som helst via ikonen uppe till höger." }, "nav_profile": { "title": "Din användarprofil", - "body": "Du kommer åt din personliga profil via skipperknappen högst upp - oavsett vilken loggbok som är aktuell." + "body": "Genom att klicka på Skipper-knappen högst upp kommer du till din personliga profil – oavsett vilken loggbok du befinner dig i just nu." }, "profile_preferences": { - "title": "Redovisning & presentation", - "body": "Här kan du hantera din konto-identitet, ditt tema och ljus/mörker-läge. Du kan när som helst starta om appturen. Passkeys och säkerhetsinställningar hittar du längre ner i profilen." + "title": "Konto & visning", + "body": "Här hanterar du din kontoidentitet, ditt tema och ljus-/mörkläget. Du kan starta appguiden om när som helst. Passkeys och säkerhetsinställningar hittar du längre ner i profilen." }, "finish": { "title": "Okej!", - "body": "Du kommer direkt till instrumentpanelen för statistik. Du kan när som helst starta om turen i din användarprofil. Ha en trevlig resa!" + "body": "Du kommer strax till statistikpanelen. Du kan när som helst starta om rundturen i din användarprofil. Trevlig resa!" } } }, "seo": { - "title": "Kapteins Daagbok - Gratis digital loggbok för båtar (reklamfri)", - "description": "Gratis, annonsfri digital loggbok för båtar med kryptering från början till slut och Passkey-inloggning. Dokumentera resdagar, GPS-spår, Crew- och fartygsdata på ett säkert sätt - även offline som PWA.", - "keywords": "Yachtloggbok, skeppsdagbok, ombordloggbok, segling, Passkey, E2E kryptering, GPS-spår, sjöfartsloggbok, gratis, reklamfri, gratis, utan reklam", + "title": "Kapteins Daagbok – Gratis digitalt loggbok för båtar (utan reklam)", + "description": "Gratis, reklamfritt digitalt båtloggbok med end-to-end-kryptering och Passkey-inloggning. Dokumentera resdagar, GPS-spår, besättning och fartygsdata på ett säkert sätt – även offline som PWA.", + "keywords": "Yachtloggbok, fartygsdagbok, loggbok, segling, Passkey, E2E-kryptering, GPS-spårning, maritim loggbok, kostnadsfri, utan reklam, gratis, utan annonser", "ogImageAlt": "Kapteins Daagbok Logotyp" } } diff --git a/client/src/utils/i18nLanguages.test.ts b/client/src/utils/i18nLanguages.test.ts index 36819e7..0bade56 100644 --- a/client/src/utils/i18nLanguages.test.ts +++ b/client/src/utils/i18nLanguages.test.ts @@ -20,14 +20,13 @@ vi.mock('../services/analytics.js', async (importOriginal) => { }) function createMockI18n(language: string): I18nInstance { - let current = language - return { - language: current, + const mock = { + language, changeLanguage: vi.fn(async (lng: string) => { - current = lng - ;(this as { language: string }).language = lng + mock.language = lng }) } as unknown as I18nInstance + return mock } describe('i18nLanguages', () => { @@ -72,11 +71,11 @@ describe('i18nLanguages', () => { }) it('cycleAppLanguage tracks the next language', () => { - const i18n = createMockI18n('nb') + const i18n = createMockI18n('es') cycleAppLanguage(i18n) expect(trackPlausibleEvent).toHaveBeenCalledWith(PlausibleEvents.LANGUAGE_CHANGED, { - from: 'nb', + from: 'es', to: 'de' }) }) diff --git a/client/src/utils/i18nLanguages.ts b/client/src/utils/i18nLanguages.ts index 36e0115..fe74d6d 100644 --- a/client/src/utils/i18nLanguages.ts +++ b/client/src/utils/i18nLanguages.ts @@ -2,7 +2,7 @@ import type { i18n as I18nInstance } from 'i18next' import { PlausibleEvents, trackPlausibleEvent } from '../services/analytics.js' /** Supported UI languages (ISO 639-1, language-only). */ -export const SUPPORTED_LANGUAGES = ['de', 'en', 'da', 'sv', 'nb'] as const +export const SUPPORTED_LANGUAGES = ['de', 'en', 'da', 'sv', 'nb', 'fr', 'es'] as const export type AppLanguage = (typeof SUPPORTED_LANGUAGES)[number] @@ -11,7 +11,9 @@ export const LANGUAGE_FLAGS: Record = { en: '🇬🇧', da: '🇩🇰', sv: '🇸🇪', - nb: '🇳🇴' + nb: '🇳🇴', + fr: '🇫🇷', + es: '🇪🇸' } export function normalizeAppLanguage(language?: string): AppLanguage { diff --git a/client/src/utils/seo.ts b/client/src/utils/seo.ts index e3e45d6..927de2d 100644 --- a/client/src/utils/seo.ts +++ b/client/src/utils/seo.ts @@ -10,7 +10,9 @@ const OG_LOCALES: Record = { en: 'en_GB', da: 'da_DK', sv: 'sv_SE', - nb: 'nb_NO' + nb: 'nb_NO', + fr: 'fr_FR', + es: 'es_ES' } let i18nRef: I18nInstance | null = null diff --git a/scripts/translate-locales.mjs b/scripts/translate-locales.mjs index 24ff322..8ac64d3 100644 --- a/scripts/translate-locales.mjs +++ b/scripts/translate-locales.mjs @@ -23,7 +23,9 @@ const defaultSource = resolve(repoRoot, 'client/src/i18n/locales/de.json') const TARGETS = { da: 'DA', sv: 'SV', - nb: 'NB' + nb: 'NB', + fr: 'FR', + es: 'ES' } /** Keys whose values stay identical to source (language names, brand). */ diff --git a/scripts/validate-i18n-keys.mjs b/scripts/validate-i18n-keys.mjs index 48b2f64..9bd0508 100644 --- a/scripts/validate-i18n-keys.mjs +++ b/scripts/validate-i18n-keys.mjs @@ -11,7 +11,7 @@ import { flattenTranslation } from './lib/deepl-translate.mjs' const __dirname = dirname(fileURLToPath(import.meta.url)) const localesDir = resolve(__dirname, '../client/src/i18n/locales') -const localeFiles = ['de.json', 'en.json', 'da.json', 'sv.json', 'nb.json'] +const localeFiles = ['de.json', 'en.json', 'da.json', 'sv.json', 'nb.json', 'fr.json', 'es.json'] async function loadKeys(filename) { const raw = await readFile(resolve(localesDir, filename), 'utf8')