فهرست منبع

Feat: add Swedish language (#3062)

maziggy 19 ساعت پیش
والد
کامیت
ba1ff35bce
3فایلهای تغییر یافته به همراه7695 افزوده شده و 1 حذف شده
  1. 20 0
      frontend/scripts/check-i18n-parity.mjs
  2. 4 1
      frontend/src/i18n/index.ts
  3. 7671 0
      frontend/src/i18n/locales/sv.ts

+ 20 - 0
frontend/scripts/check-i18n-parity.mjs

@@ -371,6 +371,25 @@ const ES_COGNATES = [
   'Simple',  // slicer settings visibility tier — identical word in Spanish
 ];
 
+// Swedish cognates — technical UI labels that Swedish speakers use verbatim
+// from English (loanwords + acronyms + format strings). Curated, not a shortcut.
+const SV_COGNATES = [
+  'MakerWorld: {{designer}}',
+  'email',
+  '{{printer}}: {{error}}',
+  'Bambu Cloud',
+  'Orca Cloud',
+  '{{name}} — {{stage}} ({{percent}}%) — {{elapsed}}',
+  'EC984C,#6CD4BC,A66EB9,D87694',
+  '({{count}}/8)',
+  '(25%, 50%, 75%)', 'System', 'Filament', 'Status', 'Total budget', 'Budget', 'Offline', 'Problem', 'Diameter', 'Standard',
+  'Live', 'Firmware', '{{filament}} @ {{temp}}°C', 'Standard (100%)', 'Sport (124%)', '{{weight}}g', 'Pipeline', 'Pipelines', 'Position', 'Batch', 'Timelapse', 'Online',
+  'Disk', 'STARTTLS (Port 587)', 'SSL/TLS (Port 465)', 'Start', 'Auto', 'Admin', 'Data', 'Material', 'Hex', 'Accent', 'Neutral', 'Orange', 'Rotation', 'Test',
+  'Port', '(System)', 'Autologin', 'Process', 'Filament {{n}}', 'Region', 'Global', 'Normal', 'Version', 'max {{n}}', 'Expert', 'Filament {{index}} ({{type}})', 'Material:',
+  '(Inv)', 'Original', 'Commit', 'Extruder', 'Gradient', 'Proxy', 'Metadata', '{{count}} filament', 'Temp', 'Min', 'ntfy, Pushover, Discord, etc.', 'Hex: #{{hex}}', 'Designer',
+  'Prefix', 'Trend', 'max(global {{global}}d, SKU {{sku}}d)', 'Slicer',
+];
+
 // Turkish cognates — technical UI labels that Turkish speakers use verbatim
 // from English (loanwords + acronyms + format strings). Curated, not a shortcut.
 const TR_COGNATES = [
@@ -465,6 +484,7 @@ const IDENTICAL_TO_EN_ALLOWED = {
   'pt-BR': new Set(PT_BR_COGNATES),
   'zh-CN': new Set(ZH_CN_COGNATES),
   'zh-TW': new Set(ZH_TW_COGNATES),
+  sv: new Set(SV_COGNATES),
   tr: new Set(TR_COGNATES),
   ru: new Set(RU_COGNATES),
   uk: new Set(UK_COGNATES),

+ 4 - 1
frontend/src/i18n/index.ts

@@ -14,6 +14,7 @@ import ko from './locales/ko';
 import ptBR from './locales/pt-BR';
 import zhCN from './locales/zh-CN';
 import zhTW from './locales/zh-TW';
+import sv from './locales/sv';
 import tr from './locales/tr';
 import ru from './locales/ru';
 import uk from './locales/uk';
@@ -30,12 +31,13 @@ const resources = {
   'pt-BR': { translation: ptBR },
   'zh-CN': { translation: zhCN },
   'zh-TW': { translation: zhTW },
+  sv: { translation: sv },
   tr: { translation: tr },
   ru: { translation: ru },
   uk: { translation: uk },
 };
 
-const SUPPORTED_LNGS = ['en', 'de', 'es', 'fr', 'ja', 'it', 'ko', 'nl', 'pt-BR', 'ru', 'tr', 'uk', 'zh-CN', 'zh-TW'];
+const SUPPORTED_LNGS = ['en', 'de', 'es', 'fr', 'ja', 'it', 'ko', 'nl', 'pt-BR', 'ru', 'sv', 'tr', 'uk', 'zh-CN', 'zh-TW'];
 const APPLIANCE_CONSUMED_KEY = 'bambuddy_appliance_locale_consumed';
 
 i18n
@@ -113,6 +115,7 @@ export const availableLanguages = [
   { code: 'pt-BR', name: 'Portuguese (Brazil)', nativeName: 'Português (Brasil)' },
   { code: 'zh-CN', name: 'Chinese (Simplified)', nativeName: '简体中文' },
   { code: 'zh-TW', name: 'Chinese (Traditional)', nativeName: '繁體中文' },
+  { code: 'sv', name: 'Swedish', nativeName: 'Svenska' },
   { code: 'tr', name: 'Turkish', nativeName: 'Türkçe' },
   { code: 'ru', name: 'Russian', nativeName: 'Русский' },
   { code: 'uk', name: 'Ukrainian', nativeName: 'Українська' },

+ 7671 - 0
frontend/src/i18n/locales/sv.ts

@@ -0,0 +1,7671 @@
+export default {
+  // Navigation
+  nav: {
+    printers: 'Skrivare',
+    archives: 'Arkiv',
+    queue: 'Utskriftskö',
+    stats: 'Statistik',
+    profiles: 'Profiler',
+    maintenance: 'Underhåll',
+    projects: 'Projekt',
+    finance: 'Finanser',
+    inventory: 'Filament',
+    files: 'Filhanterare',
+    makerworld: 'MakerWorld',
+    notifications: 'Notiser',
+    settings: 'Inställningar',
+    system: 'System',
+    collapseSidebar: 'Minimera sidofältet',
+    expandSidebar: 'Maximera sidofältet',
+    update: 'Uppdatera',
+    updateAvailable: 'Uppdatering tillgänglig: v{{version}}',
+    updateAvailableBanner: 'Version {{version}} är tillgänglig!',
+    viewUpdate: 'Visa uppdatering',
+    viewOnGithub: 'Visa på GitHub',
+    keyboardShortcuts: 'Tangentbordsgenvägar (?)',
+    switchToLight: 'Växla till ljust läge',
+    switchToDark: 'Växla till mörkt läge',
+    switchToSystem: 'Växla till systemläge',
+    smartSwitches: 'Smarta strömbrytare',
+    logout: 'Logga ut',
+    installApp: 'Installera app',
+    installAppSuccess: 'Bambuddy installerades',
+  },
+
+  // Common
+  common: {
+    plusNMore: '+{{count}} till',
+    save: 'Spara',
+    saving: 'Sparar...',
+    cancel: 'Avbryt',
+    delete: 'Ta bort',
+    edit: 'Redigera',
+    add: 'Lägg till',
+    close: 'Stäng',
+    confirm: 'Bekräfta',
+    loading: 'Laddar...',
+    error: 'Fel',
+    errorLoading: 'Fel vid inläsning av data',
+    retry: 'Försök igen',
+    success: 'Lyckades',
+    warning: 'Varning',
+    enabled: 'Aktiverad',
+    disabled: 'Inaktiverad',
+    yes: 'Ja',
+    no: 'Nej',
+    on: 'På',
+    off: 'Av',
+    all: 'Alla',
+    none: 'Inga',
+    search: 'Sök',
+    filter: 'Filtrera',
+    sort: 'Sortera',
+    refresh: 'Uppdatera',
+    download: 'Ladda ner',
+    upload: 'Ladda upp',
+    uploading: 'Laddar upp...',
+    uploadFailed: 'Uppladdning misslyckades',
+    actions: 'Åtgärder',
+    status: 'Status',
+    name: 'Namn',
+    user: 'Användare',
+    description: 'Beskrivning',
+    date: 'Datum',
+    time: 'Tid',
+    hours: 'timmar',
+    minutes: 'minuter',
+    seconds: 'sekunder',
+    days: 'dagar',
+    enable: 'Aktivera',
+    disable: 'Inaktivera',
+    permissions: 'Behörigheter',
+    noPrinters: 'Inga skrivare konfigurerade',
+    noData: 'Ingen data tillgänglig',
+    linkNotFound: 'Länk hittades ej',
+    required: 'Obligatorisk',
+    optional: 'Valfri',
+    dismiss: 'Avfärda',
+    apply: 'Tillämpa',
+    reset: 'Återställ',
+    export: 'Exportera',
+    import: 'Importera',
+    clear: 'Rensa',
+    selectAll: 'Markera alla',
+    deselectAll: 'Avmarkera alla',
+    noChange: '— Ingen ändring —',
+    unchanged: 'Oförändrad',
+    unassigned: 'Otilldelad',
+    unknown: 'Okänd',
+    unknownError: 'Okänt fel',
+    today: 'Idag',
+    tomorrow: 'Imorgon',
+    asap: 'Så snart som möjligt',
+    overdue: 'Försenad',
+    now: 'Nu',
+    collapse: 'Minimera',
+    expand: 'Maximera',
+    previous: 'Föregående',
+    next: 'Nästa',
+    viewArchive: 'Visa arkiv',
+    viewInFileManager: 'Visa i filhanterare',
+    addedBy: 'Tillagd av {{username}}',
+    prints: 'utskrifter',
+    more: '+{{count}} till',
+    ascending: 'Stigande',
+    descending: 'Sjunkande',
+    back: 'Tillbaka',
+    copy: 'Kopiera',
+    copied: 'Kopierad!',
+    printer: 'Skrivare',
+    remove: 'Ta bort',
+    type: 'Typ',
+    print: 'Skriv ut',
+    rename: 'Döp om',
+    move: 'Flytta',
+    create: 'Skapa',
+    duplicate: 'Duplicera',
+    left: 'Vänster',
+    right: 'Höger',
+    run: 'Kör',
+    running: 'Kör...',
+  },
+
+  finance: {
+    allTypes: 'Alla typer',
+    allCostCenters: 'Alla kostnadsställen',
+    title: 'Finanser',
+    subtitle: 'Plånbok, personliga transaktioner och kostnadsställen',
+    noAccess: 'Du har inte behörighet att visa finansiella data.',
+    personalView: 'Personlig vy',
+    adminView: 'Adminvy',
+    createCostCenter: 'Skapa kostnadsställe',
+    adjustWallet: 'Justera plånbok',
+    addManualPrint: 'Lägg till manuell utskrift',
+    manageMembers: 'Hantera medlemmar i kostnadsställe',
+    currentBalance: 'Aktuellt saldo',
+    transactions: 'Transaktioner',
+    personalTransactions: 'Personliga transaktioner',
+    costCenters: 'Kostnadsställen',
+    availableForPrinting: 'Tillgängligt för utskrifter',
+    costCenterName: 'Namn',
+    budgetType: 'Budgettyp',
+    monthlyBudget: 'Månadsbudget',
+    totalBudget: 'Total budget',
+    noBudget: "Ingen budget",
+    create: 'Skapa',
+    selectUser: 'Välj användare',
+    transactionType: 'Typ',
+    amount: 'Belopp',
+    noCostCenter: 'Inget kostnadsställe',
+    descriptionOptional: 'Beskrivning (valfritt)',
+    applyAdjustment: 'Tillämpa justering',
+    memberCanPrint: 'Medlem kan skriva ut',
+    addMember: 'Lägg till medlem',
+    canPrint: 'Kan skriva ut',
+    noMembers: 'Inga medlemmar tilldelade.',
+    editCostCenter: 'Redigera kostnadsställe',
+    myCostCenters: 'Mina kostnadsställen',
+    costCentersHint: 'Granska budgetgränser och håll kostnaderna under kontroll',
+    noCostCenters: 'Inga kostnadsställen hittade.',
+    owner: 'Ägare',
+    balance: 'Kontosaldo',
+    unlimited: 'Obegränsad',
+    budgetPolicyHint: 'Kontosaldon håller reda på kostnader. Utskrift är begränsat endast av det valda kostnadsställets budget; utan budget är utskriften obgränsad.',
+    budget: 'Budget',
+    shared: 'Delad',
+    cannotEditPrivateCostCenter: 'Privat kostnadsställe kan inte redigeras här',
+    recentTransactions: 'Senaste transaktioner',
+    transactionsHint: 'Filtrera efter typ och kostnadsställe',
+    first: 'Första',
+    prev: 'Föregående',
+    next: 'Nästa',
+    last: 'Sista',
+    pageNumberOf: 'Sida {{page}} av {{total}}',
+    noTransactions: 'Inga transaktioner tillgängliga.',
+    noTransactionsForFilter: 'Inga transaktioner matchar de valda filtren.',
+    costCenter: 'Kostnadsställe',
+    balanceAfter: 'Saldo efter',
+    userWithId: 'Användare #{{id}}',
+    partial: 'Delvis',
+    editTransaction: 'Redigera transaktion',
+    selectCostCenter: 'Välj kostnadsställe...',
+    costCenterRequired: 'Vänligen välj ett kostnadsställe',
+    amountExample: 't.ex., 4,00',
+    manualAdjustmentExample: 't.ex., manuell justering',
+    userRequired: 'Välj en användare',
+    amountInvalid: 'Beloppet måste vara ett giltigt nummer',
+    createdCostCenter: 'Kostnadsställe skapat',
+    createCostCenterFailed: 'Kunde inte skapa kostnadsställe',
+    transactionDeleted: 'Transaktion borttagen',
+    deleteTransactionFailed: 'Kunde inte ta bort transaktion',
+    transactionEdited: 'Transaktion uppdaterad och bokföring omberäknad',
+    editTransactionFailed: 'Kunde inte redigera transaktion',
+    manualPrintCreated: 'Manuell utskriftsavgift tillagd och bokföring omberäknad',
+    manualPrintFailed: 'Kunde inte skapa manuell utskrift',
+    memberSaved: 'Medlem sparad',
+    memberSaveFailed: 'Kunde inte spara medlem',
+    memberRemoved: 'Medlem borttagen',
+    memberRemoveFailed: 'Kunde inte ta bort medlem',
+    costCenterNameRequired: 'Namn på kostnadsställe krävs',
+    costCenterUpdated: 'Kostnadsställe uppdaterat',
+    costCenterUpdateFailed: 'Kunde inte uppdatera kostnadsställe',
+    confirmDeleteCostCenter: 'Ta bort kostnadsställe "{{name}}"?',
+    costCenterDeleted: 'Kostnadsställe borttaget',
+    costCenterDeleteFailed: 'Kunde inte ta bort kostnadsställe',
+    deleteTransactionConfirm: 'Ta bort denna transaktion? Saldon kommer att omberäknas automatiskt.',
+    deposit: 'Insättning',
+    withdraw: 'Uttag',
+    printCharge: 'Utskriftsavgift',
+    deleteTransaction: 'Ta bort transaktion',
+  },
+
+  // Printers page
+  printers: {
+    title: 'Skrivare',
+    addPrinter: 'Lägg till skrivare',
+    addPreflight: {
+      checking: 'Kontrollerar anslutning...',
+      warning: 'Vissa anslutningskontroller misslyckades. Denna skrivare kan visas som offline. Granska kontrollerna nedan, åtgärda vad du kan, eller spara ändå.',
+      back: 'Tillbaka',
+      saveAnyway: 'Spara ändå',
+    },
+    editPrinter: 'Redigera skrivare',
+    deletePrinter: 'Ta bort skrivare',
+    printerName: 'Skrivarnamn',
+    serialNumber: 'Serienummer',
+    ipAddress: 'IP-adress / värdnamn',
+    accessCode: 'Åtkomstkod',
+    model: 'Modell',
+    nozzleCount: 'Antal munstycken',
+    autoArchive: 'Autoarkivera',
+    status: {
+      available: 'Tillgänglig',
+      idle: 'Inaktiv',
+      printing: 'Skriver ut',
+      paused: 'Pausad',
+      offline: 'Offline',
+      problem: 'Problem',
+      error: 'Fel',
+      finished: 'Färdig',
+      unknown: 'Okänd',
+    },
+    temperatures: {
+      nozzle: 'Munstycke',
+      bed: 'Byggplatta',
+      chamber: 'Kammare',
+    },
+    heaterHistory: {
+      title: 'Värmehistorik',
+      openLabel: 'Visa värmehistorik',
+      nozzle: 'Munstycke',
+      nozzle2: 'Munstycke 2',
+      bed: 'Byggplatta',
+      chamber: 'Kammare',
+      error: 'Kunde inte ladda historik',
+      empty: 'Ingen data inspelad än',
+    },
+    progress: '{{percent}}% klar',
+    timeRemaining: '{{time}} kvar',
+    deleteConfirm: 'Är du säker på att du vill ta bort "{{name}}"?',
+    maintenanceOk: 'Underhåll OK',
+    maintenanceWarning: '{{count}} varning',
+    maintenanceWarning_plural: '{{count}} varningar',
+    maintenanceDue: '{{count}} utebliven',
+    maintenanceDue_plural: '{{count}} uteblivna',
+    // Sort options
+    sort: {
+      name: 'Namn',
+      status: 'Status',
+      model: 'Modell',
+      location: 'Plats',
+      eta: 'Beräknad tid',
+      ascending: 'Sortera stigande',
+      descending: 'Sortera fallande',
+    },
+    // Card size
+    cardSize: {
+      small: 'Små kort',
+      medium: 'Mellanstora kort',
+      large: 'Stora kort',
+      extraLarge: 'Extra stora kort',
+    },
+    pageView: {
+      openCamWallPage: 'Öppna kameravägg som sida',
+      cards: 'Kort',
+      camWall: 'Kameravägg',
+    },
+    camWall: {
+      page: {
+        tokenRejected:
+          'Denna länk till kameraväggen är inte längre giltig. Token kan ha löpt ut eller återkallats.',
+        loadFailed: 'Kunde inte ladda skrivarna.',
+      },
+      noPrinters: 'Inga skrivare att visa',
+      noSignal: 'Ingen signal',
+      live: 'Live',
+      snap: 'Ögonblicksbild',
+      off: 'Av',
+      summary: '{{live}} live, {{snap}} ögonblicksbilder, {{total}} totalt',
+      layer: 'Skikt {{cur}}/{{total}}',
+      timeLeft: '{{time}} kvar',
+      statusMode: {
+        off: 'Av',
+        compact: 'Kompakt',
+        full: 'Fullständig',
+      },
+      settings: {
+        title: 'Inställningar för kameravägg',
+        maxLive: 'Max antal live-sändningar',
+        maxLiveHint: 'Hur många rutor som sänds live samtidigt. Övriga uppdateras som ögonblicksbilder.',
+        snapshotInterval: 'Intervall för ögonblicksbilder (sekunder)',
+        snapshotIntervalHint: 'Hur ofta icke-live-rutor hämtar en ny ögonblicksbild.',
+        statusOverlay: 'Statusöverlägg',
+        statusOverlayHint: 'Kompakt: Endast statusmärke. Fullständig: + framsteg, skikt, tid kvar.',
+      },
+    },
+    // Controls
+    hideOffline: 'Dölj offline',
+    nextAvailable: 'Nästa tillgängliga',
+    powerOn: 'Sätt på',
+    offlinePrintersWithPlugs: 'Offline-skrivare med smarta kontakter',
+    noPrintersConfigured: 'Inga skrivare konfigurerade än',
+    search: 'Sök skrivare...',
+    noSearchResults: 'Inga skrivare matchar din sökning eller filter',
+    filter: {
+      allStatuses: 'Alla statusar',
+      allLocations: 'Alla platser',
+    },
+    toolbar: {
+      filters: 'Filter',
+      view: 'Vy',
+      actions: 'Åtgärder',
+    },
+    // Printer card
+    readyToPrint: 'Redo att skriva ut',
+    external: 'Extern',
+    extL: 'Ext-V',
+    extR: 'Ext-H',
+    deleteArchives: 'Ta bort utskriftsarkiv',
+    noLabel: 'Ingen etikett',
+    printPreview: 'Förhandsgranskning av utskrift',
+    width: 'Bredd',
+    height: 'Höjd',
+    noObjectsFound: 'Inga objekt hittade',
+    objectsLoadedOnPrintStart: 'Objekt laddas när en utskrift startar',
+    willBeSkipped: 'Kommer att hoppas över',
+    name: 'Namn',
+    serialCannotBeChanged: 'Serienummer kan inte ändras',
+    locationHelp: 'Används för att gruppera skrivare och filtrera köuppgifter',
+    // WiFi signal strength
+    wifiSignal: {
+      veryWeak: 'Mycket svag',
+      weak: 'Svag',
+      fair: 'Medel',
+      good: 'Bra',
+      excellent: 'Utmärkt',
+    },
+    // Maintenance
+    maintenanceUpToDate: 'Allt underhåll är uppdaterat - Klicka för att se',
+    // Maintenance Mode (#1476) — operator-flipped "out of service" state.
+    // Distinct from the scheduled-maintenance dashboard above; this one
+    // wraps the backend is_active flag and stops MQTT + queue dispatch.
+    maintenance: {
+      title: 'I underhållsläge',
+      subtitle: 'Denna skrivare är pausad — ej ansluten, ej berättigad för kö, skickar inga notiser.',
+      pillLabel: 'Underhåll',
+      exitButton: 'Avsluta underhåll',
+      menuEnter: 'Aktivera underhållsläge',
+      menuExit: 'Avsluta underhållsläge',
+      toastEntered: '{{name}} är nu i underhållsläge',
+      toastExited: '{{name}} är tillbaka online',
+      confirmMidPrintTitle: 'Aktivera underhållsläge under utskrift?',
+      confirmMidPrintMessage: '{{name}} skriver för närvarande ut. Om du aktiverar underhållsläge kommer MQTT att kopplas från och framstegsspårning samt färdighetsnotiser för detta jobb kommer att stoppas. Fortsätta?',
+      editFieldLabel: 'Underhållsläge',
+      editFieldHelp: 'När det är på, är denna skrivare pausad från MQTT, köutskick och notiser — användbart för reparation, parallella Bambuddy-installationer eller tillfällig paus.',
+    },
+    // Chamber light
+    chamberLightOn: 'Sätt på kammarljus',
+    chamberLightOff: 'Stäng av kammarljus',
+    // Files
+    files: 'Filer',
+    browseFiles: 'Bläddra bland skrivarens filer',
+    // Smart plug
+    autoOffAfterPrint: 'Automatisk avstängning efter utskrift',
+    autoOffExecuted: 'Auto-avstängning utfördes – sätt på skrivaren för att återställa',
+    // HMS errors
+    hmsErrors: 'HMS-fel',
+    viewHmsErrors: 'Visa {{count}} HMS-fel',
+    // Actions
+    resume: 'Fortsätt',
+    pause: 'Pausa',
+    stop: 'Stoppa',
+    camera: 'Kamera',
+    skipObject: 'Hoppa över objekt',
+    reconnect: 'Återanslut',
+    forceRefresh: 'Tvinga uppdatering',
+    forceRefreshSuccess: 'Uppdatering begärd',
+    mqttDebug: 'MQTT-felsökning',
+    printerInformation: 'Skrivarinformation',
+    copyToClipboard: 'Kopiera',
+    copied: 'Kopierad!',
+    state: 'Status',
+    wifiSignalLabel: 'WiFi-signal',
+    developerMode: 'Utvecklarläge',
+    enabled: 'Aktiverad',
+    disabled: 'Inaktiverad',
+    addedOn: 'Tillagd',
+    sdCard: 'SD-kort',
+    inserted: 'Insatt',
+    notInserted: 'Ej insatt',
+    totalPrintHours: 'Utskriftstimmar',
+    activeNozzle: 'Aktiv: {{nozzle}} munstycke',
+    amsSwitchInletTooltip: 'Filamentspårväxlare IN-{{inlet}} ({{side}}) — matar båda munstyckena',
+    nozzleRack: 'Munstyckesställ',
+    nozzleDocked: 'Parkerad',
+    nozzleMounted: 'Monterad',
+    nozzleActive: 'Aktiv',
+    nozzleIdle: 'Inaktiv',
+    nozzleDiameter: 'Diameter',
+    nozzleType: 'Typ',
+    nozzleStatus: 'Status',
+    nozzleFilament: 'Filament',
+    nozzleWear: 'Slitage',
+    nozzleMaxTemp: 'Max temp',
+    nozzleSerial: 'Serienummer',
+    nozzleHardenedSteel: 'Härdat stål',
+    nozzleStainlessSteel: 'Rostfritt stål',
+    nozzleTungstenCarbide: 'Volframkarbid',
+    nozzleFlow: 'Flöde',
+    nozzleHighFlow: 'Högt flöde',
+    nozzleStandardFlow: 'Standard',
+    // Firmware
+    firmwareUpdate: 'Firmwareuppdatering',
+    firmwareInstructions: 'På skrivarens pekskärm, gå till',
+    firmwareNav: 'Navigera till',
+    settings: 'Inställningar',
+    firmware: 'Firmware',
+    // Discovery
+    discoverPrinters: 'Hitta skrivare',
+    searching: 'Söker...',
+    manualEntry: 'Manuell inmatning',
+    addFromCloud: 'Lägg till från molnet',
+    // Toast messages
+    toast: {
+      printerDeleted: 'Skrivare borttagen',
+      missingSpoolAssignment: 'Utskrift startade på {{printer}}. Saknas spool-tilldelning för: {{slots}}',
+      killSwitchTriggered: 'Fjärrlås för fakturering stoppade en obehörig utskrift på {{printer}}: {{filename}}',
+      billingChargeFailed: 'Fakturering misslyckades för {{filename}} på {{printer}}. Budgetreservationen bibehölls; kontrollera serverloggarna.',
+      assignmentVerified: 'Filament laddat i fack {{slot}} ({{printer}})',
+      assignmentVerifiedNoKprofile: 'Fack {{slot}} på {{printer}} laddat, men flödeskalibrering (K-profil) tillämpades inte',
+      assignmentNotConfirmed: 'Kunde inte bekräfta tilldelningen för fack {{slot}} på {{printer}} — kontrollera AMS-facket',
+      printerAdded: 'Skrivare tillagd',
+      printerUpdated: 'Skrivare uppdaterad',
+      failedToDelete: 'Kunde inte ta bort skrivare',
+      failedToAdd: 'Kunde inte lägga till skrivare',
+      connectionFailedNotAdded: 'Kunde inte ansluta till skrivaren. Verifiera IP, serienummer och åtkomstkod, och bekräfta att LAN-läge är aktiverat. Skrivaren lades inte till.',
+      failedToUpdate: 'Kunde inte uppdatera skrivare',
+      commandSent: 'Kommando skickat',
+      failedToSendCommand: 'Kunde inte skicka kommando',
+      turnedOn: '{{name}} slogs på',
+      failedToPowerOn: 'Kunde inte sätta på {{name}}',
+      scriptTriggered: 'Skript utlöst',
+      printStopped: 'Utskrift stoppad',
+      printPaused: 'Utskrift pausad',
+      printResumed: 'Utskrift återupptagen',
+      referenceDeleted: 'Referens borttagen',
+      detectionAreaSaved: 'Detekteringsområde sparat',
+      failedToRunScript: 'Kunde inte köra skript',
+      failedToStopPrint: 'Kunde inte stoppa utskrift',
+      failedToPausePrint: 'Kunde inte pausa utskrift',
+      failedToResumePrint: 'Kunde inte återuppta utskrift',
+      failedToControlChamberLight: 'Kunde inte kontrollera kammarljus',
+      failedToSetSpeed: 'Kunde inte ställa in utskriftshastighet',
+      failedToUpdateSetting: 'Kunde inte uppdatera inställning',
+      failedToSkipObjects: 'Kunde inte hoppa över objekt',
+      failedToRereadRfid: 'Kunde inte läsa om RFID',
+      failedToCheckPlate: 'Kunde inte kontrollera platta',
+      failedToUpdateLabel: 'Kunde inte uppdatera etikett',
+      failedToDeleteReference: 'Kunde inte ta bort referens',
+      failedToSaveDetectionArea: 'Kunde inte spara detekteringsområde',
+      plateCheckEnabled: 'Plattkontroll aktiverad',
+      plateCheckDisabled: 'Plattkontroll inaktiverad',
+      calibrationSaved: 'Kalibrering sparad!',
+      calibrationFailed: 'Kalibrering misslyckades',
+      rfidRereadInitiated: 'Omstart av RFID-läsning påbörjad',
+      loadInitiated: 'Laddar filament…',
+      unloadInitiated: 'Laddar ur filament…',
+      failedToLoad: 'Kunde inte ladda filament',
+      failedToUnload: 'Kunde inte ladda ur filament',
+    },
+    // Connection status
+    connection: {
+      connected: 'Ansluten',
+      offline: 'Offline',
+    },
+    plateStatus: {
+      markCleared: 'Markera platta som tömd',
+      cleared: 'Platta tömd',
+      notCleared: 'Platta ej tömd',
+      inUse: 'Platta i användning',
+    },
+    // Queue info
+    queue: {
+      inQueue: '{{count}} utskrift i kö',
+      inQueue_plural: '{{count}} utskrifter i kö',
+    },
+    // Controls section
+    controls: 'Kontroller',
+    // RFID
+    rfid: {
+      reread: 'Läs om RFID',
+    },
+    // AMS load/unload (#891)
+    ams: {
+      load: 'Ladda',
+      unload: 'Ladda ur',
+      feedTitle: 'Ladda {{slot}} till vilket munstycke?',
+      feedPrompt: 'Filamentspårväxlaren kan dirigera detta fack till endera värmeblock. Välj vilken du vill mata.',
+      feedLeft: 'Vänster munstycke',
+      feedRight: 'Höger munstycke',
+      feedAlreadyLoaded: 'Redan laddad',
+      switchNotReady: 'Filamentspårväxlaren är inte konfigurerad ännu. Tilldela varje AMS till ett inlopp på skrivaren och försök sedan igen.',
+    },
+    bedJog: {
+      limitWarning: 'Rörlighetsgränser tillämpas inte under manuella förflyttningar — en Bambu-firmware-bugg ignorerar mjukvarustoppar för fjärrkommandon. Flytta försiktigt för att undvika kollision.',
+      title: 'Manuella kontroller',
+      bed: 'Byggplatta',
+      step: 'Steg (mm)',
+      up: 'Flytta upp platta',
+      down: 'Flytta ner platta',
+      toolheadUp: 'Flytta upp extruderhuvud',
+      toolheadDown: 'Flytta ner extruderhuvud',
+      disabledWhilePrinting: 'Inaktiverad under utskrift',
+      notHomedTitle: 'Skrivaren är inte riktad',
+      notHomedMessage: 'Skrivaren har inte riktats sedan senaste utskriften. Kör auto-riktning för säker positionering (parkerar verktygshuvudet, riktar sedan X, Y och Z), eller flytta ändå — mjukvarustoppar kommer att ignoreras.',
+      homeZ: 'Auto-riktning',
+      moveAnyway: 'Flytta ändå',
+      homingStarted: 'Auto-riktning pågår…',
+    },
+    // Permissions
+    permission: {
+      noAdd: 'Du har inte behörighet att lägga till skrivare',
+      noEdit: 'Du har inte behörighet att redigera skrivare',
+      noDelete: 'Du har inte behörighet att ta bort skrivare',
+      noControl: 'Du har inte behörighet att kontrollera skrivare',
+      noFiles: 'Du har inte behörighet att komma åt skrivarens filer',
+      noAmsRfid: 'Du har inte behörighet att läsa om AMS-RFID',
+      noSmartPlugControl: 'Du har inte behörighet att kontrollera smarta kontakter',
+      noCamera: 'Du har inte behörighet att visa kameror',
+    },
+    // Add/Edit modal
+    modal: {
+      addTitle: 'Lägg till skrivare',
+      editTitle: 'Redigera skrivare',
+      myPrinter: 'Min skrivare',
+      selectModel: 'Välj modell...',
+      locationGroup: 'Plats / grupp (valfritt)',
+      locationPlaceholder: 't.ex. Verkstad, Kontor, Källare',
+      autoArchiveLabel: 'Auto-arkivera färdiga utskrifter',
+      fromPrinterSettings: 'Från skrivarens inställningar',
+      modelOptional: 'Modell (valfritt)',
+      saveChanges: 'Spara ändringar',
+    },
+    // Skip objects
+    skipObjects: {
+      tooltip: 'Hoppa över objekt',
+      onlyWhilePrinting: 'Hoppa över objekt (endast under utskrift)',
+      requiresMultiple: 'Hoppa över objekt (kräver 2+ objekt)',
+      title: 'Hoppa över objekt',
+      matchIdsInfo: 'Matcha ID:n med skrivarens display',
+      printerShowsIds: 'Skrivarens skärm visar objekt-ID:n på byggplattan',
+      skipSelected: 'Hoppa över valda',
+      skipping: 'Hoppar över...',
+      noObjectsSelected: 'Inga objekt valda',
+      selectObjectsToSkip: 'Välj objekt du vill hoppa över från den aktuella utskriften',
+      skipped: 'hoppades över',
+      objectsSkipped: 'Objekt hoppades över',
+      activeCount: '{{count}} aktiva',
+      waitForLayer: 'Vänta på skikt 2+ för att hoppa över objekt (nuvarande skikt {{layer}})',
+      skip: 'Hoppa över',
+      confirmTitle: 'Hoppa över objekt?',
+      confirmMessage: 'Är du säker på att du vill hoppa över "{{name}}"? Detta kan inte ångras.',
+      confirmAllMessage: 'Alla återstående objekt är valda. Detta kommer att stoppa utskriftsjobbet. Fortsätta?',
+      confirmMultipleMessage: 'Hoppa över {{count}} valda objekt? Detta kan inte ångras.',
+    },
+    // Confirm modals
+    confirm: {
+      deleteTitle: 'Ta bort skrivare',
+      deleteMessage: 'Är du säker på att du vill ta bort "{{name}}"? Detta kommer att ta bort alla anslutningsinställningar.',
+      deleteArchivesNote: 'All utskriftshistorik för denna skrivare kommer att tas bort permanent.',
+      keepArchivesNote: 'Utskriftshistorik kommer att behållas men inte längre vara kopplad till denna skrivare.',
+      stopTitle: 'Stoppa utskrift',
+      stopMessage: 'Är du säker på att du vill stoppa den aktuella utskriften på "{{name}}"? Detta kommer att avbryta utskriftsjobbet.',
+      stopButton: 'Stoppa utskrift',
+      pauseTitle: 'Pausa utskrift',
+      pauseMessage: 'Är du säker på att du vill pausa den aktuella utskriften på "{{name}}"?',
+      pauseButton: 'Pausa utskrift',
+      resumeTitle: 'Fortsätt utskrift',
+      resumeMessage: 'Är du säker på att du vill fortsätta utskriften på "{{name}}"?',
+      resumeButton: 'Fortsätt utskrift',
+      powerOnTitle: 'Sätt på skrivare',
+      powerOnMessage: 'Är du säker på att du vill sätta på strömmen för "{{name}}"?',
+      powerOnButton: 'Sätt på',
+      powerOffTitle: 'Stäng av skrivare',
+      powerOffMessage: 'Är du säker på att du vill stänga av strömmen för "{{name}}"?',
+      powerOffWarning: 'VARNING: "{{name}}" skriver för närvarande ut! Är du säker på att du vill stänga av strömmen? Detta kommer att avbryta utskriften och kan skada skrivaren.',
+      powerOffButton: 'Stäng av',
+      haToggleTitle: 'Växla "{{name}}"',
+      haToggleMessage: 'Växla Home Assistant-enheten {{entity}}? Detta kan stänga av strömmen om den för närvarande är på.',
+      haToggleWarning: 'VARNING: "{{name}}" skriver för närvarande ut! Att växla {{entity}} kan bryta strömmen och avbryta utskriften. Fortsätta?',
+      haToggleButton: 'Växla',
+    },
+    // Bulk actions
+    bulk: {
+      select: 'Välj',
+      selectAll: 'Välj alla',
+      selectByLocation: 'Välj efter plats',
+      selected: '{{count}} valda',
+      actions: {
+        stop: 'Stoppa',
+        pause: 'Pausa',
+        resume: 'Fortsätt',
+        clearPlate: 'Töm byggplatta',
+        clearHMS: 'Rensa notiser',
+      },
+      confirm: {
+        stopTitle: 'Stoppa {{count}} utskrifter',
+        stopMessage: 'Detta kommer att avbryta aktiva utskrifter på {{count}} skrivare. Denna åtgärd kan inte ångras.',
+        stopButton: 'Stoppa alla',
+        pauseTitle: 'Pausa {{count}} utskrifter',
+        pauseMessage: 'Detta kommer att pausa aktiva utskrifter på {{count}} skrivare.',
+        pauseButton: 'Pausa alla',
+        clearPlateTitle: 'Töm {{count}} byggplattor',
+        clearPlateMessage: 'Detta kommer att tömma byggplattan på {{count}} skrivare och kan utlösa köade jobb.',
+        clearPlateButton: 'Töm alla',
+      },
+      success: '{{action}} slutförd på {{count}} skrivare',
+      partial: '{{succeeded}} lyckades, {{failed}} misslyckades',
+      noneApplicable: 'Inga valda skrivare är i rätt tillstånd för denna åtgärd',
+      selectByState: 'Välj efter status',
+    },
+    // Discovery
+    discovery: {
+      title: 'Hitta skrivare',
+      searching: 'Söker...',
+      scanning: 'Skannar...',
+      scanProgress: 'Skannar... {{scanned}}/{{total}}',
+      foundPrinters: 'Hittade {{count}} skrivare',
+      noPrintersFound: 'Inga skrivare hittade',
+      noPrintersFoundSubnet: 'Inga skrivare hittade i det angivna subnätet.',
+      noPrintersFoundNetwork: 'Inga skrivare hittade i nätverket.',
+      allConfigured: 'Alla hittade skrivare är redan konfigurerade.',
+      alreadyAdded: 'Redan tillagd',
+      select: 'Välj',
+      manualEntry: 'Manuell inmatning',
+      addFromCloud: 'Lägg till från molnet',
+      subnetToScan: 'Subnät att söka',
+      dockerNote: 'Docker upptäckt. Ange din skrivares subnät i CIDR-notation. Kräver network_mode: host i docker-compose.yml.',
+      scanSubnet: 'Skanna subnät efter skrivare',
+      discoverNetwork: 'Hitta skrivare i nätverket',
+      scanningSubnet: 'Söker subnät efter Bambu-skrivare...',
+      scanningNetwork: 'Söker nätverk...',
+      serialRequired: 'Serienummer krävs',
+      unknown: 'Okänd',
+      failedToStart: 'Kunde inte starta skanning',
+      customSubnetOption: 'Anpassat subnät...',
+      customSubnetLabel: 'Anpassat subnät (CIDR)',
+      customSubnetNote: 'Använd ett anpassat subnät om din skrivare är på ett annat nätverk än denna server. FTP (990) och MQTT (8883) portarna måste vara nåbara över routningsgränsen.',
+    },
+    // AMS Drying
+    drying: {
+      start: 'Starta torkning',
+      stop: 'Stoppa torkning',
+      temperature: 'Temperatur',
+      duration: 'Varaktighet',
+      hours: 'timmar',
+      timeRemaining: '{{time}} kvar',
+      active: 'Torkar',
+      targetSummary: '{{filament}} @ {{temp}}°C',
+      notSupported: 'Torkning stöds inte',
+      powerRequired: 'Anslut AMS-strömadapter för att aktivera torkning',
+      cannotDryNow: 'AMS kan inte börja torka just nu',
+      startingDrying: 'Startar torkning...',
+      toastCommandSent: 'Torkningskommando skickat',
+      toastStopped: 'Torkning stoppad',
+      toastNotStarted: 'Skrivaren accepterade kommandot men AMS startade aldrig torkning. Kontrollera att AMS-strömadaptern är ansluten och att skrivaren är inaktiv.',
+      screenOnly: 'AMS-torkning på denna skrivare kan endast kontrolleras från skrivarens egen skärm (Bambu-begränsning)',
+      stoppingDrying: 'Stoppar torkning...',
+      rotateTray: 'Roterar rulle under torkning',
+      rotateUnavailableReason: 'Ej tillgänglig — en slot i denna AMS är laddad till verktygshuvudet. Rullen är låst av matarröret och kan inte rotera. Dra tillbaka filamentet först.',
+      startMode: 'Starttid',
+      modeNow: 'Nu',
+      modeDelay: 'Efter fördröjning',
+      modeAtTime: 'Vid tidpunkt',
+      // Verb (button label), not the noun.
+      schedule: 'Schemalägg',
+      scheduledFor: 'Torkning schemalagd för {{time}}',
+      scheduledAsap: 'Torkning schemalagd (väntar på skrivare)',
+      cancelScheduled: 'Avbryt schemalagd torkning',
+      scheduleFailed: 'Kunde inte schemalägga torkning',
+      retractFilament: 'Dra tillbaka filamentet vid AMS-utloppet för att starta torkning',
+      waitingAmsNotFound: 'Väntar på att AMS ska upptäckas',
+      waitingOffline: 'Väntar på att skrivaren ska bli online',
+      waitingPrinterBusy: 'Väntar på att skrivaren ska bli ledig',
+      waitingAlreadyDrying: 'Väntar på att den aktuella torkningscykeln ska slutföras',
+      waitingInterrupted: 'Avbruten, kommer att starta om när skrivaren är ledig',
+      scheduleFailedReason: 'Schemalagd torkning misslyckades: {{reason}}',
+      scheduleFailedUnknown: 'Okänt fel',
+      dismissFailed: 'Avfärda',
+    },
+    // AMS Filament Backup status badge (printer-wide auto-switch to another spool)
+    amsBackup: {
+      titleOn: 'AMS filamentbackup är PÅ. Klicka för att inaktivera.',
+      titleOff: 'AMS filamentbackup är AV. Klicka för att aktivera.',
+      titleUnknown: 'AMS filamentbackupstatus ej tillgänglig på denna skrivare.',
+      toastEnabled: 'AMS filamentbackup aktiverad',
+      toastDisabled: 'AMS filamentbackup inaktiverad',
+      modalTitle: 'AMS filamentbackup',
+      modalHelp: 'När det aktiva facket tar slut går skrivaren genom alla matchande fack med samma inställningar och färg i denna ordning.',
+      modalNoSlots: 'Inga filament laddade.',
+      modalNoPairs: 'Inga backup-par — inga fack delar samma filamentprofil och färg.',
+      extruderRightShort: 'H',
+      extruderLeftShort: 'V',
+      stateOn: 'Aktiverad',
+      stateOff: 'Inaktiverad',
+      stateUnknown: 'Stöds inte på denna skrivare',
+    },
+    activeJobSlot: {
+      title: 'Detta fack är filament {{n}} i den aktiva utskriften',
+      ariaLabel: 'Aktivt fack {{n}}',
+    },
+    expectedSlot: {
+      title: 'Skrivaren väntar på filament i detta fack',
+      ariaLabel: 'Förväntat filamentfack {{n}}',
+      label: '{{ams}} · Fack {{slot}}',
+      external: 'Extern rulle',
+    },
+    // Filaments section
+    filaments: 'Filament',
+    externalSpool: {
+      hide: 'Dölj extern rulle',
+      show: 'Visa extern rulle',
+    },
+    // Camera
+    openCameraOverlay: 'Öppna kameran i överlägg',
+    openCameraWindow: 'Öppna kameran i nytt fönster',
+    // Firmware
+    firmwareUpdateAvailable: 'Firmwareuppdatering tillgänglig: {{current}} → {{latest}}',
+    firmwareUpToDate: 'Firmware {{version}} — Uppdaterad',
+    firmwareUpdateButton: 'Uppdatera',
+    // Plate detection
+    plateDetection: {
+      noPermission: 'Du har inte behörighet att uppdatera skrivare',
+      enabledClick: 'Plattkontroll aktiverad – Klicka för att inaktivera',
+      disabledClick: 'Plattkontroll inaktiverad – Klicka för att aktivera',
+      manageCalibration: 'Hantera plattdetekteringskalibrering',
+      calibrationRequired: 'Kalibrering krävs',
+      calibrationInstructions: 'Se till att byggplattan är <strong>helt tom</strong>, klicka sedan på Kalibrera.',
+      calibrationDescription: 'Kalibrering tar en referensbild av den tomma plattan. Framtida kontroller kommer att jämföras med denna referens för att upptäcka objekt.',
+      calibrationTip: '<strong>Tips:</strong> Du kan spara upp till 5 kalibreringar för olika plattor. Systemet använder automatiskt den bästa matchningen vid kontroll.',
+      plateEmpty: 'Plattan verkar tom',
+      objectsDetected: 'Objekt upptäckta på plattan',
+      confidence: 'Säkerhet',
+      difference: 'Skillnad',
+      analysisPreview: 'Analysförhandsvisning:',
+      analysisLegend: 'Grön ruta = detekteringsområde, Rött överlägg = skillnad från kalibrering',
+      savedReferences: 'Sparade referenser ({{count}}/{{max}})',
+      deleteReference: 'Ta bort referens',
+      labelPlaceholder: 'Etikett...',
+      clickToEdit: '{{label}} – Klicka för att redigera',
+      clickToAddLabel: 'Klicka för att lägga till etikett',
+    },
+    // Speed
+    speed: {
+      title: 'Utskriftshastighet',
+      silent: 'Tyst (50%)',
+      standard: 'Standard (100%)',
+      sport: 'Sport (124%)',
+      ludicrous: 'Löjlig (166%)',
+    },
+    airduct: {
+      title: 'Luftkanalsläge',
+      cooling: 'Kylning',
+      heating: 'Uppvärmning',
+    },
+    noSdCard: 'Inget SD-kort',
+    door: {
+      open: 'Öppen',
+      closed: 'Stängd',
+    },
+    // Fans
+    fans: {
+      partCooling: 'Delkylningsfläkt',
+      auxiliary: 'Hjälpfläkt',
+      leftAuxiliary: 'Vänster hjälpfläkt',
+      exhaust: 'Frånluft',
+      chamber: 'Kammarfläkt',
+    },
+    // HMS errors
+    clickToViewHmsErrors: 'Klicka för att visa HMS-fel',
+    aiDetection: {
+      safe: 'Säker',
+      warning: 'Varning',
+      failure: 'Fel',
+      idle: 'Inaktiv',
+      error: 'Kontrollerar ej',
+      unknown: 'Startar',
+      tooltipError: 'AI-feldetektering kontrollerar inte denna utskrift: {{reason}} - klicka för detaljer',
+      tooltipUnknown: 'AI-feldetektering: väntar på det första resultatet - klicka för detaljer',
+      errorHint: 'Denna utskrift kontrolleras ej. Detekteringen återupptas automatiskt när problemet nedan är åtgärdat.',
+      tooltip: 'AI-feldetektering: {{status}} (score {{score}}) - klicka för detaljer',
+      tooltipIdle: 'AI-feldetektering aktiverad – övervakning startar med nästa utskrift – klicka för detaljer',
+      modalTitle: 'AI-feldetektering – {{name}}',
+      currentStatus: 'Status',
+      score: 'Poäng',
+      framesAnalyzed: 'Analyserade bilder',
+      idleHint: 'Ingen utskrift övervakas för närvarande. Övervakning startar automatiskt med nästa utskrift.',
+      lastError: 'Senaste fel',
+      openSettings: 'Öppna inställningar',
+    },
+    estimatedCompletion: 'Beräknad färdigställningstid',
+    plateNumber: 'Platta {{number}}',
+    slotOptions: 'Fackalternativ',
+    // AMS hover popup
+    amsPopup: {
+      friendlyName: 'AMS-namn',
+      friendlyNamePlaceholder: 't.ex. AMS Vänligt Namn',
+      serialNumber: 'Serienummer',
+      firmwareVersion: 'Firmware',
+      save: 'Spara',
+      clear: 'Rensa',
+      noEditPermission: 'Du har inte behörighet att döpa om AMS-enheter',
+    },
+    // Firmware modal
+    firmwareModal: {
+      title: 'Firmwareuppdatering',
+      titleUpToDate: 'Firmwareinformation',
+      currentVersion: 'Aktuell:',
+      latestVersion: 'Senaste:',
+      releaseNotes: 'Versionsinformation',
+      checkingPrereqs: 'Kontrollerar förutsättningar...',
+      sdCardReady: 'SD-kort redo. Klicka nedan för att ladda upp firmware.',
+      uploadedSuccess: 'Firmware uppladdat till SD-kort!',
+      applyInstructions: 'För att tillämpa uppdateringen på din skrivare:',
+      step1: 'På skrivarens pekskärm, gå till <strong>Inställningar</strong>',
+      step2: 'Navigera till <strong>Firmware</strong>',
+      step3: 'Välj <strong>Uppdatera från SD-kort</strong>',
+      step4: 'Uppdateringen tar 10-20 minuter',
+      done: 'Klar',
+      starting: 'Startar...',
+      uploadFirmware: 'Ladda upp firmware',
+      uploadFailed: 'Kunde inte starta uppladdning: {{error}}',
+      uploadedToast: 'Firmware uppladdat! Trigga uppdatering från skrivarens skärm.',
+      availableVersions: 'Tillgängliga versioner',
+      usable: 'Användbar',
+      unavailable: 'Ej tillgänglig',
+      installed: 'Installerad',
+      newerBadge: 'nyare',
+      olderBadge: 'äldre',
+      currentBadge: 'aktuell',
+    },
+    accessCodePlaceholder: 'Lämna tomt för att behålla nuvarande',
+    // ROI editor
+    roi: {
+      title: 'Detekteringsområde (ROI)',
+      xStart: 'X start',
+      yStart: 'Y start',
+      width: 'Bredd',
+      height: 'Höjd',
+      instruction: 'Justera detekteringsområdet för att fokusera på byggplattan. Den gröna rutan i förhandsvisningen visar det aktuella området.',
+    },
+    developerModeWarning: 'Utvecklar-LAN-läge är inte aktiverat på: {{names}}. Vissa funktioner kommer kanske inte att fungera.',
+    howToEnable: 'Hur man aktiverar',
+    incompatibleFile: 'Denna fil var slicad för {{slicedFor}}, men denna skrivare är en {{printerModel}}',
+    dropNotPrintable: 'Endast .gcode- och .gcode.3mf-filer kan skrivas ut',
+    dropToPrint: 'Släpp för att skriva ut',
+    dropToQueue: 'Skrivare upptagen',
+  },
+
+  // Archives page
+  archives: {
+    media: {
+      title: 'Skrivarvideor',
+      download: 'Ladda ner skrivarvideor',
+      searching: 'Kollar skrivaren efter videor',
+      searchFailed: 'Kunde inte kolla efter videor.',
+      none: 'Ingen timelapse- eller IP-kamerabitar hittades för denna utskrift.',
+      attachedTimelapse: 'Bifogad timelapse',
+      printerFiles: 'Filer kvar på skrivaren',
+      downloadSelected: 'Nerladdning vald',
+      printerMissing: 'Skrivaren är inte längre konfigurerad',
+      timelapseUnavailable: 'Timelapse-mappen kunde inte läsas',
+      ipcamUnavailable: 'IP-kameramappen kunde inte läsas',
+    },
+    title: 'Utskriftsarkiv',
+    no3mfBanner: {
+      title: 'Vissa av de senaste utskrifterna kunde inte arkiveras med minibilder',
+      body: 'Slicer-programmet lämnade inte .gcode.3mf på skrivarens SD-kort så Bambuddy kunde inte hämta minibilden eller slicer-programmets metadata. Detta beror vanligtvis på att "Lagra skickade filer på extern lagring" är avstängt i slicer-programmet (Bambu Studio / OrcaSlicer).',
+      docsLink: 'Se installationssteg 4',
+      dismissLabel: 'Avfärda denna notis',
+      docsLinkInternalStorage: 'Varför detta händer',
+      titleInternalStorage: 'Vissa av de senaste utskrifterna blev kvar i skrivarens interna lagring',
+      bodyInternalStorage: 'Bambu Studio placerade den slicade filen på skrivarens interna lagring istället för på kortet, så det fanns ingenting för Bambuddy att läsa via FTP. På H2-serien och P2S gör dess Skriv ut-knapp alltid det — endast Skicka erbjuder ett val, och det förvalet är Cache också. Dessa utskrifter arkiveras ändå med sitt namn och tid, bara utan en minibild eller slicer-inställningar. För kompletta arkiv, starta utskriften från Bambuddy, eller slica i OrcaSlicer — eller i Bambu Studio, använd Skicka med Extern valt och starta utskriften därefter. Alla kräver ett kort eller en USB-minne i skrivaren.',
+      titleNoExternalStorage: 'Vissa av de senaste utskrifterna kunde inte arkiveras — ingen lagring i skrivaren',
+      bodyNoExternalStorage: 'Skrivaren rapporterar inget kort eller USB-minne i sitt fack, så den slicade filen hade ingenstans att hamna och Bambuddy hade ingenting att läsa. Sätt in ett och nästa utskrift kommer att arkiveras fullständigt.',
+      titleInternalHistory: 'Vissa av de senaste utskrifterna startades från en fil som redan fanns på skrivaren',
+      bodyInternalHistory: 'Dessa utskrifter kördes från skrivarens eget bibliotek — en omutskrift från dess skärm, en start från Handy, eller en fil som skickades tidigare och skrivits ut senare. Bambuddy läser utskriftsfiler via FTP, som endast betjänar kortet eller USB-minnet, medan skrivaren håller det biblioteket i ett område som FTP inte kan nå, så det fanns ingen 3MF att läsa. Ingen slicer-inställning ändrar detta, eftersom ingenting skickades för dessa utskrifter. De arkiveras ändå med sitt namn och tid, och Redigera arkiv låter dig fylla i det använda filamentet manuellt. För ett komplett arkiv, starta utskriften från Bambuddy eller från din slicer istället.',
+      titleFtpsCooloff: 'Vissa av de senaste utskrifterna kunde inte arkiveras – skrivaren vägrade filanslutningen',
+      bodyFtpsCooloff: 'Bambuddy öppnade skrivarens filöverföringsport (FTPS 990) och skrivaren svarade med något som inte är TLS, så inget kunde läsas från det. Dessa utskrifter arkiveras fortfarande med deras namn och tidpunkt, bara utan en miniatyrbild eller metadata för slicer. Det här är inte en slicer-inställning och inte något du har ändrat - samma modeller och firmware körs normalt på andra installationer, och en påverkad skrivare fungerar vanligtvis igen senare på egen hand. Efter ett sådant misslyckande pausar Bambuddy överföringarna till den skrivaren i fem minuter och kommer tillbaka för filen när pausen försvinner, så ett kort avsnitt fylls av sig själv; ett kort som fortfarande är tomt betyder att vägran var längre än ett nytt försök. Vad som utlöser det är ännu inte känt. Om det fortsätter att hända, aktivera felsökningsloggning på systemsidan och bifoga ett supportpaket till din rapport.',
+      titleFtpTransferFailed: 'Vissa av de senaste utskrifterna kunde inte arkiveras – filöverföringen fick slut på tid',
+      bodyFtpTransferFailed: 'Den slicade filen fanns på skrivarens minneskort och skrivaren serverade den, men överföringen slutfördes inte inom den tillåtna tiden. Vid utskriftsstart hanterar skrivaren också sin kamera, dess statusmeddelanden och uppladdningen av jobb, och en stor 3MF kommer inte alltid igenom allt detta. Dessa utskrifter arkiveras fortfarande med deras namn och timing, bara utan en miniatyrbild eller slicer-metadata. Det här är inte en slicer-inställning och inte något du har ändrat. Bambuddy kommer tillbaka för filen tre gånger under de följande tio minuterna, så de flesta av dessa fyller i sig själva; ett minneskort som fortfarande är tomt betyder att varje försök också fick slut på tid. Om det fortsätter att hända, höj anslutningstidsgränsen under Inställningar > Nätverk > FTP-försök igen.',
+    },
+    searchPlaceholder: 'Sök i arkiv...',
+    filterByPrinter: 'Filtrera efter skrivare',
+    filterByStatus: 'Filtrera efter status',
+    sortBy: 'Sortera efter',
+    sortNewest: 'Nyaste först',
+    sortOldest: 'Äldsta först',
+    sortName: 'Namn',
+    sortDuration: 'Varaktighet',
+    sortLargest: 'Största först',
+    sortSmallest: 'Minsta först',
+    sortSize: 'Storlek',
+    noArchives: 'Inga arkiv hittade',
+    noArchivesSearch: 'Inga arkiv matchar din sökning',
+    originalPrintNotVisible: 'Originalutskriften syns inte – prova att nollställa filter',
+    noArchivesYet: 'Inga arkiv än',
+    prints: 'utskrifter',
+    pagination: {
+      showing: 'Visar',
+      to: 'till',
+      of: 'av',
+      show: 'Visa',
+      page: 'Sida',
+      all: 'Alla',
+    },
+    loadingArchives: 'Laddar arkiv...',
+    releaseToUpload: 'Släpp för att ladda upp',
+    showAll: 'Visa alla',
+    showFavoritesOnly: 'Visa endast favoriter',
+    gridView: 'Rutnätsvy',
+    listView: 'Listvy',
+    calendarView: 'Kalendervy',
+    logView: 'Utskriftslogg',
+    manageTags: 'Hantera taggar',
+    showFailedPrints: 'Visa misslyckade utskrifter',
+    hideFailedPrints: 'Dölj misslyckade utskrifter',
+    hideDuplicates: 'Dölj dubbletter',
+    viewOriginalPrint: 'Klicka för att visa originalutskrift (#{{id}})',
+    printTime: 'Utskriftstid',
+    filamentUsed: 'Filament använt',
+    cost: 'Kostnad',
+    preview: 'Förhandsgranskning',
+    deleteArchive: 'Ta bort arkiv',
+    deleteConfirm: 'Är du säker på att du vill ta bort detta arkiv?',
+    favorite: 'Favorit',
+    unfavorite: 'Ta bort från favoriter',
+    viewDetails: 'Visa detaljer',
+    status: {
+      completed: 'Slutförd',
+      failed: 'Misslyckad',
+      stopped: 'Stoppad',
+    },
+    toast: {
+      source3mfAttached: '3MF-källfil bifogad: {{filename}}',
+      failedUploadSource3mf: 'Kunde inte ladda upp 3MF-källfil',
+      source3mfRemoved: '3MF-källfil borttagen',
+      failedRemoveSource3mf: 'Kunde inte ta bort 3MF-källfil',
+      f3dAttached: 'F3D bifogad: {{filename}}',
+      failedUploadF3d: 'Kunde inte ladda upp F3D',
+      f3dRemoved: 'F3D borttagen',
+      failedRemoveF3d: 'Kunde inte ta bort F3D',
+      timelapseAttached: 'Timelapse bifogad: {{filename}}',
+      timelapseAlreadyAttached: 'Timelapse redan bifogad',
+      noMatchingTimelapse: 'Ingen matchande timelapse hittad',
+      failedScanTimelapse: 'Kunde inte söka efter timelapse',
+      failedAttachTimelapse: 'Kunde inte bifoga timelapse',
+      timelapseRemoved: 'Timelapse borttagen',
+      failedRemoveTimelapse: 'Kunde inte ta bort timelapse',
+      timelapseUploaded: 'Timelapse uppladdad: {{filename}}',
+      failedUploadTimelapse: 'Kunde inte ladda upp timelapse',
+      archiveDeleted: 'Arkiv borttaget',
+      failedDeleteArchive: 'Kunde inte ta bort arkiv',
+      addedToFavorites: 'Tillagd i favoriter',
+      removedFromFavorites: 'Borttagen från favoriter',
+      projectUpdated: 'Projekt uppdaterat',
+      failedUpdateProject: 'Kunde inte uppdatera projekt',
+      linkCopied: 'Länk kopierad till urklipp',
+      failedCopyLink: 'Kunde inte kopiera länk',
+      photoDeleted: 'Foto borttaget',
+      failedDeletePhoto: 'Kunde inte ta bort foto',
+      failedDeleteArchives: 'Kunde inte ta bort arkiv',
+      failedUpdateFavorites: 'Kunde inte uppdatera favoriter',
+      exportDownloaded: 'Nedladdning exporterad',
+      exportFailed: 'Export misslyckades',
+    },
+    menu: {
+      print: 'Skriv ut',
+      openInBambuStudio: 'Öppna i slicer-program',
+      slice: 'Slica',
+      externalLink: 'Extern länk',
+      viewOnMakerWorld: 'Visa på MakerWorld',
+      preview3d: '3D-förhandsgranskning',
+      viewTimelapse: 'Visa timelapse',
+      scanForTimelapse: 'Sök efter timelapse',
+      uploadTimelapse: 'Ladda upp timelapse',
+      removeTimelapse: 'Ta bort timelapse',
+      downloadSource3mf: 'Ladda ner 3MF-källfil',
+      uploadSource3mf: 'Ladda upp 3MF-källfil',
+      replaceSource3mf: 'Ersätt 3MF-källfil',
+      removeSource3mf: 'Ta bort 3MF-källfil',
+      uploadF3d: 'Ladda upp F3D',
+      replaceF3d: 'Ersätt F3D',
+      downloadF3d: 'Ladda ner F3D',
+      removeF3d: 'Ta bort F3D',
+      download: 'Ladda ner',
+      copyDownloadLink: 'Kopiera nedladdningslänk',
+      qrCode: 'QR-kod',
+      viewPhotos: 'Visa bilder',
+      viewPhotosCount: 'Visa bilder ({{count}})',
+      projectPage: 'Projektsida',
+      addToFavorites: 'Lägg till i favoriter',
+      removeFromFavorites: 'Ta bort från favoriter',
+      edit: 'Redigera',
+      printLog: 'Utskriftslogg',
+      goToProject: 'Gå till projekt: {{name}}',
+      addToProject: 'Lägg till i projekt',
+      removeFromProject: 'Ta bort från projekt',
+      loading: 'Laddar...',
+      noProjectsAvailable: 'Inga projekt tillgängliga',
+      searchProjects: 'Sök projekt...',
+      select: 'Välj',
+      deselect: 'Avmarkera',
+      delete: 'Ta bort',
+    },
+    permission: {
+      noReprint: 'Du har inte behörighet att skriva ut detta arkiv igen',
+      noAddToQueue: 'Du har inte behörighet att lägga till i kö',
+      noUpdateArchives: 'Du har inte behörighet att uppdatera arkiv',
+      noUploadFiles: 'Du har inte behörighet att ladda upp filer',
+      noDownload: 'Du har inte behörighet att ladda ner arkiv',
+      noCopyLink: 'Du har inte behörighet att kopiera nedladdningslänkar',
+      noDelete: 'Du har inte behörighet att ta bort detta arkiv',
+      noEdit: 'Du har inte behörighet att redigera denna post',
+      noCreate: 'Du har inte behörighet att skapa arkiv',
+    },
+    platePicker: {
+      title: 'Välj platta för förhandsgranskning',
+      hint: 'Detta arkiv har flera plattor. Välj en för att öppna i GCode-visaren.',
+      plateLabel: 'Platta {{index}}',
+      objectCount: '{{count}} objekt',
+      objectCount_plural: '{{count}} objekt',
+      noGcode: 'Detta arkiv har ingen slicad G-kod för förhandsgranskning. Öppna det i Bambu Studio för att slica först.',
+    },
+    card: {
+      previousPlate: 'Föregående platta',
+      nextPlate: 'Nästa platta',
+      plateNumber: 'Platta {{index}}',
+      moreOptions: 'Högerklicka för fler alternativ',
+      addToFavorites: 'Lägg till i favoriter',
+      removeFromFavorites: 'Ta bort från favoriter',
+      cancelled: 'avbruten',
+      failed: 'misslyckad',
+      duplicate: 'kopia',
+      duplicateTitle: 'Denna modell har skrivits ut tidigare',
+      openSource3mf: 'Öppna 3MF-källfil i Bambu Studio (högerklicka för fler alternativ)',
+      downloadF3d: 'Ladda ner Fusion 360-designfil',
+      viewTimelapse: 'Visa timelapse',
+      viewPhoto: 'Visa 1 foto',
+      viewPhotos: 'Visa {{count}} foton',
+      openFolder: 'Öppna mapp: {{name}}',
+      slicedFile: 'Slicad fil – redo att skriva ut',
+      sourceFile: 'Endast källfil – ingen AMS-mappning tillgänglig',
+      gcode: 'GCODE',
+      source: 'KÄLLA',
+      project: 'Projekt: {{name}}',
+      runsBadge: '{{count}} utskrifter',
+      runsBadgeTitle: '{{count}} utskrifter totalt — {{successful}} lyckade, {{failed}} misslyckade. Klicka för att se hela utskriftsloggen.',
+      estimated: 'Uppskattad: {{time}}',
+      actual: 'Faktisk: {{time}}',
+      accuracy: 'Noggrannhet: {{percent}}%',
+      filament: '{{weight}}g',
+      layer: '{{count}} skikt',
+      layers: '{{count}} skikt',
+      object: '{{count}} objekt',
+      objects: '{{count}} objekt',
+      slicedFor: 'Slicad för {{model}}',
+      uploadedBy: 'Uppladdad av',
+      noPermissionReprint: 'Du har inte behörighet att skriva ut igen',
+      noFileForReprint: 'Ingen 3MF-fil tillgänglig — filen kunde inte laddas ner från skrivaren när utskriften registrerades',
+      slicerAmsMapping: 'AMS-mappning sparad ({{printer}})',
+      slicerAmsMappingTooltip: 'Slicer-programmets eget val av AMS-fack sparades för {{printer}}. Bricknummer betyder endast något på den skrivaren, så en omutskrift återanvänder dem endast när den riktas till {{printer}} igen.',
+      noPermissionEdit: 'Du har inte behörighet att redigera arkiv',
+      noPermissionDelete: 'Du har inte behörighet att ta bort arkiv',
+      openInBambuStudio: 'Öppna i slicer-program',
+      openInBambuStudioToSlice: 'Öppna i slicer-program för att slica',
+      slice: 'Slica',
+      externalLink: 'Extern länk',
+      makerWorld: 'MakerWorld: {{designer}}',
+      viewProject: 'Visa projekt',
+      noExternalLink: 'Ingen extern länk',
+      preview3d: '3D-förhandsgranskning',
+      download: 'Ladda ner',
+      edit: 'Redigera',
+      delete: 'Ta bort',
+    },
+    runLog: {
+      title: 'Utskriftslogg',
+      modalTitle: 'Utskriftslogg — {{name}}',
+      modalTitleFallback: 'detta arkiv',
+      empty: 'Inga utskriftshändelser registrerade för detta arkiv än.',
+      col: {
+        date: 'Datum',
+        status: 'Status',
+        duration: 'Varaktighet',
+        filament: 'Filament',
+        cost: 'Kostnad',
+      },
+      status: {
+        completed: 'Slutförd',
+        failed: 'Misslyckad',
+        cancelled: 'Avbruten',
+        stopped: 'Stoppad',
+        skipped: 'Hoppad över',
+        printing: 'Skriver ut',
+      },
+    },
+    modal: {
+      deleteArchive: 'Ta bort arkiv',
+      deleteConfirm: 'Är du säker på att du vill ta bort "{{name}}"? Denna åtgärd kan inte ångras.',
+      deleteButton: 'Ta bort',
+      deletePurgeStats: 'Ta också bort denna utskrift från Snabbstatistik (filament, tid, kostnad, energi)',
+      deleteQueueItemsWarning: '{{count}} köade artiklar kopplade till detta arkiv kommer också att tas bort.',
+      deleteBlockedByPrinting: 'Kan inte ta bort — {{count}} köade artiklar skrivs för närvarande ut. Stoppa utskriften först och försök sedan igen.',
+      removeSource3mf: 'Ta bort 3MF-källfil',
+      removeSource3mfConfirm: 'Är du säker på att du vill ta bort 3MF-källfilen från "{{name}}"? Detta kommer att ta bort originalfilen från slicer-programmet.',
+      removeButton: 'Ta bort',
+      removeF3d: 'Ta bort F3D',
+      removeF3dConfirm: 'Är du säker på att du vill ta bort Fusion 360-designfilen från "{{name}}"?',
+      removeTimelapse: 'Ta bort timelapse',
+      removeTimelapseConfirm: 'Är du säker på att du vill ta bort timelapse-videon från "{{name}}"?',
+      timelapse: '{{name}} — Timelapse',
+      selectTimelapse: 'Välj timelapse',
+      selectTimelapseDesc: 'Ingen automatisk matchning hittad. Välj timelapse för denna utskrift:',
+      deleteArchives: 'Ta bort arkiv',
+      deleteArchivesConfirm: 'Är du säker på att du vill ta bort {{count}} arkiv? Denna åtgärd kan inte ångras.',
+      deleteCount: 'Ta bort {{count}}',
+    },
+    page: {
+      title: 'Arkiv',
+      printsCount: '{{filtered}} av {{total}} utskrifter',
+      dropFilesHere: 'Släpp .3mf-filer här',
+      releaseToUpload: 'Släpp för att ladda upp',
+      only3mfSupported: 'Endast .3mf-filer stöds',
+      close: 'Stäng',
+      selected: '{{count}} valda',
+      selectAll: 'Välj alla',
+      tags: 'Taggar',
+      project: 'Projekt',
+      favorite: 'Favorit',
+      delete: 'Ta bort',
+      toggledFavorites: 'Växlade favoriter för {{count}} arkiv',
+      failedUpdateFavorites: 'Kunde inte uppdatera favoriter',
+      archivesDeleted: '{{count}} arkiv borttagna',
+      failedDeleteArchives: 'Kunde inte ta bort arkiv',
+      photoDeleted: 'Foto borttaget',
+      failedDeletePhoto: 'Kunde inte ta bort foto',
+    },
+    list: {
+      name: 'Namn',
+      printer: 'Skrivare',
+      date: 'Datum',
+      size: 'Storlek',
+      actions: 'Åtgärder',
+      hasTimelapse: 'Har timelapse',
+    },
+    log: {
+      date: 'Datum',
+      printName: 'Utskriftsnamn',
+      printer: 'Skrivare',
+      user: 'Användare',
+      status: 'Status',
+      duration: 'Varaktighet',
+      filament: 'Filament',
+      filamentUsed: 'Filament använt',
+      cost: 'Kostnad',
+      energy: 'Energi',
+      energyCost: 'Energikostnad',
+      completedAt: 'Slutförd',
+      columns: 'Kolumner',
+      sortBy: 'Sortera efter {{column}}',
+      allPrinters: 'Alla skrivare',
+      allUsers: 'Alla användare',
+      allStatuses: 'Alla statusar',
+      cancelled: 'Avbruten',
+      skipped: 'Hoppad över',
+      dateFrom: 'Från',
+      dateTo: 'Till',
+      noEntries: 'Inga utskriftsloggposter hittade',
+      showing: 'Visar {{count}} av {{total}} poster',
+      rowsPerPage: 'Rader',
+      page: 'Sida',
+      prev: 'Föregående',
+      next: 'Nästa',
+      clearLog: 'Rensa logg',
+      clearLogTitle: 'Rensa utskriftslogg',
+      clearLogConfirm: 'Alla utskriftsloggposter kommer att tas bort permanent. Arkiv och köposter påverkas inte. Denna åtgärd kan inte ångras. Är du säker?',
+      clearLogButton: 'Rensa alla',
+      cleared: '{{count}} loggposter rensade',
+      clearFailed: 'Kunde inte rensa utskriftslogg',
+      deleteEntryTitle: 'Ta bort utskriftsloggpost',
+      deleteEntryConfirm: 'Denna post kommer att tas bort från loggen och dess bidrag till filament, tid och kostnad kommer att tas bort från Snabbstatistik. Matchande arkiv (om något) påverkas inte. Denna åtgärd kan inte ångras.',
+      entryDeleted: 'Utskriftsloggpost borttagen',
+      entryDeleteFailed: 'Kunde inte ta bort utskriftsloggpost',
+      editEntryTitle: 'Redigera utskriftsloggpost',
+      editEntryDescription: 'Klassificera denna utskrift. Widgeten för felanalys grupperar efter dessa värden, så uppdateringar flödar omedelbart till statistiken.',
+      entryUpdated: 'Utskriftsloggpost uppdaterad',
+      entryUpdateFailed: 'Kunde inte uppdatera utskriftsloggpost',
+      statuses: {
+        completed: 'Slutförd',
+        failed: 'Misslyckad',
+        stopped: 'Stoppad',
+        cancelled: 'Avbruten',
+        skipped: 'Hoppad över',
+      },
+    },
+  },
+
+  // Sticky upload-progress toast (#1625 follow-up — restored the
+  // legacy bg-dispatch toast UI for the scheduler-driven dispatch path).
+  // Strings mirror 0b43ac0d's backgroundDispatch namespace.
+  dispatchToast: {
+    untitled: 'Utskriftsjobb',
+    startingPrints: 'Startar utskrifter',
+    progressSummary: '{{complete}}/{{total}} klara • Bearbetar: {{processing}}',
+    expandDetails: 'Visa detaljer för utskicksinformation',
+    collapseDetails: 'Dölj detaljer för utskicksinformation',
+    awaitingPrinter: 'Väntar på skrivare…',
+    status: {
+      processing: 'Bearbetar',
+      completed: 'Slutförd',
+      failed: 'Misslyckad',
+    },
+    failed: {
+      generic: 'Utskick misslyckades',
+      upload_failed: 'Kunde inte ladda upp till skrivare',
+      start_command_failed: 'Skrivaren avvisade startkommandot',
+    },
+    dismiss: 'Avfärda',
+  },
+
+  // Pipeline Runs dashboard (#1425 PR C). Lists every Slicer Pipeline run
+  // across every pipeline with status + pipeline filters and pagination.
+  // Each row expands to per-copy job status; partial-failure runs get a
+  // Retry-failed button; in-flight runs get a Cancel button.
+  pipelineRuns: {
+    title: 'Pipeline-körningar',
+    loading: 'Laddar…',
+    empty: 'Inga pipeline-körningar än.',
+    filter: {
+      pipeline: 'Pipeline',
+      status: 'Status',
+      target: 'Mål',
+      all: 'Alla',
+      allPipelines: 'Alla pipelines',
+      allStatus: 'Alla statusar',
+      allTargets: 'Alla mål',
+      clear: 'Rensa filter',
+      noMatches: 'Inga körningar matchar de aktuella filtren.',
+    },
+    totalCount_one: '{{n}} körning',
+    totalCount_other: '{{n}} körningar',
+    copies: '{{n}} kopior',
+    failedCount: '{{n}} misslyckade',
+    copyN: 'Kopiera {{n}}',
+    retryFailed: 'Kunde inte försöka igen',
+    retryOf: 'omförsök av #{{n}}',
+    pagination: '{{start}}–{{end}} av {{total}}',
+    cancelledByUser: 'Avbruten av användare',
+    toast: {
+      cancelled: 'Körning avbruten',
+      cancelFailed: 'Kunde inte avbryta',
+      retryStarted: 'Omförsök påbörjat',
+      retryFailed: 'Kunde inte försöka igen',
+      cleared: '{{n}} körningar rensade',
+      clearFailed: 'Kunde inte rensa',
+    },
+    clearLog: 'Rensa logg',
+    clearConfirmTitle: 'Rensa logg?',
+    clearConfirmBody: 'Ta bort alla slutförda, misslyckade, avbrutna och delvis misslyckade pipeline-körningar? Pågående körningar behålls. Denna åtgärd kan inte ångras.',
+    clearConfirmAction: 'Rensa',
+    jobStatus: {
+      pending: 'väntande',
+      awaiting_printer: 'väntar på skrivare',
+      queued: 'i kö',
+      printing: 'skriver ut',
+      completed: 'slutförd',
+      failed: 'misslyckad',
+      cancelled: 'avbruten',
+    },
+  },
+
+  // Queue page
+  queue: {
+    title: 'Utskriftskö',
+    subtitle: 'Schemalägg och hantera dina utskriftsjobb',
+    filamentShort: {
+      rowBadge: 'Otillräckligt filament för den tilldelade rullen',
+      rowTooltip: 'Utskicksschemaläggaren markerade denna post. Klicka på Spela för att se underskottet per fack och bestämma om du vill skriva ut ändå.',
+      confirmTitle: 'Otillräckligt filament',
+      confirmIntro: 'Den tilldelade rullen kan inte tillfredsställa åtminstone ett fack. Skriv ut ändå?',
+      lineItem: 'Fack {{slot}}: behöver {{required}} g, {{remaining}} g kvar',
+      unknown: 'okänd',
+      printAnyway: 'Skriv ut ändå',
+    },
+    slicerAmsMapping: {
+      rowBadge: 'AMS-fack sparade för denna skrivare',
+      rowTooltip: 'Detta arkiv innehåller de exakta AMS-fack som slicer-programmet valde, sparade för den skrivare denna post riktar sig till. En omutskrift på den kan återanvända dessa brickor istället för att matcha igen efter typ och färg.',
+    },
+    // Print modal
+    editQueueItem: 'Redigera köad artikel',
+    selectAllPlates: 'Markera alla {{count}} plattor',
+    deselectAll: 'Avmarkera alla',
+    printQueued: 'Utskrift köad',
+    printQueuedWillStartWhenIdle: 'Kommer att starta när skrivaren är inaktiv',
+    itemsQueued: '{{count}} poster i kö',
+    sending: 'Skickar...',
+    sendingProgress: 'Skickar {{current}}/{{total}}...',
+    adding: 'Lägg till...',
+    addingProgress: 'Lägger till {{current}}/{{total}}...',
+    savingProgress: 'Sparar {{current}}/{{total}}...',
+    clearQueue: 'Rensa kö',
+    clearHistory: 'Rensa historik',
+    emptyQueue: 'Kön är tom',
+    position: 'Position',
+    scheduledTime: 'Schemalagd tid',
+    moveUp: 'Flytta upp',
+    moveDown: 'Flytta ner',
+    startNow: 'Starta nu',
+    printingInProgress: 'Skriver ut...',
+    viewArchive: 'Visa arkiv',
+    viewInFileManager: 'Visa i Filhanteraren',
+    itemCount: '{{count}} artikel',
+    itemCount_plural: '{{count}} artiklar',
+    dragToReorder: 'Dra för att ordna om (endast ASAP)',
+    reorderHint: 'Position påverkar endast ASAP-poster. Schemalagda poster körs vid sin inställda tid.',
+    sjf: {
+      label: 'SJF',
+      tooltip: 'Kortast jobb först — schemaläggaren prioriterar korta utskrifter',
+    },
+    addedBy: 'Tillagd av {{name}}',
+    nextInQueue: 'Nästa i kön',
+    clearPlateSuccess: 'Platta rensad — redo för nästa utskrift',
+    plateNumber: 'Platta {{index}}',
+    // Batch / quantity
+    quantity: 'Kvantitet',
+    quantityHint: 'Skapar {{count}} köade artiklar',
+    plateQuantityLabel: 'Körningar av {{plate}}',
+    plateQuantityTotal_one: '{{count}} körning totalt',
+    plateQuantityTotal_other: '{{count}} körningar totalt',
+    batchOrders: {
+      title: 'Batchordrar',
+      emptyTitle: 'Inga batchordrar',
+      emptyDescription: 'Köa en fil med flera plattor, eller mer än en kopia av en platta, så visas ordern här med dess framsteg.',
+      filter: {
+        active: 'Aktiv',
+        completed: 'Slutförd',
+        cancelled: 'Avbruten',
+        all: 'Alla',
+      },
+      status: {
+        active: 'Aktiv',
+        completed: 'Slutförd',
+        cancelled: 'Avbruten',
+      },
+      noTargets: 'Endast gruppering',
+      noTargetsHint: 'Skapad innan per-platta-mål existerade, så den spårar de körningar den köade istället för ett mål.',
+      dispatchRemaining: 'Kö {{count}} återstående',
+      dispatchPlate: 'Kö återstående',
+      strandedPlate: 'Inget kvar att kopiera inställningar från',
+      strandedNotice: 'Kan inte köa {{runs}} av {{owed}} körningar som fortfarande är i skuld: den plattan har ingen kö eller färdig körning kvar att kopiera inställningar från. Ställ plattan i kö en gång från filen, eller avbryt beställningen.',
+      dispatched: 'Köade de återstående körningarna för {{name}}',
+      plateProgress: '{{completed}} av {{target}} klara',
+      remaining: '{{count}} återstående',
+      failed: '{{count}} misslyckade',
+      printing: '{{count}} skriver ut',
+      wholeFile: 'Hela filen',
+      due: 'Förfaller {{date}}',
+      costSoFar: '{{amount}} hittills',
+      costRemaining: '({{amount}} kvar)',
+    },
+    activeBatches: 'Aktiva batcher',
+    batchProgress: '{{completed}} av {{total}} slutförda',
+    cancelBatch: 'Avbryt återstående',
+    batchCancelled: 'Återstående batchartiklar avbrutna',
+    cancelBatchConfirmTitle: 'Avbryt batch',
+    cancelBatchConfirmMessage: 'Avbryt alla återstående väntande artiklar i denna batch?',
+    batch: {
+      defaultName: 'Batch',
+      label: '{{count}} artikel',
+      label_plural: '{{count}} artiklar',
+      pendingCount: '{{count}} väntande',
+      pendingCount_plural: '{{count}} väntande',
+      expand: 'Expandera batch',
+      collapse: 'Minimera batch',
+      groupAsBatch: 'Gruppera som batch...',
+      groupAsBatchDescription: 'Kombinera de {{count}} markerade posterna till en enda hopfällbar batch.',
+      nameLabel: 'Batchnamn',
+      namePlaceholder: 't.ex. Fredagspresenter',
+      create: 'Skapa batch',
+      ungroup: 'Avgruppera',
+      ungroupConfirmTitle: 'Avgruppera batch?',
+      ungroupConfirmMessage: 'Posterna kommer att förbli i kön men kommer inte längre att grupperas ihop.',
+      dragGroup: 'Dra grupp',
+    },
+    // Tabs
+    tabs: {
+      batches: 'Batchar',
+      queue: 'Kö',
+      history: 'Historik',
+      timeline: 'Tidslinje',
+      pipelines: 'Pipelines',
+    },
+    // Layout toggle on the Queue tab — distinct from the sort dropdown
+    // (those control order; these control whether items render as one flat
+    // list or grouped under per-printer section headers).
+    layout: {
+      flatList: 'Lista',
+      byPrinter: 'Efter skrivare',
+      groupByPrinter: 'Gruppera efter skrivare',
+    },
+    // History tab empty state
+    history: {
+      emptyTitle: 'Ingen historik än',
+      emptyDescription: 'Slutförda, avbrutna och misslyckade utskrifter kommer att visas här.',
+      showMore: 'Visa mer',
+      showingCount: 'Visar {{shown}} av {{total}}',
+    },
+    // Drag ghost label when multi-dragging
+    dragGhost: {
+      multiCount: '{{count}} poster',
+      batch: '{{name}} ({{count}} kopia)',
+      batch_plural: '{{name}} ({{count}} kopior)',
+    },
+    // Sections
+    sections: {
+      currentlyPrinting: 'Skriver ut nu',
+      queued: 'I kö',
+      history: 'Historik',
+    },
+    // Status
+    status: {
+      pending: 'Väntande',
+      waiting: 'Väntar',
+      printing: 'Skriver ut',
+      paused: 'Pausad',
+      completed: 'Slutförd',
+      failed: 'Misslyckad',
+      skipped: 'Hoppad över',
+      cancelled: 'Avbruten',
+    },
+    // Summary cards
+    summary: {
+      printing: 'Skriver ut',
+      queued: 'I kö',
+      totalTime: 'Total kötid',
+      totalWeight: 'Total kövikt',
+      history: 'Historik',
+    },
+    // Filters
+    filter: {
+      allPrinters: 'Alla skrivare',
+      unassigned: 'Otilldelad',
+      allStatus: 'Alla statusar',
+      allLocations: 'Alla platser',
+      any: 'Valfri',
+    },
+    // Sort
+    sort: {
+      byPosition: 'Sortera efter position',
+      byName: 'Sortera efter namn',
+      byPrinter: 'Sortera efter skrivare',
+      bySchedule: 'Sortera efter schema',
+      byDate: 'Sortera efter datum',
+      ascendingOldest: 'Stigande (äldst först)',
+      descendingNewest: 'Fallande (nyast först)',
+    },
+    // Badges
+    badges: {
+      staged: 'Förberedd',
+      requiresPrevious: 'Kräver tidigare framgång',
+      autoPowerOff: 'Auto-avstängning',
+      gcodeInjection: 'G-kod',
+    },
+    // Empty state
+    empty: {
+      title: 'Inga utskrifter schemalagda',
+      description: 'Schemalägg en utskrift från Arkiv-sidan med hjälp av "Schemalägg"-alternativet i kontextmenyn, eller dra och släpp filer för att komma igång.',
+    },
+    // Time
+    time: {
+      etaIfStartedNow: 'Färdigställningstid om detta jobb startar nu',
+      whenFree: 'När en skrivare är ledig',
+      overdue: 'Försenad',
+      now: 'Nu',
+      lessThanMinute: 'Om mindre än en minut',
+      inMinutes: 'Om {{count}} min',
+      inHours: 'Om {{count}} timmar',
+    },
+    // Actions
+    actions: {
+      startPrint: 'Starta utskrift',
+      stopPrint: 'Stoppa utskrift',
+      requeue: 'Lägg tillbaka i kö',
+    },
+    // Bulk edit
+    bulkEdit: {
+      title: 'Redigera {{count}} post',
+      title_plural: 'Redigera {{count}} poster',
+      description: 'Endast ändrade inställningar kommer att tillämpas på valda poster.',
+      printer: 'Skrivare',
+      noChange: '— Ingen ändring —',
+      queueOptions: 'Köalternativ',
+      staged: 'Förberedd (manuell start)',
+      autoPowerOff: 'Auto-avstängning efter utskrift',
+      requirePrevious: 'Kräv tidigare framgång',
+      gcodeInjection: 'Injicera G-kod',
+      printOptions: 'Utskriftsalternativ',
+      bedLevelling: 'Byggplattsnivåinställning',
+      flowCalibration: 'Flödeskalibrering',
+      vibrationCalibration: 'Vibrationskalibrering',
+      layerInspection: 'Förstaskiktsinspektion',
+      timelapse: 'Timelapse',
+      useAms: 'Använd AMS',
+      nozzleOffsetCali: 'Munstyckesoffsetskalibrering',
+      applyChanges: 'Tillämpa ändringar',
+      selectAll: 'Markera alla',
+      deselectAll: 'Avmarkera alla',
+      selected: '{{count}} valda',
+      editSelected: 'Redigera valda',
+      cancelSelected: 'Avbryt valda',
+    },
+    // Confirmations
+    confirm: {
+      cancelTitle: 'Avbryt schemalagd utskrift',
+      cancelMessage: 'Är du säker på att du vill avbryta "{{name}}"?',
+      stopTitle: 'Stoppa utskrift',
+      stopMessage: 'Är du säker på att du vill stoppa den aktuella utskriften "{{name}}"? Detta kommer att avbryta utskriftsjobbet på skrivaren.',
+      removeTitle: 'Ta bort från historik',
+      removeMessage: 'Är du säker på att du vill ta bort "{{name}}" från köhistoriken?',
+      clearHistoryTitle: 'Rensa historik',
+      clearHistoryMessage: 'Är du säker på att du vill ta bort alla {{count}} poster från historiken?',
+      cancelButton: 'Avbryt utskrift',
+      stopButton: 'Stoppa utskrift',
+      thisPrint: 'denna utskrift',
+      thisItem: 'denna post',
+    },
+    // Toast messages
+    toast: {
+      cancelled: 'Köpost avbruten',
+      cancelFailed: 'Kunde inte avbryta post',
+      removed: 'Köpost borttagen',
+      keptForOrder: 'Avbruten istället för borttagen: detta är den enda körningen som dess batchorder kan återställa den här plattan från',
+      historyKeptForOrders: 'Behöll {{kept}} som batchordrar fortfarande behöver.',
+      removeFailed: 'Kunde inte ta bort post',
+      stopped: 'Utskrift stoppad',
+      stopFailed: 'Kunde inte stoppa utskrift',
+      released: 'Utskrift släppt till kö',
+      startFailed: 'Kunde inte starta utskrift',
+      reorderFailed: 'Kunde inte ordna om kö',
+      historyCleared: 'Rensade {{count}} historikpost(er)',
+      clearHistoryFailed: 'Kunde inte rensa historik',
+      updateFailed: 'Kunde inte uppdatera poster',
+      bulkCancelled: 'Avbröt {{count}} post(er)',
+      bulkCancelFailed: 'Kunde inte avbryta poster',
+      batchCreated: 'Batch "{{name}}" skapad',
+      batchCreateFailed: 'Kunde inte skapa batch',
+      batchUngrouped: 'Avgrupperade {{count}} post(er)',
+      batchUngroupFailed: 'Kunde inte avgruppera batch',
+      resumedAfterFailure: 'Återupptog kö — {{restored}} jobb återställda till väntande',
+      resumeAfterFailureFailed: 'Kunde inte återuppta kö',
+    },
+    resumeAfterFailure: {
+      banner: '{{printer}} är blockerad av ett tidigare utskriftsfel — {{count}} jobb hoppades över',
+      bannerHint: 'Åtgärda skrivarproblemet, sedan återuppta för att återställa de hoppade jobben och rensa blockeringen.',
+      button: 'Återuppta efter fel',
+      confirmTitle: 'Återuppta kö efter fel?',
+      confirmMessage: 'Återställ {{count}} hoppade jobb på {{printer}} till väntande och rensa blockeringen för tidigare utskrift. Se till att skrivaren är redo innan du fortsätter.',
+    },
+    // Timeline view
+    timeline: {
+      listView: 'Lista',
+      timelineView: 'Tidslinje',
+      unassigned: 'Otilldelad',
+      noData: 'Inga schemalagda utskrifter för denna dag',
+      nothingCommitted: 'Inga fastställda scheman i detta fönster. Förberedda poster, väntande poster och ASAP-jobb på inaktiva skrivare visas inte — ange en schemalagd tid eller släpp en förberedd post för att se den här.',
+      allDoneBy: 'Alla utskrifter beräknas vara klara till {{time}}',
+      staged: 'Förberedd',
+      filterAll: 'Visa alla',
+      filterPrinting: 'Skriver ut',
+      filterQueued: 'I kö',
+      time: {
+        anyMoment: 'när som helst',
+        minutesLeft: '{{minutes}}m kvar',
+        hoursLeft: '{{hours}}h kvar',
+        hoursMinutesLeft: '{{hours}}h {{minutes}}m kvar',
+      },
+      day: {
+        previous: 'Föregående dag',
+        next: 'Nästa dag',
+        today: 'Idag',
+      },
+      // Rolling-24h Gantt window
+      window: {
+        back12h: 'Bakåt 12 timmar',
+        forward12h: 'Framåt 12 timmar',
+        now: 'Nu',
+      },
+      printerColumnHeader: 'Skrivare',
+    },
+    // Permissions
+    permissions: {
+      noStopPrint: 'Du har inte behörighet att stoppa utskrifter',
+      noStartPrint: 'Du har inte behörighet att starta utskrifter',
+      noEdit: 'Du har inte behörighet att redigera denna köpost',
+      noCancel: 'Du har inte behörighet att avbryta denna köpost',
+      noRequeue: 'Du har inte behörighet att lägga tillbaka poster i kön',
+      noRemove: 'Du har inte behörighet att ta bort denna köpost',
+      noClearHistory: 'Du har inte behörighet att rensa all historik',
+      noEditItems: 'Du har inte behörighet att redigera köposter',
+      noCancelItems: 'Du har inte behörighet att avbryta köposter',
+    },
+  },
+
+  // Statistics page
+  stats: {
+    title: 'Statistik',
+    subtitle: 'Dra widgetar för att omordna. Klicka på ögonikonen för att dölja.',
+    overview: 'Översikt',
+    totalPrints: 'Totala utskrifter',
+    successRate: 'Framgångsgrad',
+    totalPrintTime: 'Total utskriftstid',
+    printTime: 'Utskriftstid',
+    totalFilament: 'Totalt filament använt',
+    filamentUsed: 'Filament använt',
+    filamentCost: 'Filamentkostnad',
+    totalCost: 'Total kostnad',
+    energyUsed: 'Energi använt',
+    energyCost: 'Energikostnad',
+    energyWarmingUpTooltip: 'Energispårning samlar fortfarande in timvisa ögonblicksbilder. Datumintervallstotaler kommer att bli korrekta när åtminstone en ögonblicksbild existerar före det valda intervallet. Tidiga värden kan underskattas.',
+    averagePrintTime: 'Genomsnittlig utskriftstid',
+    printsPerDay: 'Utskrifter per dag',
+    byPrinter: 'Efter skrivare',
+    printsByPrinter: 'Utskrifter efter skrivare',
+    byMaterial: 'Efter material',
+    byMonth: 'Efter månad',
+    last7Days: 'Senaste 7 dagarna',
+    last30Days: 'Senaste 30 dagarna',
+    last90Days: 'Senaste 90 dagarna',
+    allTime: 'All tid',
+    // Widgets
+    quickStats: 'Snabbstatistik',
+    printActivity: 'Utskriftsaktivitet',
+    filamentTypes: 'Filamenttyper',
+    filamentTrends: 'Filamenttrender',
+    failureAnalysis: 'Felanalys',
+    timeAccuracy: 'Tidsnoggrannhet',
+    successful: 'Lyckade:',
+    failed: 'Misslyckade:',
+    cancelled: 'Avbrutna:',
+    perfectEstimate: '100% = perfekt uppskattning',
+    noTimeAccuracyData: 'Ingen tidsnoggrannhetsdata än',
+    noFilamentData: 'Ingen filamentdata tillgänglig',
+    noPrinterData: 'Ingen skrivardata tillgänglig',
+    noPrintData: 'Ingen utskriftsdata tillgänglig',
+    noPrintDataLast30Days: 'Ingen utskriftsdata de senaste 30 dagarna',
+    failureReasons: 'Orsaker till fel',
+    topFailureReasons: 'Vanligaste orsaker till fel',
+    failedPrintsCount: '{{failed}} / {{total}} utskrifter misslyckades',
+    lastWeekRate: 'Förra veckan: {{rate}}%',
+    // Actions
+    resetLayout: 'Återställ layout',
+    recalculateCosts: 'Omberäkna kostnader',
+    recalculateCostsHint: 'Omberäkna alla arkivkostnader med nuvarande filamentpriser',
+    exportStats: 'Exportera statistik',
+    exportAsCsv: 'Exportera som CSV',
+    exportAsExcel: 'Exportera som Excel',
+    hiddenCount: '{{count}} dolda',
+    // Toast
+    exportDownloaded: 'Export nedladdad',
+    exportFailed: 'Kunde inte exportera',
+    layoutReset: 'Layout återställd',
+    recalculatedCosts: 'Omberäknade kostnader för {{count}} arkiv',
+    recalculateFailed: 'Kunde inte omberäkna kostnader',
+    // Loading
+    loadingStats: 'Laddar statistik...',
+    // Permissions
+    noPermissionResetLayout: 'Du har inte behörighet att återställa layout',
+    noPermissionRecalculate: 'Du har inte behörighet att omberäkna kostnader',
+    noPrintDataInRange: 'Ingen utskriftsdata i det valda intervallet',
+    periodFilament: 'Periodens filament',
+    periodCost: 'Periodens kostnad',
+    avgPerPrint: 'Genomsnitt per utskrift',
+    usageOverTime: 'Användning över tid',
+    energyOverTime: 'Energi över tid',
+    filamentByWeight: 'Vikt',
+    printDuration: 'Utskriftsvaraktighet',
+    printerUtilization: 'Skrivaranvändning',
+    filamentSuccess: 'Framgång efter material',
+    printHabits: 'Utskriftsvanor',
+    printTimeOfDay: 'Utskriftstid på dagen',
+    colorDistribution: 'Färgsfördelning',
+    noColorData: 'Ingen färgdata tillgänglig',
+    records: 'Rekord',
+    longestPrint: 'Längsta utskrift',
+    heaviestPrint: 'Tungsta utskrift',
+    mostExpensivePrint: 'Dyraste utskrift',
+    busiestDay: 'Mest aktiva dagen',
+    successStreak: 'Framgångssvit',
+    streakPrint: 'utskrift i rad',
+    streakPrints: '{{count}} utskrifter i rad',
+    printerStats: 'Skrivarstatistik',
+    hours: 'timmar',
+    avgPrints: 'Genomsnittliga utskrifter',
+    noArchiveData: 'Ingen utskriftsdata tillgänglig',
+    filamentByTime: 'Tid',
+    avgWeight: 'Genomsnittsvikt',
+    avgTime: 'Genomsnittstid',
+    filamentByPrints: 'Utskrifter',
+    timeframe: {
+      'today': 'Idag',
+      'this-week': 'Denna vecka',
+      'this-month': 'Denna månad',
+      'last-7': 'Senaste 7 dagarna',
+      'last-30': 'Senaste 30 dagarna',
+      'last-90': 'Senaste 90 dagarna',
+      'this-year': 'Detta år',
+      'all-time': 'All tid',
+      'custom': 'Anpassat intervall',
+      from: 'Från',
+      to: 'Till',
+    },
+    // User filter
+    allUsers: 'Alla användare',
+    noUser: 'Ingen användare (System)',
+    filterByUser: 'Filtrera efter användare',
+  },
+
+  // Maintenance page
+  maintenance: {
+    title: 'Underhåll',
+    overview: 'Översikt',
+    allOk: 'Allt underhåll är gjort',
+    dueCount: '{{count}} underhåll uteblivet',
+    dueCount_plural: '{{count}} underhåll uteblivna',
+    warningCount: '{{count}} varning',
+    warningCount_plural: '{{count}} varningar',
+    totalPrintTime: 'Total utskriftstid',
+    nextMaintenance: 'Nästa underhåll',
+    nothingDue: 'Inget uteblivet',
+    tasks: 'Uppgifter',
+    lastPerformed: 'Senast utfört',
+    interval: 'Intervall',
+    hoursRemaining: '{{hours}}h kvar',
+    hoursOverdue: '{{hours}}h försenat',
+    markDone: 'Markera som klar',
+    performMaintenance: 'Utför underhåll',
+    history: 'Historik',
+    noHistory: 'Ingen underhållshistorik',
+    editPrintHours: 'Redigera utskriftstimmar',
+    currentHours: 'Aktuella timmar',
+    // Tabs
+    statusTab: 'Status',
+    settingsTab: 'Inställningar',
+    // Status
+    overdueCount: '{{count}} försenade',
+    dueSoonCount: '{{count}} förfaller snart',
+    dueSoon: 'Förfaller snart',
+    allGood: 'Allt bra',
+    overdueBy: 'Försenat med {{duration}}',
+    dueIn: 'Förfaller om {{duration}}',
+    timeLeft: '{{duration}} kvar',
+    // Duration formats
+    day: '1 dag',
+    days: '{{count}} dagar',
+    week: '1 vecka',
+    weeks: '{{count}} veckor',
+    month: '1 månad',
+    months: '{{count}} månader',
+    year: '1 år',
+    // Settings
+    maintenanceTypes: 'Underhållstyper',
+    maintenanceTypesDescription: 'Systemtyper och dina anpassade underhållsuppgifter',
+    addCustomType: 'Lägg till anpassad typ',
+    restoreDefaults: 'Återställ standarduppgifter',
+    intervalType: 'Intervalltyp',
+    intervalValue: 'Intervall ({{type}})',
+    icon: 'Ikon',
+    documentationLink: 'Dokumentationslänk (valfritt)',
+    assignToPrinters: 'Tilldela till skrivare',
+    selectAtLeastOnePrinter: 'Välj minst en skrivare',
+    addType: 'Lägg till typ',
+    custom: 'Anpassad',
+    printHours: 'Utskriftstimmar',
+    calendarDays: 'Kalenderdagar',
+    exampleName: 't.ex. Byt HEPA-filter',
+    viewDocumentation: 'Visa dokumentation',
+    timeBasedInterval: 'Tidsbaserat intervall',
+    // Interval overrides
+    intervalOverrides: 'Intervall-överskridningar',
+    intervalOverridesDescription: 'Anpassa intervall för specifika skrivare',
+    // Printer assignment
+    assignedToPrinters: 'Tilldelad till skrivare:',
+    noPrintersAssigned: 'Inga skrivare tilldelade',
+    addPrinterShort: 'Lägg till:',
+    printersAssignedClick: '{{count}} skrivare tilldelade – klicka för att hantera',
+    removeFromPrinter: 'Ta bort från denna skrivare',
+    // Types
+    types: {
+      lubricateCarbonRods: 'Smörj karbonstänger',
+      lubricateRails: 'Smörj linjära skenor',
+      cleanNozzle: 'Rengör munstycke/värmeblock',
+      checkBelts: 'Kontrollera remspänning',
+      cleanBuildPlate: 'Rengör byggplatta',
+      checkExtruder: 'Kontrollera extruderarkugghjul',
+      checkCooling: 'Kontrollera kylfläktar',
+      generalInspection: 'Allmän besiktning',
+      cleanCarbonRods: 'Rengör karbonstänger',
+      lubricateSteelRods: 'Smörj stålstänger',
+      cleanSteelRods: 'Rengör stålstänger',
+      cleanLinearRails: 'Rengör linjära skenor',
+      checkPtfeTube: 'Kontrollera PTFE-rör',
+      replaceHepaFilter: 'Byt HEPA-filter',
+      replaceCarbonFilter: 'Byt kolfilter',
+      lubricateLeftNozzleRail: 'Smörj vänster munstyckesskena',
+    },
+    // Toast
+    maintenanceComplete: 'Underhåll markerat som klart',
+    typeUpdated: 'Underhållstyp uppdaterad',
+    typeDeleted: 'Underhållstyp borttagen',
+    defaultsRestored: 'Återställde {{count}} standarduppgift(er)',
+    printHoursUpdated: 'Utskriftstimmar uppdaterade',
+    printerAssigned: 'Skrivare tilldelad',
+    printerRemoved: 'Skrivare borttagen',
+    // Confirmation
+    deleteTypeConfirm: 'Ta bort "{{name}}"?',
+    deleteSystemTypeTitle: 'Ta bort standardunderhållsuppgift?',
+    deleteSystemTypeMessage: 'Är du säker på att du vill ta bort standardunderhållsuppgift "{{name}}"?',
+    // Permissions
+    noPermissionUpdate: 'Du har inte behörighet att uppdatera underhållsposter',
+    noPermissionPerform: 'Du har inte behörighet att utföra underhåll',
+    noPermissionEditTypes: 'Du har inte behörighet att redigera underhållstyper',
+    noPermissionDeleteTypes: 'Du har inte behörighet att ta bort underhållstyper',
+    noPermissionEditHours: 'Du har inte behörighet att redigera utskriftstimmar',
+    noPermissionRemovePrinter: 'Du har inte behörighet att ta bort skrivartilldelningar',
+    noPermissionAssignPrinter: 'Du har inte behörighet att tilldela skrivare',
+    noPermissionEditIntervals: 'Du har inte behörighet att redigera intervall',
+    // Configure link
+    configureSettings: 'Konfigurera underhållstyper och intervall',
+  },
+
+  // Settings page
+  settings: {
+    sliceEngine: 'Slicer-motor',
+    sliceEngineSidecar: 'Server-sidecar',
+    sliceEngineSidecarHint: 'Slicing körs på servern, i slicerns sidecar-container.',
+    sliceEngineBrowser: 'I webbläsaren',
+    sliceEngineBrowserHint: 'Slicing körs på denna enhet, utan server inblandad.',
+    title: 'Inställningar',
+    general: 'Allmänt',
+    // Tab names
+    tabs: {
+      general: 'Allmänt',
+      smartPlugs: 'Smarta kontakter',
+      sensors: 'Sensorer',
+      notifications: 'Notiser',
+      queue: 'Arbetsflöde',
+      queueDispatch: 'Kö och utskick',
+      queuePipelines: 'Pipelines',
+      filament: 'Filament',
+      network: 'Nätverk',
+      apiKeys: 'API-nycklar',
+      virtualPrinter: 'Virtuell skrivare',
+      spoolbuddy: 'SpoolBuddy',
+      failureDetection: 'Feldetektering',
+      users: 'Autentisering',
+      backup: 'Säkerhetskopia',
+      emailAuth: 'E-postautentisering',
+      ldap: 'LDAP',
+      twoFa: 'Tvåfaktorsautentisering',
+      oidc: 'SSO / OIDC',
+      security: 'Säkerhet',
+    },
+    spoolbuddy: {
+      infoTitle: 'SpoolBuddy-enheter',
+      infoBody: 'SpoolBuddy-kiosker registrerar sig automatiskt via hjärtklapp. Avregistrera en enhet här om den inte längre används eller om en gammal dubblett lämnats kvar av en krasch i demonen.',
+      duplicatesTitle: '{{count}} enheter registrerade',
+      duplicatesBody: 'Endast den första registrerade enheten används av kiosk-gränssnittet. Om en av dessa är en gammal dubblett från en krasch, avregistrera den — en online-enhet kommer att registrera sig själv igen vid nästa hjärtklapp.',
+      empty: 'Inga SpoolBuddy-enheter registrerade än.',
+      online: 'Online',
+      offline: 'Offline',
+      unregister: 'Avregistrera',
+      unregisterSuccess: 'Enhet avregistrerad',
+      unregisterError: 'Kunde inte avregistrera enhet',
+      confirmTitle: 'Avregistrera SpoolBuddy-enhet?',
+      confirmBody: 'Detta kommer att ta bort "{{hostname}}" ({{deviceId}}) från databasen. Om enheten är online kommer den att registrera sig själv igen vid nästa hjärtklapp.',
+      ipAddress: 'IP-adress',
+      firmware: 'Firmware',
+      lastSeen: 'Senast sedd',
+      daemonUptime: 'Demonens upptid',
+      systemUptime: 'Systemets upptid',
+      never: 'aldrig',
+      nfc: 'NFC',
+      scale: 'Skala',
+      cpuTemp: 'CPU-temperatur',
+      cpuLoad: 'CPU-belastning',
+      memory: 'Minne',
+      disk: 'Disk',
+      // Device actions
+      update: 'Uppdatera',
+      updateConfirmTitle: 'Uppdatera SpoolBuddy-demon?',
+      updateConfirmBody: 'Trigga en programuppdatering på "{{hostname}}"? Demonen kommer att starta om när uppdateringen är klar.',
+      restartBrowser: 'Starta om webbläsaren',
+      restartBrowserConfirmTitle: 'Starta om kiosk-webbläsaren?',
+      restartBrowserConfirmBody: 'Starta om kiosk-webbläsaren på "{{hostname}}"? Skärmen kommer att vara tom en kort stund.',
+      restartDaemon: 'Starta om demonen',
+      restartDaemonConfirmTitle: 'Starta om SpoolBuddy-demonen?',
+      restartDaemonConfirmBody: 'Starta om SpoolBuddy-demonen på "{{hostname}}"? Enheten kommer att vara offline i några sekunder.',
+      reboot: 'Starta om',
+      rebootConfirmTitle: 'Starta om enheten?',
+      rebootConfirmBody: 'Starta om "{{hostname}}"? Enheten kommer att vara offline i cirka en minut.',
+      shutdown: 'Stäng av',
+      shutdownConfirmTitle: 'Stäng av enhet?',
+      shutdownConfirmBody: 'Stäng av "{{hostname}}"? Du kommer att behöva fysisk åtkomst för att starta den igen.',
+      commandConfirm: 'Bekräfta',
+      commandQueued: 'Kommando köat',
+      commandError: 'Kunde inte skicka kommando',
+    },
+    // LDAP settings
+    ldap: {
+      title: 'LDAP-autentisering',
+      enabledDesc: 'LDAP-autentisering är aktiverat',
+      disabledDesc: 'LDAP-autentisering är inaktiverat',
+      disabledHint: 'Konfigurera och spara LDAP-inställningar nedan, aktivera sedan.',
+      enabled: 'LDAP-autentisering aktiverad',
+      disabled: 'LDAP-autentisering inaktiverad',
+      feature1: 'Användare kan logga in med LDAP-uppgifter',
+      feature2: 'Lokalt admin-konto kvarstår som reserv',
+      feature3: 'LDAP-grupper mappas till Bambuddy-grupper vid inloggning',
+      serverConfig: 'LDAP-serverkonfiguration',
+      serverUrl: 'Server-URL',
+      serverUrlHint: 'Använd ldaps:// för SSL eller ldap:// med StartTLS',
+      security: 'Säkerhet',
+      securityHint: 'StartTLS uppgraderar en vanlig anslutning till TLS. LDAPS använder TLS från början.',
+      bindDn: 'Bind DN (Service-konto)',
+      bindPassword: 'Bind-lösenord',
+      searchBase: 'Sök bas-DN',
+      userFilter: 'Användarsökfilter',
+      userFilterHint: '{username} ersätts med inloggningsanvändarnamnet. Använd (uid={username}) för OpenLDAP.',
+      advanced: 'Avancerat',
+      autoProvision: 'Auto-provisionera användare',
+      autoProvisionHint: 'Skapa automatiskt ett Bambuddy-konto vid första LDAP-inloggning',
+      defaultGroup: 'Standardgrupp',
+      defaultGroupNone: '— Ingen (ingen reserv) —',
+      defaultGroupHint: 'Reservgrupp som tilldelas när en LDAP-användare autentiseras men inte finns i någon mappad LDAP-grupp. Lämna tomt för att lämna omappade användare utan behörigheter.',
+      groupMapping: 'Gruppmappning (JSON)',
+      groupMappingHint: 'Mappa LDAP-grupp-DN till Bambuddy-grupper. Tillgängliga grupper: ',
+      testConnection: 'Testa anslutning',
+      settingsSaved: 'LDAP-inställningar sparade',
+      errors: {
+        serverRequired: 'LDAP-server-URL krävs',
+        searchBaseRequired: 'Sök bas-DN krävs',
+        enableAuthFirst: 'Aktivera autentisering först',
+        configureLdapFirst: 'Spara LDAP-inställningar först',
+      },
+    },
+    // Email settings
+    email: {
+      smtpSettings: 'SMTP-konfiguration',
+      smtpHost: 'SMTP-server',
+      smtpPort: 'SMTP-port',
+      security: 'Säkerhet',
+      authentication: 'Autentisering',
+      username: 'Användarnamn',
+      password: 'Lösenord',
+      fromEmail: 'Från e-post',
+      fromName: 'Från namn',
+      testConnection: 'Testa SMTP-anslutning',
+      testRecipient: 'Testmottagare e-post',
+      sendTest: 'Skicka test-e-post',
+      sending: 'Skickar...',
+      save: 'Spara inställningar',
+      saving: 'Sparar...',
+      advancedAuth: 'Avancerad autentisering',
+      advancedAuthEnabled: 'Avancerad autentisering är aktiverad',
+      advancedAuthEnabledDesc: 'E-postbaserade användarhanteringsfunktioner är aktiva. Nya användare kommer att få autogenererade lösenord via e-post, och användare kan återställa sina lösenord via "Glömt lösenord"-funktionen.',
+      advancedAuthDisabled: 'Avancerad autentisering är inaktiverad',
+      advancedAuthDisabledDesc: 'Aktivera avancerad autentisering för att aktivera e-postbaserade funktioner för användarhantering.',
+      enable: 'Aktivera',
+      disable: 'Inaktivera',
+      feature1: 'Lösenord genereras automatiskt och skickas via e-post till nya användare',
+      feature2: 'Användare kan logga in med användarnamn eller e-post',
+      feature3: '"Glömt lösenord"-funktionen är tillgänglig',
+      feature4: 'Admin kan återställa användarlösenord via e-post',
+      // Error messages
+      errors: {
+        requiredFields: 'Fyll i alla obligatoriska fält',
+        usernameRequired: 'Användarnamn krävs när autentisering är aktiverad',
+        enterTestEmail: 'Ange en test-e-postadress',
+        smtpServerAndEmail: 'Fyll i SMTP-server och Från e-post innan du testar',
+        usernamePasswordRequired: 'Användarnamn och lösenord krävs när autentisering är aktiverat',
+        configureSmtpFirst: 'Konfigurera och testa SMTP-inställningar först',
+        enableAuthFirst: 'Aktivera autentisering först för att använda e-postbaserade funktioner.',
+      },
+      // Success messages
+      success: {
+        settingsSaved: 'SMTP-inställningar sparade',
+      },
+      // Security options
+      securityOptions: {
+        starttls: 'STARTTLS (Port 587)',
+        ssl: 'SSL/TLS (Port 465)',
+        none: 'Ingen (Port 25)',
+      },
+      // Authentication options
+      authOptions: {
+        enabled: 'Aktiverad',
+        disabled: 'Inaktiverad',
+      },
+    },
+    appearance: 'Utseende',
+    notifications: 'Notiser',
+    smartPlugs: 'Smarta kontakter',
+    spoolman: 'Spoolman',
+    updates: 'Uppdateringar',
+    language: 'Språk',
+    languageDescription: 'Välj ditt föredragna språk',
+    theme: 'Tema',
+    themeLight: 'Ljust',
+    themeDark: 'Mörkt',
+    themeSystem: 'System',
+    defaultView: 'Standardvy',
+    defaultViewDescription: 'Sida att visa när appen öppnas',
+    checkForUpdates: 'Sök efter uppdateringar',
+    autoUpdate: 'Auto-uppdatering',
+    currentVersion: 'Aktuell version',
+    latestVersion: 'Senaste version',
+    upToDate: 'Du har den senaste versionen',
+    updateAvailable: 'Uppdatering tillgänglig',
+    // Notifications
+    notificationLanguage: 'Notisspråk',
+    notificationLanguageDescription: 'Språk för push-notiser',
+    bedCooledThreshold: 'Tröskelvärde för sval byggplatta',
+    bedCooledThresholdDescription: 'Temperatur under vilken byggplattan anses sval efter en utskrift',
+    userNotificationsEnabled: 'Användarnotiser',
+    userNotificationsEnabledDescription: 'Aktivera menyn för användarnotiser och e-postnotiser för utskriftshändelser. Kräver avancerad autentisering.',
+    userNotificationsDisabledHint: 'Aktivera avancerad autentisering för att använda användarnotiser.',
+    notificationProviders: 'Notisleverantörer',
+    addProvider: 'Lägg till leverantör',
+    editProvider: 'Redigera leverantör',
+    providerType: 'Leverantörstyp',
+    testNotification: 'Testnotis',
+    testSuccess: 'Testnotis skickad',
+    testFailed: 'Kunde inte skicka testnotis',
+    quietHours: 'Tysta timmar',
+    quietHoursDescription: 'Stör ej under dessa timmar',
+    quietHoursStart: 'Start',
+    quietHoursEnd: 'Slut',
+    events: {
+      title: 'Notishändelser',
+      printStart: 'Utskrift startad',
+      printComplete: 'Utskrift slutförd',
+      printFailed: 'Utskrift misslyckades',
+      printStopped: 'Utskrift stoppad',
+      printProgress: 'Förloppsmilstolpar',
+      printProgressDescription: 'Notis vid 25%, 50%, 75%',
+      printerOffline: 'Skrivare offline',
+      printerError: 'Skrivarfel',
+      filamentLow: 'Lågt filament',
+      maintenanceDue: 'Underhåll behövs',
+      maintenanceDueDescription: 'Notis när underhåll behövs',
+    },
+    // Smart Plugs
+    smartPlug: {
+      title: 'Smarta kontakter',
+      add: 'Lägg till smart kontakt',
+      edit: 'Redigera smart kontakt',
+      name: 'Namn',
+      ipAddress: 'IP-adress',
+      linkedPrinter: 'Länkad skrivare',
+      autoOn: 'Auto ström på',
+      autoOnDescription: 'Sätt på när utskrift startar',
+      autoOff: 'Auto ström av',
+      autoOffDescription: 'Stäng av efter att utskrift slutförts',
+      offDelay: 'Avstängningsfördröjning',
+      offDelayMinutes: 'Minuter efter utskrift',
+      offDelayTemp: 'När munstycket är under temperatur',
+      currentState: 'Aktuell status',
+      turnOn: 'Sätt på',
+      turnOff: 'Stäng av',
+    },
+    // Filament Tracking Mode
+    filamentTracking: 'Filamentspårning',
+    filamentTrackingDesc: 'Välj hur du vill spåra dina filamentrullar. Du kan använda det inbyggda inventariet eller ansluta till en extern Spoolman-server.',
+    autoAddUnknownRfid: 'Lägg automatiskt till okända RFID-rullar',
+    autoAddUnknownRfidDesc: 'Skapa automatiskt en inventariepost när en rulle med en okänd RFID-tagg upptäcks. Stäng av om du förregistrerar nya rullar manuellt för att undvika dubbletter.',
+    filamentChecks: 'Filamentkontroller',
+    disableFilamentWarnings: 'Inaktivera filamentvarningar',
+    disableFilamentWarningsDesc: 'Visa inte varningar om otillräckligt filament vid utskrift eller kö',
+    preferLowestFilament: 'Föredra rulle med minst filament kvar',
+    preferLowestFilamentDesc: 'När flera rullar matchar, använd den med minst filament kvar',
+    preferLowestFilamentBackupNote: 'Gäller endast när AMS filamentbackup är aktiverat på skrivaren — annars kan skrivaren inte byta till en andra rulle när den valda tar slut.',
+    trackingModeBuiltIn: 'Inbyggd inventering',
+    trackingModeBuiltInDesc: 'RFID-auto-matchning och användningsspårning inkluderad',
+    trackingModeSpoolmanDesc: 'Extern filamenthanteringsserver',
+    builtInFeatureRfid: 'Upptäcker automatiskt Bambu Lab RFID-rullar i AMS',
+    builtInFeatureUsage: 'Spårar filamentförbrukning per utskrift',
+    builtInFeatureCatalog: 'Hantera rullar, färger och K-faktorprofiler',
+    builtInFeatureThirdParty: 'Tredjepartsrullar kan tilldelas till inventeringsrullar',
+    amsSyncButton: 'Synkronisera vikter från AMS',
+    amsSyncTitle: 'Synkronisera rullvikter från AMS',
+    amsSyncMessage: 'Detta kommer att skriva över alla rullar i inventariet med vikter från de aktuella AMS-procentvärdena från anslutna skrivare. Använd detta för att återställa från korrupt viktdata. Skrivaren måste vara online.',
+    amsSyncing: 'Synkroniserar...',
+    amsSyncSuccess: '{{synced}} rulle(ar) synkroniserade, {{skipped}} hoppades över',
+    amsSyncError: 'Kunde inte synkronisera vikter från AMS',
+    spoolmanAmsSyncButton: 'Synkronisera Spoolman-vikter från AMS',
+    spoolmanAmsSyncTitle: 'Synkronisera Spoolman-rullvikter från AMS',
+    spoolmanAmsSyncMessage: 'Detta kommer att uppdatera alla Spoolman-rullars vikter baserat på de aktuella AMS-procentvärdena från anslutna skrivare. Skrivaren måste vara online.',
+    spoolmanAmsSyncing: 'Synkroniserar...',
+    spoolmanAmsSyncSuccess: '{{synced}} rulle(ar) synkroniserade, {{skipped}} hoppades över',
+    spoolmanAmsSyncError: 'Kunde inte synkronisera Spoolman-vikter från AMS',
+    spoolmanAmsSyncErrorUnreachable: 'Kunde inte synkronisera Spoolman-vikter (Spoolman otillgänglig)',
+    spoolmanAmsSyncErrorNotConfigured: 'Kunde inte synkronisera Spoolman-vikter (Spoolman ej konfigurerad)',
+    spoolmanNotConfigured: 'Spoolman ej konfigurerad',
+    // Spoolman filament catalog section in spool catalog settings
+    spoolmanFilamentCatalogTitle: 'Spoolman filamentkatalog',
+    spoolmanFilamentCatalogDesc: 'Filamentnamn och taravikter från din Spoolman-instans. Namn och rullvikt kan redigeras här; alla andra egenskaper hanteras direkt i Spoolman.',
+    // Spoolman settings
+    spoolmanUrl: 'Spoolman-URL',
+    spoolmanUrlHint: 'URL till din Spoolman-server (t.ex. http://localhost:7912)',
+    spoolmanConnected: 'Ansluten',
+    spoolmanDisconnected: 'Frånkopplad',
+    status: 'Status',
+    connect: 'Anslut',
+    disconnect: 'Koppla från',
+    howSyncWorks: 'Hur synkronisering fungerar',
+    syncInfoRfidOnly: 'Endast officiella Bambu Lab-rullar med RFID synkroniseras',
+    syncInfoAutoCreate: 'Nya rullar skapas automatiskt i Spoolman vid första synkronisering',
+    syncInfoThirdPartySkipped: 'Icke-Bambu Lab-rullar (tredjepart, påfyllda) hoppas över',
+    linkingExistingSpools: 'Länka befintliga rullar',
+    linkingExistingSpoolsDesc: 'För att länka befintliga Spoolman-rullar till din AMS, håll musen över ett AMS-fack och klicka på "Länka till Spoolman".',
+    syncMode: 'Synkroniseringsläge',
+    syncModeAuto: 'Automatisk',
+    syncModeManual: 'Endast manuell',
+    syncModeAutoDesc: 'AMS-data synkroniseras automatiskt när ändringar upptäcks',
+    syncModeManualDesc: 'Synkroniserar endast vid manuell aktivering',
+    syncAmsData: 'Synkronisera AMS-data',
+    syncAmsDataDesc: 'Synkronisera skrivarens AMS-data till Spoolman manuellt',
+    allPrinters: 'Alla skrivare',
+    // Default printer
+    noDefaultPrinter: 'Ingen standard (fråga varje gång)',
+    // Sidebar
+    sidebarOrder: 'Sidofältsordning',
+    // Camera
+    saveThumbnails: 'Spara minibilder',
+    captureFinishPhoto: 'Ta färdig-foto',
+    noPrintersConfigured: 'Inga skrivare konfigurerade',
+    // Archive settings
+    archiveMode: {
+      always: 'Skapa alltid arkivpost',
+      never: 'Skapa aldrig arkivpost',
+      ask: 'Fråga varje gång',
+    },
+    // Updates
+    checkForUpdatesLabel: 'Sök efter uppdateringar',
+    checkPrinterFirmware: 'Kontrollera skrivarens firmware',
+    includeBetaUpdates: 'Inkludera betaversioner',
+    includeBetaUpdatesDesc: 'Notis om betaversioner och förhandsversioner vid sökning av uppdateringar',
+    localLogin: {
+      disable: 'Inaktivera lokal användarnamn/lösenordsinloggning',
+      disableHint: 'När aktiverat kan endast SSO-leverantörer logga in. LDAP påverkas inte. Sätt BAMBUDDY_LOCAL_LOGIN=true på servern för att behålla en återställningsväg.',
+    },
+    // Queue
+    enableRetry: 'Aktivera försök igen',
+    // Home Assistant
+    homeAssistantDescription: 'Kontrollera smarta kontakter via Home Assistant',
+    environmentManagedLabel: '(Hanterad av miljövariabler)',
+    autoEnabledViaEnv: 'Automatiskt aktiverad via miljövariabler',
+    urlFromEnvReadOnly: 'Värde inställt av HA_URL-miljövariabel (skrivskyddad)',
+    tokenFromEnvReadOnly: 'Värde inställt av HA_TOKEN-miljövariabel (skrivskyddad)',
+    // MQTT
+    mqttConnectedTo: 'Ansluten till',
+    // Prometheus
+    prometheusDescription: 'Exponera skrivardata i Prometheus-format',
+    // Smart plugs empty state
+    noSmartPlugsTitle: 'Inga smarta kontakter konfigurerade',
+    noSmartPlugsDescription: 'Lägg till en Tasmota-baserad smart kontakt för att spåra energiförbrukning och automatisera strömkontroll.',
+    // Notifications empty state
+    noProvidersTitle: 'Inga leverantörer konfigurerade',
+    noProvidersDescription: 'Lägg till en leverantör för att ta emot aviseringar.',
+    noTemplatesAvailable: 'Inga mallar tillgängliga. Starta om backend för att ladda standardmallar.',
+    // API permissions
+    apiPermissionView: 'Visa skrivarstatus och kö',
+    apiPermissionEdit: 'Lägg till och ta bort poster från utskriftskö',
+    // API keys
+    apiKeysEmptyTitle: 'Inga API-nycklar',
+    apiKeysEmptyDescription: 'Skapa en API-nyckel för att integrera med externa tjänster.',
+    // Users
+    noUsersFound: 'Inga användare hittade',
+    noGroupsFound: 'Inga grupper hittade',
+    noGroupsAvailable: 'Inga grupper tillgängliga',
+    passwordsDoNotMatch: 'Lösenorden matchar ej',
+    systemGroupWarning: 'Systemgruppnamn kan inte ändras',
+    // Auth disabled
+    authDisabledTitle: 'Autentisering är inaktiverat',
+    authDisabledFeature1: 'Kräv inloggning för att komma åt systemet',
+    authDisabledFeature2: 'Skapa flera användare med gruppbaserade behörigheter',
+    authDisabledFeature3: 'Kontrollera åtkomst med 50+ detaljerade behörigheter',
+    // User deletion
+    userHasCreated: 'Denna användare har skapat:',
+    userItemsQuestion: 'Vad vill du göra med dessa objekt?',
+    deleteUserConfirm: 'Är du säker på att du vill ta bort denna användare?',
+    actionCannotBeUndone: 'Denna åtgärd kan inte ångras.',
+    // Smart plugs
+    addFirstSmartPlug: 'Lägg till din första smarta kontakt',
+    // Notifications
+    providers: 'Leverantörer',
+    log: 'Logg',
+    testAll: 'Testa alla',
+    testResults: 'Testresultat',
+    testPassedCount: '{{count}} godkända',
+    testFailedCount: '{{count}} misslyckade',
+    messageTemplates: 'Meddelandemallar',
+    messageTemplatesDescription: 'Anpassa notismeddelanden för varje händelse.',
+    // API Keys section
+    apiKeys: 'API-nycklar',
+    apiKeysDescription: 'Skapa API-nycklar för externa integrationer och webhooks.',
+    createKey: 'Skapa nyckel',
+    apiKeyCreated: 'API-nyckel skapad',
+    apiKeyCopyWarning: 'Kopiera denna nyckel nu – den kommer inte att visas igen!',
+    useInApiBrowser: 'Använd i API-läsaren',
+    apiKeyQrButton: 'QR-kod',
+    apiKeyQrTitle: 'Skanna för att konfigurera',
+    apiKeyQrCaption: 'Skanna med din mobilapp för att lägga till denna server och API-nyckel.',
+    apiKeyQrWarning: 'Innehåller din hemliga API-nyckel — dela inte eller ta skärmdump där andra kan se den.',
+    createNewApiKey: 'Skapa ny API-nyckel',
+    keyName: 'Nyckelnamn',
+    keyNamePlaceholder: 't.ex. Home Assistant, OctoPrint',
+    readStatus: 'Läs status',
+    readStatusDescription: 'Visa skrivarstatus och kö',
+    manageQueue: 'Hantera kö',
+    manageQueueDescription: 'Lägg till och ta bort poster från utskriftskö',
+    controlPrinter: 'Kontrollera skrivare',
+    controlPrinterDescription: 'Pausa, fortsätt och stoppa utskrifter',
+    manageLibrary: 'Hantera bibliotek',
+    manageLibraryDescription: 'Ladda upp, döp om och ta bort biblioteksfiler; importera modeller från MakerWorld',
+    manageInventory: 'Hantera inventarier',
+    manageInventoryDescription: 'Skapa, uppdatera och ta bort rullar och inventeringsposter. Krävs för SpoolBuddy-kiosker (NFC-skanning, vågläsningar, kiosksystemkommandon).',
+    manageMaintenance: 'Hantera underhåll',
+    manageMaintenanceDescription: 'Logga slutfört underhåll, återställ räknare, redigera intervall och hantera underhållstypkatalogen. Lämplig för Home Assistant-automatiseringar som registrerar "Jag rengjorde munstycket" utan att ge bredare skrivarkontroll.',
+    manageArchives: 'Hantera arkiv',
+    manageArchivesDescription: 'Redigera och ta bort utskriftsarkiv, inklusive borttagning av gamla utskrifter. Inkluderar inte borttagning av deras statistikbidrag. Lämplig för automatiseringar som rensar utskriftshistoriken.',
+    manageProjects: 'Hantera projekt',
+    manageProjectsDescription: 'Skapa, uppdatera och ta bort projekt, samt lägg till arkiv i dem. Lämplig för automatiseringar som organiserar utskrifter i projekt.',
+    libraryBadge: 'Bibliotek',
+    inventoryBadge: 'Inventarium',
+    maintenanceBadge: 'Underhåll',
+    archivesBadge: 'Arkiv',
+    projectsBadge: 'Projekt',
+    cloudAccess: 'Tillåt molnåtkomst',
+    cloudAccessDescription: 'Läs Bambu Cloud-inställningar och filament å dina vägnar. Kräver att du är inloggad på Bambu Cloud.',
+    cloudBadge: 'Moln',
+    updateEnergyCost: 'Uppdatera elpris',
+    updateEnergyCostDescription: 'Tillåt denna nyckel att POST:a ett nytt pris per kWh till /settings/electricity-price. Användbart för Home Assistants dynamiska tariffautomatiseringar (Tibber, Octopus, etc.). Detta är det enda inställningsfält som kan skrivas via API-nyckel.',
+    energyCostBadge: 'Energi',
+    legacyKey: 'Äldre nyckel',
+    legacyKeyTooltip: 'Skapad före användarägande; skapa igen för att använda molnåtkomst',
+    unnamedKey: 'Namnlös nyckel',
+    lastUsed: 'Senast använd',
+    read: 'Läs',
+    control: 'Kontroll',
+    createFirstKey: 'Skapa din första nyckel',
+    webhookEndpoints: 'Webhook-ändpunkter',
+    webhookApiKeyHint: 'Använd din API-nyckel i adressinformationen för X-API-Key.',
+    webhook: {
+      getAllStatus: 'Hämta alla skrivarstatusar',
+      getSpecificStatus: 'Hämta specifik skrivarstatus',
+      addToQueue: 'Lägg till i utskriftskö',
+      pausePrint: 'Pausa utskrift',
+      resumePrint: 'Fortsätt utskrift',
+      stopPrint: 'Stoppa utskrift',
+    },
+    apiBrowser: 'API-läsare',
+    apiBrowserDescription: 'Utforska och testa alla tillgängliga API-ändpunkter.',
+    apiKeyForTesting: 'API-nyckel för testning',
+    apiKeyPlaceholder: 'Klistra in din API-nyckel här för att testa autentiserade ändpunkter...',
+    apiKeyHint: 'Denna nyckel kommer att skickas som X-API-Key-adressinformation med förfrågningarna.',
+    deleteApiKeyTitle: 'Ta bort API-nyckel',
+    deleteApiKeyMessage: 'Är du säker på att du vill ta bort denna API-nyckel? Alla integrationer som använder denna nyckel kommer att sluta fungera.',
+    deleteKey: 'Ta bort nyckel',
+    // Filament tab
+    amsDisplayThresholds: 'AMS-visningströskelvärden',
+    amsThresholdsDescription: 'Konfigurera färgernas tröskelvärden för AMS:ens luftfuktighets- och temperaturindikatorer.',
+    humidity: 'Luftfuktighet',
+    goodGreen: 'God (grön)',
+    fairOrange: 'Godkänd (orange)',
+    aboveFairBad: 'Över godkänt tröskelvärde visas som röd (dålig)',
+    fairAlsoDryingThreshold: 'Detta tröskelvärde används också för att trigga auto-torkning när det är aktiverat',
+    fairBelowDryingFloor: 'Auto-torkning kan inte nå detta värde: en AMS läser {{floor}}% eller mer medan dess värmare körs, så varje cykel skulle sluta och starta om omedelbart. Höj den över {{floor}}% om auto-torkning är på.',
+    temperature: 'Temperatur',
+    goodBlue: 'God (blå)',
+    aboveFairHot: 'Över godkänt tröskelvärde visas som röd (varm)',
+    tempAlarmThreshold: 'Larma över',
+    tempAlarmSeparateFromBand: 'Endast larmtröskeln skickar meddelanden — God och Godkänd färgar displayen. Lämna den tom för att larma vid Godkänd-tröskeln, som tidigare.',
+    tempAlarmMustBePositive: 'Ett tröskelvärde på 0 eller lägre ignoreras — larmet faller tillbaka till Godkänd-tröskelvärdet.',
+    historyRetention: 'Bevarande av historik',
+    keepSensorHistory: 'Bevara sensordata för',
+    historyRetentionDescription: 'Äldre luftfuktighets- och temperaturdata kommer att tas bort automatiskt',
+    defaultPrintOptions: 'Standardutskriftsalternativ',
+    defaultPrintOptionsDescription: 'Sätt standardvärden för utskriftsalternativ när nya utskrifter startas. Dessa kan åsidosättas per utskrift i utskriftsdialogrutan.',
+    defaultBedLevelling: 'Byggplattsnivåinställning',
+    defaultBedLevellingDesc: 'Ställer in byggplattan automatiskt före utskrift',
+    defaultFlowCali: 'Flödeskalibrering',
+    defaultFlowCaliDesc: 'Kalibrera extruderingsflöde',
+    defaultVibrationCali: 'Vibrationskalibrering',
+    defaultVibrationCaliDesc: 'Minska ringningsartefakter',
+    defaultLayerInspect: 'Förstaskiktsinspektion',
+    defaultLayerInspectDesc: 'AI-inspektion av första skiktet',
+    defaultTimelapse: 'Timelapse',
+    defaultTimelapseDesc: 'Spela in timelapse-video',
+    defaultNozzleOffsetCali: 'Munstyckesoffsetkalibrering',
+    defaultNozzleOffsetCaliDesc: 'Kalibrera munstyckesoffsetar mellan extruderare',
+    tempFanPresetsTitle: 'Temperatur- och fläktförinställningar',
+    tempFanPresetsDescription: 'Anpassa snabbvalsvärden som visas i skrivarkortets temperatur- och fläkthastighets-popovers. Av-knappen visas alltid.',
+    tempFanPresetsNozzle: 'Munstyckstemperatur',
+    tempFanPresetsBed: 'Byggplattstemperatur',
+    tempFanPresetsChamber: 'Kammartemperatur',
+    tempFanPresetsFan: 'Fläkthastighet',
+    tempFanPresetsReset: 'Återställ till standard',
+    concurrentUploadsTitle: 'Samtidiga uppladdningar',
+    concurrentUploadsDescription: 'Hur många skrivare kön kan skicka filer till samtidigt. Skrivare tar emot filer långsamt (en stor utskrift kan ta flera minuter), och varje skrivare väntar på sin tur — så med en större flotta är det detta som förhindrar att den sista skrivaren i en batch väntar på alla överföringar före den. Sänk detta om ditt nätverk eller din Bambuddy-värd har svårt med parallella överföringar.',
+    concurrentUploadsLabel: 'Skrivare som laddas upp till samtidigt',
+    concurrentUploadsHelp: '1 skickar till en skrivare i taget (gammalt beteende). Standard är 4.',
+    staggeredStart: 'Förskjuten start',
+    staggeredStartDescription: 'Standardgruppstorlek och intervall vid förskjuten start av batchutskrifter på flera skrivare. Kan åsidosättas per batch i utskriftsdialogrutan.',
+    preheatTitle: 'Förvärme',
+    preheatDescription: 'Värm byggplattan (och kammaren, om stödjes) och håll temperaturen före varje köad utskrift startar. Användbart för tekniska filament (PA, ABS) på skrivare utan aktiv kammarvärmare — byggplattan värmer kammaren med värmestrålning medan varmhållningstimern går. Måltemperaturen för byggplattan läses från utskriftsfilen; kammarbeteendet beror på skrivarmodell.',
+    preheatEnabled: 'Aktivera förvärme och varmhållning',
+    preheatEnabledDesc: 'När avstängt skickas köade utskrifter omedelbart. Varje köpost kan åsidosättas per utskrift.',
+    preheatFilamentTargetsLabel: 'Kammarmål per filamenttyp (°C)',
+    preheatFilamentTargetsHint: 'Bambuddy väljer det högsta målet bland de laddade AMS-facken; utskrifter med endast PLA får värdet 0 och hoppar automatiskt över kammarfasen.',
+    preheatFilamentTargetsReset: 'Återställ till standard',
+    preheatFilamentTargetsDefaultRow: 'Övrigt / omappat',
+    preheatMaxWait: 'Max väntetid (sekunder)',
+    preheatMaxWaitHelp: 'Begränsning för kammaruppvärmningsfasen innan den hoppar över.',
+    preheatSoak: 'Varmhållning (sekunder)',
+    preheatSoakHelp: 'Hålltid efter att måltemperaturen nåtts eller max-väntetiden passerat.',
+    preheatHardwareTitle: 'Handlingssätt per skrivare:',
+    preheatHardwareDetail: 'H2C/H2D/H2D Pro/H2S/X2D/X1E värmer kammaren aktivt via M141. X1C/P2S läser kammartemperatur men förlitar sig på byggplattans byggplattsvärme. P1S/P1P/A1/A1 Mini har ingen kammarsensor — endast varmhållningstimern gäller.',
+    preheatPerItemDesc: 'Värm byggplattan och kammaren före denna utskrift startar. Standard är den globala inställningen Inställningar → Arbetsflöde.',
+    preheatOverride_inherit: 'Ärv',
+    preheatOverride_on: 'På',
+    preheatOverride_off: 'Av',
+    calibrationMode_off: 'Av',
+    calibrationMode_on: 'På',
+    calibrationMode_auto: 'Auto',
+    preheatTargetOverride: 'Kammartemperatur-åsidosättning (°C, tom = standard för filamentet)',
+    preheatTargetOverrideHelp: '0 värmer plattan och kör uppvärmningen utan kammaren. Lämna tomt och en utskrift utan kammarkrav hoppar över förvärmningen helt.',
+    plateClear: 'Bekräftelse för tömd platta',
+    requirePlateClear: 'Kräv bekräftelse för tömd platta',
+    requirePlateClearDescription: 'När aktiverat väntar schemaläggaren på bekräftelse för tömd platta per skrivare innan köade utskrifter startar på skrivare med slutförda jobb. Om detta inaktiveras döljs också plattstatusbadgen och knappen "Markera platta som tömd" på skrivarkorten.',
+    keepBedWarm: 'Håll plattan varm mellan utskrifterna',
+    keepBedWarmDesc: 'Tills plattan är tömd, håll plattan vid varmhållningstemperaturen nedan så att kammaren förblir varm - eller vid nästa utskrifts egen plattemperatur om den är högre. Gäller endast när nästa utskrift behöver kammarvärme (ASA, ABS, PA, PC etc.). Kräver en bekräftelse på tömd platta för att vara aktiverad.',
+    keepWarmBedTemp: 'Varmhållningstemperatur för platta (°C)',
+    keepWarmBedTempHelp: 'Används när plattans uppgift är att värma upp kammaren — hålla värmen och förvärma när utskriftsfilen inte har någon plattemperatur. En högre plattemperatur från utskriftsfilen vinner alltid.',
+    keepWarmMaxMinutes: 'Sluta hålla värmen efter (minuter)',
+    keepWarmMaxMinutesHelp: 'Om plattan inte töms inom denna tid, stängs värmarna av istället för att hållas på obestämd tid.',
+    gcodeInjection: 'G-kodinjicering',
+    gcodeInjectionDescription: 'Konfigurera anpassad G-kod för att injiceras i början och/eller slutet av utskrifter för auto-utskriftssystem som Farmloop, SwapMod, AutoClear och Printflow 3D. Kodsnuttar konfigureras per skrivarmodell och tillämpas när "Injicera G-kod" är aktiverat på en köpost.',
+    gcodeInjectionNoPrinters: 'Inga skrivare hittade. Lägg till skrivare för att konfigurera G-kod-snuttar.',
+    gcodeStartLabel: 'Start-G-kod',
+    gcodeEndLabel: 'Slut-G-kod',
+    gcodeStartPlaceholder: 'G-kod som läggs till före utskriftens start...',
+    gcodeEndPlaceholder: 'G-kod som läggs till efter utskriftens slut...',
+    staggerGroupSize: 'Gruppstorlek',
+    staggerGroupSizeHelp: 'Skrivare som startar samtidigt per grupp',
+    staggerInterval: 'Intervall (minuter)',
+    staggerIntervalHelp: 'Fördröjning mellan varje grupps start',
+    queueDrying: 'Köa auto-torkning',
+    queueDryingDescription: 'Torka AMS-filament automatiskt när skrivaren är inaktiv mellan köade utskrifter. Använder tröskelvärdet för luftfuktighet ovan för att trigga torkning.',
+    queueDryingEnabled: 'Aktivera auto-torkning',
+    queueDryingEnabledDescription: 'Starta AMS-torkning automatiskt när skrivaren är inaktiv och luftfuktigheten är över tröskelvärdet',
+    queueDryingBlock: 'Vänta på att torkning slutförts',
+    queueDryingBlockDescription: 'Blockera utskriftskön tills torkningen är klar. När avstängt prioriteras utskrifter över torkning.',
+    ambientDryingEnabled: 'Bakgrundstorkning',
+    ambientDryingEnabledDescription: 'Torka filament automatiskt på inaktiva skrivare när luftfuktigheten överskrider tröskelvärdet, även utan köade utskrifter.',
+    printDryingEnabled: 'Fortsätt torka under utskrift',
+    printDryingEnabledDescription: 'Tillåt auto-torkning att fortsätta köra under en utskrift på hårdvara som stödjer det (H2D, H2C, H2S, P2S, H2D Pro, X2D, X1C, A2L med senaste firmware). Torkningstemperaturen begränsas automatiskt till 5°C under idle-förinställningen för att skydda rullar.',
+    dryingPresets: 'Torkningsförinställningar',
+    dryingPresetsDescription: 'Temperatur och varaktighet per filamenttyp. AMS 2 Pro använder lägre temperaturer, AMS-HT stöder högre temperaturer.',
+    dryingFilament: 'Filament',
+    humidityThresholds: 'Tröskelvärden för luftfuktighet',
+    humidityThresholdsDescription: 'Luftfuktighetsutlösare per filament för auto-torkning och larm. Blandade laddningar i en AMS använder det lägsta tröskelvärdet.',
+    humidityThresholdCol: 'Tröskelvärde',
+    humidityThresholdDefault: 'Standard (okända typer)',
+    printModal: 'Utskriftsdialogruta',
+    expandCustomMapping: 'Expandera anpassad mappning som standard',
+    expandCustomMappingDescription: 'När utskrift skickas till flera skrivare, visa utökad AMS-mappning per skrivare',
+    // User management
+    authentication: 'Autentisering',
+    authEnabledDescription: 'Din instans är skyddad med användarautentisering',
+    authDisabledDescription: 'Aktivera för att kräva inloggning och hantera användaråtkomst',
+    authDisabledMessage: 'Aktivera autentisering för att skapa användarkonton, hantera behörigheter och skydda din Bambuddy-instans.',
+    enableAuthentication: 'Aktivera autentisering',
+    currentUser: 'Aktuell användare',
+    changePassword: 'Ändra lösenord',
+    admin: 'Admin',
+    users: 'Användare',
+    addUser: 'Lägg till användare',
+    groups: 'Grupper',
+    addGroup: 'Lägg till grupp',
+    system: 'System',
+    noDescription: 'Ingen beskrivning',
+    userCount: '{{count}} användare',
+    permissionCount: '{{count}} behörigheter',
+    createUser: 'Skapa användare',
+    username: 'Användarnamn',
+    enterUsername: 'Ange användarnamn',
+    password: 'Lösenord',
+    enterPassword: 'Ange lösenord',
+    passwordRequirements: 'Minst 8 tecken, med en versal, en gemen, en siffra och ett specialtecken.',
+    confirmPassword: 'Bekräfta lösenord',
+    confirmPasswordPlaceholder: 'Bekräfta lösenord',
+    // Title tooltips
+    viewReleaseOnGitHub: 'Visa release på GitHub',
+    turnAllPlugsOn: 'Sätt på alla kontakter',
+    turnAllPlugsOff: 'Stäng av alla kontakter',
+    // Modal: Clear logs
+    clearNotificationLogs: 'Rensa notisloggar',
+    clearLogsMessage: 'Detta kommer permanent ta bort alla notisloggar äldre än 30 dagar. Denna åtgärd kan inte ångras.',
+    clearLogs: 'Rensa loggar',
+    // Modal: Reset UI
+    resetUiPreferences: 'Återställ UI-inställningar',
+    resetUiPreferencesMessage: 'Detta kommer återställa alla UI-inställningar till standard: sidofältsordning, tema, instrumentpanelslayout, visningslägen och sorteringsinställningar. Dina skrivare, arkiv och serverinställningar kommer INTE att påverkas. Sidan kommer att laddas om efter rensning.',
+    resetPreferences: 'Återställ inställningar',
+    // Modal: Delete group
+    deleteGroupTitle: 'Ta bort grupp',
+    deleteGroupMessage: 'Är du säker på att du vill ta bort denna grupp? Användare i denna grupp kommer att förlora dessa behörigheter.',
+    deleteGroup: 'Ta bort grupp',
+    // Modal: Disable auth
+    disableAuthenticationTitle: 'Inaktivera autentisering',
+    disableAuthenticationMessage: 'Är du säker på att du vill inaktivera autentisering? Detta kommer att göra din Bambuddy-instans tillgänglig utan inloggning. Alla användare kommer att finnas kvar i databasen, men autentisering kommer att vara inaktiverat.',
+    disableAuthentication: 'Inaktivera autentisering',
+    // Additional settings
+    configureBambuddy: 'Konfigurera Bambuddy',
+    systemDefault: 'Systemstandard',
+    archiveSettings: 'Arkivinställningar',
+    newWindow: 'Nytt fönster',
+    embeddedOverlay: 'Inbäddat överlägg',
+    preferredSlicer: 'Föredragen slicer',
+    preferredSlicerDescription: 'Slicer som används för slicing i appen via API-sidecar',
+    openInSlicerLabel: 'Öppna i slicer',
+    openInSlicerInherit: 'Samma som API-slicer',
+    openInSlicerDescription: "Slicer som används av knappen 'Öppna i slicer'. Lämna på 'Samma som API-slicer' för att ärva, eller välj en annan slicer för lokal användning.",
+    orcaslicerKnownIssuesWarning: 'OrcaSlicer 2.3.2 / 2.4.0-dev har kända CLI-buggar som blockerar slicing av många Bambu-skapade 3MF-filer — se uppströmsproblem #12426 (segmenteringsfel på målade multi-extruder-filer) och #13386 (parameterintervall strikt valideringsavvisning). Bambu Studio rekommenderas tills uppströmsfixarna landar.',
+    useSlicerApi: 'Använd Slicer API',
+    useSlicerApiDescription: 'När aktiverat öppnar slicing-åtgärder den inbyggda slicing-dialogrutan och anropar slicer-API-sidecar. När avstängt (standard) skickas de vidare till slicern via URI-schema.',
+    slicerCard: 'Slicer',
+    orcaslicerApiUrl: 'OrcaSlicer sidecar-URL',
+    bambuStudioApiUrl: 'Bambu Studio sidecar-URL',
+    slicerStallTimeout: 'Slicer-timeout (minuter)',
+    slicerStallTimeoutDescription: 'Ge upp på en slicing efter denna tid utan framsteg från sidecaren. Tunga modeller som fortsätter rapportera framsteg avbryts aldrig, oavsett hur lång tid de tar. Sidecars som inte rapporterar framsteg använder denna tid som total tidsgräns istället.',
+    slicerApiUrlDescription: 'URL till slicing-API-sidecar-containern. Lämna tomt för att använda SLICER_API_URL / BAMBU_STUDIO_API_URL-miljövariablerna som standard.',
+    externalCameras: 'Externa kameror',
+    costTracking: 'Kostnadsspårning',
+    billingEnabled: 'Aktivera fakturering',
+    billingEnabledDescription: 'Debitera användare för utskrifter och aktivera finansfunktioner',
+    printerKillSwitch: 'Nödstoppsknapp för obehörig utskrift',
+    printerKillSwitchDescription: 'Stoppa omedelbart utskrifter som startar utan auktorisering.',
+    financeBudgetReset: 'Återställ månadsbudget för finanser',
+    financeBudgetResetDay: 'Återställningsdag',
+    financeBudgetResetDayHelp: 'För korta månader används den sista dagen i månaden för återställning.',
+    financeBudgetResetTimezone: 'Återställningstidszon',
+    financeBudgetResetTimezoneHelp: 'Budgetfönstrets start beräknas i denna tidszon.',
+    rebuildLedger: 'Regenerera bokföring',
+    rebuildLedgerStarted: 'Regenerering av bokföring påbörjad',
+    rebuildLedgerConfirmTitle: 'Regenerera bokföring?',
+    rebuildLedgerConfirmMessage:
+      'Detta kommer att regenerera bokföringen för att reparera historiska saldovärden. Kör detta endast om du vet vad du gör.',
+    rebuildLedgerInProgress: 'Startar regenerering...',
+    printsOnly: 'Endast utskrifter',
+    totalConsumption: 'Total förbrukning',
+    dataManagement: 'Datahantering',
+    storageUsage: 'Lagringsanvändning',
+    storageUsageDescription: 'Fördelning av dataanvändning per kategori',
+    storageUsageTotal: 'Totalt',
+    storageUsageErrors: 'Felmeddelanden',
+    storageUsageOtherBreakdown: 'Övrigt (inkluderar statiska objekt, skript och konfigurationsfiler)',
+    storageUsageSystem: 'System',
+    storageUsageData: 'Data',
+    storageUsageUnavailable: 'Lagringsinformation ej tillgänglig',
+    clearNotificationLogsDescription: 'Ta bort notisloggar äldre än 30 dagar',
+    resetUiPreferencesDescription: 'Återställ sidofältsordning, tema, visningslägen och layoutinställningar. Skrivare, arkiv och inställningar påverkas inte.',
+    enableHomeAssistant: 'Aktivera Home Assistant',
+    enableMqtt: 'Aktivera MQTT',
+    useTls: 'Använd TLS',
+    enableMetricsEndpoint: 'Aktivera mätvärdesändpunkt',
+    availableMetrics: 'Tillgängliga mätvärden',
+    editUser: 'Redigera användare',
+    deleteUserTitle: 'Ta bort användare',
+    groupName: 'Gruppnamn',
+    // Placeholders
+    leaveEmptyForAnonymous: 'Lämna tomt för anonym',
+    leaveEmptyForNoAuth: 'Lämna tomt för ingen autentisering',
+    enterNewPassword: 'Ange nytt lösenord',
+    confirmNewPassword: 'Bekräfta nytt lösenord',
+    enterGroupName: 'Ange gruppnamn',
+    enterDescriptionOptional: 'Ange beskrivning (valfritt)',
+    enterCurrentPassword: 'Ange nuvarande lösenord',
+    enterNewPasswordMin6: 'Ange nytt lösenord (minst 6 tecken)',
+    toast: {
+      keyCopied: 'Nyckel kopierad till urklipp',
+      copyFailed: 'Kunde inte kopiera nyckel',
+      keyAddedToBrowser: 'Nyckel tillagd till API-läsaren',
+      clearLogsFailed: 'Kunde inte rensa loggar',
+      uiPreferencesReset: 'UI-inställningar återställda. Uppdaterar...',
+      authDisabled: 'Autentisering inaktiverad',
+      authDisableFailed: 'Kunde inte inaktivera autentisering',
+      apiKeyCreated: 'API-nyckel skapad',
+      apiKeyDeleted: 'API-nyckel borttagen',
+      userCreated: 'Användare skapad',
+      userUpdated: 'Användare uppdaterad',
+      userDeleted: 'Användare borttagen',
+      groupCreated: 'Grupp skapad',
+      groupUpdated: 'Grupp uppdaterad',
+      groupDeleted: 'Grupp borttagen',
+      fillRequiredFields: 'Fyll i alla obligatoriska fält',
+      passwordsDoNotMatch: 'Lösenorden matchar ej',
+      passwordTooShort: 'Lösenordet måste vara minst 8 tecken',
+      passwordNeedsUppercase: 'Lösenordet måste innehålla minst en versal',
+      passwordNeedsLowercase: 'Lösenordet måste innehålla minst en gemen',
+      passwordNeedsDigit: 'Lösenordet måste innehålla minst en siffra',
+      passwordNeedsSpecial: 'Lösenordet måste innehålla minst ett specialtecken',
+      enterGroupName: 'Ange ett gruppnamn',
+      settingsSaved: 'Inställningar sparade',
+      noPermissionUpdate: 'Du har inte behörighet att ändra inställningar',
+      cameraSettingsSaved: 'Kamerainställningar sparade',
+      enterCameraUrl: 'Ange URL för en kamera',
+      passwordChanged: 'Lösenord ändrat',
+      connectionFailed: 'Anslutning misslyckades',
+      testFailed: 'Test misslyckades',
+      cameraConnected: 'Kamera ansluten{{resolution}}',
+      cameraConnectedCoalesced: 'Kamera ansluten{{resolution}} (delad med en pågående inspelning)',
+    },
+    testConnection: 'Testa anslutning',
+    catalog: {
+      spoolCatalog: 'Rullkatalog',
+      spoolCatalogDescription: 'Tomma rullvikter efter märke/typ. Används för automatisk viktsökning när rullar läggs till.',
+      searchCatalog: 'Sök i katalogen...',
+      addNewEntry: 'Lägg till ny post',
+      namePlaceholder: 'Namn (t.ex. Bambu Lab - Plast)',
+      weight: 'Vikt',
+      type: 'Typ',
+      default: 'Standard',
+      custom: 'Anpassad',
+      noMatch: 'Inga poster matchar din sökning',
+      empty: 'Inga poster i katalogen',
+      deleteEntry: 'Ta bort post',
+      deleteConfirm: 'Är du säker på att du vill ta bort "{{name}}"?',
+      resetCatalog: 'Återställ katalog',
+      resetConfirm: 'Återställ katalog till standard? Detta kommer att ta bort alla anpassade poster.',
+      loadFailed: 'Kunde inte ladda rullkatalogen',
+      nameWeightRequired: 'Namn och vikt krävs',
+      entryAdded: 'Post tillagd',
+      addFailed: 'Kunde inte lägga till post',
+      entryUpdated: 'Post uppdaterad',
+      updateFailed: 'Kunde inte uppdatera post',
+      entryDeleted: 'Post borttagen',
+      deleteFailed: 'Kunde inte ta bort post',
+      resetSuccess: 'Katalog återställd till standard',
+      resetFailed: 'Kunde inte återställa katalog',
+      exported: 'Exporterade {{count}} poster',
+      imported: 'Importerade {{added}} poster ({{skipped}} hoppade över)',
+      importFailed: 'Kunde inte importera: ogiltigt JSON-format',
+      exportTooltip: 'Exportera katalog till JSON',
+      importTooltip: 'Importera katalog från JSON',
+      resetTooltip: 'Återställ till standard',
+      selectedCount: '{{count}} valda',
+      deleteSelected: 'Ta bort valda',
+      bulkDeleteConfirm: 'Är du säker på att du vill ta bort {{count}} poster?',
+      bulkDeleted: 'Tog bort {{count}} poster',
+      bulkDeleteFailed: 'Kunde inte ta bort poster',
+      material: 'Material',
+      spoolWeight: 'Rullvikt',
+      color: 'Färg',
+      updateSpoolWeight: 'Uppdatera rullvikt',
+      filamentUpdated: 'Filament uppdaterat',
+      filamentUpdateFailed: 'Kunde inte uppdatera filament',
+      filamentUpdateInvalid: 'Ogiltig filamentdata',
+      keepExistingSpoolWeight: 'Behåll tidigare vikt för befintliga rullar',
+      keepExistingSpoolWeightDesc: 'Rullar som redan skapats med denna filamenttyp behåller den gamla taravikten. Nya rullar använder den uppdaterade vikten.',
+      applyToAllSpools: 'Tillämpa på alla rullar',
+      applyToAllSpoolsDesc: 'Alla viktberäkningar för denna filamenttyp använder omedelbart den nya taravikten.',
+    },
+    colorCatalog: {
+      title: 'Färgkatalog',
+      description: 'Filamentfärger efter tillverkare/material. Används för automatisk färgsökning när rullar läggs till.',
+      searchColors: 'Sök färger...',
+      allManufacturers: 'Alla tillverkare',
+      addNewColor: 'Lägg till ny färg',
+      manufacturer: 'Tillverkare',
+      colorName: 'Färgnamn',
+      hex: 'Hex',
+      materialOptional: 'Material (valfritt)',
+      showing: 'Visar {{filtered}} av {{total}} färger',
+      noMatch: 'Inga färger matchar din sökning',
+      empty: 'Inga färger i katalogen',
+      deleteColor: 'Ta bort färg',
+      deleteConfirm: 'Är du säker på att du vill ta bort "{{name}}"?',
+      resetCatalog: 'Återställ färgkatalog',
+      resetConfirm: 'Återställ katalog till standard? Detta kommer att ta bort alla anpassade färger.',
+      sync: 'Synkronisera',
+      starting: 'Startar...',
+      syncTooltip: 'Synkronisera från FilamentColors.xyz (2000+ färger, kan ta en minut)',
+      loadFailed: 'Kunde inte ladda färgkatalogen',
+      fieldsRequired: 'Tillverkare, färgnamn och hex-färg krävs',
+      colorAdded: 'Färg tillagd',
+      addFailed: 'Kunde inte lägga till färg',
+      colorUpdated: 'Färg uppdaterad',
+      updateFailed: 'Kunde inte uppdatera färg',
+      colorDeleted: 'Färg borttagen',
+      deleteFailed: 'Kunde inte ta bort färg',
+      resetSuccess: 'Färgkatalog återställd till standard',
+      resetFailed: 'Kunde inte återställa katalog',
+      syncUpToDate: 'Redan uppdaterad ({{count}} färger kontrollerade)',
+      syncComplete: 'Lade till {{added}} nya färger ({{skipped}} fanns redan)',
+      syncError: 'Synkroniseringsfel',
+      syncFailed: 'Kunde inte synkronisera från FilamentColors.xyz',
+      exported: 'Exporterade {{count}} färger',
+      imported: 'Importerade {{added}} färger ({{skipped}} hoppade över)',
+      importFailed: 'Kunde inte importera: ogiltigt JSON-format',
+      selectedCount: '{{count}} valda',
+      deleteSelected: 'Ta bort valda',
+      bulkDeleteConfirm: 'Är du säker på att du vill ta bort {{count}} färger?',
+      bulkDeleted: 'Tog bort {{count}} färger',
+      bulkDeleteFailed: 'Kunde inte ta bort färger',
+    },
+    // General tab
+    dateFormat: 'Datumformat',
+    dateFormatUs: 'US (MM/DD/ÅÅÅÅ)',
+    dateFormatEu: 'EU (DD/MM/ÅÅÅÅ)',
+    dateFormatIso: 'ISO (ÅÅÅÅ-MM-DD)',
+    timeFormat: 'Tidsformat',
+    timeFormat12: '12-timmars (3:30 PM)',
+    timeFormat24: '24-timmars (15:30)',
+    defaultPrinter: 'Standardskrivare',
+    defaultPrinterDescription: 'Förvälj denna skrivare för uppladdningar, omutskrifter och andra operationer.',
+    slicerBambuStudio: 'Bambu Studio',
+    slicerOrcaSlicer: 'OrcaSlicer',
+    sidebarOrderDescription: 'Använd sidofältet för att ordna om objekt, återställa synlighet och hantera anpassade länkar.',
+    setDefault: 'Sätt som standard',
+    sidebarOrderSetDefaultHint: 'Sätt som standard tillämpar den aktuella menyordningen på användare som inte har anpassat sin.',
+    sidebarDefaultSet: 'Standardmenyordning har ställts in.',
+    sidebarDefaultCleared: 'Standardmenyordning rensad.',
+    sidebarDefaultFailed: 'Kunde inte ställa in standardmenyordning.',
+    reset: 'Återställ',
+    // Appearance
+    darkMode: 'Mörkt läge',
+    lightMode: 'Ljust läge',
+    active: '(aktivt)',
+    background: 'Bakgrund',
+    accent: 'Accent',
+    style: 'Stil',
+    bgNeutral: 'Neutral',
+    bgWarm: 'Varm',
+    bgCool: 'Kall',
+    bgOled: 'OLED Svart',
+    bgSlate: 'Skifferblå',
+    bgForest: 'Skogsgrön',
+    accentGreen: 'Grön',
+    accentTeal: 'Blågrön',
+    accentBlue: 'Blå',
+    accentOrange: 'Orange',
+    accentPurple: 'Lila',
+    accentRed: 'Röd',
+    styleClassic: 'Klassisk',
+    styleGlow: 'Sken',
+    styleVibrant: 'Livfull',
+    themeToggleHint: 'Växla mellan mörkt, ljust och systemläge med ikonen i sidomenyn.',
+    progressInTitle: 'Utskriftsförlopp i flik',
+    progressInTitleDescription: 'Visa den aktiva utskriftens procentförlopp och en ring i webbläsarfliken.',
+    // Archive
+    autoArchivePrints: 'Auto-arkivera utskrifter',
+    autoArchiveDescription: 'Spara automatiskt 3MF-filer när utskrifter slutförs',
+    saveThumbnailsDescription: 'Extrahera och spara förhandsvisningsbilder från 3MF-filer',
+    captureFinishPhotoDescription: 'Ta ett foto från skrivarkameran när utskriften slutförs. Bambuddy spelar in en kort timelapse under utskriften så att fotot kan hämtas från ögonblicket innan byggplattan sänks; timelapse-filen behålls om du aktiverat timelapse för denna utskrift, annars tas den automatiskt bort efter att fotot tagits.',
+    finishPhotoRestorePlate: 'Återställ platta för foto',
+    finishPhotoRestorePlateDescription: 'Skrivaren sänker byggplattan cirka 100 mm när en utskrift slutförs, vilket lämnar den färdiga utskriften under kamerans bildruta. Bambuddy höjer tillbaka den precis ovanför det sista utskrivna skiktet, tar fotot och sänker den igen. Hoppas över när utskriftshöjden är okänd eller om ett annat jobb är köat.',
+    ffmpegNotInstalled: 'ffmpeg är inte installerat',
+    ffmpegRequired: 'Kamerainspelning kräver ffmpeg. Installera det via <brew>brew install ffmpeg</brew> (macOS) eller <apt>apt install ffmpeg</apt> (Linux).',
+    // Camera
+    camera: 'Kamera',
+    cameraViewMode: 'Kameravy',
+    cameraOverlayDescription: 'Kameran öppnas i en storleksändringsbart överlägg på huvudskärmen',
+    cameraWindowDescription: 'Kameran öppnas i ett separat webbläsarfönster',
+    externalCamerasDescription: 'Konfigurera externa kameror för att ersätta den inbyggda skrivarkameran. Stöder MJPEG-strömmar, RTSP, HTTP-ögonblicksbilder och USB-kameror (V4L2). När aktiverad används den externa kameran för live-vy och färdigbilder.',
+    cameraPlaceholderUsb: 'Enhetssökväg (/dev/video0)',
+    cameraPlaceholderUrl: 'Kamera-URL (rtsp://... eller http://...)',
+    cameraTypeMjpeg: 'MJPEG-ström',
+    cameraTypeRtsp: 'RTSP-ström',
+    cameraTypeSnapshot: 'HTTP-ögonblicksbild',
+    cameraTypeUsb: 'USB-kamera (V4L2)',
+    cameraSnapshotUrl: 'Ögonblicksbild-URL (valfritt)',
+    cameraSnapshotUrlPlaceholder: 'http://192.168.1.61:1984/api/frame.jpeg?src=printer',
+    cameraSnapshotUrlHelp: 'Enkelbild-URL som används för notisminibilder, färdigbilder, layer-timelapse-bilder och plattdetektering. Timelapse och plattdetektering kräver varsin per-skrivare-växel — denna URL är bara bildkällan de använder när aktiva. Lämna tomt för att fånga från live-strömmen ovan. Användbart för go2rtc (/api/frame.jpeg) och IP-kameror med en dedikerad ögonblicksbild-ändpunkt.',
+    cameraRotation: 'Rotation',
+    test: 'Test',
+    connected: 'Ansluten',
+    disconnected: 'Frånkopplad',
+    // Cost tracking
+    currency: 'Valuta',
+    defaultFilamentCost: 'Standardfilamentkostnad (per kg)',
+    electricityCost: 'Elkostnad per kWh',
+    energyDisplayMode: 'Energivisningsläge',
+    energyModePrintDescription: 'Instrumentpanelen visar summan av energin som använts under utskrifter',
+    energyModeTotalDescription: 'Instrumentpanelen visar livstidsenergi från smarta kontakter',
+    // File Manager
+    fileManager: 'Filhanterare',
+    createArchiveEntry: 'Skapa arkivpost vid utskrift',
+    createArchiveEntryDescription: 'När du skriver ut från Filhanteraren, skapa en arkivpost',
+    lowDiskSpaceWarning: 'Varning för lågt diskutrymme',
+    lowDiskSpaceDescription: 'Visa en varning när tillgängligt diskutrymme är under detta tröskelvärde',
+    // Updates
+    printerFirmware: 'Skrivarens firmware',
+    checkFirmwareDescription: 'Kontrollera om det finns firmwareuppdateringar för skrivaren från Bambu Lab',
+    bambuddySoftware: 'Bambuddy-programvara',
+    autoCheckDescription: 'Sök automatiskt efter nya versioner vid start',
+    checkNow: 'Sök nu',
+    updateAvailableVersion: 'Uppdatering tillgänglig: v{{version}}',
+    releaseNotes: 'Versionsinformation',
+    updateViaDocker: 'Uppdatera via Docker Compose:',
+    composeDirectory: 'Compose-katalog',
+    composeDirectoryHint: 'Mappen som innehåller din docker-compose.yml. Lämna tomt för att utelämna cd.',
+    copyUpdateCommand: 'Kopiera uppdateringskommando',
+    updateViaHomeAssistant: 'Uppdateringar hanteras av Home Assistant Supervisor. Öppna Inställningar → Tillägg → Bambuddy i Home Assistant för att installera den nya versionen.',
+    updateViaWindowsInstaller: 'Windows-installationer uppdateras genom att köra installationsprogrammet igen. Ladda ner den nya versionen nedan — din data, inställningar och skrivare bevaras.',
+    downloadWindowsInstaller: 'Ladda ner installationsprogram för v{{version}}',
+    installUpdate: 'Installera uppdatering',
+    latestVersionRunning: 'Du kör den senaste versionen',
+    failedToCheckUpdates: 'Kunde inte kontrollera uppdateringar: {{error}}',
+    // Data Management
+    backupRestore: 'Säkerhetskopia och återställning',
+    backupRestoreDescription: 'Exportera/importera inställningar och konfigurera GitHub-säkerhetskopia',
+    goToBackup: 'Gå till säkerhetskopia',
+    // Network tab
+    externalUrl: 'Extern URL',
+    externalUrlDescription: 'Den externa URL:en där Bambuddy kan nås. Används för notisbilder och externa integrationer.',
+    bambuddyUrl: 'Bambuddy-URL',
+    externalUrlHint: 'Inkludera protokoll och port (t.ex. http://192.168.1.100:8000)',
+    ftpRetry: 'FTP-omförsök',
+    ftpRetryDescription: 'Försök igen med FTP-operationer när skrivarens WiFi är opålitlig. Gäller för 3MF-nedladdningar, utskriftsuppladdningar, timelapse-nedladdningar och firmwareuppdateringar.',
+    autoRetryDescription: 'Försök automatiskt igen med misslyckade FTP-operationer',
+    retryAttempts: 'Försök igen',
+    retryDelay: 'Fördröjning mellan försök',
+    connectionTimeout: 'Anslutningstimeout',
+    time_one: '{{count}} gång',
+    time_other: '{{count}} gånger',
+    second_one: '{{count}} sekund',
+    second_other: '{{count}} sekunder',
+    nSeconds: '{{count}} sekunder',
+    increaseForWeakWifi: 'Öka för skrivare med svag WiFi',
+    // Home Assistant
+    homeAssistant: 'Home Assistant',
+    homeAssistantFullDescription: 'Anslut till Home Assistant för att styra smarta kontakter via HA:s REST API. Stöder switch, light, input_boolean och script-entiteter.',
+    homeAssistantUrl: 'Home Assistant-URL',
+    longLivedAccessToken: 'Långlivad åtkomst-token',
+    haTokenHint: 'Skapa en token i HA: Profil → Långlivade åtkomst-tokens → Skapa token',
+    connectionSuccessful: 'Anslutning lyckades',
+    connectionFailed: 'Anslutning misslyckades',
+    haConnectionSuccess: 'Anslöt framgångsrikt till Home Assistant.',
+    haConnectionFailed: 'Kunde inte ansluta till Home Assistant.',
+    // MQTT
+    mqttPublishing: 'MQTT-publicering',
+    mqttDescription: 'Publicera Bambuddy-händelser till en extern MQTT-mäklare för integration med Node-RED, Home Assistant och andra automatiseringssystem.',
+    mqttEnableDescription: 'Publicera händelser till extern MQTT-mäklare',
+    brokerHostname: 'Mäklarens värdnamn',
+    port: 'Port',
+    usernameOptional: 'Användarnamn (valfritt)',
+    passwordOptional: 'Lösenord (valfritt)',
+    topicPrefix: 'Ämnesprefix',
+    topicPrefixHint: 'Ämnen kommer att vara: {{prefix}}/printers/<serial>/status, etc.',
+    // Prometheus
+    prometheusMetrics: 'Prometheus-mätvärden',
+    prometheusEndpointDescription: 'Exponera skrivarmätvärden på <code>/api/v1/metrics</code> för Prometheus/Grafana-övervakning.',
+    bearerTokenOptional: 'Bärar-token (valfritt)',
+    bearerTokenHint: 'Om inställt måste förfrågningar inkludera <code>Authorization: Bearer <token></code>',
+    metricsConnectionStatus: 'Anslutningsstatus',
+    metricsPrinterState: 'Skrivarstatus (inaktiv/skriver ut/etc)',
+    metricsPrintProgress: 'Utskriftsförlopp 0-100%',
+    metricsBedTemp: 'Byggplattstemperatur',
+    metricsNozzleTemp: 'Munstyckstemperatur',
+    metricsPrintsTotal: 'Totala utskrifter efter resultat',
+    metricsMore: '...och mer (skikt, fläktar, kö, filamentanvändning)',
+    // Smart Plugs
+    smartPlugsDescription: 'Anslut smarta kontakter (Tasmota eller Home Assistant) för att automatisera strömkontroll och spåra energiförbrukning för dina skrivare.',
+    allOn: 'Sätt på alla',
+    allOff: 'Stäng av alla',
+    addSmartPlug: 'Lägg till smart kontakt',
+    energySummary: 'Energisammanfattning',
+    currentPower: 'Aktuell effekt',
+    plugsOnline: '{{reachable}}/{{total}} kontakter online',
+    today: 'Idag',
+    yesterday: 'Igår',
+    total: 'Totalt',
+    enablePlugsForSummary: 'Aktivera kontakter för att se energisammanfattning',
+    addNotificationProvider: 'Lägg till',
+    // Users
+    systemBadge: '(System)',
+    creating: 'Skapar...',
+    changing: 'Ändrar...',
+    deleteUserAndItems: 'Ta bort användare OCH deras objekt',
+    deleteUserKeepItems: 'Ta bort användare, behåll objekt (blir ägarlösa)',
+    ok: 'OK',
+
+    // 2FA settings
+    twoFa: {
+      totpTitle: 'Autentiseringsapp (TOTP)',
+      totpDesc: 'Använd en autentiseringsapp som Google Authenticator, Aegis eller Authy.',
+      emailOtpTitle: 'E-post OTP',
+      emailOtpDesc: 'Skicka en engångskod till {{email}} när du loggar in.',
+      emailOtpNoEmail: 'Lägg till en e-postadress till ditt konto för att aktivera denna metod.',
+      addEmailFirst: 'Ditt konto har ingen e-postadress. Be en admin att lägga till en innan du aktiverar e-post OTP.',
+      setupTotp: 'Ställ in autentiseringsapp',
+      setupAuthApp: 'Ställ in autentiseringsapp',
+      setupInstructions: 'Skanna QR-koden nedan med din autentiseringsapp, bekräfta sedan med en kod.',
+      manualEntry: 'Kan du inte skanna? Ange denna hemlighet manuellt:',
+      scannedContinue: 'Jag har skannat koden — fortsätt',
+      enterCodeToConfirm: 'Ange den 6-siffriga koden från din autentiseringsapp för att bekräfta konfigurationen.',
+      activate: 'Aktivera',
+      disableTotp: 'Inaktivera autentiseringsapp',
+      disableConfirmHint: 'Ange en giltig TOTP-kod eller en reservkod för att inaktivera autentiseraren.',
+      totpDisabled: 'Autentiseringsapp inaktiverad.',
+      emailOtpEnabled: 'E-post OTP aktiverad.',
+      emailOtpDisabled: 'E-post OTP inaktiverad.',
+      smtpRequired: 'Konfigurera och testa SMTP-inställningar först.',
+      invalidCode: 'Ogiltig kod. Försök igen.',
+      enableEmailOtp: 'Aktivera e-post OTP',
+      disableEmailOtp: 'Inaktivera e-post OTP',
+      emailSetupEnterCode: 'En verifieringskod har skickats till din e-postadress. Ange den nedan för att bekräfta att du äger denna inkorg.',
+      verifyAndEnable: 'Verifiera och aktivera',
+      emailDisablePasswordHint: 'Ange ditt kontolösenord för att bekräfta inaktiveringen av e-post OTP.',
+      passwordPlaceholder: 'Ange ditt lösenord',
+      backupCodesTitle: 'Spara dina reservkoder',
+      backupCodesWarning: 'Spara dessa koder på en säker plats. Varje kod kan endast användas en gång och de kommer inte att visas igen.',
+      backupCodesRemaining: '{{count}} reservkoder kvar',
+      savedCodes: 'Jag har sparat mina koder',
+      regenBackup: 'Regenerera reservkoder',
+      regenBackupHint: 'Ange din nuvarande TOTP-kod för att generera 10 nya reservkoder. Alla befintliga reservkoder kommer att ogiltigförklaras.',
+      newBackupCodes: 'Nya reservkoder',
+      linkedAccounts: 'Länkade SSO-konton',
+      linkedAccountsDesc: 'Dessa externa identitetsleverantörer är länkade till ditt konto.',
+      oidcUnlinked: 'Konto bortkopplat.',
+    },
+
+    // Session Policy (#1706) — admin-configurable session lifetime ceiling.
+    sessionPolicy: {
+      title: 'Sessionspolicy',
+      description: 'Maximal sessionstid för nya användarinloggningar. Redan utfärdade tokens behåller sin ursprungliga utgångstid.',
+      preset24h: '24 timmar',
+      preset7d: '7 dagar',
+      preset30d: '30 dagar',
+      customHoursLabel: 'Anpassad sessionstid i timmar',
+      hoursSuffix: 'timmar',
+      warning: 'Längre sessioner minskar skyddet mot automatisk utloggning. Rekommenderas endast för betrodda enanvändarutplaceringar.',
+    },
+
+    // OIDC provider settings
+    oidc: {
+      title: 'SSO / OIDC-leverantörer',
+      desc: 'Konfigurera OpenID Connect-leverantörer för att tillåta enstegsinloggning via externa identitetsleverantörer.',
+      addProvider: 'Lägg till leverantör',
+      newProvider: 'Ny leverantör',
+      empty: 'Inga OIDC-leverantörer konfigurerade än.',
+      created: 'Leverantör skapad.',
+      updated: 'Leverantör uppdaterad.',
+      deleted: 'Leverantör borttagen.',
+      refreshIcon: 'Uppdatera ikon',
+      removeIcon: 'Ta bort ikon',
+      iconRefreshed: 'Ikon uppdaterad.',
+      iconRemoved: 'Ikon borttagen.',
+      iconFetchFailed: 'Kunde inte hämta ikon från leverantörs-URL:en.',
+      deleteTitle: 'Ta bort leverantör',
+      deleteMessage: 'Ta bort "{{name}}"? Alla länkade användarkonton kommer att kopplas från.',
+      form: {
+        name: 'Visningsnamn',
+        issuerUrl: 'Utgivar-URL',
+        clientId: 'Klient-ID',
+        clientSecret: 'Klienthemlighet',
+        scopes: 'Omfång',
+        iconUrl: 'Ikon-URL (valfritt)',
+        enabled: 'Aktiverad',
+        autoCreate: 'Auto-skapa användare',
+        autoCreateDesc: 'Skapa automatiskt ett lokalt konto vid första inloggning.',
+        autoLink: 'Auto-länka befintliga konton',
+        autoLinkDesc: 'Länka befintliga lokala konton genom att matcha e-post vid första inloggning.',
+        secretHint: 'lämna tomt för att behålla nuvarande',
+        secretPlaceholder: 'ny hemlighet',
+        emailClaim: 'E-postanspråk',
+        emailClaimDesc: 'JWT-anspråk som används som e-postidentitet. Använd "preferred_username" eller "upn" för Azure Entra ID (som inte skickar email_verified). Använd endast betrodda anspråksnamn.',
+        emailClaimPlaceholder: 'email',
+        emailClaimCustomClaimAutoLinkWarning: 'Anpassade anspråk är säkra för auto-länk endast när värdet administreras av hyresvärden (t.ex. Azure Entra ID upn / preferred_username). Aktivera inte auto-länk om din IdP tillåter användare att självhävda detta anspråk.',
+        requireEmailVerified: 'Kräv verifierad e-post',
+        requireEmailVerifiedDesc: 'Acceptera endast e-postanspråket när leverantören markerar det som verifierat.',
+        requireEmailVerifiedWarning: 'Varning: e-post kommer att accepteras även utan verifiering. Använd endast med betrodda leverantörer.',
+        requireEmailVerifiedAutoLink: 'Inaktivera auto-länk först för att ändra denna inställning.',
+        defaultGroup: 'Standardgrupp',
+        defaultGroupDesc: 'Grupp som tilldelas auto-skapade användare. Faller tillbaka till Åskådare om inte inställt.',
+        defaultGroupViewersFallback: 'Åskådare (standard)',
+        autologin: 'Autologin',
+        autologinDesc: 'Omdirigera icke autentiserade besökare direkt till denna leverantör. Endast en leverantör kan ha denna flagga.',
+      },
+    },
+
+    encryption: {
+      title: 'MFA-krypteringsstatus',
+      enabledFromEnv: 'Kryptering i vila aktiverad (nyckel från MFA_ENCRYPTION_KEY-miljövariabel)',
+      enabledFromFile: 'Kryptering i vila aktiverad (nyckel laddad från datakatalog)',
+      enabledGenerated: 'Kryptering i vila aktiverad med auto-genererad nyckel',
+      notConfigured: 'Kryptering i vila ej konfigurerad',
+      notConfiguredDesc: 'TOTP-hemligheter och OIDC client_secrets lagras i klartext. Sätt MFA_ENCRYPTION_KEY eller starta om Bambuddy med en skrivbar datakatalog för att auto-generera en.',
+      allEncrypted: 'Alla MFA-hemligheter är krypterade i vila.',
+      legacyRowsLabel: 'Äldre klartextrader',
+      encryptedRowsLabel: 'Krypterade rader',
+      legacyRowsWarning: '{{count}} äldre klartextrad(er) upptäckta. Spara om OIDC-leverantören eller registrera om användarens autentiseringsapp för att migrera till krypterad lagring.',
+      backupHint: 'Den auto-genererade nyckeln lagras på DATA_DIR/.mfa_encryption_key och ingår i lokala säkerhetskopior. Håll dina säkerhetskopior säkra eller sätt MFA_ENCRYPTION_KEY explicit.',
+      decryptionBrokenTitle: 'Krypteringsnyckel saknas',
+      decryptionBrokenError: '{{count}} krypterad(e) post(er) kan inte dekrypteras eftersom krypteringsnyckeln inte längre är tillgänglig. Återställ den tidigare MFA_ENCRYPTION_KEY eller DATA_DIR/.mfa_encryption_key för att återställa.',
+      migrationErrorWarning: '{{count}} äldre rad(er) kunde inte krypteras om vid start. Kontrollera serverloggar och starta om Bambuddy för att försöka igen.',
+    },
+
+    // Slicer Pipeline limits (#1425 PR C). Admin-tunable cap that constrains
+    // the copies input in the Run-with-pipeline modal. Lives on the Workflow
+    // tab's Queue & Dispatch sub-tab.
+    pipelineLimits: {
+      title: 'Gränser för slicer-pipeline',
+      maxCopiesLabel: 'Max kopior per körning',
+      maxCopiesDesc: 'Övre gräns för antalet kopior som operatörer kan begära vid körning av en pipeline. Server-sidans hårda gräns är 1000.',
+    },
+
+    // Slicer Pipelines (#1425): list/edit/delete preset bundles users saved
+    // from the Slice dialog. Lives in Settings → Workflow → Pipelines sub-tab.
+    pipelines: {
+      title: 'Slicer-pipelines',
+      subtitle: 'Återanvändbara inställningspaket (skrivare + process + filament + byggplattstyp). Spara en från slicing-dialogrutan och använd den med ett klick på nästa fil.',
+      loading: 'Laddar pipelines...',
+      loadError: 'Kunde inte ladda pipelines.',
+      confirmDelete: 'Ta bort denna pipeline? Detta kan inte ångras.',
+      staleWarning: 'En eller flera refererade inställningar finns inte längre. Spara om denna pipeline från slicing-dialogrutan för att åtgärda.',
+      empty: {
+        title: 'Inga pipelines än.',
+        howto: 'Öppna slicing-dialogrutan för någon fil, välj din skrivare/process/filament/byggplattstyp, klicka sedan på "Spara som pipeline". Dina sparade pipelines kommer att visas här.',
+      },
+      field: {
+        name: 'Pipeline-namn',
+        description: 'Beskrivning',
+        targetPrinter: 'Målskrivare',
+        noTarget: '— Inget mål —',
+        // PR C
+        targetKind: 'Måltyp',
+        targetKindSpecific: 'Specifik skrivare',
+        targetKindClass: 'Skrivarklass',
+        targetModelClass: 'Skrivarmodell',
+        fanoutStrategy: 'Fördelningsstrategi',
+        fanout: {
+          max_parallel: 'Max parallell — fördela över alla lediga matchande skrivare',
+          round_robin: 'Rotationskö — cykla genom berättigade skrivare',
+          fill_one_first: 'Fyll en först — fäst alla kopior till en skrivare',
+        },
+        // Short labels for the inline target chip on each pipeline card.
+        // The verbose ones above explain the strategy in the editor; the
+        // card just needs a compact reminder of which one is in use.
+        fanoutShort: {
+          max_parallel: 'parallell',
+          round_robin: 'rotationskö',
+          fill_one_first: 'fyll en först',
+        },
+      },
+      action: {
+        save: 'Spara',
+        cancel: 'Avbryt',
+        rename: 'Döp om',
+        delete: 'Ta bort',
+      },
+      slot: {
+        printer: 'Skrivare',
+        process: 'Process',
+        filament: 'Filament',
+        filamentN: 'Filament {{n}}',
+        filamentAll: 'Alla {{n}} fack',
+        bed: 'Byggplatta',
+      },
+      // PR C polish — grouped sections in the card body, plus the
+      // panel-level search + filter row.
+      group: {
+        profiles: 'Profiler',
+        filaments: 'Filament',
+      },
+      searchPlaceholder: 'Sök pipelines...',
+      filterTargetType: 'Filtrera efter måltyp',
+      filterTarget: 'Filtrera efter mål',
+      filter: {
+        all: 'Alla mål',
+        noTarget: 'Inget mål inställt',
+        count: '{{shown}} / {{total}}',
+        noMatches: 'Inga pipelines matchar de aktuella filtren.',
+      },
+      toast: {
+        saved: 'Pipeline sparad',
+        saveFailed: 'Kunde inte spara',
+        deleted: 'Pipeline borttagen',
+        deleteFailed: 'Kunde inte ta bort',
+      },
+      // PR B target binding + last-run summary
+      noTargetHint: 'Sätt en målskrivare för att köra denna',
+      noTargetWarning: 'Sätt en målskrivare innan du kör denna pipeline.',
+      runs: {
+        lastRun: 'Senaste körning',
+        status: {
+          queued: 'köad',
+          slicing: 'slicar',
+          dispatching: 'skickar',
+          in_progress: 'skriver ut',
+          completed: 'slutförd',
+          failed: 'misslyckad',
+          partial_failure: 'delvis misslyckad',
+          cancelled: 'avbruten',
+        },
+      },
+    },
+  },
+
+  // Notifications (for push notifications)
+  notification: {
+    printStarted: {
+      title: 'Utskrift startad',
+      body: '{{printer}}: {{filename}} har börjat skrivas ut',
+    },
+    printCompleted: {
+      title: 'Utskrift slutförd',
+      body: '{{printer}}: {{filename}} slutfördes',
+    },
+    printFailed: {
+      title: 'Utskrift misslyckades',
+      body: '{{printer}}: {{filename}} misslyckades',
+    },
+    printStopped: {
+      title: 'Utskrift stoppad',
+      body: '{{printer}}: {{filename}} stoppades',
+    },
+    printProgress: {
+      title: 'Utskriftsförlopp',
+      body: '{{printer}}: {{filename}} är {{percent}}% klar',
+    },
+    printerOffline: {
+      title: 'Skrivare offline',
+      body: '{{printer}} är offline',
+    },
+    printerError: {
+      title: 'Skrivarfel',
+      body: '{{printer}}: {{error}}',
+    },
+    filamentLow: {
+      title: 'Lågt filament',
+      body: '{{printer}}: Filamentet håller på att ta slut',
+    },
+    maintenanceDue: {
+      title: 'Underhåll uteblivet',
+      body: '{{printer}}: {{items}} behöver uppmärksamhet',
+    },
+  },
+
+  // Errors
+errors: {
+    generic: 'Något gick fel',
+    networkError: 'Nätverksfel. Kontrollera din anslutning.',
+    notFound: 'Hittades ej',
+    unauthorized: 'Ej behörig',
+    serverError: 'Serverfel',
+    validationError: 'Kontrollera din inmatning',
+    printerConnectionFailed: 'Kunde inte ansluta till skrivare',
+    saveFailed: 'Kunde inte spara ändringar',
+    deleteFailed: 'Kunde inte ta bort',
+    loadFailed: 'Kunde inte ladda data',
+  },
+
+  // HMS Errors modal
+  hmsErrors: {
+    title: 'Fel - {{name}}',
+    noErrors: 'Inga fel',
+    viewOnWiki: 'Visa på Bambu Lab Wiki',
+    mqttVerifyFailedRemedy: 'Aktivera utvecklarläge på skrivaren, starta om skrivaren och starta sedan jobbet igen.',
+    unknownCode: 'Okänd HMS-kod — se Bambu Lab wiki för detaljer.',
+    clearInstructions: 'Rensa fel på skrivaren för att avfärda dem här.',
+    clearErrors: 'Rensa fel',
+    clearSuccess: 'HMS-fel rensade',
+    clearFailed: 'Kunde inte rensa HMS-fel',
+    actionSuccess: 'Åtgärd skickad till skrivare',
+    actionFailed: 'Kunde inte skicka åtgärd',
+    runoutExpectedSlot: 'Filamentet tog slut i {{ranOut}}. Skrivaren väntar nu på kompatibelt filament i {{expected}}. Sätt in en rulle i {{expected}} och välj sedan Försök igen.',
+    runoutExpectedSlotOnly: 'Skrivaren väntar på kompatibelt filament i {{expected}}. Sätt in en rulle där och välj sedan Försök igen.',
+    runoutSlotUnknown: 'Filament tog slut och utskriften är pausad. Bambuddy kunde inte avgöra vilket fack skrivaren nu väntar på — kontrollera skrivarens skärm för det begärda facket.',
+    actions: {
+      RESUME_PRINTING: "Fortsätt utskrift",
+      RESUME_PRINTING_DEFECTS: "Fortsätt (defekter acceptabla)",
+      RESUME_PRINTING_PROBELM_SOLVED: "Fortsätt (problem löst)",
+      STOP_PRINTING: "Stoppa utskrift",
+      CHECK_ASSISTANT: "Kontrollera assistent",
+      FILAMENT_EXTRUDED: "Filament extruderat, fortsätt",
+      RETRY_FILAMENT_EXTRUDED: "Inte extruderat än, försök igen",
+      CONTINUE: "Klar, fortsätt",
+      LOAD_VIRTUAL_TRAY: "Ladda filament",
+      OK_BUTTON: "OK",
+      FILAMENT_LOAD_RESUME: "Filament laddat, fortsätt",
+      JUMP_TO_LIVEVIEW: "Visa livevy",
+      NO_REMINDER_NEXT_TIME: "Ingen påminnelse nästa gång",
+      REFRESH_NOZZLE: "Kontrollera om",
+      IGNORE_NO_REMINDER_NEXT_TIME: "Ignorera. Ingen påminnelse nästa gång",
+      IGNORE_RESUME: "Ignorera och fortsätt",
+      PROBLEM_SOLVED_RESUME: "Problemet löst och fortsätt",
+      TURN_OFF_FIRE_ALARM: "Förstått, stäng av brandlarmet.",
+      RETRY_PROBLEM_SOLVED: "Försök igen (problem löst)",
+      CANCLE: "Avbryt",
+      STOP_DRYING: "Stoppa torkning",
+      PROCEED: "Fortsätt",
+      OK_JUMP_RACK: "OK",
+      ABORT: "Avbryt",
+      DISABLE_PURIFICATION: "Inaktivera rening för denna utskrift",
+      DONT_REMIND_NEXT_TIME: "Påminn mig inte nästa gång",
+      DBL_CHECK_CANCEL: "Avbryt",
+      DBL_CHECK_DONE: "Klar",
+      DBL_CHECK_RETRY: "Försök igen",
+      DBL_CHECK_RESUME: "Fortsätt",
+      DBL_CHECK_OK: "Bekräfta",
+      REMOVE_CLOSE_BTN: "Stäng",
+    }
+  },
+
+  // MQTT Debug modal
+  mqttDebug: {
+    title: 'MQTT-felsökningslogg',
+    searchPlaceholder: 'Sök ämne eller nyttolast...',
+    noMessages: 'Inga meddelanden loggade än',
+    startLoggingHint: 'Klicka på "Starta loggning" för att börja fånga MQTT-meddelanden',
+    noMessagesMatch: 'Inga meddelanden matchar ditt filter',
+    adjustFilterHint: 'Försök justera din sökning eller filterkriterier',
+    incoming: 'Inkommande',
+    outgoing: 'Utgående',
+    loggingStopped: 'Loggning stoppad',
+    loggingActive: 'Loggning aktiv - meddelanden kommer att uppdateras automatiskt',
+    startLogging: 'Starta loggning',
+    stopLogging: 'Stoppa loggning',
+    clearLog: 'Rensa logg',
+    topic: 'Ämne',
+    timestamp: 'Tidsstämpel',
+    direction: 'Riktning',
+    all: 'Alla',
+  },
+
+  // Printer File Manager modal (printer internal storage)
+  printerFiles: {
+    zipStarted_one: 'Startade ZIP-nedladdning för {{count}} fil',
+    zipStarted_other: 'Startade ZIP-nedladdning för {{count}} files',
+    zipPartial: 'Startade ZIP-nedladdning med {{successful}} av {{total}} filer; resten kunde inte hämtas',
+    downloadFailed: 'Nedladdning misslyckades: {{error}}',
+    unknownError: 'Okänt fel',
+    shiftSelectHint: 'Skift-klicka för att välja ett intervall',
+    selectFile: 'Markera {{name}}',
+    deselectFile: 'Avmarkera {{name}}',
+    title: 'Filhanterare',
+    storageUsed: 'Använt:',
+    storageFree: 'Ledigt:',
+    filterPlaceholder: 'Filtrera filer...',
+    deleteButton: 'Ta bort',
+    deleteFiles: 'Ta bort {{count}} filer',
+    deleteFileConfirm: 'Ta bort "{{name}}"? Detta kan inte ångras.',
+    deleteFilesConfirm: 'Ta bort {{count}} markerade filer? Detta kan inte ångras.',
+    noFiles: 'Inga filer på skrivaren',
+    printerUnavailable: 'Skrivarfiltjänsten är inte tillgänglig. Försök igen när skrivaren är tillgänglig.',
+    loadingFiles: 'Laddar filer...',
+    failedToLoad: 'Kunde inte ladda filer',
+    toast: {
+      filesDeleted: 'Tog bort {{count}} fil(er)',
+      deleteFailed: 'Kunde inte ta bort: {{error}}',
+    },
+  },
+
+  // Confirmations
+  confirm: {
+    delete: 'Är du säker på att du vill ta bort detta?',
+    unsavedChanges: 'Du har osparade ändringar. Är du säker på att du vill lämna?',
+    clearQueue: 'Är du säker på att du vill rensa kön?',
+  },
+
+  // Login page
+  login: {
+    title: 'Bambuddy-inloggning',
+    subtitle: 'Logga in på ditt konto',
+    username: 'Användarnamn',
+    usernamePlaceholder: 'Ange ditt användarnamn',
+    usernameOrEmail: 'Användarnamn eller e-post',
+    usernameOrEmailPlaceholder: 'Användarnamn eller @ e-post',
+    password: 'Lösenord',
+    passwordPlaceholder: 'Ange ditt lösenord',
+    signIn: 'Logga in',
+    signingIn: 'Loggar in...',
+    rememberMe: 'Kom ihåg mig',
+    forgotPassword: 'Glömt ditt lösenord?',
+    autologinFailed: 'Automatisk SSO-inloggning misslyckades. Välj en leverantör nedan för att fortsätta.',
+    localDisabledNotice: 'Lokal inloggning är inaktiverad. Använd en av SSO-leverantörerna nedan.',
+    loginSuccess: 'Inloggad',
+    loginFailed: 'Inloggning misslyckades',
+    enterCredentials: 'Ange användarnamn och lösenord',
+    enterEmail: 'Ange din e-postadress',
+    oidcLoginFailed: 'OIDC-inloggning misslyckades',
+    oidcErrors: {
+      providerError: 'Identitetsleverantören returnerade ett fel',
+      missingParameters: 'OIDC-återanrop saknar obligatoriska parametrar',
+      invalidState: 'OIDC-status är ogiltig eller har redan använts',
+      stateExpired: 'OIDC-inloggningssession har löpt ut — försök igen',
+      providerNotFound: 'OIDC-leverantör hittades ej',
+      discoveryFailed: 'Kunde inte hämta OIDC-upptäcktsdokument',
+      invalidDiscovery: 'OIDC-upptäcktsdokument är ogiltigt',
+      networkError: 'Nätverksfel under OIDC-tokenutbyte',
+      badResponse: 'Oväntat svar under OIDC-tokenutbyte',
+      noIdToken: 'OIDC-leverantören returnerade ingen ID-token',
+      validationFailed: 'OIDC-tokenvalidering misslyckades',
+      nonceMismatch: 'OIDC-nonce-felmatchning — möjlig replay-attack',
+      missingSubClaim: 'OIDC-token saknar sub-anspråk',
+      noLinkedAccount: 'Ingen lokal användare är länkad till denna OIDC-identitet',
+      accountInactive: 'Ditt konto är inaktivt',
+      userResolutionFailed: 'Kunde inte lösa ditt konto',
+      internalError: 'Ett internt fel uppstod under OIDC-inloggning',
+      tokenExchangeFailed: 'OIDC-tokenutbyte misslyckades',
+    },
+    forgotPasswordTitle: 'Glömt lösenord',
+    forgotPasswordMessage: 'Om du har glömt ditt lösenord, kontakta din systemadministratör för att återställa det.',
+    forgotPasswordEmailMessage: 'Ange din e-postadress så skickar vi ett nytt lösenord till dig.',
+    emailAddress: 'E-postadress',
+    emailPlaceholder: 'din.e-post@example.com',
+    cancel: 'Avbryt',
+    sending: 'Skickar...',
+    sendResetEmail: 'Skicka återställnings-e-post',
+    howToReset: 'Så här återställer du ditt lösenord:',
+    resetStep1: 'Kontakta din Bambuddy-administratör',
+    resetStep2: 'Be dem återställa ditt lösenord i Användarhantering',
+    resetStep3: 'De kan sätta ett nytt tillfälligt lösenord åt dig',
+    resetStep4: 'Logga in med det nya lösenordet och ändra det under Inställningar',
+    gotIt: 'Förstått',
+    resetPassword: {
+      title: 'Sätt nytt lösenord',
+      subtitle: 'Ange och bekräfta ditt nya lösenord nedan.',
+      newPassword: 'Nytt lösenord',
+      newPasswordPlaceholder: 'Minst 8 tecken',
+      confirmPassword: 'Bekräfta lösenord',
+      confirmPasswordPlaceholder: 'Upprepa nytt lösenord',
+      saving: 'Sparar…',
+      submit: 'Sätt nytt lösenord',
+      backToLogin: 'Tillbaka till inloggning',
+      passwordsDoNotMatch: 'Lösenorden matchar inte',
+      passwordTooShort: 'Lösenordet måste vara minst 8 tecken',
+      resetFailed: 'Lösenordsåterställning misslyckades. Länken kan ha löpt ut.',
+    },
+    twoFA: {
+      title: 'Tvåfaktorsautentisering',
+      subtitle: 'Ditt konto är skyddat med 2FA. Ange verifieringskoden nedan.',
+      methodAuthenticator: 'Autentiseringsapp',
+      methodEmail: 'E-postkod',
+      methodBackup: 'Reservkod',
+      instructionsTotp: 'Öppna din autentiseringsapp och ange den 6-siffriga koden för Bambuddy.',
+      instructionsEmail: 'En 6-siffrig kod har skickats till din e-postadress. Den går ut om 10 minuter.',
+      instructionsEmailNotSent: 'Klicka på knappen nedan för att ta emot en verifieringskod via e-post.',
+      instructionsBackup: 'Ange en av dina 8-teckens reservåterställningskoder. Varje kod kan endast användas en gång.',
+      sendCodeButton: 'Skicka kod via e-post',
+      sendingCode: 'Skickar...',
+      resendCode: 'Skicka kod igen',
+      codeLabel: 'Verifieringskod',
+      backupCodeLabel: 'Reservkod',
+      codePlaceholder: '000000',
+      backupCodePlaceholder: 'XXXXXXXX',
+      verifyButton: 'Verifiera',
+      verifyingButton: 'Verifierar...',
+      backToLogin: '← Tillbaka till inloggning',
+      orContinueWith: 'eller fortsätt med',
+      signInWith: 'Logga in med {{provider}}',
+      enterCode: 'Ange verifieringskoden',
+      sendCodeFailed: 'Kunde inte skicka verifieringskod',
+      invalidCode: 'Ogiltig kod. Försök igen.',
+    },
+
+  },
+
+  // Setup page
+  setup: {
+    title: 'Bambuddy-inställning',
+    subtitle: 'Konfigurera autentisering för din Bambuddy-instans',
+    enableAuth: 'Aktivera autentisering',
+    adminAccount: 'Admin-konto',
+    adminAccountDesc: 'Om admin-användare redan finns kommer autentisering att aktiveras med de befintliga admin-kontona. Lämna fälten nedan tomma för att använda befintliga admins, eller ange nya inloggningsuppgifter för att skapa en ny admin-användare.',
+    adminUsername: 'Admin-användarnamn',
+    adminPassword: 'Admin-lösenord',
+    optionalIfAdminExists: '(valfritt om admin-användare finns)',
+    adminUsernamePlaceholder: 'Ange admin-användarnamn (valfritt)',
+    adminPasswordPlaceholder: 'Ange admin-lösenord (valfritt)',
+    confirmPassword: 'Bekräfta lösenord',
+    confirmPasswordPlaceholder: 'Bekräfta admin-lösenord',
+    settingUp: 'Ställer in...',
+    completeSetup: 'Slutför inställning',
+    toast: {
+      authEnabledAdminCreated: 'Autentisering aktiverad och admin-användare skapad',
+      authEnabledExistingAdmins: 'Autentisering aktiverad med befintliga admin-användare',
+      setupCompleted: 'Inställning slutförd',
+      enterBothCredentials: 'Ange både admin-användarnamn och lösenord, eller lämna båda tomma för att använda befintliga admin-användare',
+      passwordsDoNotMatch: 'Lösenorden matchar ej',
+      passwordTooShort: 'Lösenordet måste vara minst 6 tecken',
+    },
+  },
+
+  // Password change
+  changePassword: {
+    title: 'Ändra lösenord',
+    currentPassword: 'Nuvarande lösenord',
+    currentPasswordPlaceholder: 'Ange nuvarande lösenord',
+    newPassword: 'Nytt lösenord',
+    newPasswordPlaceholder: 'Ange nytt lösenord (minst 6 tecken)',
+    confirmPassword: 'Bekräfta nytt lösenord',
+    confirmPasswordPlaceholder: 'Bekräfta nytt lösenord',
+    passwordsDoNotMatch: 'Lösenorden matchar ej',
+    passwordTooShort: 'Lösenordet måste vara minst 6 tecken',
+    changing: 'Ändrar...',
+    success: 'Lösenord ändrat',
+    failed: 'Kunde inte ändra lösenord',
+  },
+
+  // Plate detection alert
+  plateAlert: {
+    title: 'Utskrift pausad!',
+    message: 'Objekt upptäckta på byggplattan. Utskriften har pausats automatiskt. Töm plattan och fortsätt utskriften.',
+    understand: 'Jag förstår',
+  },
+
+  // Camera page
+  camera: {
+    title: 'Kameravy',
+    invalidPrinterId: 'Ogiltigt skrivar-ID',
+    live: 'Live',
+    snapshot: 'Ögonblicksbild',
+    restartStream: 'Starta om strömmen',
+    refreshSnapshot: 'Uppdatera ögonblicksbild',
+    fullscreen: 'Helskärm',
+    exitFullscreen: 'Avsluta helskärm',
+    connectingToCamera: 'Ansluter till kamera...',
+    capturingSnapshot: 'Fångar ögonblicksbild...',
+    connectionLost: 'Anslutning tappades',
+    connectionFailed: 'Kunde inte ansluta till kamera',
+    reconnecting: 'Återansluter om {{countdown}}s... (försök {{attempt}}/{{max}})',
+    reconnectNow: 'Återanslut nu',
+    cameraUnavailable: 'Kamera otillgänglig',
+    cameraUnavailableDesc: 'Se till att skrivaren är påslagen och ansluten.',
+    noCamera: 'Ingen kamera tillgänglig',
+    retry: 'Försök igen',
+    cameraStream: 'Kameraström',
+    zoomOut: 'Zooma ut',
+    zoomIn: 'Zooma in',
+    resetZoom: 'Återställ zoom',
+    recording: 'Spelar in',
+    startRecording: 'Starta inspelning',
+    stopRecording: 'Stoppa inspelning',
+    chamberLight: 'Växla kammarljus',
+    unavailable: 'Kamera ej tillgänglig',
+    diagnose: {
+      button: 'Diagnostisera',
+      modalTitle: 'Kameradiagnostik',
+      running: 'Kör diagnostik...',
+      runFailed: 'Kunde inte köra diagnostik: {{error}}',
+      retry: 'Kör igen',
+      stage: {
+        tcp_reachable: 'Nätverksåtkomlighet',
+        first_frame: 'Bildtagning',
+        live_stream_active: 'Liveström aktiv',
+      },
+      summary: {
+        all_ok: 'Kameran fungerar. Diagnostiken slutförde alla steg.',
+        live_stream_active_healthy: 'Kameran strömmar för närvarande med nya bilder — ingen test nödvändig.',
+        printer_unreachable: 'Skrivaren är ej nåbar. Kontrollera IP-adress, nätverksanslutning och att skrivaren är påslagen.',
+        camera_port_closed: 'Skrivaren är nåbar men kameraporten är stängd. Se till att LAN-läge och utvecklarläge är aktiverade i skrivarinställningarna.',
+        no_frame: 'Ansluten till kameran men inga bilder togs emot. Försök igen eller kontrollera att kameran är aktiverad i skrivarinställningarna.',
+        unknown_failure: 'Kameradiagnostik misslyckades av okänd anledning. Kontrollera supportloggen för detaljer.',
+      },
+      meta: {
+        protocol: 'Protokoll',
+        port: 'Port',
+        profile: 'Profil',
+      },
+    },
+  },
+
+  // Groups management
+  groups: {
+    title: 'Grupphantering',
+    subtitle: 'Hantera behörighetsgrupper för åtkomstkontroll',
+    backToSettings: 'Tillbaka till inställningar',
+    createGroup: 'Skapa grupp',
+    noPermission: 'Du har inte behörighet att komma åt denna sida.',
+    system: 'System',
+    noDescription: 'Ingen beskrivning',
+    usersCount: '{{count}} användare',
+    permissionsCount: '{{count}} behörigheter',
+    edit: 'Redigera',
+    delete: 'Ta bort',
+    toast: {
+      created: 'Grupp skapad',
+      updated: 'Grupp uppdaterad',
+      deleted: 'Grupp borttagen',
+      enterGroupName: 'Ange ett gruppnamn',
+    },
+    modal: {
+      editGroup: 'Redigera grupp',
+      createGroup: 'Skapa grupp',
+      cancel: 'Avbryt',
+      saving: 'Sparar...',
+      creating: 'Skapar...',
+      saveChanges: 'Spara ändringar',
+    },
+    form: {
+      groupName: 'Gruppnamn',
+      groupNamePlaceholder: 'Ange gruppnamn',
+      systemGroupWarning: 'Systemgruppnamn kan inte ändras',
+      description: 'Beskrivning',
+      descriptionPlaceholder: 'Ange beskrivning (valfritt)',
+      permissions: 'Behörigheter ({{count}} valda)',
+    },
+    deleteModal: {
+      title: 'Ta bort grupp',
+      message: 'Är du säker på att du vill ta bort denna grupp? Användare i denna grupp kommer att förlora dessa behörigheter.',
+      confirm: 'Ta bort grupp',
+    },
+    editor: {
+      title: 'Redigera grupp',
+      createTitle: 'Skapa grupp',
+      search: 'Sök behörigheter...',
+      selectAll: 'Markera alla',
+      clearAll: 'Avmarkera alla',
+      permissionsSelected: '{{count}} valda',
+      noResults: 'Inga behörigheter matchar din sökning',
+      websocketHint: 'Krävs för liveuppdateringar. Utan det faller gränssnittet tillbaka på periodisk avfrågning.',
+    },
+  },
+
+  // Users management
+  users: {
+    title: 'Användarhantering',
+    subtitle: 'Hantera användare och deras åtkomst till din Bambuddy-instans',
+    backToSettings: 'Tillbaka till inställningar',
+    createUser: 'Skapa användare',
+    noPermission: 'Du har inte behörighet att komma åt denna sida.',
+    admin: 'Admin',
+    noGroups: 'Inga grupper',
+    active: 'Aktiv',
+    inactive: 'Inaktiv',
+    edit: 'Redigera',
+    delete: 'Ta bort',
+    system: 'System',
+    noGroupsAvailable: 'Inga grupper tillgängliga',
+    table: {
+      username: 'Användarnamn',
+      groups: 'Grupper',
+      status: 'Status',
+      actions: 'Åtgärder',
+    },
+    toast: {
+      created: 'Användare skapad',
+      updated: 'Användare uppdaterad',
+      deleted: 'Användare borttagen',
+      fillRequired: 'Fyll i alla obligatoriska fält',
+      passwordsDoNotMatch: 'Lösenorden matchar ej',
+      passwordTooShort: 'Lösenordet måste vara minst 6 tecken',
+      ldapProvisioned: 'LDAP-användare "{{username}}" skapad',
+    },
+    modal: {
+      createUser: 'Skapa användare',
+      editUser: 'Redigera användare',
+      cancel: 'Avbryt',
+      creating: 'Skapar...',
+      saving: 'Sparar...',
+      saveChanges: 'Spara ändringar',
+      advancedAuthSubtitle: 'med avancerad autentisering',
+      // LDAP manual provisioning
+      tabsAriaLabel: 'Användarkälla',
+      localTab: 'Lokal',
+      ldapTab: 'LDAP',
+      ldapSearchLabel: 'Sök katalog',
+      ldapSearchPlaceholder: 'Ange användarnamn, namn eller e-post...',
+      ldapMinChars: 'Ange minst 2 tecken för att söka',
+      ldapTypeToSearch: 'Börja skriva för att söka i LDAP-katalogen',
+      ldapSearching: 'Söker i katalog...',
+      ldapNoResults: 'Inga matchande användare i katalogen',
+      ldapSearchError: 'Katalogsökning misslyckades. Kontrollera LDAP-serverstatus.',
+      ldapAlreadyProvisioned: 'Redan skapad',
+      ldapSelectedLabel: 'Valda',
+      ldapProvision: 'Skapa användare',
+      ldapProvisioning: 'Skapar...',
+      ldapErrorProvision: 'Kunde inte skapa användare. Kontrollera LDAP-serverstatus och försök igen.',
+    },
+    form: {
+      username: 'Användarnamn',
+      usernamePlaceholder: 'Ange användarnamn',
+      email: 'E-post',
+      emailPlaceholder: 'användare@example.com',
+      password: 'Lösenord',
+      passwordPlaceholder: 'Ange lösenord',
+      confirmPassword: 'Bekräfta lösenord',
+      confirmPasswordPlaceholder: 'Bekräfta lösenord',
+      newPasswordPlaceholder: 'Ange nytt lösenord',
+      confirmNewPasswordPlaceholder: 'Bekräfta nytt lösenord',
+      leaveBlankToKeep: 'lämna tomt för att behålla nuvarande',
+      groups: 'Grupper',
+      optional: 'valfritt',
+      autoGeneratedPassword: 'Ett säkert lösenord kommer att genereras automatiskt och skickas via e-post till användaren.',
+      passwordManagedByAdvancedAuth: 'Lösenordet hanteras av avancerad autentisering. Använd "Återställ lösenord" för att skicka ett nytt lösenord till användaren via e-post.',
+      resetPassword: 'Återställ lösenord',
+      resettingPassword: 'Återställer lösenord...',
+    },
+    deleteModal: {
+      title: 'Ta bort användare',
+      message: 'Är du säker på att du vill ta bort denna användare? Denna åtgärd kan inte ångras.',
+      confirm: 'Ta bort användare',
+    },
+  },
+
+  // Stream overlay
+  streamOverlay: {
+    title: 'Strömöverlägg',
+    invalidPrinterId: 'Ogiltigt skrivar-ID',
+    cameraStream: 'Kameraström',
+    progress: 'Förlopp',
+    eta: 'Beräknad tid',
+    printerIdle: 'Skrivaren är inaktiv',
+    printerOffline: 'Skrivare offline',
+    builder: {
+      title: 'Strömningsöverlägg',
+      description: 'Bygg URL:en för ett strömningsöverlägg — en helskärmskameravy med live utskriftsdata som visas ovanpå. Välj de fält du vill ha och kopiera URL:en.',
+      printer: 'Skrivare',
+      size: 'Textstorlek',
+      sizeSmall: 'Liten',
+      sizeMedium: 'Mellanstor',
+      sizeLarge: 'Stor',
+      fps: 'Bildfrekvens',
+      fpsHint: 'A1- och P1-kameror når upp till cirka 5 fps oavsett vad du anger.',
+      token: 'Strömningsöverläggs-token (valfritt)',
+      tokenHint: 'Krävs endast när inloggning är aktiverad: OBS har ingen egen session. Skapa en ovan med strömningsöverläggsomfång.',
+      tokenWarning: 'Denna URL innehåller en token — vem som helst som kan läsa den kan titta på strömmen och se filnamnet. Återkalla token för att blockera den.',
+      fields: 'Fält att visa',
+      fieldPrinter: 'Skrivarnamn',
+      fieldFilename: 'Filnamn',
+      fieldStatus: 'Status',
+      fieldProgress: 'Förloppsindikator',
+      fieldLayers: 'Antal skikt',
+      fieldEta: 'Återstående tid och beräknad tid',
+      fieldCamera: 'Kameramatning',
+      chamberHint: 'Kammartemperatur visas endast på modeller med en riktig kammarsensor — P1- och A1-skrivare rapporterar ett meningslöst värde, så det utelämnas där.',
+      urlTitle: 'Överläggs-URL',
+      open: 'Öppna',
+      showPreview: 'Visa förhandsvisning',
+      hidePreview: 'Dölj förhandsvisning',
+      previewTitle: 'Förhandsvisning av överlägg',
+    },
+    status: {
+      printing: 'Skriver ut',
+      paused: 'Pausad',
+      finished: 'Slutförd',
+      failed: 'Misslyckad',
+      idle: 'Inaktiv',
+      unknown: 'Okänd',
+    },
+  },
+
+  // Profiles
+  profiles: {
+    title: 'Profiler',
+    subtitle: 'Hantera dina slicer-inställningar och tryckkalibreringar',
+    tabs: {
+      bambuCloud: 'Bambu Cloud',
+      orcaCloud: 'Orca Cloud',
+      local: 'Lokala profiler',
+      kprofiles: 'K-profiler',
+    },
+    orcaCloud: {
+      connectedAs: 'Ansluten som',
+      connectedShort: 'Ansluten till Orca Cloud',
+      logout: 'Koppla från',
+      noLogoutPermission: 'Du har inte behörighet att koppla från',
+      noConnectPermission: 'Du har inte behörighet att ansluta till Orca Cloud',
+      retry: 'Försök igen',
+      connectButton: 'Anslut till Orca Cloud',
+      connect: {
+        title: 'Anslut till Orca Cloud',
+        description: 'Logga in på ditt Orca Cloud-konto för att synkronisera dina slicer-profiler till Bambuddy.',
+      },
+      device: {
+        title: 'Godkänn Bambuddy i Orca Cloud',
+        instruction: 'Öppna Orca Cloud och godkänn denna kod. Bambuddy ansluter automatiskt när du godkänner.',
+        codeLabel: 'Din parningskod',
+        openButton: 'Öppna Orca Cloud-godkänningssida',
+        manualHint: 'Eller gå till {{url}} och ange koden ovan.',
+        waiting: 'Väntar på att du godkänner...',
+        cancel: 'Avbryt',
+      },
+      profiles: {
+        title: 'Dina Orca Cloud-profiler ({{count}})',
+        refresh: 'Uppdatera',
+        empty: 'Inga profiler hittade i ditt Orca Cloud-konto än.',
+      },
+      toast: {
+        disconnected: 'Kopplad från Orca Cloud',
+      },
+      errors: {
+        startFailed: 'Kunde inte starta Orca Cloud-parning.',
+        denied: 'Parningen nekades i Orca Cloud.',
+        expired: 'Parningskoden har löpt ut. Klicka på Anslut för att försöka igen.',
+        pollFailed: 'Förlorade anslutningen medan vi väntade på godkännande. Försök igen.',
+      },
+    },
+    localProfiles: {
+      title: 'Lokala profiler',
+      subtitle: 'Importera och hantera slicer-inställningar från OrcaSlicer',
+      import: 'Importera profiler',
+      importDesc: 'Släpp .bbscfg, .bbsflmt, .orca_filament, .zip eller .json-filer här',
+      importing: 'Importerar...',
+      search: 'Sök lokala förinställningar...',
+      noPresets: 'Inga lokala förinställningar än',
+      noSearchResults: 'Inga förinställningar matchar din sökning',
+      badge: 'Lokal',
+      edit: 'Redigera',
+      delete: 'Ta bort',
+      cancel: 'Avbryt',
+      deleteConfirmTitle: 'Ta bort förinställning',
+      deleteConfirm: 'Är du säker på att du vill ta bort denna förinställning? Detta kan inte ångras.',
+      source: 'Källa',
+      inheritsFrom: 'Ärver',
+      filamentType: 'Typ',
+      vendor: 'Leverantör',
+      compatiblePrinters: 'Skrivare',
+      nozzleTemp: 'Munstyckstemperatur',
+      cost: 'Kostnad',
+      density: 'Densitet',
+      pressureAdvance: 'Tryckförskott',
+      filament: 'Filament',
+      process: 'Process',
+      printer: 'Skrivare',
+      toast: {
+        importSuccess: '{{count}} förinställning(ar) importerade',
+        importSkipped: '{{count}} förinställning(ar) hoppade över (dubbletter)',
+        importError: '{{count}} fel under import',
+        deleted: 'Förinställning borttagen',
+        updated: 'Förinställning uppdaterad',
+      },
+    },
+    connectedAs: 'Ansluten som',
+    signInExpiredTitle: 'Bambu Cloud-inloggning har löpt ut',
+    signInExpiredBody: 'Bambu Lab accepterar inte längre lagrad token. Logga in igen för att återställa molnprofiler, MakerWorld-import och firmware-kontroller.',
+    logout: 'Logga ut',
+    noLogoutPermission: 'Du har inte behörighet att logga ut',
+    failedToLoad: 'Kunde inte ladda profiler',
+    retry: 'Försök igen',
+    time: {
+      justNow: 'Just nu',
+      minsAgo: '{{count}}m sedan',
+      hoursAgo: '{{count}}t sedan',
+      daysAgo: '{{count}}d sedan',
+    },
+    toast: {
+      loggedOut: 'Utloggad',
+    },
+    login: {
+      title: 'Anslut till Bambu Cloud',
+      subtitle: 'Synkronisera dina slicer-inställningar över enheter',
+      email: 'E-post',
+      password: 'Lösenord',
+      region: 'Region',
+      regionGlobal: 'Global',
+      regionChina: 'Kina',
+      verificationCode: 'Verifieringskod',
+      totpCode: 'Autentiseringskod',
+      checkEmail: 'Kontrollera din e-post ({{email}}) för en 6-siffrig kod',
+      enterTotpHint: 'Ange den 6-siffriga koden från din autentiseringsapp',
+      accessToken: 'Åtkomsttoken',
+      accessTokenHint: 'Klistra in din Bambu Cloud-åtkomsttoken. Konton i Kina måste använda denna metod (telefonbundet — e-postinloggning ej tillgänglig). Se wikin för hur du hämtar token från MakerWorld-cookies.',
+      back: 'Tillbaka',
+      loginButton: 'Logga in',
+      verifyButton: 'Verifiera',
+      setTokenButton: 'Sätt token',
+      useToken: 'Använd åtkomsttoken istället',
+      captchaTitle: 'Bambu Cloud begär en CAPTCHA',
+      captchaBody: 'Bambu utmanar ditt nätverk innan det accepterar en inloggning, och utmaningen kan inte besvaras från Bambuddy. Ditt e-post och lösenord är inte problemet. Blockeringen är kopplad till din offentliga IP-adress och brukar lösa sig själv inom några timmar — upprepade försök gör att den varar längre. För att logga in nu, använd en åtkomsttoken från en webbläsarsession istället.',
+      useEmail: 'Logga in med e-post istället',
+      toast: {
+        loggedIn: 'Inloggad',
+        codeSent: 'Verifieringskod skickad till din e-post',
+        enterTotp: 'Ange kod från din autentiseringsapp',
+        tokenSet: 'Token inställd',
+      },
+    },
+    presets: {
+      myPreset: 'Min förinställning (redigerbar)',
+      duplicate: 'Duplicera',
+      editable: 'Redigerbar',
+      failedToLoadDetails: 'Kunde inte ladda förinställningsdetaljer',
+      deleteConfirm: 'Ta bort denna förinställning?',
+      deleteWarning: 'Detta kommer permanent ta bort "{{name}}" från Bambu Cloud. Detta kan inte ångras.',
+      noDuplicatePermission: 'Du har inte behörighet att duplicera förinställningar',
+      noEditPermission: 'Du har inte behörighet att redigera förinställningar',
+      noDeletePermission: 'Du har inte behörighet att ta bort förinställningar',
+      types: {
+        filament: 'Filamentförinställning',
+        printer: 'Skrivarförinställning',
+        process: 'Processförinställning',
+      },
+      toast: {
+        deleted: 'Förinställning borttagen',
+        created: 'Förinställning skapad',
+        updated: 'Förinställning uppdaterad',
+        duplicated: 'Förinställning duplicerad',
+        fieldAdded: 'Fält "{{key}}" tillagt',
+        exported: 'Förinställning exporterad',
+      },
+      baseLabel: 'Bas: {{name}}',
+      currentLabel: 'Nuvarande: {{name}}',
+      newPreset: 'Ny förinställning',
+      editPreset: 'Redigera förinställning',
+      duplicatePreset: 'Duplicera förinställning',
+      createNewPreset: 'Skapa ny förinställning',
+      customizeSettings: 'Anpassa inställningar för din nya förinställning',
+      compareWithBase: 'Jämför med basförinställning',
+      compare: 'Jämför',
+      // CreatePresetModal - Basic Info
+      basePreset: 'Basförinställning',
+      selectBasePreset: 'Välj basförinställning...',
+      presetName: 'Förinställningsnamn',
+      myCustomPreset: 'Min anpassade förinställning',
+      inheritsFrom: 'Ärver',
+      dropJsonToImport: 'Släpp JSON för att importera',
+      // CreatePresetModal - Tabs
+      tabs: {
+        common: 'Allmänna',
+        allFields: 'Alla fält',
+      },
+      // CreatePresetModal - All Fields Tab
+      availableFields: 'Tillgängliga fält',
+      searchFieldsPlaceholder: 'Sök fält...',
+      noMatchingFields: 'Inga matchande fält',
+      allFieldsAdded: 'Alla fält tillagda',
+      addCustomField: 'Lägg till anpassat fält',
+      yourOverrides: 'Dina åsidosättningar',
+      noOverridesYet: 'Inga åsidosättningar än',
+      clickFieldsToAdd: 'Klicka på fält till vänster för att lägga till dem',
+      saveAsTemplate: 'Spara som mall',
+      jsonTip: 'Tips: Dra och släpp en .json-fil var som helst i denna modal för att importera inställningar',
+    },
+    cloudView: {
+      searchPlaceholder: 'Sök förinställningar...',
+      templates: 'Mallar',
+      refresh: 'Uppdatera',
+      newPreset: 'Ny förinställning',
+      clearFilters: 'Rensa filter',
+      // Compare mode
+      compareMode: 'Jämförelseläge',
+      selectAnotherPreset: 'Välj en annan {{type}}-förinställning',
+      clickTwoPresets: 'Klicka på två förinställningar av samma typ för att jämföra',
+      selectFirst: '1. Välj första',
+      selectSecond: '2. Välj andra',
+      compareNow: 'Jämför nu',
+      // Status row
+      lastSynced: 'Senast synkroniserad:',
+      showingCount: 'Visar {{showing}} av {{total}} förinställningar',
+      noPresetsFound: 'Inga förinställningar hittade',
+      // Column headers
+      columns: {
+        filament: 'Filament',
+        process: 'Process',
+        printer: 'Skrivare',
+      },
+      noFilamentPresets: 'Inga filamentförinställningar',
+      noProcessPresets: 'Inga processförinställningar',
+      noPrinterPresets: 'Inga skrivarförinställningar',
+      // Filters
+      filters: {
+        type: 'Typ',
+        owner: 'Ägare',
+        printer: 'Skrivare',
+        nozzle: 'Munstycke',
+        filament: 'Filament',
+        layer: 'Skikt',
+        all: 'Alla',
+        myPresets: 'Mina förinställningar',
+        builtIn: 'Inbyggda',
+        process: 'Process',
+      },
+      // Permissions
+      noTemplatesPermission: 'Du har inte behörighet att hantera mallar',
+      noRefreshPermission: 'Du har inte behörighet att uppdatera profiler',
+      noCreatePermission: 'Du har inte behörighet att skapa förinställningar',
+    },
+    templates: {
+      title: 'Snabbmallar',
+      noTemplates: 'Inga mallar än',
+      createFirst: 'Skapa mallar från förinställningseditorn',
+      typeFilter: 'Typ:',
+      deleteTitle: 'Ta bort mall',
+      deleteWarning: 'Denna åtgärd kan inte ångras',
+      deleteConfirm: 'Är du säker på att du vill ta bort "{{name}}"?',
+      namePlaceholder: 'Mallnamn',
+      descriptionPlaceholder: 'Beskrivning',
+      settingsJson: 'Inställningar (JSON)',
+      fieldsCount: '{{count}} fält',
+      shownInModals: 'Visas i modaler',
+      hiddenInModals: 'Dold i modaler',
+      apply: 'Tillämpa',
+      toast: {
+        deleted: 'Mall borttagen',
+        updated: 'Mall uppdaterad',
+        created: 'Mall skapad',
+        applied: 'Mall tillämpad',
+      },
+    },
+  },
+
+  // Support/Debug
+  support: {
+    debugLoggingActive: 'Felsökningsloggning är aktiv',
+    manageLogs: 'Hantera',
+    collectItem7: 'Skrivaranslutning och firmwareversioner',
+    collectItem8: 'Integrationsstatus (Spoolman, MQTT, HA)',
+    collectItem9: 'Nätverksgränssnitt (endast subnät)',
+    collectItem10: 'Python-paketversioner',
+    collectItem11: 'Databashälsokontroller',
+    collectItem12: 'Docker-miljödetaljer',
+    bundleGenerating: 'Genererar paket...',
+    bundleStepConnection: 'Kör skrivaranslutningskontroller',
+    bundleStepVirtualPrinters: 'Kör kontroll av virtuella skrivare',
+    bundleStepLogScan: 'Söker i senaste loggar efter kända problem',
+    bundleStepBuild: 'Bygger supportpaket-ZIP',
+  },
+
+  // File manager
+  fileManager: {
+    variants: {
+      badge: '{{count}} versioner',
+      groupAction: 'Gruppera som versioner',
+      groupTooltip: 'Markera dessa filer som samma jobb slicade för olika skrivare',
+      grouped: 'Grupperade {{count}} filer som versioner',
+      printAlternatives: 'Skriv ut ({{count}} alternativ)',
+    },
+    title: 'Filhanterare',
+    subtitle: 'Organisera och hantera dina utskriftsfiler',
+    uploadFiles: 'Ladda upp filer',
+    newFolder: 'Ny mapp',
+    folderName: 'Mappnamn',
+    folderNamePlaceholder: 't.ex. Funktionella delar',
+    renameFile: 'Döp om fil',
+    renameFolder: 'Döp om mapp',
+    invalidFilenameChar: 'Tecknet "{{char}}" är inte tillåtet i utskriftsfilnamn. Skrivarens SD-kort avvisar: < > : " / \\ | ? *',
+    moveFiles: 'Flytta {{count}} fil(er)',
+    rootNoFolder: 'Rot (ingen mapp)',
+    current: 'nuvarande',
+    linkFolder: 'Länka mapp',
+    linkFolderDescription: 'Länka "{{name}}" till ett projekt eller arkiv för snabb åtkomst.',
+    project: 'Projekt',
+    archive: 'Arkiv',
+    noProjectsFound: 'Inga projekt hittade',
+    noArchivesFound: 'Inga arkiv hittade',
+    unlink: 'Avlänka',
+    link: 'Länka',
+    dragDropFiles: 'Dra och släpp filer här',
+    dropFilesHere: 'Släpp filer här',
+    releaseToUpload: 'Släpp för att ladda upp',
+    orClickToBrowse: 'eller klicka för att bläddra',
+    allFileTypesSupported: 'Alla filtyper stöds. ZIP-filer kommer att packas upp.',
+    zipFilesDetected: 'ZIP-filer upptäckta',
+    zipExtractOptions: 'ZIP-filer kommer att packas upp. Välj hur du vill hantera mappstrukturen:',
+    preserveZipStructure: 'Bevara mappstruktur från ZIP',
+    createFolderFromZip: 'Skapa mapp från ZIP-filnamn',
+    stlThumbnailGeneration: 'Generering av STL-minibilder',
+    zipMayContainStl: 'ZIP-filer kan innehålla STL-filer. Minibilder kan genereras under extraktion.',
+    thumbnailsCanBeGenerated: 'Minibilder kan genereras för STL-filer. Stora modeller kan ta längre tid att bearbeta.',
+    generateThumbnailsForStl: 'Generera minibilder för STL-filer',
+    threemfDetected: '3MF-filer upptäckta',
+    threemfExtractionInfo: 'Skrivarmodell, material, färg och utskriftsinställningar kommer automatiskt att extraheras från 3MF-filer.',
+    willBeExtracted: 'Kommer att extraheras',
+    filesExtracted: '{{count}} filer extraherade',
+    uploadComplete: 'Uppladdning slutförd: {{succeeded}} lyckades',
+    uploadFailed: 'Kunde inte ladda upp',
+    zipFilesFailed: '{{count}} filer misslyckades',
+    uploading: 'Laddar upp...',
+    changeLink: 'Ändra länk...',
+    linkTo: 'Länka till...',
+    linkToProjectOrArchive: 'Länka till projekt eller arkiv',
+    generateThumbnail: 'Generera minibild',
+    generateThumbnails: 'Generera minibilder',
+    generateThumbnailsForMissing: 'Generera minibilder för STL-filer som saknar dem',
+    gridView: 'Rutnätsvy',
+    listView: 'Listvy',
+    lowDiskSpaceWarning: 'Varning för lågt diskutrymme',
+    lowDiskSpaceDetails: 'Endast {{free}} ledigt av {{total}} totalt. Tröskelvärdet är inställt på {{threshold}} GB i inställningar.',
+    files: 'Filer',
+    folders: 'Mappar',
+    size: 'Storlek',
+    free: 'Ledigt',
+    allFiles: 'Alla filer',
+    allExternal: 'Externa',
+    externalIsEmpty: 'Inga externa filer',
+    externalEmptyDescription: 'Filer i dina länkade externa mappar kommer att visas här.',
+    wrap: 'Radbryt',
+    enableTextWrapping: 'Aktivera radbrytning',
+    disableTextWrapping: 'Inaktivera radbrytning',
+    collapse: 'Fäll in',
+    collapseFoldersByDefault: 'Fäll in mappar som standard',
+    expandFoldersByDefault: 'Fäll ut mappar som standard',
+    folderSort: 'Sortera mappar',
+    folderSortByName: 'Efter namn',
+    folderSortByActivity: 'Efter senaste aktivitet',
+    dragToResizeTooltip: 'Dra för att ändra storlek, dubbelklicka för att återställa',
+    searchFiles: 'Sök filer...',
+    searchSubfoldersHint: 'Inklusive undermappar',
+    readme: {
+      truncated: 'Avkortad',
+      show: 'Visa README',
+      hide: 'Dölj README',
+      label: 'README',
+    },
+    tags: {
+      title: 'Taggar',
+      subtitle: 'Märk filer för tvärgående filtrering — leksaker, barnsäkra, endast PETG, vad som helst.',
+      manage: 'Taggar',
+      manageTitle: 'Hantera taggkatalog',
+      add: 'Ny tagg',
+      edit: 'Döp om tagg',
+      name: 'Namn',
+      fileCount: 'Filer',
+      empty: 'Inga taggar än. Skapa en för att börja märka filer.',
+      noMatches: 'Inga matchande taggar.',
+      createPlaceholder: 't.ex. leksaker, barnsäkra, petg',
+      createButton: 'Skapa',
+      nameRequired: 'Namn krävs.',
+      searchPlaceholder: 'Filtrera taggar...',
+      created: 'Tagg skapad.',
+      updated: 'Tagg omdöpt.',
+      deleted: 'Tagg borttagen.',
+      saveFailed: 'Kunde inte spara tagg.',
+      deleteFailed: 'Kunde inte ta bort tagg.',
+      applyFailed: 'Kunde inte tillämpa taggar.',
+      applyAdd: 'Lägg till taggar',
+      applyRemove: 'Ta bort taggar',
+      applyAddSuccess: 'Lade till {{count}} tagg(ar) på {{files}} fil(er).',
+      applyRemoveSuccess: 'Tog bort {{count}} tagg(ar) från {{files}} fil(er).',
+      actionAdd: 'Lägg till på valda filer',
+      actionRemove: 'Ta bort från valda filer',
+      tagAction: 'Tagg',
+      bulkTitle: 'Tagga {{count}} valda fil(er)',
+      bulkTooltip: 'Lägg till eller ta bort taggar på alla valda filer.',
+      noPermission: 'Du har inte behörighet att tagga filer.',
+      filterLabel: 'Filtrerar efter:',
+      clearAll: 'Rensa alla',
+      confirmDelete: 'Ta bort tagg "{{name}}"?',
+      confirmDeleteMessage: 'Detta tar bort taggen från katalogen. Filerna behåller sina andra taggar.',
+      confirmDeleteInUseMessage: 'Denna tagg används på {{count}} fil(er). Om du tar bort den kommer taggen att tas bort från alla filer; själva filerna påverkas ej.',
+      editAria: 'Redigera {{name}}',
+      deleteAria: 'Ta bort {{name}}',
+    },
+    allTypes: 'Alla typer',
+    prints: 'Utskrifter',
+    ascending: 'Stigande',
+    descending: 'Fallande',
+    showModified: 'Visa ändringsdatum',
+    hideModified: 'Dölj ändringsdatum',
+    lastModified: 'Senast ändrad',
+    lastActivity: 'Senaste aktivitet',
+    resultsCount: 'Visar {{showing}} av {{total}} filer',
+    selectAll: 'Markera alla',
+    deselectAll: 'Avmarkera alla',
+    selected: '{{count}} valda',
+    adding: 'Lägger till...',
+    loadingFiles: 'Laddar filer...',
+    folderIsEmpty: 'Mappen är tom',
+    noFilesYet: 'Inga filer än',
+    folderEmptyDescription: 'Ladda upp filer eller flytta filer till denna mapp för att komma igång.',
+    noFilesDescription: 'Ladda upp filer för att börja organisera dina utskriftsrelaterade filer.',
+    noMatchingFiles: 'Inga matchande filer',
+    noMatchingFilesDescription: 'Inga filer matchar din aktuella sökning eller filterkriterier.',
+    clearFilters: 'Rensa filter',
+    printedCount: 'Utskrivet {{count}} gånger',
+    uploadedBy: 'Uppladdad av',
+    deleteFolder: 'Ta bort mapp',
+    deleteFile: 'Ta bort fil',
+    deleteFilesCount: 'Ta bort {{count}} filer',
+    deleteFolderConfirm: 'Är du säker på att du vill ta bort denna mapp? Alla filer inuti kommer också att tas bort.',
+    deleteFileConfirm: 'Är du säker på att du vill ta bort denna fil?',
+    deleteFilesConfirm: 'Är du säker på att du vill ta bort {{count}} valda filer? Denna åtgärd kan inte ångras.',
+    deleting: 'Tar bort...',
+    noPermissionRenameFolder: 'Du har inte behörighet att döpa om mappar',
+    noPermissionLinkFolder: 'Du har inte behörighet att länka mappar',
+    noPermissionDeleteFolder: 'Du har inte behörighet att ta bort mappar',
+    onlyEmptyFoldersDeletable: 'Du kan endast ta bort tomma mappar',
+    noPermissionPrint: 'Du har inte behörighet att skriva ut',
+    noPermissionAddToQueue: 'Du har inte behörighet att lägga till i kö',
+    noPermissionSlice: 'Du har inte behörighet att slica filer',
+    noPermissionDownload: 'Du har inte behörighet att ladda ner filer',
+    noPermissionPreview: 'Du har inte behörighet att förhandsgranska filer',
+    preview3d: '3D-förhandsgranskning',
+    noPermissionRenameFile: 'Du har inte behörighet att döpa om denna fil',
+    noPermissionGenerateThumbnail: 'Du har inte behörighet att generera minibilder',
+    noPermissionDeleteFile: 'Du har inte behörighet att ta bort denna fil',
+    noPermissionCreateFolder: 'Du har inte behörighet att skapa mappar',
+    noPermissionUpload: 'Du har inte behörighet att ladda upp filer',
+    noPermissionMoveFiles: 'Du har inte behörighet att flytta filer',
+    noPermissionDeleteFiles: 'Du har inte behörighet att ta bort filer',
+    // External folder
+    linkExternal: 'Länka extern',
+    linkExternalFolder: 'Länka extern mapp',
+    linkExternalFolderDescription: 'Montera en värdkatalog (NAS, USB, nätverksdelning) i Filhanteraren. Filerna kopieras inte — de nås direkt från den ursprungliga sökvägen.',
+    externalFolderNamePlaceholder: 't.ex. NAS-utskrifter',
+    externalPath: 'Värdsökväg',
+    externalPathHelp: 'Absolut sökväg till katalogen på Docker-värden. Måste vara bind-monterad i containern.',
+    readOnly: 'Skrivskyddad',
+    readOnlyHelp: 'förhindrar uppladdningar och borttagningar',
+    showHiddenFiles: 'Visa dolda filer (doldfiler)',
+    externalFolder: 'Extern mapp',
+    scanFolder: 'Sök',
+    toast: {
+      folderCreated: 'Mapp skapad',
+      openInSlicerFailed: 'Kunde inte öppna i slicer',
+      folderDeleted: 'Mapp borttagen',
+      fileDeleted: 'Fil borttagen',
+      filesDeleted: 'Tog bort {{count}} filer',
+      filesMoved: 'Filer flyttade',
+      folderLinked: 'Mapp länkad',
+      folderUnlinked: 'Mapp avlänkad',
+      externalFolderLinked: 'Extern mapp länkad och skannad',
+      folderScanned: 'Skanning slutförd: {{added}} tillagda, {{removed}} borttagna',
+      addedToQueue: 'Lade till {{count}} fil(er) i kön',
+      addedToQueuePartial: 'Lade till {{added}} fil(er), {{failed}} misslyckades',
+      failedToAddToQueue: 'Kunde inte lägga till filer: {{error}}',
+      fileRenamed: 'Fil omdöpt',
+      folderRenamed: 'Mapp omdöpt',
+      thumbnailsGenerated: 'Genererade {{count}} minibild(er)',
+      thumbnailsGeneratedPartial: 'Genererade {{succeeded}} minibild(er), {{failed}} misslyckades',
+      noStlMissingThumbnails: 'Inga STL-filer saknar minibilder',
+      failedToGenerateThumbnails: 'Kunde inte generera minibilder: {{error}}',
+      thumbnailGenerated: 'Minibild genererad',
+      failedToGenerateThumbnail: 'Kunde inte generera minibild: {{error}}',
+    },
+  },
+
+  // Projects
+  projects: {
+    parentLabel: 'Överordnat projekt',
+    parentNone: 'Ingen (toppnivåprojekt)',
+    parentHint: 'Placera detta projekt under ett annat så att dess siffror rullas upp i ett huvudprojekt',
+    partOf: 'Del av {{name}}',
+    subProjectCount: '{{count}} delprojekt',
+    subProjectsOf: 'Delprojekt till {{name}}',
+    collapseSubProjects: 'Fäll in delprojekt',
+    expandSubProjects: 'Fäll ut delprojekt',
+    title: 'Projekt',
+    subtitle: 'Organisera och spåra dina 3D-utskriftsprojekt',
+    newProject: 'Nytt projekt',
+    editProject: 'Redigera projekt',
+    deleteProject: 'Ta bort projekt',
+    projectName: 'Projektnamn',
+    description: 'Beskrivning',
+    noProjects: 'Inga projekt än',
+    noProjectsFiltered: 'Inga {{status}}-projekt',
+    noProjectsFilteredHelp: 'Du har inga {{status}}-projekt. Projekt kommer att visas här när deras status ändras.',
+    createFirst: 'Skapa ditt första projekt för att börja organisera relaterade utskrifter, spåra framsteg och hantera dina byggen.',
+    createFirstButton: 'Skapa ditt första projekt',
+    create: 'Skapa',
+    files: 'Filer',
+    prints: 'Utskrifter',
+    plates: 'plattor',
+    parts: 'delar',
+    lastModified: 'Senast ändrad',
+    deleteConfirm: 'Är du säker på att du vill ta bort detta projekt? Arkiv och köposter kommer att avlänkas men inte tas bort.',
+    addFiles: 'Lägg till filer',
+    removeFile: 'Ta bort fil',
+    viewDetails: 'Visa detaljer',
+    // Modal fields
+    namePlaceholder: 't.ex. Voron 2.4 bygge',
+    descriptionPlaceholder: 'Valfri beskrivning...',
+    urlLabel: 'URL',
+    urlPlaceholder: 'https://makerworld.com/...',
+    urlInvalid: 'URL måste börja med http:// eller https://',
+    openExternalUrl: 'Öppna projekt-URL',
+    coverImageLabel: 'Omslagsbild',
+    coverImageAlt: 'Projektomslagsbild',
+    coverImageUpload: 'Ladda upp',
+    coverImageReplace: 'Ersätt',
+    coverImageRemove: 'Ta bort',
+    color: 'Färg',
+    targetPlates: 'Målplattor',
+    targetPlatesPlaceholder: 't.ex. 25',
+    targetPlatesHelp: 'Antal utskriftsjobb',
+    targetParts: 'Måldelar',
+    targetPartsPlaceholder: 't.ex. 150',
+    targetPartsHelp: 'Totalt antal objekt som behövs',
+    targetSets: 'Kopior per fil',
+    targetSetsPlaceholder: 't.ex. 10',
+    targetSetsHelp: 'Antal gånger varje utskriftsbar fil ska skrivas ut',
+    tagsLabel: 'Taggar (komma-separerade)',
+    tagsPlaceholder: 't.ex. voron, funktionella, present',
+    dueDate: 'Förfallodatum',
+    priority: 'Prioritet',
+    priorityLow: 'Låg',
+    priorityNormal: 'Normal',
+    priorityHigh: 'Hög',
+    priorityUrgent: 'Brådskande',
+    // Status
+    statusActive: 'Aktivt',
+    statusCompleted: 'Slutfört',
+    statusArchived: 'Arkiverat',
+    done: 'Klar',
+    completed: 'slutförd',
+    failed: 'misslyckad',
+    inQueue: 'i kö',
+    noPrintsYet: 'Inga utskrifter än',
+    // Footer stats
+    printJobs: 'Utskriftsjobb (plattor)',
+    partsPrinted: 'Delar utskrivna',
+    failedParts: 'Misslyckade delar',
+    // Actions
+    import: 'Importera',
+    export: 'Exportera',
+    importProject: 'Importera projekt',
+    exportAll: 'Exportera alla projekt',
+    loading: 'Laddar projekt...',
+    // Permissions
+    noEditPermission: 'Du har inte behörighet att redigera projekt',
+    noDeletePermission: 'Du har inte behörighet att ta bort projekt',
+    noCreatePermission: 'Du har inte behörighet att skapa projekt',
+    noImportPermission: 'Du har inte behörighet att importera projekt',
+    noExportPermission: 'Du har inte behörighet att exportera projekt',
+    // Toast
+    toast: {
+      created: 'Projekt skapat',
+      updated: 'Projekt uppdaterat',
+      deleted: 'Projekt borttaget',
+      imported: 'Projekt importerat',
+      multipleImported: '{{count}} projekt importerade',
+      importFailed: 'Kunde inte importera',
+      exported: 'Projekt exporterade (endast metadata)',
+    },
+  },
+
+  // Project detail page
+  projectDetail: {
+    notFound: 'Projekt hittades ej',
+    backToProjects: 'Tillbaka till projekt',
+    export: 'Exportera',
+    exportProject: 'Exportera projekt',
+    noExportPermission: 'Du har inte behörighet att exportera projekt',
+    noEditPermission: 'Du har inte behörighet att redigera projekt',
+    partOf: 'Del av:',
+    priorityLabel: 'Prioritet:',
+    noPrints: 'Inga utskrifter i detta projekt än',
+    status: {
+      active: 'Aktivt',
+      completed: 'Slutfört',
+      archived: 'Arkiverat',
+    },
+    priority: {
+      low: 'Låg',
+      normal: 'Normal',
+      high: 'Hög',
+      urgent: 'Brådskande',
+    },
+    dueDate: {
+      overdue: 'Försenad',
+      today: 'Förfaller idag',
+      daysLeft: '{{count}} dagar kvar',
+    },
+    progress: {
+      platesProgress: 'Plattförlopp',
+      partsProgress: 'Delförlopp',
+      setsProgress: 'Kompletta set',
+      sets: 'set',
+      setsHint: 'Ett set är komplett när varje utskriftsbar fil har nått detta antal',
+      printJobs: 'utskriftsjobb',
+      parts: 'delar',
+      percentComplete: '{{percent}}% klar',
+      remaining: '{{count}} återstående',
+    },
+    stats: {
+      printJobs: 'Utskriftsjobb',
+      total: 'totalt',
+      failed: '{{count}} misslyckade',
+      partsPrinted: '{{count}} delar utskrivna',
+      printTime: 'Utskriftstid',
+      filamentUsed: 'Filament använt',
+    },
+    cost: {
+      title: 'Kostnadsspårning',
+      filamentCost: 'Filamentkostnad',
+      energy: 'Energi',
+      totalCost: 'Uppskattad kostnad',
+      total: 'Totalt',
+      includesBom: 'inkl. BOM',
+      budget: 'Budget',
+      remaining: 'Återstående',
+    },
+    subProjects: {
+      title: 'Delprojekt ({{count}})',
+      jobs: '{{count}} jobb',
+    },
+    rollup: {
+      title: 'Inkluderar {{count}} delprojekt',
+      progress: 'Total förlopp',
+      percentComplete: '{{percent}}% klar',
+    },
+    notes: {
+      title: 'Anteckningar',
+      noEditPermission: 'Du har inte behörighet att redigera anteckningar',
+      placeholder: 'Lägg till anteckningar om detta projekt...',
+      empty: 'Inga anteckningar än. Klicka på Redigera för att lägga till anteckningar.',
+    },
+    files: {
+      title: 'Filer',
+      linkFolders: 'Länka mappar från Filhanteraren',
+      forQuickAccess: 'till detta projekt för snabb åtkomst.',
+      fileCount: '{{count}} fil(er)',
+      empty: 'Inga mappar länkade. Gå till Filhanteraren och länka en mapp till detta projekt.',
+      printedCount: 'Utskrivet {{count}} gång(er)',
+      progressTooltip: '{{done}} av {{target}} slutförda utskrifter',
+      noFiles: 'Inga filer i denna mapp.',
+    },
+    bom: {
+      title: 'Materialförteckning',
+      acquired: '{{completed}}/{{total}} anskaffade',
+      showAll: 'Visa alla',
+      hideDone: 'Dölj klara',
+      addPart: 'Lägg till del',
+      noAddPermission: 'Du har inte behörighet att lägga till delar',
+      partNamePlaceholder: 'Delnamn (t.ex. M3x8 skruvar)',
+      partName: 'Delnamn',
+      qty: 'Antal',
+      price: 'Pris ({{currency}})',
+      sourcingUrlPlaceholder: 'Inköps-URL (valfritt)',
+      remarksPlaceholder: 'Anteckningar (valfritt)',
+      deletePart: 'Ta bort del',
+      deleteConfirm: 'Är du säker på att du vill ta bort "{{name}}"?',
+      noUpdatePermission: 'Du har inte behörighet att uppdatera delar',
+      noEditPermission: 'Du har inte behörighet att redigera delar',
+      noDeletePermission: 'Du har inte behörighet att ta bort delar',
+      totalCost: 'Total kostnad:',
+      empty: 'Inga delar i materialförteckningen. Lägg till hårdvara, elektronik eller andra komponenter för att spåra vad som behöver anskaffas.',
+    },
+    timeline: {
+      title: 'Aktivitetstidslinje',
+      empty: 'Ingen aktivitet än.',
+    },
+    template: {
+      saveAsTemplate: 'Spara som mall',
+      noCreatePermission: 'Du har inte behörighet att skapa mallar',
+    },
+    queue: {
+      title: 'Kö',
+      viewAll: 'Visa alla',
+      printing: '{{count}} skriver ut',
+      queued: '{{count}} i kö',
+    },
+    prints: {
+      title: 'Utskrifter ({{count}})',
+    },
+    toast: {
+      projectUpdated: 'Projekt uppdaterat',
+      partAdded: 'Del tillagd',
+      partRemoved: 'Del borttagen',
+      exportFailed: 'Kunde inte exportera',
+      projectExported: 'Projekt exporterat',
+      templateCreated: 'Mall skapad',
+    },
+  },
+
+  // System info
+  system: {
+    title: 'Systeminformation',
+    version: 'Version',
+    uptime: 'Driftstid',
+    cpuUsage: 'CPU-användning',
+    memoryUsage: 'Minnesanvändning',
+    diskUsage: 'Diskanvändning',
+    networkInfo: 'Nätverksinformation',
+    logs: 'Loggar',
+    debugMode: 'Felsökningsläge',
+    enableDebug: 'Aktivera felsökningsloggning',
+    disableDebug: 'Inaktivera felsökningsloggning',
+    downloadLogs: 'Ladda ner loggar',
+    clearLogs: 'Rensa loggar',
+    dockerInfo: 'Docker-information',
+    containerName: 'Container-namn',
+    imageName: 'Avbildsnamn',
+    platform: 'Plattform',
+    architecture: 'Arkitektur',
+  },
+
+  // Sponsor surface (System page)
+  sponsors: {
+    sectionTitle: 'Oberoende och community-finansierat',
+    tagline: 'Bambuddy är gratis och förblir det tack vare att människor väljer att stödja det. Inga riskkapitalister, ingen molninlåsning.',
+    viewSupporters: 'Visa supporters',
+    toastPrints: 'Du har slutfört {{count}} utskrifter med Bambuddy. Bambuddy förblir gratis tack vare sina supporters.',
+    toastCost: 'Du har spårat {{total}} i filament med Bambuddy. Se vilka som håller projektet oberoende.',
+    toastArchives: '{{count}} utskrifter arkiverade med Bambuddy. Se vilka som håller det oberoende.',
+    toastAnniversary: 'Ett år med Bambuddy! Se vilka som håller projektet oberoende.',
+    toastVersionUpdate: 'Uppdaterad till v{{version}}. Bambuddy förblir gratis tack vare sina supporters.',
+    toastBusiness: 'Kör du Bambuddy på {{count}} skrivare? Det finns ett supportavtal för team — prioriterade åtgärder, fakturering och direktkontakt med underhållaren.',
+    businessCta: 'Bambuddy för företag',
+    businessTitle: 'Bambuddy för företag',
+    businessTagline: 'Du kör {{count}} skrivare. Prioriterad support, kommersiell licensiering och fakturering är tillgängliga för team och utskriftsfarmar.',
+  },
+
+  // Library (K Profiles)
+  library: {
+    title: 'Filamentbibliotek',
+    addFilament: 'Lägg till filament',
+    editFilament: 'Redigera filament',
+    deleteFilament: 'Ta bort filament',
+    vendor: 'Leverantör',
+    material: 'Material',
+    color: 'Färg',
+    kFactor: 'K-faktor',
+    temperature: 'Temperatur',
+    noFilaments: 'Inga filament i biblioteket',
+    deleteConfirm: 'Är du säker på att du vill ta bort detta filament?',
+    importFromPrinter: 'Importera från skrivare',
+    exportToFile: 'Exportera till fil',
+    // Slicer Pipelines run from the File Manager (#1425 PR B). The Run-with-pipeline
+    // modal is a two-step dialog: pick a pipeline, then either fire (eligibility ok)
+    // or confirm-and-fire (eligibility report shown). Lives in components/RunWithPipelineModal.tsx.
+    runWithPipeline: {
+      actionLabel: 'Kör med pipeline',
+      noPermission: 'Du har inte behörighet att köra pipelines',
+      modalTitle: 'Kör med pipeline',
+      confirmTitle: 'Bekräfta körning',
+      confirmIntro: 'Förkontroll fann problem med denna körning',
+      sourceHint: 'Källa',
+      pipelineHint: 'Pipeline',
+      targetHint: 'Mål',
+      pipelineListAria: 'Tillgängliga pipelines',
+      runAnyway: 'Kör ändå',
+      loading: 'Laddar…',
+      empty: 'Inga pipelines sparade än. Öppna slicing-dialogrutan och klicka på "Spara som pipeline" för att skapa en.',
+      noTarget: 'Ingen målskrivare inställd',
+      noTargetMessage: 'Denna pipeline har ingen målskrivare inställd. Öppna den i Inställningar för att välja en.',
+      // PR C — copies input + class-targeted pipelines.
+      copies: 'Kopierar',
+      copiesHint: 'max {{n}}',
+      classTarget: 'Alla {{model}}',
+      toast: {
+        started: 'Pipeline-körning startad',
+        failed: 'Kunde inte starta körning',
+      },
+      issue: {
+        printerNotSet: 'Ingen målskrivare inställd på denna pipeline.',
+        printerNotFound: 'Målskrivaren finns inte längre.',
+        printerDisabled: 'Målskrivaren är inaktiverad.',
+        printerOffline: 'Målskrivaren är offline.',
+        filamentType: 'Filament-fack {{slot}}: förväntade {{expected}}, AMS har {{actual}}',
+        filamentColor: 'Filament-fack {{slot}}: färg skiljer sig (förväntad {{expected}}, AMS har {{actual}})',
+        amsSlotMissing: 'AMS-fack {{slot}} inte tillgängligt på denna skrivare',
+        filamentUnverified: 'Filament-fack {{slot}} kommer från en moln-/standardförinställning och kunde inte verifieras statiskt.',
+        // PR C — class targeting
+        noClassMatches: 'Inga skrivare i denna installation matchar pipelines målskrivarklass ({{expected}}).',
+        classNotSet: 'Pipeline-målet är inställt på en skrivarklass men ingen modell valdes.',
+      },
+    },
+  },
+
+  // Slice (slicer-API integration via SliceModal)
+  slicerSettings: {
+    presetValuesOutdatedSidecar: "Visar slicer-standardvärden: din slicer-sidecar är äldre än denna funktion och kan inte rapportera en förinställnings värden. Uppdatera sidecar-bilden för att se dem. Allt du inte ändrar använder fortfarande förinställningen.",
+    presetValuesNotConfigured: "Visar slicer-standardvärden: ingen slicer-sidecar är konfigurerad, så en förinställnings värden kan inte läsas. Allt du inte ändrar använder fortfarande förinställningen.",
+    presetValuesSidecarUnavailable: "Visar slicer-standardvärden: slicer-sidecaren svarade inte, så en förinställnings värden kan inte läsas. Allt du inte ändrar använder fortfarande förinställningen.",
+    presetValuesUnavailable: "Visar slicer-standardvärden: den valda förinställningens egna värden kunde inte läsas. Allt du inte ändrar använder fortfarande förinställningen.",
+    filamentDefault: 'Standard',
+    fromFile: 'från fil',
+    fromFileHint: 'Designern ändrade detta i källfilen. Dess värde är {{value}}.',
+    fromFilePrinterCoupled: "designerns skrivare",
+    fromFilePrinterCoupledHint: 'Optimerad för den skrivare denna fil designades för — kan vara fel eller utanför intervallet på din.',
+    fromFileOverridesPreset: 'åsidosätter förinställning',
+    fromFileOverridesPresetHint:
+      'Filen sätter detta till {{value}} där förinställningen du valde använder {{preset}}. Markera endast om filen ska gälla.',
+    useFromFile: "Använd källfilens värde för {{option}}",
+    otherFromFile: 'Andra inställningar från denna fil',
+    fromFileSummary: 'Designern ändrade {{count}} processinställningar i denna fil. Endast de du markerar används.',
+    fromFileUseAll: "Använd designerns inställningar",
+    fromFileUseAllHint: "Markerar inställningar som gäller över skrivare. De som är optimerade för designerns egen skrivare, och de som definierar förinställningen du valde, förblir avmarkerade.",
+    fromFileClear: 'Rensa {{count}}',
+    loading: 'Laddar slicer-inställningar…',
+    mode: {
+      simple: 'Enkel',
+      advanced: 'Avancerad',
+      expert: 'Expert',
+    },
+    searchPlaceholder: 'Sök inställningar',
+    resetAll: 'Återställ {{count}}',
+    resetOption: 'Återställ till standard',
+    noMatches: 'Inga inställningar matchar denna sökning.',
+  },
+  slice: {
+    filamentSlotUnset: 'inte inställt',
+    processSettingsEmbedded: 'Används inte medan "Använd filens inbyggda inställningar" är på -- filens egna inställningar driver denna slicing.',
+    processSettingsInactive: 'Inaktiv',
+    presetsHidden: '{{count}} dold',
+    showAllPresets: 'Visa alla',
+    showFewerPresets: 'Visa färre',
+    processSettings: 'Processinställningar',
+    processSettingsHint: "Justera den valda förinställningen för denna slicing. Allt du inte rör förblir som förinställningen definierar det.",
+    processSettingsChanged: '{{count}} ändrades',
+    processSettingsUnchanged: 'Standardförinställningar',
+    title: 'Slica modell',
+    action: 'Slica',
+    actionAll: 'Slica alla {{count}} plattor',
+    actionAllTitle: 'Slica varje platta till en enda flerplattsutskrift (ett enda arkiv). Filamentvalet täcker alla fack som projektet definierar.',
+    allPlatesToggle: 'Slica alla {{count}} plattor',
+    slicing: 'Slicar',
+    printer: 'Skrivarprofil',
+    process: 'Processprofil',
+    filament: 'Filamentprofil',
+    filamentSlot: 'Filament {{index}} ({{type}})',
+    filamentColour: 'Filamentfärg',
+    selectPreset: '— Välj en förinställning —',
+    loadingPresets: 'Laddar förinställningar…',
+    analyzingPlateFilaments: 'Analyserar plattfilament…',
+    analyzingPlateFilamentsHint: 'Kör en förhandsgransknings-slicing för att upptäcka vilka AMS-fack denna platta använder. Cachad efteråt — omöjligt att öppna igen.',
+    previewToast: 'Analyserar {{name}} — {{elapsed}}',
+    previewWithProgress: 'Analyserar {{name}} — {{stage}} ({{percent}}%) — {{elapsed}}',
+    notUsedByPlate: '— används inte av denna platta',
+    noPresetsForSlot: 'Inga förinställningar tillgängliga',
+    otherPrinters: 'Andra skrivare',
+    presetsLoadFailed: 'Kunde inte ladda förinställningar. Öppna Inställningar → Profiler för att importera dem först.',
+    refreshPresets: 'Uppdatera',
+    refreshPresetsTitle: 'Uppdatera förinställningar — hämta de senaste moln- och buntade listorna (använd efter att ha tagit bort en förinställning i Bambu Studio eller Bambu Handy)',
+    allPresetsRequired: 'Alla förinställningar måste väljas',
+    useEmbedded: 'Använd filens inbyggda inställningar',
+    useEmbeddedHint: 'Slica den på det sätt designern ställt in den (väggar, fyllning, filament) istället för profilerna ovan. Erbjuds eftersom din skrivare matchar filens.',
+    autoOrient: 'Auto-orientera objekt',
+    autoOrientHint: 'Låt slicern vända varje objekt till dess bästa utskriftssida först. Åsidosätter det sätt modellen lades ner i filen.',
+    autoArrange: 'Auto-placera på plattan',
+    autoArrangeHint: 'Låt slicern positionera objekten så att de inte längre överlappar. Ersätter layouten som filen kom med.',
+    enqueuing: 'Skickar slicing-jobb…',
+    queued: 'Köad…',
+    failed: 'Slicing misslyckades. Kontrollera slicer-sidecar-loggarna.',
+    startedToast: 'Slicar {{name}} i bakgrunden…',
+    queuedToast: 'Köat: {{name}} — {{elapsed}}',
+    runningToast: 'Slicar {{name}} — {{elapsed}}',
+    runningWithProgress: '{{name}} — {{stage}} ({{percent}}%) — {{elapsed}}',
+    runningWithProgressMultiPlate: 'Platta {{plateIndex}} av {{plateCount}} • {{name}} — {{stage}} ({{percent}}%) — {{elapsed}}',
+    completedToast: 'Slicad {{name}}',
+    externalWriteFallbackToast: 'Sparad i det interna biblioteket: den externa mappen kunde inte skrivas till',
+    failedTitle: 'Slicing misslyckades',
+    failedToast: 'Slicing {{name}} misslyckades: {{detail}}',
+    tier: {
+      local: 'Importerad',
+      cloud: 'Bambu Cloud',
+      orcaCloud: 'Orca Cloud',
+      standard: 'Standard',
+    },
+    cloud: {
+      notAuthenticated: 'Logga in på Bambu Cloud (Inställningar → Profiler → Bambu Cloud) för att se dina förinställningar i molnet.',
+      expired: 'Bambu Cloud-session har löpt ut — logga in igen för att uppdatera dina förinställningar i molnet.',
+      unreachable: 'Bambu Cloud är otillgänglig just nu. Lokala och standardförinställningar fungerar fortfarande.',
+    },
+    orcaCloud: {
+      notAuthenticated: 'Logga in på Orca Cloud (Profiler → Orca Cloud) för att se dina Orca-förinställningar.',
+      expired: 'Orca Cloud-session har löpt ut — logga in igen för att uppdatera dina Orca-förinställningar.',
+      unreachable: 'Orca Cloud är otillgänglig just nu. Andra förinställningar fungerar fortfarande.',
+    },
+    bedType: {
+      label: 'Byggplatta',
+      auto: 'Auto (använd processförinställning)',
+      coolPlate: 'Cool Plate',
+      coolPlateSuperTack: 'Cool Plate SuperTack',
+      engineering: 'Engineering Plate',
+      highTemp: 'High Temp Plate',
+      texturedPEI: 'Texturerad PEI-platta',
+      smoothPEI: 'Slät PEI-platta',
+    },
+    // Slicer Pipelines (#1425) — apply a saved bundle or save the current pick.
+    pipelines: {
+      label: 'Pipeline',
+      applyAria: 'Tillämpa pipeline',
+      applyPrompt: 'Tillämpa pipeline…',
+      empty: 'Inga sparade pipelines',
+      saveButton: 'Spara som pipeline',
+      saveTitle: 'Spara det aktuella fyrfacks-valet som en återanvändbar pipeline',
+      namePlaceholder: 'Pipeline-namn',
+      nameAria: 'Nytt pipeline-namn',
+      toast: {
+        applied: 'Tillämpade "{{name}}"',
+        saved: 'Pipeline sparad',
+        saveFailed: 'Kunde inte spara',
+      },
+    },
+  },
+
+  // Spoolman
+  spoolman: {
+    title: 'Spoolman-integration',
+    enabled: 'Spoolman aktiverad',
+    url: 'Spoolman-URL',
+    connected: 'Ansluten',
+    disconnected: 'Inte ansluten',
+    testConnection: 'Testa anslutning',
+    sync: 'Synkronisera',
+    syncing: 'Synkroniserar…',
+    lastSync: 'Senaste synkronisering',
+    linkToSpoolman: 'Länka till Spoolman',
+    openInSpoolman: 'Öppna i Spoolman',
+    unlinkSpool: 'Avlänka rulle',
+    unlinkConfirmTitle: 'Avlänka rulle?',
+    unlinkConfirmMessage: 'Detta kommer att ta bort rullen från detta fack. Rulldatan i sig kommer att förbli oförändrad.',
+    selectSpool: 'Välj rulle',
+    noUnlinkedSpools: 'Inga olänkade rullar tillgängliga',
+    linkSuccess: 'Rulle tilldelad',
+    linkFailed: 'Kunde inte tilldela rulle',
+    unlinkSuccess: 'Rulle avlänkad',
+    unlinkFailed: 'Kunde inte avlänka rulle',
+    linkedSpool: 'Tilldelad rulle',
+    spoolId: 'Rull-ID',
+    fillSourceLabel: '(Spoolman)',
+    weight: 'Vikt',
+    remaining: 'Återstående',
+    disableWeightSync: 'Inaktivera AMS uppskattade vikt-synkronisering',
+    disableWeightSyncDesc: 'Uppdatera inte återstående kapacitet från AMS-uppskattningar. Använd detta om du föredrar Spoolmans användningsspårning framför AMS-procentbaserade uppskattningar. Nya rullar kommer fortfarande att använda AMS-uppskattningen som sin initiala vikt.',
+    reportPartialUsage: 'Rapportera partiell användning för misslyckade utskrifter',
+    reportPartialUsageDesc: 'När en utskrift misslyckas eller avbryts, rapportera den uppskattade filamentanvändningen fram till den punkten baserat på skiktförloppet.',
+  },
+
+  locations: {
+    title: 'Lagringsplatser',
+    subtitle: 'Hantera hyllor, lådor och andra fysiska lagringsplatser för dina rullar',
+    add: 'Lägg till plats',
+    addShort: 'Lägg till',
+    edit: 'Redigera plats',
+    name: 'Namn',
+    spools: 'Rullar',
+    sensors: 'Sensorer',
+    empty: 'Inga lagringsplatser än. Skapa din första hylla eller låda.',
+    manage: 'Platser',
+    createPlaceholder: 't.ex. Hylla A, Låda 1',
+    nameRequired: 'Platsnamn krävs',
+    created: 'Plats skapad',
+    updated: 'Plats uppdaterad',
+    deleted: 'Plats borttagen',
+    saveFailed: 'Kunde inte spara plats',
+    deleteFailed: 'Kunde inte ta bort plats',
+    deleteBlocked: 'Ta bort alla rullar från denna plats innan du tar bort den',
+    confirmDelete: 'Ta bort "{{name}}"?',
+    confirmDeleteMessage: 'Denna plats kommer att tas bort från katalogen. Rullar måste flyttas först.',
+    confirmDeleteMessageWithSensors:
+      'Denna plats kommer att tas bort från katalogen. Spolar måste flyttas först. Anslutna sensorer kommer också att raderas.',
+  },
+
+  // Inventory
+  inventory: {
+    title: 'Rullinventarium',
+    subtitle: 'Hantera dina rullar',
+    addToInventory: 'Lägg till i inventariet',
+    addToInventoryPending: 'Lägger till…',
+    addToInventorySuccess: 'Rulle tillagd i inventariet',
+    addToInventoryFailed: 'Kunde inte lägga till rulle i inventariet',
+    unknownSpoolTitle: 'Nytt filament upptäckt',
+    unknownSpoolMessage: 'En rulle med en okänd RFID-tagg upptäcktes på {{location}}. Lägg till den i ditt inventarium nu?',
+    unknownSpoolSlot: 'Fack',
+    bulk: {
+      selectAllVisible: 'Markera alla synliga',
+      selectRow: 'Markera rad',
+      selectGroup: 'Markera grupp',
+      selectionCount: '{{count}} valda',
+      edit: 'Redigera',
+      printLabels: 'Skriv ut etiketter',
+      resetUsage: 'Återställ användning',
+      restore: 'Återställ',
+      archive: 'Arkivera',
+      delete: 'Ta bort',
+      clearSelection: 'Rensa val',
+      editTitle: 'Massredigera rullar',
+      editSubtitle: 'Tillämpas på {{count}} valda rullar. Endast de fält du markerar kommer att uppdateras.',
+      editHint: 'Skriv i ett fält för att markera det för uppdatering — endast markerade rader skickas. Lämna ett fält tomt för att behålla rullarna oförändrade (rensning av fält är endast per rulle).',
+      useCustom: 'Använd "{{value}}"',
+      toggleField: 'Växla uppdatering för detta fält',
+      changeCount: '{{count}} fält kommer att uppdateras.',
+      applyPending: 'Tillämpar…',
+      applyButton: 'Tillämpa på {{count}} rullar',
+      deleteTitle: 'Ta bort valda rullar',
+      archiveTitle: 'Arkivera valda rullar',
+      restoreTitle: 'Återställ valda rullar',
+      resetUsageTitle: 'Återställ användning på valda rullar',
+      deleteMessage: 'Ta bort {{count}} rullar permanent? Detta kan inte ångras.',
+      archiveMessage: 'Arkivera {{count}} rullar? De kan återställas senare.',
+      restoreMessage: 'Återställ {{count}} arkiverade rullar?',
+      resetUsageMessage: 'Återställ "Totalt förbrukat"-räknaren på {{count}} rullar? Återstående vikt bevaras.',
+      updateSuccess: '{{count}} rullar uppdaterade',
+      updateFailed: 'Kunde inte uppdatera',
+      updatePartial: '{{ok}} rullar uppdaterade, {{failed}} misslyckades',
+      updateAllFailed: 'Alla {{count}} rulluppdateringar misslyckades — val bevaras så att du kan försöka igen',
+      deleteSuccess: '{{count}} rullar borttagna',
+      deleteFailed: 'Kunde inte ta bort',
+      deletePartial: '{{ok}} rullar borttagna, {{failed}} misslyckades',
+      deleteAllFailed: 'Alla {{count}} rullborttagningar misslyckades — val bevaras så att du kan försöka igen',
+      archiveSuccess: '{{count}} rullar arkiverade',
+      archiveFailed: 'Kunde inte arkivera',
+      archivePartial: '{{ok}} rullar arkiverade, {{failed}} misslyckades',
+      archiveAllFailed: 'Alla {{count}} rullarkiveringar misslyckades — val bevaras så att du kan försöka igen',
+      restoreSuccess: '{{count}} rullar återställda',
+      restoreFailed: 'Kunde inte återställa',
+      restorePartial: '{{ok}} rullar återställda, {{failed}} misslyckades',
+      restoreAllFailed: 'Alla {{count}} rullåterställningar misslyckades — val bevaras så att du kan försöka igen',
+      invalidHex: 'Ange 6 hex-tecken (RRGGBB) eller 8 (RRGGBBAA). Fältet kommer inte att tillämpas annars.',
+    },
+    spoolmanMixedContentTitle: 'Spoolman kan inte laddas över HTTPS — blandat innehåll blockeras av din webbläsare',
+    spoolmanMixedContentBody: 'Bambuddy serveras över HTTPS (via din omvända proxy), men din Spoolman-URL är fortfarande vanlig HTTP. Webbläsare blockerar blandat innehåll av säkerhetsskäl, så det inbäddade Spoolman-gränssnittet kan inte renderas. Spoolman måste vara åtkomligt över HTTPS för att detta ska fungera.',
+    spoolmanMixedContentFixReverseProxy: 'Placera Spoolman bakom samma omvända proxy som Bambuddy (Traefik / Nginx / Caddy) med HTTPS, uppdatera sedan Spoolman-URL:en i Inställningar till den nya HTTPS-adressen.',
+    spoolmanMixedContentFixOpenNewTab: 'För en tillfällig lösning, öppna Spoolman i en ny webbläsarflik över HTTP — regler för blandat innehåll gäller endast för inbäddade ramar, så en fristående flik fungerar fortfarande.',
+    spoolmanOpenInNewTab: 'Öppna Spoolman i en ny flik',
+    labels: {
+      title: 'Skriv ut rulletiketter',
+      selectedCount: '{{count}} valda',
+      pickSpools: 'Välj vilka rullar du vill skriva ut etiketter för:',
+      monochrome: 'Monokrom (svartvit skrivare)',
+      monochromeHint: 'Tar bort färgprovet och breddar texten',
+      startingPosition: 'Startposition för etikett',
+      startingPositionRange: 'Endast arkmallar: L7160 stöder 1–21; 5160 stöder 1–30.',
+      startingPositionInvalid: 'Ange ett heltal från 1 till {{capacity}}.',
+      startingPositionFirst: 'Utskriften börjar vid position 1.',
+      startingPositionSkipped: 'Positionerna 1 till {{lastPosition}} lämnas tomma på det första arket.',
+      startingPositionRangeError: 'Startpositionen måste vara mellan 1 och {{capacity}} för detta ark.',
+      searchPlaceholder: 'Sök namn, märke eller #ID',
+      filterByMaterial: 'Material:',
+      allMaterials: 'Alla',
+      selectVisible: 'Markera alla synliga ({{count}})',
+      deselectVisible: 'Avmarkera synliga',
+      clearAll: 'Rensa alla',
+      noSpoolsToShow: 'Inga rullar att visa. Justera ditt filter och försök igen.',
+      noMatches: 'Inga rullar matchar den aktuella sökningen eller filtren.',
+      printOne: 'Skriv ut etikett för denna rulle',
+      printLabels: 'Skriv ut etiketter…',
+      bulkTitle: 'Välj rullar för att skriva ut etiketter från de {{count}} som visas',
+      noSpoolsTitle: 'Inga rullar att göra etikett för',
+      error: 'Kunde inte generera etiketter: {{msg}}',
+      sortBy: {
+        label: 'Sortera:',
+        id: 'Efter ID',
+        color: 'Efter färg',
+      },
+      templates: {
+        amsHolderSmall: {
+          label: 'AMS-hållare — liten (74 × 33 mm)',
+          hint: 'En etikett per sida; matchar den utskrivbara etiketten från MakerWorld-modell 752566 (AMS Filament Label Holder).',
+        },
+        amsHolderLarge: {
+          label: 'AMS-hållare — stor (75 × 55 mm)',
+          hint: 'En etikett per sida; passar varianten med pappersinsats av AMS Filament Label Holder. Tillräckligt med utrymme för färgprov, märke, material, ID och QR-kod.',
+        },
+        box40x30: {
+          label: 'Lådetikett (40 × 30 mm)',
+          hint: 'En etikett per sida; vanlig DK/Brother-rullstorlek, bra för filamentpåse- och lagringslådetiketter.',
+        },
+        box: {
+          label: 'Lådetikett (62 × 29 mm)',
+          hint: 'En etikett per sida; storlek för Brother PT/QL och Dymo små etiketter.',
+        },
+        averyL7160: {
+          label: 'Avery L7160 — A4-ark (38,1 × 63,5 mm × 21)',
+          hint: 'EU-ark; 21 etiketter per A4-sida.',
+        },
+        avery5160: {
+          label: 'Avery 5160 — US Letter-ark (25,4 × 66,7 mm × 30)',
+          hint: 'US-ark; 30 etiketter per Letter-sida.',
+        },
+      },
+    },
+    csv: {
+      importButton: 'Importera CSV',
+      exportButton: 'Exportera CSV',
+      modalTitle: 'Importera rullar från CSV',
+      selectFile: 'Välj en CSV-fil eller dra den hit',
+      dragHint: 'Rubrik: material (obligatoriskt), brand, subtype, color_name, rgba, …',
+      parsing: 'Läser fil…',
+      previewError: 'Kunde inte läsa CSV-filen',
+      validCount: '{{count}} giltiga',
+      errorCount: '{{count}} fel',
+      skippedCount: '{{count}} hoppade över',
+      colRow: 'Rad',
+      colStatus: 'Status',
+      colColor: 'Färg',
+      colorResolved: 'Färg ifylld från katalog',
+      colorCrossMaterial: 'Färg tagen från ett annat material — ingen exakt matchning i katalogen',
+      duplicateExisting: 'En rulle med detta material, märke och färg finns redan — den kommer fortfarande att importeras som en ny rulle',
+      spoolmanHint: 'I Spoolman-läge, använd Spoolmans inbyggda CSV-import/export.',
+      importValidRows: 'Importera {{count}} giltiga rader',
+      noValidRows: 'Inga giltiga rader',
+      importing: 'Importerar…',
+      importSuccess: '{{count}} rullar importerade',
+      importError: 'Kunde inte importera',
+      exportError: 'Kunde inte exportera',
+    },
+    addSpool: 'Lägg till rulle',
+    editSpool: 'Redigera rulle',
+    copySpool: 'Kopiera rulle',
+    material: 'Material',
+    selectMaterial: 'Välj material...',
+    subtype: 'Subtyp',
+    brand: 'Märke',
+    searchBrand: 'Sök märke...',
+    useCustomBrand: 'Använd "{{brand}}"',
+    useCustomMaterial: 'Använd anpassat material: {{material}}',
+    suggestedOptions: 'Föreslagna',
+    allOptions: 'Alla',
+    colorName: 'Färgnamn',
+    colorNamePlaceholder: 'Jade-vit, Eldröd...',
+    color: 'Färg',
+    hexColor: 'Hex-färg',
+    pickColor: 'Välj anpassad färg',
+    labelWeight: 'Etikettvikt',
+    coreWeight: 'Tom rullvikt',
+    searchSpoolWeight: 'Sök rullvikt...',
+    weightUsed: 'Använt',
+    currentWeight: 'Återstående vikt',
+    measuredWeight: 'Uppmätt vikt',
+    spoolName: 'Rulle',
+    costPerKg: 'Kostnad per kg',
+    storageLocation: 'Lagringsplats',
+    temperature: 'Temperatur',
+    humidity: 'Luftfuktighet',
+    battery: 'Batteri',
+    storageLocationPlaceholder: 't.ex. Hylla A, Låda 1',
+    openInInventory: 'Öppna i inventarium',
+    measuredWeightError: 'Uppmätt vikt måste vara mellan {{min}}g och {{max}}g.',
+    slicerFilament: 'Slicer-filament',
+    slicerFilamentName: 'Slicer-förinställningsnamn',
+    slicerPreset: 'Slicer-förinställning',
+    searchPresets: 'Sök filamentförinställningar...',
+    selectedPreset: 'Vald',
+    noPresetsFound: 'Inga förinställningar hittade',
+    tempOverrides: 'Temperaturåsidosättningar',
+    note: 'Anteckning',
+    notePlaceholder: 'Eventuella ytterligare anteckningar om denna rulle...',
+    // Per-spool category + low-stock threshold override (#729)
+    category: 'Kategori',
+    categoryPlaceholder: 't.ex. Produktion, Prototyp, Kund A',
+    categoryNone: 'Okategoriserad',
+    // #1400: storage-location filter chip — `storageLocation` label is
+    // already defined above for the spool-edit field, reused here for the
+    // dropdown header. `storageLocationNone` is new (the "no location set"
+    // group, mirrors `categoryNone`).
+    storageLocationNone: 'Ingen lagringsplats inställd',
+    lowStockThresholdOverride: 'Lågt lagertröskelvärde (denna rulle)',
+    lowStockThresholdOverrideHelp: 'Lämna tomt för att använda det globala tröskelvärdet ({{global}}%).',
+    // RFID button rename (was "Delete Tag" — confusing because it sounds like a
+    // taxonomy delete; this clears the RFID tag/UUID off the spool record)
+    clearRfid: 'Rensa RFID-tagg',
+    rfidCleared: 'RFID-tagg rensad',
+    archive: 'Arkivera',
+    restore: 'Återställ',
+    noSpools: 'Inga rullar än. Lägg till din första rulle för att komma igång.',
+    noAvailableSpools: 'Inga rullar tillgängliga. Lägg till en rulle i ditt inventarium eller avlänka en från ett annat fack först.',
+    kProfiles: 'K-profiler',
+    addKProfile: 'Lägg till K-profil',
+    assignSpool: 'Tilldela rulle',
+    unassignSpool: 'Avlänka',
+    assignSuccess: 'Rulle tilldelad och AMS-fack konfigurerat',
+    assignPendingInsert: 'Tilldelad. Facket kommer att konfigureras när du sätter in rullen.',
+    assignFailed: 'Kunde inte tilldela rulle',
+    selectSpool: 'Välj en rulle att tilldela detta fack',
+    assigned: 'Tilldelad',
+    assigning: 'Tilldelar…',
+    searchSpools: 'Sök rullar...',
+    showAllSpools: 'Visa alla rullar',
+    spoolmanSpools: 'Spoolman-rullar',
+    allMaterials: 'Alla material',
+    filterByBrand: 'Filtrera efter märke...',
+    showArchived: 'Visa arkiverade',
+    quickAdd: 'Snabb-lägg-till (Lager)',
+    quantity: 'Kvantitet',
+    stock: 'Lager',
+    configured: 'Konfigurerad',
+    spoolsCreated: '{{count}} rullar skapade',
+    spoolsPartiallyCreated: '{{created}} av {{total}} rullar skapade (några misslyckades)',
+    spoolCreated: 'Rulle skapad',
+    spoolUpdated: 'Rulle uppdaterad',
+    spoolDeleted: 'Rulle borttagen',
+    deepLinkSpoolNotFound: 'Rulle hittades ej',
+    deepLinkFetchFailed: 'Kunde inte ladda rulle — försök igen',
+    spoolArchived: 'Rulle arkiverad',
+    spoolRestored: 'Rulle återställd',
+    kProfileSaveFailed: 'K-profilinställningar kunde inte sparas',
+    syncWeightSpoolNotFound: 'Rulle hittades inte — den kan ha tagits bort',
+    syncWeightSpoolmanUnreachable: 'Spoolman är otillgänglig — försök igen senare',
+    syncWeightFailed: 'Kunde inte synkronisera vikt',
+    spoolmanUnreachable: 'Spoolman kan ej nås — försök igen senare',
+    deleteSpoolNotFound: 'Rulle hittades inte — den kan redan ha tagits bort',
+    deleteFailed: 'Kunde inte ta bort rulle',
+    archiveSpoolNotFound: 'Rulle hittades inte — den kan redan ha tagits bort',
+    archiveFailed: 'Kunde inte arkivera rulle',
+    restoreSpoolNotFound: 'Rulle hittades inte — den kan redan ha tagits bort',
+    restoreFailed: 'Kunde inte återställa rulle',
+    saveFailed: 'Kunde inte spara ändringar',
+    tagClearFailed: 'Kunde inte rensa tagg',
+    deleteConfirm: 'Är du säker på att du vill ta bort denna rulle? Detta kan inte ångras.',
+    archiveConfirm: 'Är du säker på att du vill arkivera denna rulle?',
+    advancedSettings: 'Avancerade inställningar',
+    // Tabs
+    filamentInfoTab: 'Filamentinformation',
+    paProfileTab: 'PA-profil',
+    colorAndCostTab: 'Färg & kostnad',
+    printersTab: 'Skrivare',
+    filamentInfo: 'Filament',
+    additional: 'Ytterligare',
+    // Cloud
+    loadingPresets: 'Laddar molnförinställningar…',
+    cloudConnected: 'Moln anslutet',
+    cloudNotConnected: 'Moln ej anslutet (använder standard)',
+    // Colors
+    recentColors: 'Senaste',
+    searchColors: 'Sök färger...',
+    searchResults: 'Sökresultat',
+    allColors: 'Alla färger',
+    commonColors: 'Vanliga färger',
+    showLess: 'Visa färre',
+    showAll: 'Visa alla',
+    noColorsFound: 'Inga färger matchar din sökning',
+    noResults: 'Inga matchningar hittade',
+    // Multi-color gradient + visual effect (#1154)
+    extraColorsLabel: 'Extra färger',
+    extraColorsPlaceholder: 'EC984C,#6CD4BC,A66EB9,D87694',
+    extraColorsHint: 'Klistra in 2 till 8 hex-stoppar, åtskilda av kommatecken. Renderas som en gradient.',
+    extraColorsInvalid: 'Ignorerade ogiltiga hex: {{tokens}}',
+    colorEffectLabel: 'Effekt',
+    colorEffect: {
+      none: 'Ingen',
+      // Surface effects
+      sparkle: 'Gnistrande',
+      wood: 'Trä',
+      marble: 'Marmor',
+      glow: 'Lysande',
+      matte: 'Matt',
+      // Sheen / finish variants
+      silk: 'Silke',
+      galaxy: 'Galax',
+      rainbow: 'Regnbåge',
+      metal: 'Metall',
+      translucent: 'Genomskinlig',
+      // Multi-color structural variants
+      gradient: 'Gradient',
+      dualColor: 'Dubbelfärg',
+      triColor: 'Trippelfärg',
+      multicolor: 'Multifärg',
+    },
+    // PA Profiles
+    selectMaterialFirst: 'Välj ett material först i fliken Filamentinformation.',
+    noPrintersConfigured: 'Inga skrivare konfigurerade. Lägg till skrivare för att använda PA-profiler.',
+    matchingFilter: 'Matchande',
+    anyBrand: 'Alla märken',
+    anyVariant: 'Alla varianter',
+    autoSelect: 'Auto-välj',
+    matches: 'matchningar',
+    match: 'matchning',
+    noMatches: 'Inga matchningar',
+    connected: 'Ansluten',
+    offline: 'Offline',
+    printerOffline: 'Skrivaren är offline. Anslut för att visa kalibreringsprofiler.',
+    noKProfilesMatch: 'Inga K-profiler matchar det valda filamentet.',
+    leftNozzle: 'Vänster munstycke',
+    rightNozzle: 'Höger munstycke',
+    profilesSelected: 'kalibreringsprofil(er) valda',
+    // Printers tab: per-model filament preset + per-hotend K profile
+    filamentPreset: 'Filamentförinställning',
+    presetUseSpoolDefault: 'Använd rullens förinställning',
+    presetInherited: 'ärvd',
+    presetOverride: 'åsidosättning',
+    presetNeedsModel: 'Den här skrivaren har inte rapporterat sin modell än, så den kan inte ha en egen förinställning.',
+    autoMatchPresets: 'Auto-matcha',
+    autoMatchPresetsHint: 'Hitta varianten av den här rullens förinställning som namnger varje modell',
+    kProfilesPerPrinter: 'K-profiler',
+    kProfileNotSet: 'Ej inställt',
+    kProfileFlowMismatch: 'Denna profil mättes på ett {{profile}} munstycke men ett {{fitted}} munstycke är monterat, så det kommer inte att appliceras',
+    nozzle: 'Munstycke',
+    unknownModel: 'Okänd modell',
+    onePrinter: '1 skrivare',
+    nPrinters: '{{n}} skrivare',
+    filamentPresetsLoadFailed: 'Det gick inte att ladda denna rullens per-modell-förinställningar',
+    filamentPresetSaveFailed: 'Det gick inte att spara per modell-förinställningarna',
+    // Stats & enhanced table
+    totalInventory: 'Total inventarium',
+    totalConsumed: 'Totalt förbrukat',
+    byMaterial: 'Efter material',
+    inPrinter: 'I skrivare',
+    lowStock: 'Lågt lager',
+    sinceTracking: 'Sedan räkning startade',
+    resetConsumedCounter: 'Återställ räknare',
+    resetConsumedCounterTooltip: 'Nollställ den förbrukade gramräknaren för denna rulle. Återstående vikt ändras ej.',
+    resetConsumedCounterConfirm: 'Återställ denna rulles förbrukade gramräknare till 0? Framtida utskrifter kommer att räknas från noll igen. Rullen själv, dess återstående viktberäkning och dina inställningar ändras ej.',
+    resetAllConsumedCounters: 'Återställ alla räknare',
+    resetAllConsumedCountersTooltip: 'Nollställ den förbrukade gramräknaren på varje rulle. Återstående vikter ändras inte.',
+    resetAllConsumedCountersConfirm: 'Återställ den förbrukade gramräknaren till 0 på alla {{count}} rullar (inklusive arkiverade)? Detta rensar "Totalt förbrukat"-statistiken så att framtida utskrifter räknas från noll. Rullar och återstående vikter ändras ej.',
+    consumedCounterReset: 'Räknare återställd',
+    allConsumedCountersReset: 'Räknare återställd för {{count}} rulle(r)',
+    resetConsumedCounterFailed: 'Kunde inte återställa räknare',
+    loadedInAms: 'Laddad i AMS/Ext',
+    remaining: 'Återstående',
+    weightCheck: 'Viktkontroll',
+    lastWeighed: 'Senast vägd',
+    neverWeighed: 'Aldrig vägd',
+    search: 'Sök rullar...',
+    showing: 'Visar',
+    to: 'till',
+    of: 'av',
+    show: 'Visa',
+    spools: 'rullar',
+    spool: 'rulle',
+    page: 'Sida',
+    noSpoolsMatch: 'Inga resultat hittade',
+    noSpoolsMatchDesc: 'Försök justera din sökning eller filter för att hitta det du letar efter.',
+    active: 'Aktiv',
+    archived: 'Arkiverad',
+    all: 'Alla',
+    used: 'Använd',
+    new: 'Ny',
+    clearFilters: 'Rensa filter',
+    table: 'Tabell',
+    cards: 'Kort',
+    net: 'Nät',
+    // Grouping
+    groupSimilar: 'Gruppera',
+    groupedSpools: '{{count}} identiska rullar',
+    groupedRows: 'rader',
+    // Column config
+    columns: 'Kolumner',
+    configureColumns: 'Konfigurera kolumner',
+    configureColumnsDesc: 'Dra för att omordna kolumner eller använd pilarna. Växla synlighet med ögonikonen.',
+    visible: 'synlig',
+    reset: 'Återställ',
+    cancel: 'Avbryt',
+    applyChanges: 'Tillämpa ändringar',
+    moveUp: 'Flytta upp',
+    moveDown: 'Flytta ner',
+    hideColumn: 'Dölj kolumn',
+    showColumn: 'Visa kolumn',
+    // Tag linking
+    linkToSpool: 'Länka till rulle',
+    tagLinked: 'Tagg länkad till rulle',
+    tagLinkFailed: 'Kunde inte länka tagg',
+    tagAlreadyLinked: 'Tagg är redan länkad till en annan rulle #{{id}}',
+    unknownTag: 'Okänd RFID-tagg upptäckt',
+    // Usage history
+    usageHistory: 'Användningshistorik',
+    noUsageHistory: 'Ingen användning registrerad än',
+    printName: 'Utskriftsnamn',
+    weightConsumed: 'Vikt förbrukat',
+    clearHistory: 'Rensa',
+    historyCleared: 'Användningshistorik rensad',
+    fillSourceLabel: '(Inv)',
+    lowStockThresholdError: 'Tröskelvärdet måste vara mellan 0,1 och 99,9',
+    assignMismatchTitle: 'Materialfelmatchning',
+    assignMismatchMessage: 'Det valda rullmaterialet "{{spoolMaterial}}" matchar inte fackmaterialet "{{trayMaterial}}" för {{location}}. Tilldela ändå?',
+    assignMismatchConfirm: 'Tilldela ändå',
+    assignPartialMismatchMessage: 'Rullmaterialet "{{spoolMaterial}}" liknar "{{trayMaterial}}" i {{location}} men matchar inte exakt. Vill du fortsätta?',
+    assignProfileMismatchMessage: 'Rullprofilen "{{spoolProfile}}" matchar inte fackprofilen "{{trayProfile}}" i {{location}}. Vill du fortsätta?',
+    assignReconfigureNote: 'AMS-facket kommer att omkonfigureras för att använda rullens profil.',
+    // Spoolman filament catalog picker
+    spoolmanFilamentCatalog: 'Spoolman Filamentkatalog',
+    pickFromSpoolmanCatalog: 'Välj från Spoolman-katalog…',
+    spoolmanFilamentSelected: 'Filament valt från Spoolman-katalog',
+    spoolmanFilamentUnlinked: 'Filamentkataloglänk rensad',
+    noSpoolmanFilaments: 'Inga filament hittade i Spoolman-katalog',
+    spoolmanFilamentColorSwatch: 'Filamentfärg',
+    spoolWeightManagedBySpoolman: 'Tom rullvikt hanteras per filamenttyp i Spoolman',
+    spoolmanCatalogLoadFailed: 'Kunde inte ladda Spoolman filamentkatalog',
+  },
+
+  // Timelapse
+  timelapse: {
+    title: 'Timelapse',
+    create: 'Skapa timelapse',
+    download: 'Ladda ner',
+    delete: 'Ta bort',
+    preview: 'Förhandsvisning',
+    frameRate: 'Bildfrekvens',
+    quality: 'Kvalitet',
+    processing: 'Bearbetar...',
+    noTimelapses: 'Inga timelapse tillgängliga',
+  },
+
+  // AMS
+  ams: {
+    title: 'AMS',
+    slot: 'Fack',
+    empty: 'Tomt',
+    emptySlot: 'Tomt fack',
+    slotEmpty: 'Tomt',
+    slotUnconfigured: '?',
+    emptySlotReset: 'Inget filament tilldelat',
+    unknown: 'Okänd',
+    humidity: 'Luftfuktighet',
+    temperature: 'Temperatur',
+    filamentType: 'Filamenttyp',
+    filamentColor: 'Färg',
+    remaining: 'Återstående',
+    history: 'AMS-historik',
+    noHistory: 'Ingen historik tillgänglig',
+    configureSlot: 'Konfigurera fack',
+    externalSpool: 'Extern rulle',
+    profile: 'Profil',
+    kFactor: 'K-faktor',
+    kFactorShort: 'K',
+    fill: 'Fyll',
+    configure: 'Konfigurera',
+    used: 'använt',
+    remainingUnit: 'återstående',
+  },
+
+  // Print modal
+  printModal: {
+    variants: {
+      editNote: 'Dessa alternativ sattes när jobbet köades. Avbryt och köa om för att ändra dem.',
+      title: 'Skrivaralternativ',
+      help: 'Ett jobb, en köplats. Den första matchande skrivaren som blir ledig kör sin fil.',
+      unknownModel: 'Okänd modell',
+      plateFor: 'Platta för {{filename}}',
+      moveUp: 'Flytta upp',
+      moveDown: 'Flytta ner',
+      queued: 'Köat med {{count}} alternativ',
+    },
+    selectPrinter: 'Välj skrivare',
+    selectPlate: 'Välj platta',
+    filamentMapping: 'Filamentmappning',
+    useArchiveMapping: 'Mappning',
+    useArchiveMappingTooltip: 'Välj alla fack från AMS-mappningen som sparades med detta arkiv (från slicern), istället för att matcha efter typ/färg.',
+    clickToChangeSlot: 'Klicka för att ändra facktilldelning',
+    reRead: 'Läs om',
+    plateN: 'Platta {{n}}',
+    plateFilamentsUnreadable: 'Filamenten för en vald platta kunde inte läsas, så den kan inte mappas. Avmarkera den för att köa de andra.',
+    totalCost: 'Total kostnad:',
+    slotRemainingShort: ' - {{grams}}g kvar',
+    printSettings: 'Utskriftsinställningar',
+    bedLeveling: 'Byggplattsnivåinställning',
+    flowCalibration: 'Flödeskalibrering',
+    vibrationCalibration: 'Vibrationskalibrering',
+    layerInspection: 'Förstaskiktsinspektion',
+    timelapse: 'Timelapse',
+    cancel: 'Avbryt',
+    noPrintersAvailable: 'Inga skrivare tillgängliga',
+    printerBusy: 'Skrivaren är upptagen',
+    printerOffline: 'Skrivaren är offline',
+    sameTypeDifferentColor: 'Samma typ, olika färg',
+    filamentTypeNotLoaded: 'Filamenttyp inte laddad',
+    statusReady: 'Redo',
+    statusColorMismatch: 'Färg matchar ej',
+    statusTypeNotFound: 'Typ hittades ej',
+    requiredTooltip: 'Kräver: {{name}} - {{color}}',
+    manuallySelected: 'Manuellt vald',
+    autoMatched: 'Auto-matchad',
+    selectSlot: 'Välj fack',
+    sameTypeDifferentColorDetail: 'Samma typ, annan färg: behöver {{required}}, facket har {{loaded}}',
+    requiredTypeNotInPrinter: 'Krävd filamenttyp hittades inte i skrivaren.',
+    whenToPrint: 'När utskriften ska starta',
+    asap: 'Så snart som möjligt',
+    queue: 'Kö',
+    schedule: 'Schemalägg',
+    dateTime: 'Datum & tid',
+    invalidDateTime: 'Ange ett giltigt datum och tid',
+    openCalendar: 'Öppna kalender',
+    requireManualStart: 'Kräv manuell start',
+    requirePreviousSuccess: 'Starta endast om föregående utskrift lyckades',
+    autoOffAfter: 'Stäng av skrivaren när den är klar',
+    helpAsap: 'Utskriften kommer att läggas till i toppen av kön och starta så snart en lämplig skrivare är ledig.',
+    helpSchedule: 'Utskriften kommer att starta vid den schemalagda tiden om skrivaren är ledig. Om den är upptagen kommer den att vänta tills skrivaren blir tillgänglig.',
+    helpQueue: 'Utskriften kommer att läggas till i slutet av kön.',
+    leftNozzle: 'V',
+    rightNozzle: 'H',
+    leftNozzleTooltip: 'Vänster munstycke',
+    rightNozzleTooltip: 'Höger munstycke',
+    ftsSameInletHint: 'Alla filament för denna print sitter på filamentspårväljare IN-{{inlet}}. Växlingen mellan filament på samma ingång är långsammare — flytta den ena till en AMS på den andra ingången för att snabba upp växlingen.',
+    rackPosition: 'Hyllposition',
+    rackPositionTooltip: 'Vilket munstycke på hyllan skriver ut detta filament? Positionerna är numrerade som på skrivaren..',
+    rackEmptyPosition: 'Denna hyllposition är tom',
+    rackWrongNozzle: 'Har {{has}} munstycke; detta filament behöver {{needs}}',
+    filamentOverride: 'Åsidosätt filament',
+    filamentOverrideHint: 'Välj att åsidosätta filament för modellbaserad tilldelning. Schemaläggaren kommer att matcha mot dina valda filament istället för de ursprungliga 3MF-värdena.',
+    originalFilament: 'Original',
+    overrideWith: 'Åsidosätt med',
+    resetToOriginal: 'Återställ till original',
+    insufficientFilamentTitle: 'Otillräckligt filament',
+    waitingForAmsStatus: 'Väntar på AMS-status från {{printer}}…',
+    insufficientFilamentMessage: 'Vissa tilldelade rullar har mindre filament kvar än denna utskrift behöver:',
+    insufficientFilamentLine: '{{printer}} - {{slot}}: behöver {{required}}g, återstående {{remaining}}g',
+    insufficientFilamentLinePooled: '{{printer}} - {{slot}}: behöver {{required}}g, {{remaining}}g tillgängligt över matchande rullar (AMS-filamentbackup)',
+    printAnyway: 'Skriv ut ändå',
+    forceColorMatch: 'Tvinga färgmatchning',
+    staggerPrinterStarts: 'Förskjut skrivarstart',
+    staggerGroupSize: 'Gruppstorlek',
+    staggerInterval: 'Intervall (min)',
+    staggerPreview: '{{printers}} skrivare → {{groups}} grupper om {{size}}, startar var {{interval}} minut',
+    staggerLastGroup: 'sista grupp: {{count}}',
+    staggerTotal: 'totalt: {{minutes}} min',
+    staggerToPrinters: 'Förskjut till {{count}} skrivare',
+    gcodeInjection: 'Injicera auto-utskrifts-G-kod',
+    insufficientBudget: 'Otillräcklig budget',
+    unlimitedNoBudget: 'Obgränsad – ingen budgetgräns är inställd.',
+    noPrintableCostCenters: 'Inget aktivt kostnadsställe är tillgängligt för utskrift. Be en administratör att ge dig utskriftsåtkomst.',
+  },
+
+  // Backup
+  backup: {
+    includesEncryptionKey: 'Lokala säkerhetskopior inkluderar MFA-krypteringsnyckelfilen (DATA_DIR/.mfa_encryption_key), så en säkerhetskopie-ZIP är självständig. Behandla ZIP-filen som känslig — vem som helst med filen kan dekryptera OIDC-klienthemligheterna och TOTP-hemligheterna som lagras inuti.',
+    title: 'Säkerhetskopia & Återställning',
+    createBackup: 'Skapa säkerhetskopia',
+    restoreBackup: 'Återställ säkerhetskopia',
+    restoreDescription: 'Ersätt all data från en säkerhetskopia',
+    downloadBackup: 'Ladda ner säkerhetskopia',
+    uploadBackup: 'Ladda upp säkerhetskopia',
+    lastBackup: 'Senaste säkerhetskopia',
+    autoBackup: 'Automatisk säkerhetskopia',
+    backupNow: 'Säkerhetskopiera nu',
+    restoreWarning: 'Varning: Återställning av en säkerhetskopia kommer att skriva över all nuvarande data.',
+    includeArchives: 'Inkludera arkiv',
+    includeSettings: 'Inkludera inställningar',
+    includeProfiles: 'Inkludera profiler',
+    backupSuccess: 'Säkerhetskopia skapad',
+    restoreSuccess: 'Säkerhetskopia återställd',
+    backupFailed: 'Kunde inte skapa säkerhetskopia',
+    restoreFailed: 'Kunde inte återställa säkerhetskopia',
+    restoreNote: 'Virtuell skrivare kommer att stoppas under återställning',
+
+    // GitHub Backup
+    githubBackup: 'Git-säkerhetskopia',
+    enabled: 'Aktiverad',
+    cloudLoginRequired: 'Inloggning till Bambu Cloud krävs. Logga in under Profiler → Molnprofiler för att aktivera GitHub-säkerhetskopia.',
+    cloudLoginRequiredShort: 'Molninloggning krävs',
+    githubDescription: 'Synkronisera dina profiler automatiskt till ett privat GitHub-kodförråd för säkerhetskopiering och versionshistorik.',
+    repoIsPrivate: 'Kodförrådet är privat — säkert att säkerhetskopiera till.',
+    repoIsPublicWarning: 'Kodförrådet är PUBLIKT. Bambuddy-säkerhetskopior inkluderar MQTT-uppgifter, Home Assistant-tokens, Prometheus-tokens, din Bambu Cloud-e-post och skrivaråtkomstkoder via K-profiler. Sparning blockeras tills du gör repositoryt privat i din leverantörs inställningar.',
+    repoVisibilityUnknown: 'Kunde inte fastställa repositoryns synlighet. Bambuddy vägrar att säkerhetskopiera till något som inte bekräftats som privat; sparande kommer att blockeras.',
+    repositoryUrl: 'Kodförråd-URL',
+    repoUrlPlaceholderGitHub: 'https://github.com/användarnamn/repo-namn',
+    repoUrlPlaceholderGitea: 'https://gitea.example.com/användarnamn/repo-namn',
+    repoUrlPlaceholderForgejo: 'https://forgejo.example.com/användarnamn/repo-namn',
+    repoUrlPlaceholderGitLab: 'https://gitlab.com/användarnamn/repo-namn',
+    allowInsecureHttp: 'Tillåt osäker HTTP',
+    allowInsecureHttpHint: 'Aktivera för självhostade instanser på privata nätverk utan TLS',
+    personalAccessToken: 'Personlig åtkomsttoken',
+    tokenSaved: '(sparad)',
+    enterNewToken: 'Ange ny token för att uppdatera',
+    tokenHintGitHub: 'Finkornig token med Contents-läs- och skrivåtkomst, eller en klassisk token med repo-omfång.',
+    tokenHintGitLab: 'Token med api-omfång, eller read_repository och write_repository tillsammans.',
+    tokenHintGitea: 'Token med write:repository-omfång.',
+    tokenHintForgejo: 'Token med write:repository-omfång. En token begränsad till detta enda kodförråd räcker.',
+    branch: 'Gren',
+    provider: 'Git-leverantör',
+    providerGitHub: 'GitHub',
+    providerGitLab: 'GitLab',
+    providerGitea: 'Gitea',
+    providerForgejo: 'Forgejo',
+    manualOnly: 'Endast manuell',
+    hourly: 'Varje timme',
+    daily: 'Dagligen',
+    weekly: 'Veckovis',
+    includeInBackup: 'Inkludera i säkerhetskopia',
+    kProfiles: 'K-profiler',
+    kProfilesDescription: 'Tryckförskottskalibrering från anslutna skrivare',
+    noPrintersConnected: 'Inga skrivare anslutna',
+    printersConnected: '{{connected}}/{{total}} anslutna',
+    cloudProfiles: 'Molnprofiler',
+    cloudProfilesDescription: 'Filament-, skrivar- och processförinställningar från Bambu Cloud och Orca Cloud',
+    cloudProfilesAccounts: 'Anslutna konton — Bambu Cloud: {{bambu}}, Orca Cloud: {{orca}}',
+    appSettings: 'App-inställningar',
+    appSettingsDescription: 'Bambuddy-konfiguration (komplett databas)',
+    spoolInventory: 'Rullinventarium',
+    spoolInventoryDescription: 'Filamentrullar, användningshistorik och kostnadsspårning',
+    printArchives: 'Utskriftsarkiv',
+    printArchivesDescription: 'Utskriftshistorik-metadata (inga gcode/3MF-filer)',
+    lastBackupAt: 'Senaste säkerhetskopia:',
+    noBackupsYet: 'Inga säkerhetskopior än',
+    next: 'Nästa:',
+    startingBackup: 'Startar säkerhetskopia...',
+    test: 'Test',
+    enableBackup: 'Aktivera säkerhetskopia',
+    testConnection: 'Testa anslutning',
+    enterRepoUrl: 'Ange kodförråds-URL',
+    enterRepoAndToken: 'Ange kodförråds-URL och åtkomsttoken',
+    repoRequired: 'Kodförråds-URL krävs',
+    tokenRequired: 'Åtkomsttoken krävs',
+    githubBackupEnabled: 'GitHub-säkerhetskopia aktiverad',
+    tokenUpdated: 'Token uppdaterad',
+    settingsSaved: 'Inställningar sparade',
+    failedToSave: 'Kunde inte spara: {{message}}',
+    backupCompleteFiles: 'Säkerhetskopia slutförd - {{count}} filer uppdaterade',
+    backupSkippedNoChanges: 'Säkerhetskopia hoppade över - inga ändringar',
+    backupFailed2: 'Kunde inte skapa säkerhetskopia: {{message}}',
+    clearedLogs: 'Rensade {{count}} loggar',
+    failedToClearLogs: 'Kunde inte rensa loggar: {{message}}',
+
+    // Restore from Git backup (#2656)
+    restoreFromGit: {
+      button: 'Återställ från Git',
+      title: 'Återställ från Git-säkerhetskopia',
+      subtitle: 'Välj en commit och välj vad som ska återställas',
+      commitLabel: 'Säkerhetskopie-commit',
+      latestCommit: 'Senaste säkerhetskopia (grenens topp)',
+      categoriesLabel: 'Vad som ska återställas',
+      inspecting: 'Läser säkerhetskopieinnehåll...',
+      itemCount: '{{count}} i säkerhetskopian',
+      overwriteLabel: 'Skriv över befintliga poster',
+      overwriteOn: 'Befintliga poster kommer att uppdateras från säkerhetskopian.',
+      overwriteOff: 'Endast saknade poster läggs till; befintliga lämnas orörda.',
+      selectedCount: '{{count}} valda',
+      restoring: 'Återställer...',
+      confirmTitle: 'Återställ från säkerhetskopia?',
+      confirmMessage: 'De valda kategorierna kommer att återställas från denna commit. Saknade poster läggs till; befintliga poster förblir oförändrade.',
+      confirmMessageOverwrite: 'De valda kategorierna kommer att återställas från denna commit, och skriva över poster som redan finns lokalt. Detta kan inte ångras.',
+      kprofilesOverwriteCaveat: 'K-profiler är undantaget: att skriva till ett fack ersätter alltid kalibreringen på skrivaren.',
+      tally: '{{restored}} återställda, {{skipped}} hoppade över, {{failed}} misslyckades',
+      reloadHint: 'Ladda om Bambuddy så att den återställda datan visas överallt.',
+      partialHint: 'Kategorierna som listas ovan är klara och på disken. Eventuella saknade kategorier kördes inte.',
+      failed: 'Kunde inte återställa.',
+      loadFailed: 'Kunde inte läsa säkerhetskopiekodförrådet.',
+      // Preview caveats. The server sends detail_code + detail_params and the
+      // English detail as defaultValue, same contract as backup.pathCheck.
+      details: {
+        notPresent: 'Finns inte i denna säkerhetskopie-commit',
+        unreadableJson: 'Oläsliga JSON: {{paths}}',
+        settingsNoPayload: 'Inga inställningar i nyttolast',
+        settingsCredentialsWillSkip: '{{count}} uppgift(er) av typen lösenord kommer att hoppas över',
+        settingsCompanionWillSkip: '{{count}} uppgift(er) av typen lösenord kommer att hoppas över, och {{companion}} växlar som beror på dem kommer att lämnas av',
+        settingsCompanionOnlyWillSkip: '{{companion}} växlar kommer att lämnas av — den uppgift som var och en behöver kan inte återställas från en säkerhetskopia',
+        spoolsUsageCount: 'inklusive {{count}} användningspost(er)',
+        archivesMetadataOnly: 'Endast metadata — 3MF-filer och minibilder finns inte i en Git-säkerhetskopia',
+        kprofilesPrinterCount: 'över {{count}} skrivare',
+      },
+      // Tally notes, same contract. noData is shared by all four categories:
+      // the category heading renders beside it, so naming the category again
+      // would be redundant.
+      notes: {
+        noData: 'Ingen data av denna typ i denna säkerhetskopia',
+        archivesPrinterMissing: 'Vissa arkiv refererade till skrivare som inte längre finns — länk rensad',
+        archivesProjectMissing: 'Vissa arkiv refererade till projekt som inte längre finns — länk rensad',
+        archivesOwnerCleared: 'Vissa arkiv refererade till användare som inte längre finns — ägare rensad, så de är synliga endast för användare med behörigheten archives:read_all tills en admin tilldelar dem på nytt',
+        archivesOwnerUnmatched: 'Vissa arkiv namnger en ägare som denna instans inte har — ägare rensad snarare än gissad från säkerhetskopians användar-ID, så de är synliga endast för användare med behörigheten archives:read_all tills en admin tilldelar dem på nytt',
+        archivesOwnerUnknown: 'Vissa arkiv återställdes utan en ägare — denna säkerhetskopia registrerar ingen, så de är synliga endast för användare med behörigheten archives:read_all tills en admin tilldelar dem på nytt',
+        archivesUndeleted: 'Arkiv som tagits bort sedan säkerhetskopian är synliga igen — skriv över var aktiverad',
+        archivesMetadataOnly: 'Återställda arkiv innehåller endast metadata — 3MF- och minibildfiler finns inte i en Git-säkerhetskopia',
+        spoolUsageUnresolved: '{{count}} användningspost(er) hoppade över — deras rulle finns inte i denna säkerhetskopias rulllista, så det finns inget att koppla dem till.',
+        spoolUsageUnlinked: '{{count}} användningspost(er) återställda utan sin utskriftshistorik-länk — välj Utskriftsarkiv tillsammans med Rullinventering för att behålla den.',
+        spoolTagKept: '{{count}} rulletagg(ar) lämnade som de är — säkerhetskopian skulle ha rensat en tagg som sedan dess skannats, eller flyttat en till en andra rulle.',
+        settingsCredentialsSkipped: '{{count}} uppgift(er) av typen lösenord hoppade över — ange hemligheter manuellt igen',
+        settingsAuthSkipped: '{{count}} autentiseringsinställning(ar) hoppade över — ändra dem i Inställningar > Autentisering så att uteslutningskontrollerna fortfarande körs',
+        settingsCompanionSkipped: '{{keys}} lämnade avstängda — den uppgift som var och en behöver kan inte återställas från en säkerhetskopia och denna instans har ingen lagrad, så att slå på dem skulle lämna integrationen oautentiserad',
+        settingsMqttRelayFailed: 'MQTT-inställningar återställda, men reläet kunde inte återanslutas — starta om Bambuddy',
+        kprofilesAlwaysOverwrite: 'K-profiler skriver alltid över det matchande facket på skrivaren',
+        kprofilesAckUnreliable: 'En skrivare som inte svarar räknas ändå som återställd — verifiera profilerna på skrivaren',
+        kprofilesPrinterMissing: 'Ingen skrivare med serienummer {{serial}} — hoppade över',
+        kprofilesPrinterOffline: '{{printer}} ({{serial}}) är inte ansluten — hoppade över',
+        kprofilesUnknownNozzle: 'Oväntad munstyckesdiameter {{nozzle}} för {{serial}} — skickad som den är',
+        kprofilesUnmatched: '{{count}} profil(er) för {{nozzle}} hade ingen motsvarighet på {{printer}} — lades till som nya profiler',
+        kprofilesSendFailed: 'Kunde inte skicka {{nozzle}}-profiler till {{printer}} ({{serial}})',
+        kprofilesRefused: '{{printer}} ({{serial}}) vägrade {{nozzle}}-profilerna: {{reason}}',
+        kprofilesStepFailed: 'K-profil-steget kunde inte slutföras — {{reason}}. Allt som återställdes före det är fortfarande sparat.',
+      },
+    },
+
+    // History
+    history: 'Historik',
+    clear: 'Rensa',
+    date: 'Datum',
+    status: 'Status',
+    trigger: 'Typ',
+    triggers: {
+      manual: 'Säkerhetskopia (manuell)',
+      scheduled: 'Säkerhetskopia (schemalagd)',
+      restore: 'Återställning',
+    },
+    commit: 'Commit',
+
+    // Local Backup
+    localBackup: 'Lokal säkerhetskopia',
+    localBackupDescription: 'Skapa en komplett säkerhetskopia av din Bambuddy-data inklusive databas, arkiv, uppladdningar och alla filer.',
+    downloadBackupLabel: 'Ladda ner säkerhetskopia',
+    completeBackupZip: 'Komplett säkerhetskopia: databas + alla filer (ZIP)',
+    download: 'Ladda ner',
+    preparingBackup: 'Förbereder säkerhetskopia...',
+    creatingArchive: 'Skapar säkerhetskopiearkiv... Detta kan ta en stund för stora arkiv.',
+    downloadingFile: 'Laddar ner säkerhetskopia...',
+    backupDownloaded: 'Säkerhetskopia nedladdad',
+    failedToCreateBackup: 'Kunde inte skapa säkerhetskopia: {{message}}',
+    restore: 'Återställ',
+    restoreReplacesAll: 'Återställning ersätter all data.',
+    restoreReplacesAllDetail: 'Din nuvarande databas och filer kommer att ersättas fullständigt. En omstart krävs efter återställning.',
+    restoreConfirmTitle: 'Återställ säkerhetskopia',
+    restoreConfirmMessage: 'Är du säker på att du vill återställa från "{{filename}}"? Detta kommer att ersätta din nuvarande databas och alla filer fullständigt. Applikationen måste startas om efter återställning.',
+    restoreConfirmButton: 'Återställ säkerhetskopia',
+    uploadingFile: 'Laddar upp säkerhetskopia...',
+    backupRestoredRestart: 'Säkerhetskopia återställd. Starta om Bambuddy.',
+    failedToRestore: 'Kunde inte återställa säkerhetskopia. Kontrollera filformatet.',
+    reloadNow: 'Ladda om nu',
+    creatingBackup: 'Skapar säkerhetskopia',
+    restoringBackup: 'Återställer säkerhetskopia',
+    preparing: 'Förbereder...',
+    processing: 'Bearbetar...',
+    doNotClosePage: 'Stäng inte denna sida eller navigera bort. Denna operation kan ta flera minuter för stora säkerhetskopior.',
+
+    // RestoreModal
+    restoring: 'Återställer...',
+    restoreComplete: 'Återställning slutförd',
+    restoreFailed2: 'Kunde inte återställa',
+    importSettings: 'Importera inställningar från en säkerhetskopia',
+    pleaseWaitRestoring: 'Vänligen vänta medan din data återställs',
+    selectBackupFile: 'Klicka för att välja säkerhetskopia (.json eller .zip)',
+    duplicateHandling: 'Hur dubbletter hanteras:',
+    matchPrinters: 'Skrivare',
+    matchPrintersBy: 'matchade efter serienummer',
+    matchSmartPlugs: 'Kontakter',
+    matchSmartPlugsBy: 'matchade efter IP-adress',
+    matchNotificationProviders: 'Notisleverantörer',
+    matchNotificationProvidersBy: 'matchade efter namn',
+    matchFilaments: 'Filament',
+    matchFilamentsBy: 'matchade efter namn + typ + märke',
+    matchArchives: 'Arkiv',
+    matchArchivesBy: 'matchade efter innehållshash (hoppas alltid över)',
+    matchPendingUploads: 'Väntande uppladdningar',
+    matchPendingUploadsBy: 'matchade efter filnamn',
+    matchSettingsTemplates: 'Inställningar & mallar',
+    matchSettingsTemplatesBy: 'skrivs alltid över',
+    replaceExisting: 'Ersätt befintlig data',
+    keepExisting: 'Behåll befintlig data',
+    overwriteDescription: 'Skriv över objekt som redan finns med säkerhetskopiedata',
+    keepDescription: 'Endast återställ objekt som inte redan finns',
+    overwriteCaution: 'Försiktighet:',
+    overwriteWarning: 'Att skriva över kommer att ersätta dina nuvarande konfigurationer med data från säkerhetskopian. Skrivaråtkomstkoder skrivs aldrig över av säkerhetskäl.',
+    cancel: 'Avbryt',
+    processingBackup: 'Bearbetar säkerhetskopia...',
+    itemsRestored: 'Objekt återställda',
+    itemsSkipped: 'Objekt hoppades över',
+    restored: 'Återställd',
+    skippedAlreadyExist: 'Hoppade över (finns redan)',
+    filesCategory: 'Filer (3MF, minibilder, etc.)',
+    andMore: '...och {{count}} till',
+    newApiKeysGenerated: 'Nya API-nycklar genererade',
+    keysShownOnce: 'Dessa nycklar visas endast en gång. Kopiera dem nu!',
+    copy: 'Kopiera',
+    noDataFound: 'Ingen data att återställa hittades i säkerhetskopian.',
+    close: 'Stäng',
+
+    // Scheduled local backups (#884)
+    scheduledBackup: 'Schemalagda säkerhetskopior',
+    scheduledBackupDescription: 'Skapa säkerhetskopieögonblicksbilder automatiskt enligt ett schema. Utdata-katalogen kan monteras till en NAS eller extern lagring.',
+    frequency: 'Frekvens',
+    backupTime: 'Tid',
+    retention: 'Bevarande',
+    retentionDescription: 'Antal säkerhetskopior att behålla',
+    outputPath: 'Utdata-sökväg',
+    outputPathPlaceholder: 'Standard: {{path}}',
+    outputPathDescription: 'Lämna tom för standardplats',
+    runNow: 'Kör nu',
+    backupFiles: 'säkerhetskopior',
+    noScheduledBackups: 'Inga säkerhetskopior än',
+    deleteBackup: 'Ta bort',
+    deleteBackupConfirm: 'Ta bort denna säkerhetskopia?',
+    backupRunning: 'Säkerhetskopiering pågår...',
+    scheduledBackupComplete: 'Säkerhetskopia slutförd',
+    scheduledBackupFailed: 'Kunde inte skapa säkerhetskopia',
+    nextBackup: 'Nästa säkerhetskopia',
+    backupSize: 'Storlek',
+    localTimeHint: 'Lokal tid ({{tz}})',
+    defaultPathLabel: 'Standard:',
+    // Backup output-path probe (#2544)
+    pathCheck: {
+      title: 'Bambuddy kan inte skriva till denna katalog',
+      howToFix: 'Så här åtgärdar du:',
+      sandboxed: 'Bambuddy-tjänsten kan inte skriva till {{path}}. Dess systemd-enhet körs med ProtectSystem=strict, vilket gör varje katalog utanför installations-, data- och loggkatalogerna skrivskyddade för tjänsten — även om du själv kan skriva till den från ditt eget skal.',
+      read_only: '{{path}} är på ett skrivskyddat filsystem.',
+      permission_denied: 'Bambuddy har inte behörighet att skriva till {{path}}. Kontrollera katalogägaren och behörigheterna.',
+      no_space: 'Filsystemet som innehåller {{path}} är fullt.',
+      not_a_directory: '{{path}} finns men är inte en katalog.',
+      missing: '{{path}} finns inte och kunde inte skapas.',
+      error: 'Bambuddy kan inte skriva till {{path}}.',
+      ephemeralTitle: 'Dessa säkerhetskopior kommer inte att överleva en container-omstart',
+      container_ephemeral: '{{path}} är inne i Bambuddy-containern, inte på värden. Säkerhetskopior som skrivs dit försvinner när containern skapas om. Montera katalogen från värden:',
+    },
+
+    // Category labels
+    categories: {
+      settings: 'Inställningar',
+      notification_providers: 'Notisleverantörer',
+      notification_templates: 'Notismallar',
+      smart_plugs: 'Kontakter',
+      printers: 'Skrivare',
+      filaments: 'Filament',
+      maintenance_types: 'Underhållstyper',
+      archives: 'Arkiv',
+      projects: 'Projekt',
+      pending_uploads: 'Väntande uppladdningar',
+      external_links: 'Externa länkar',
+      api_keys: 'API-nycklar',
+    },
+  },
+
+  // Tags
+  tags: {
+    title: 'Taggar',
+    addTag: 'Lägg till tagg',
+    editTag: 'Redigera tagg',
+    deleteTag: 'Ta bort tagg',
+    tagName: 'Taggnamn',
+    tagColor: 'Taggfärg',
+    noTags: 'Inga taggar',
+    deleteConfirm: 'Är du säker på att du vill ta bort denna tagg?',
+    manageTags: 'Hantera taggar',
+  },
+
+  // Upload modal (archives)
+  uploadModal: {
+    title: 'Ladda upp 3MF-filer',
+    dragDrop: 'Dra och släpp .3mf-filer här',
+    or: 'eller',
+    browseFiles: 'Bläddra bland filer',
+    extractionInfo: 'Skrivarmodellen kommer automatiskt att extraheras från 3MF-filens metadata.',
+    uploaded: 'uppladdade',
+    failed: 'misslyckades',
+    uploading: 'Laddar upp...',
+    upload: 'Ladda upp',
+    uploadFailed: 'Kunde inte ladda upp',
+  },
+
+  // Edit archive modal
+  // Edit Archive Modal
+  editArchive: {
+    title: 'Redigera arkiv',
+    name: 'Namn',
+    namePlaceholder: 'Utskriftsnamn',
+    printer: 'Skrivare',
+    noPrinter: 'Ingen skrivare',
+    project: 'Projekt',
+    noProject: 'Ingen projekt',
+    itemsPrinted: 'Antal utskrivna objekt',
+    itemsPrintedHelp: 'Antal objekt som producerats i detta utskriftsjobb',
+    filamentUsed: 'Filament använt (g)',
+    filamentUsedPlaceholder: 't.ex. 46,16',
+    filamentUsedHelp: 'Ställ in detta manuellt när en utskrift arkiveras utan sin 3MF, så att den fortfarande räknas mot filamenttotalen. Om man skannar om ett arkiv som har sin 3MF läser man tillbaka siffran från filen.',
+    notes: 'Anteckningar',
+    notesPlaceholder: 'Lägg till anteckningar om denna utskrift...',
+    externalLink: 'Extern länk',
+    externalLinkPlaceholder: 'https://printables.com/model/...',
+    externalLinkHelp: 'Länk till Printables, Thingiverse eller annan källa',
+    tags: 'Taggar',
+    tagsPlaceholder: 'Lägg till taggar...',
+    addMoreTags: 'Lägg till fler taggar...',
+    matchingTags: 'Matchande "{{query}}"',
+    existingTags: 'Befintliga taggar',
+    clickToAdd: '(klicka för att lägga till)',
+    status: 'Status',
+    failureReason: 'Orsak till fel',
+    selectReason: 'Välj orsak...',
+    photos: 'Bilder av utskriftsresultat',
+    photosHelp: 'Klicka på + för att lägga till bilder av ditt utskriftsresultat',
+    printResult: 'Utskriftsresultat',
+    saving: 'Sparar...',
+    // Failure reasons
+    failureReasons: {
+      adhesionFailure: 'Vidhäftningsfel',
+      spaghettiDetached: 'Spaghetti / lossning',
+      layerShift: 'Skiktförskjutning',
+      cloggedNozzle: 'Igensatt munstycke',
+      filamentRunout: 'Filament tog slut',
+      warping: 'Förskevning',
+      stringing: 'Trådighet',
+      underExtrusion: 'Under-extrudering',
+      powerFailure: 'Strömavbrott',
+      userCancelled: 'Användare avbröt',
+      noStatusUpdate: 'Ingen statusuppdatering mottogs',
+      other: 'Annat',
+    },
+    // Archive statuses
+    statuses: {
+      completed: 'Slutförd',
+      failed: 'Misslyckad',
+      aborted: 'Avbruten',
+      printing: 'Skriver ut',
+    },
+  },
+
+  // K-Profiles
+  kProfiles: {
+    title: 'K-profiler',
+    noPrintersConfigured: 'Inga skrivare konfigurerade',
+    addPrinterInSettings: 'Lägg till en skrivare i Inställningar för att hantera K-profiler',
+    noActivePrinters: 'Inga aktiva skrivare',
+    enablePrinterConnection: 'Aktivera skrivaranslutning för att visa dess K-profiler',
+    loadingProfiles: 'Laddar K-profiler...',
+    printerOffline: 'Skrivare offline',
+    printerOfflineDesc: 'Den valda skrivaren är inte ansluten. Sätt på den för att visa K-profiler.',
+    noMatchingProfiles: 'Inga matchande profiler',
+    noMatchingProfilesDesc: 'Inga profiler matchar dina sökvillkor',
+    noKProfiles: 'Inga K-profiler',
+    noKProfilesDesc: 'Inga tryckförskottsprofiler hittade för {{diameter}} mm munstycke',
+    createFirstProfile: 'Skapa en första profil',
+    // Controls
+    printer: 'Skrivare',
+    nozzle: 'Munstycke',
+    refresh: 'Uppdatera',
+    addProfile: 'Lägg till profil',
+    export: 'Exportera',
+    import: 'Importera',
+    select: 'Välj',
+    selectAll: 'Markera alla',
+    delete: 'Ta bort',
+    // Filters
+    searchPlaceholder: 'Sök efter namn eller filament...',
+    allExtruders: 'Alla extrudrar',
+    leftOnly: 'Endast vänster',
+    rightOnly: 'Endast höger',
+    allFlow: 'Allt flöde',
+    hfOnly: 'Endast HF',
+    sOnly: 'Endast S',
+    sortName: 'Sortera: Namn',
+    sortKValue: 'Sortera: K-värde',
+    sortFilament: 'Sortera: Filament',
+    // Dual extruder labels
+    leftExtruder: 'Vänster extruder',
+    rightExtruder: 'Höger extruder',
+    // Modal
+    modal: {
+      addTitle: 'Lägg till K-profil',
+      editTitle: 'Redigera K-profil',
+      profileName: 'Profilnamn',
+      profileNamePlaceholder: 'Min PLA-profil',
+      kValue: 'K-värde',
+      kValuePlaceholder: '0,020',
+      kValueHelp: 'Typiskt intervall: 0,01 - 0,06 för PLA, 0,02 - 0,10 för PETG',
+      filament: 'Filament',
+      selectFilament: 'Välj filament...',
+      source: {
+        local: 'Importerad',
+        orcaCloud: 'Orca Cloud',
+        bambuCloud: 'Bambu Cloud',
+        builtin: 'Inbyggd',
+      },
+      noFilamentsHelp: 'Inga filament tillgängliga. Logga in på Bambu Cloud, eller importera förinställningar under Profiler → Lokala profiler.',
+      searchFilaments: 'Sök filament...',
+      noFilamentMatches: 'Inga filament matchar den sökningen',
+      flowType: 'Flödestyp',
+      highFlow: 'Högt flöde',
+      standard: 'Standard',
+      nozzleSize: 'Munstyckesstorlek',
+      extruder: 'Extruder',
+      extruders: 'Extrudrar',
+      left: 'Vänster',
+      right: 'Höger',
+      notes: 'Anteckningar (lagras lokalt)',
+      notesPlaceholder: 'Lägg till anteckningar om denna profil...',
+      notesHelp: 'Anteckningar sparas i Bambuddy, inte på skrivaren',
+      syncing: 'Synkroniserar med skrivare...',
+      savingExtruder: 'Sparar till extruder {{current}}/{{total}}...',
+      pleaseWait: 'Vänligen vänta',
+    },
+    // Delete confirmation
+    deleteConfirm: {
+      title: 'Ta bort profil',
+      cannotUndo: 'Denna åtgärd kan inte ångras',
+      message: 'Är du säker på att du vill ta bort "{{name}}" från skrivaren?',
+    },
+    // Bulk delete
+    bulkDelete: {
+      title: 'Ta bort profiler',
+      cannotUndo: 'Denna åtgärd kan inte ångras',
+      message: 'Är du säker på att du vill ta bort {{count}} valda profiler från skrivaren?',
+    },
+    // Toast
+    toast: {
+      profileSaved: 'K-profil sparad',
+      profilesSaved: 'K-profil sparad till {{count}} extrudrar',
+      selectAtLeastOneExtruder: 'Välj minst en extruder',
+      selectFilament: 'Välj ett filament först',
+      filamentNotResolvable: 'Inget Bambu-filament-ID för {{name}} — skrivaren kan inte lagra en profil för den',
+      profileDeleted: 'K-profil borttagen',
+      profilesDeleted: 'Tog bort {{count}} profiler',
+      exportedProfiles: 'Exporterade {{count}} profiler',
+      importedProfiles: 'Importerade {{count}} av {{total}} profiler',
+      noProfilesToExport: 'Inga profiler att exportera',
+      invalidFileFormat: 'Ogiltigt filformat',
+      failedToParseImport: 'Kunde inte tolka importfil',
+      failedToSaveBatch: 'Kunde inte spara K-profiler',
+      noteSaved: 'Anteckning sparad',
+      failedToSaveNote: 'Kunde inte spara anteckning',
+    },
+    // Permissions
+    permission: {
+      noRead: 'Du har inte behörighet att uppdatera profiler',
+      noCreate: 'Du har inte behörighet att lägga till profiler',
+      noUpdate: 'Du har inte behörighet att uppdatera K-profiler',
+      noDelete: 'Du har inte behörighet att ta bort K-profiler',
+      noExport: 'Du har inte behörighet att exportera profiler',
+      noImport: 'Du har inte behörighet att importera profiler',
+    },
+  },
+
+  // Virtual Printer
+  virtualPrinter: {
+    title: 'Virtuell skrivare',
+    running: 'Körs',
+    stopped: 'Stoppad',
+    description: {
+      default: 'Aktivera en virtuell skrivare som visas i Bambu Studio och OrcaSlicer. Filer som skickas till denna skrivare kommer att arkiveras direkt utan utskrift.',
+      proxy: 'Aktivera en proxy som vidarebefordrar slicer-trafik till en riktig skrivare, vilket möjliggör fjärrutskrift över vilket nätverk som helst.',
+    },
+    enable: {
+      title: 'Aktivera virtuell skrivare',
+      visibleInSlicer: 'Synlig som "Bambuddy" i slicer-uppäckt',
+      proxyingTo: 'Vidarebefordrar till {{name}}',
+      notActive: 'Inte aktiv',
+    },
+    model: {
+      title: 'Skrivarmodell',
+      description: 'Välj vilken skrivarmodell som ska emuleras.',
+      restartWarning: 'Att ändra modellen kommer att starta om den virtuella skrivaren',
+    },
+    accessCode: {
+      title: 'Åtkomstkod',
+      isSet: 'Åtkomstkod är inställd',
+      notSet: 'Ingen åtkomstkod inställd — krävs för att aktivera',
+      placeholder: 'Ange 8-teckens kod',
+      placeholderChange: 'Ange ny kod för att ändra',
+      hint: 'Måste vara exakt 8 tecken. Används av slicer för autentisering.',
+      charCount: '({{count}}/8)',
+      inheritedFromTarget: 'Ärvd från mål',
+      derivedFromTargetHint: 'Använder målskrivarens åtkomstkod. Bryggan vidarebefordrar slicer-autentisering till den riktiga skrivaren, så koderna måste matcha — redigera målskrivarens åtkomstkod för att ändra detta värde.',
+      reveal: 'Visa åtkomstkod',
+      hide: 'Dölj åtkomstkod',
+    },
+    targetPrinter: {
+      title: 'Målskrivare',
+      configured: 'Proxy-mål konfigurerat',
+      notConfigured: 'Ingen målskrivare vald — krävs för proxyläge',
+      placeholder: 'Välj en skrivare...',
+      hint: 'Välj den skrivare som slicer-trafiken ska vidarebefordras till. Skrivaren måste vara i LAN-läge.',
+      noPrinters: 'Inga skrivare konfigurerade. Lägg till en skrivare först för att använda proxyläge.',
+    },
+    remoteInterface: {
+      title: 'Åsidosättning för nätverksgränssnitt',
+      configured: 'Åsidosättning för nätverksgränssnitt aktiv',
+      optional: 'Valfritt — använd om auto-upptäckt IP är fel (t.ex. flera nätverkskort, Docker, VPN)',
+      placeholder: 'Auto-upptäckt (standard)...',
+      hint: 'Åsidosätter IP-adressen som annonseras via SSDP och används i TLS-certifikatet. Användbart när Bambuddy har flera nätverksgränssnitt.',
+    },
+    mode: {
+      title: 'Läge',
+      archive: 'Arkiv',
+      archiveDesc: 'Arkivera filer omedelbart',
+      review: 'Granskning',
+      reviewDesc: 'Granska innan arkivering',
+      queue: 'Kö',
+      queueDesc: 'Arkivera och lägg till i kö',
+      proxy: 'Proxy',
+      proxyDesc: 'Vidarebefordra till riktig skrivare',
+    },
+    autoDispatch: {
+      title: 'Auto-utskick',
+      description: 'Starta utskrifter automatiskt när de läggs till i kön. När avstängd väntar utskrifter på manuell utskickning.',
+    },
+    queueForceColorMatch: {
+      title: 'Tvinga färgmatchning',
+      description: 'Vägra att skicka till en skrivare som inte har exakt filamenttyp och färg laddad. Avstängd som standard — utan detta använder kön endast modellmatchning och kan välja en skrivare med fel färg laddad.',
+    },
+    saveAmsMapping: {
+      title: 'Spara AMS-mappning',
+      description: 'Bevara slicerns egna AMS-facksval (från project_file MQTT-kommando) i arkivet, så att en senare omutskrift återanvänder den exakta fysiska rullen istället för att härleda en ny från filens typ/färg. Avstängd som standard.',
+    },
+    gcodeInjection: {
+      title: 'G-kod-injektering',
+      description: 'Tillämpa de modellspecifika G-kodsnuttar som konfigurerats i Inställningar på jobb från denna VP. Avstängd som standard.',
+    },
+    tailscaleDisabled: {
+      title: 'Tailscale-integration',
+      description: 'Aktivera för att markera denna VP som exponerad över Tailscale. Visar värdens Tailscale-adress så att du vet vilken IP du ska klistra in i slicern. CA-import-steget är oförändrat — denna växling har ingen effekt på certifikat.',
+    },
+    setupRequired: {
+      title: 'Inställning krävs',
+      description: 'Funktionen för virtuell skrivare kräver ytterligare systemkonfiguration innan den fungerar. Detta inkluderar portvidarebefordran, brandväggsregler och plattformsspecifika inställningar.',
+      readGuide: 'Läs inställningsguiden innan du aktiverar',
+    },
+    archiveNameSource: {
+      title: 'Källa för arkivnamn',
+      description: 'Välj hur nya arkiv ska namnges när filer anländer via den virtuella skrivaren. "Metadata" använder den inbäddade titeln från slicern från 3MF (standard). "Filnamn" använder filnamnet som Bambu Studio skickade via FTP. Obs: Bambu Studio skriver över det namn du skriver i dialogrutan "Skicka till skrivare" med 3MF:ens Titel-fält när sådant finns, så båda lägen producerar ofta samma sträng.',
+      metadata: 'Metadata',
+      filename: 'Filnamn',
+    },
+    caCert: {
+      title: 'Slicer-certifikat',
+      description: 'Virtuella skrivare använder ett TLS-certifikat signerat av Bambuddy-CA. Importera detta CA-certifikat till din slicers betroda lagring en gång så att den accepterar anslutningen — ingen anledning att kopiera det från kommandoraden.',
+      copy: 'Kopiera',
+      copied: 'Kopierad',
+      download: 'Ladda ner',
+      fingerprint: 'SHA-256',
+    },
+    howItWorks: {
+      title: 'Hur det fungerar',
+      step1: 'På samma subnät visas virtuella skrivare automatiskt i din slicer (Bambu Studio / OrcaSlicer) via upptäckt. Från andra nätverk lägger du till dem manuellt via IP-adress och åtkomstkod.',
+      step2: 'I Arkiv-, Gransknings- och Kölägen, använd knappen "Skicka" i din slicer för att ladda upp 3MF-filer till Bambuddy. Slicern kommer att visa "Utskrift lyckades" — filen lagras, inte skrivs ut.',
+      step3: 'I Proxyläge vidarebefordrar den virtuella skrivaren all trafik till en riktig skrivare — utskrifter startar omedelbart som om den vore ansluten direkt.',
+    },
+    status: {
+      title: 'Statusdetaljer',
+      printerName: 'Skrivarnamn',
+      model: 'Modell',
+      serialNumber: 'Serienummer',
+      mode: 'Läge',
+      pendingFiles: 'Väntande filer',
+      targetPrinter: 'Målskrivare',
+      ftpPort: 'FTP-port',
+      mqttPort: 'MQTT-port',
+      ftpConnections: 'FTP-anslutningar',
+      mqttConnections: 'MQTT-anslutningar',
+    },
+    toast: {
+      updated: 'Inställningar för virtuell skrivare uppdaterade',
+      failedToUpdate: 'Kunde inte uppdatera inställningar',
+      copyFailed: 'Kunde inte kopiera — försök markera texten manuellt',
+      accessCodeRequired: 'Ange en åtkomstkod först',
+      targetPrinterRequired: 'Välj en målskrivare först',
+      bindIpRequired: 'Ange en bind-IP först',
+      accessCodeEmpty: 'Åtkomstkod kan inte vara tom',
+      accessCodeLength: 'Åtkomstkod måste vara exakt 8 tecken',
+      targetCodeChangedRebind: 'Åtkomstkoden matchar nu den nya målskrivaren. Lägg till denna enhet igen i din slicer för att hämta den nya koden.',
+      created: 'Virtuell skrivare skapad',
+      failedToCreate: 'Kunde inte skapa virtuell skrivare',
+      deleted: 'Virtuell skrivare borttagen',
+      failedToDelete: 'Kunde inte ta bort virtuell skrivare',
+    },
+    list: {
+      title: 'Virtuella skrivare',
+      add: 'Lägg till',
+      addFirst: 'Lägg till virtuell skrivare',
+      empty: 'Inga virtuella skrivare konfigurerade. Lägg till en för att komma igång.',
+    },
+    bindIp: {
+      title: 'Bind gränssnitt',
+      placeholder: 'Välj gränssnitt...',
+      hint: 'Nätverksgränssnitt för denna virtuella skrivare att binda till. Måste vara unikt per skrivare.',
+    },
+    proxy: {
+      accessCodeHint: 'I proxyläge, använd din målskrivares åtkomstkod i slicern. Anslutningen vidarebefordras transparant till den riktiga skrivaren.',
+    },
+    addDialog: {
+      title: 'Lägg till virtuell skrivare',
+      name: 'Namn',
+      hint: 'Du kan konfigurera åtkomstkod, målskrivare och andra inställningar efter skapande.',
+      create: 'Skapa',
+    },
+    deleteConfirm: {
+      title: 'Ta bort virtuell skrivare',
+      message: 'Är du säker på att du vill ta bort "{{name}}"? Detta kommer att stoppa alla tjänster för denna skrivare.',
+    },
+  },
+
+  // Model Viewer
+  modelViewer: {
+    openInSlicer: 'Öppna i slicer',
+    openInSlicerWith: 'Öppna i {{slicer}}',
+    moreSlicerOptions: 'Fler slicer-alternativ',
+    openInSlicerFailed: 'Kunde inte öppna i slicer',
+    tabs: {
+      model: '3D-modell',
+    },
+    notAvailable: 'ej tillgänglig',
+    plates: 'Plattor',
+    allPlates: 'Alla plattor',
+    plateNumber: 'Platta {{number}}',
+    plateCount: '{{count}} platta',
+    plateCount_other: '{{count}} plattor',
+    objectCount: '{{count}} objekt',
+    objectCount_other: '{{count}} objekt',
+    filamentCount: '{{count}} filament',
+    filamentCount_other: '{{count}} filament',
+    eta: 'Beräknad tid: {{minutes}} min',
+    noPreview: 'Ingen förhandsvisning tillgänglig för denna fil',
+    pagination: {
+      pageOf: 'Sida {{current}} av {{total}}',
+      prev: 'Föregående',
+      next: 'Nästa',
+    },
+    errors: {
+      failedToLoad: 'Kunde inte ladda fil',
+      noMeshes: 'Inga nät hittade i 3MF-fil',
+      unsupportedFormat: 'Filformatet stöds inte',
+    },
+  },
+
+  // Maintenance type descriptions (built-in)
+  maintenanceDescriptions: {
+    lubricateCarbonRods: 'Applicera smörjmedel på kolstänger för jämn rörelse',
+    lubricateRails: 'Applicera smörjmedel på linjärskenor för jämn rörelse',
+    cleanNozzle: 'Rengör varmblock och munstycke för att förhindra igensättning',
+    checkBelts: 'Kontrollera remspänning för noggranna utskrifter',
+    cleanBuildPlate: 'Rengör byggplatta för bättre vidhäftning',
+    checkExtruder: 'Kontrollera extruderkugghjul för slitage',
+    checkCooling: 'Se till att kylfläktar fungerar korrekt',
+    generalInspection: 'Allmän skrivarkontroll',
+    cleanCarbonRods: 'Rengör kolstänger för att minska friktion',
+    lubricateSteelRods: 'Applicera smörjmedel på stålstänger för jämn rörelse',
+    cleanSteelRods: 'Rengör stålstänger för att minska friktion',
+    cleanLinearRails: 'Torka av linjärskenor för att ta bort damm och smuts',
+    checkPtfeTube: 'Kontrollera PTFE-rör för slitage eller skador',
+    replaceHepaFilter: 'Byt HEPA-filter för bättre luftkvalitet',
+    replaceCarbonFilter: 'Byt aktivt kolfilter',
+    lubricateLeftNozzleRail: 'Smörj vänster munstyckesskena (H2-serien)',
+  },
+
+  // Smart Plugs
+  haSensors: {
+    label: 'Sensorer',
+    unavailable: 'Ej tillgänglig',
+    blocksPrints: '{{entity}} — håller på utskrifter medan larmet är aktivt',
+    states: {
+      open: 'Öppen',
+      closed: 'Stängd',
+      unlocked: 'Olåst',
+      locked: 'Låst',
+      detected: 'Upptäckt',
+      clear: 'Tom',
+      wet: 'Blöt',
+      dry: 'Torr',
+      problem: 'Problem',
+      ok: 'OK',
+      running: 'Körs',
+      stopped: 'Stoppad',
+      on: 'På',
+      off: 'Av',
+    },
+    sectionTitle: 'Home Assistant-sensorer',
+    add: 'Lägg till sensor',
+    addTitle: 'Lägg till Home Assistant-sensor',
+    editTitle: 'Redigera Home Assistant-sensor',
+    empty: 'Inga sensorer än. Binda en dörrkontakt eller termometer från Home Assistant för att visa den på ett skrivarkort.',
+    unknownPrinter: 'Okänd skrivare',
+    badgeBlocks: 'Håller på utskrifter',
+    badgeNotifies: 'Notiserar',
+    badgeHidden: 'Dold på kort',
+    printer: 'Skrivare',
+    entity: 'Entitet',
+    searchPlaceholder: 'Sök entiteter...',
+    noEntities: 'Inga matchande entiteter',
+    name: 'Visningsnamn',
+    alertWhen: 'Larma när',
+    alertNever: 'Aldrig — visa endast',
+    alertAbove: 'Ovanför',
+    alertBelow: 'Under',
+    alertHint: 'Larmtillståndet markerar sensorn på skrivarkortet och aktiverar alternativen nedan.',
+    showOnCard: 'Visa på skrivarkort',
+    notifyOnAlert: 'Skicka en notis när larmet startar',
+    blockPrint: 'Håll köade utskrifter medan larmet är aktivt',
+    blockPrintHint: 'Jobb förblir köade och startar automatiskt när sensorn återgår till normalt. Ignoreras medan Home Assistant är otillgänglig.',
+    toast: {
+      created: 'Sensor tillagd',
+      updated: 'Sensor sparad',
+      deleted: 'Sensor borttagen',
+    },
+    error: {
+      pickEntity: 'Välj en Home Assistant-entitet',
+      nameRequired: 'Ange ett visningsnamn',
+      printerRequired: 'Välj en skrivare',
+      alertRequired: 'Sätt ett larmvillkor först',
+    },
+  },
+  locationHaSensors: {
+    sectionTitle: 'Home Assistant-sensorer (lagringsplatser)',
+    sectionDescription:
+      'Bind Home Assistant-temperatur-, luftfuktighets- eller batterisensorer till dina lagringsplatser för att visa liveavläsningar på filamentkortet och i tabellen. Endast en sensor per kategori är tillåten per plats.',
+    add: 'Lägg till sensor',
+    addTitle: 'Lägg till Home Assistant-sensor',
+    editTitle: 'Redigera Home Assistant-sensor',
+    empty: 'Inga sensorer än. Bind en temperatur- eller luftfuktighetssensor från Home Assistant för att visa den på filamentkortet.',
+    unknownLocation: 'Okänd plats',
+    location: 'Lagringsplats',
+    showOnCard: 'Visa på filamentkort',
+    overwriteConfirm: {
+      title: 'Ersätt befintlig sensor?',
+      messageTemperature: '"{{location}}" har redan en temperatursensor kopplad: {{name}}. Om du fortsätter kommer den att ersättas.',
+      messageHumidity: '"{{location}}" har redan en luftfuktighetssensor kopplad: {{name}}. Om du fortsätter kommer den att ersättas.',
+      messageBattery: '"{{location}}" har redan en batterisensor kopplad: {{name}}. Om du fortsätter kommer den att ersättas.',
+    },
+    autoAdd: {
+      confirmTitle: 'Lägg till de andra sensorerna också?',
+      confirmMessage: 'Bambuddy hittade också andra sensorer för denna plats. Välj vilka du också vill lägga till.',
+      added: 'Lade också till: {{names}}',
+      noneFound: 'Inga matchande temperatur-, luftfuktighets- eller batterisensorer hittade för denna plats.',
+      onlyThisOne: 'Endast denna',
+    },
+    options: {
+      buttonLabel: 'Sensoralternativ',
+      title: 'Platssensoralternativ',
+      description: 'Dessa värden används när en temperatur-, luftfuktighets- eller batterisensor binds automatiskt tillsammans med den första sensorn för en plats.',
+      generalSettings: 'Allmänna inställningar',
+      pollInterval: 'Uppdateringsintervall (sekunder)',
+      pollIntervalHint: 'Hur ofta Bambuddy avfrågar Home Assistant och uppdaterar sensorvärden på skärmen. Minimum 60 sekunder.',
+      colorizeValues: 'Färga sensorvärden enligt deras larmtröskelvärden',
+      aboveColor: 'Färg för överstiget tröskelvärde',
+      belowColor: 'Färg för understiget tröskelvärde',
+      optimalColor: 'Färg för optimalt värde',
+      colors: {
+        red: 'Röd',
+        orange: 'Orange',
+        yellow: 'Gul',
+        green: 'Grön',
+        blue: 'Blå',
+        purple: 'Lila',
+        pink: 'Rosa',
+      },
+      saved: 'Alternativ sparade',
+      saveFailed: 'Kunde inte spara alternativ',
+      reset: 'Återställ',
+      resetConfirm: {
+        title: 'Återställ alla befintliga platssensorer?',
+        message:
+          'Detta skriver över larmtröskelvärden, notiser och kortsynlighet för alla befintliga lagringsplats-temperatur-, luftfuktighets- och batterisensorer med de värden som konfigurerats ovan, och återställer varje sensors namn till dess Home Assistant-vänliga namn — skrivarsensorer påverkas inte. Detta kan inte ångras. Beroende på hur många sensorer du har, kan detta ta en stund.',
+      },
+      resetDone: 'Tillämpat på {{count}} plats-sensorer',
+      resetFailed: 'Kunde inte återställa plats-sensorer',
+    },
+    deleteAllConfirm: {
+      title: 'Ta bort alla sensorer?',
+      message: 'Detta tar bort alla {{count}} sensorer bundna till "{{location}}". Detta kan inte ångras.',
+    },
+    currentlyBound: 'För närvarande kopplad: {{entity}}',
+    error: {
+      locationRequired: 'Välj en lagringsplats',
+    },
+    toast: {
+      created: 'Sensor tillagd',
+      updated: 'Sensor sparad',
+      deleted: 'Sensor borttagen',
+    },
+  },
+  smartPlugs: {
+    offline: 'Offline',
+    admin: 'Admin',
+    openPlugAdminPage: 'Öppna kontakt-adminsida',
+    deleteSmartPlug: 'Ta bort kontakt',
+    turnOnSmartPlug: 'Sätt på kontakt',
+    turnOffSmartPlug: 'Stäng av kontakt',
+    turnOn: 'Sätt på',
+    turnOff: 'Stäng av',
+    addSmartPlug: {
+      scanningNetwork: 'Söker i subnät...',
+      chooseEntity: 'Välj en entitet...',
+      connectionFailed: 'Kunde inte ansluta',
+      searchEntities: 'Sök entiteter...',
+      searchPowerSensors: 'Sök effektsensorer...',
+      searchEnergySensors: 'Sök energisensorer...',
+      placeholders: {
+        plugName: 'Kontakt i vardagsrummet',
+        mqttStateOnValue: 'PÅ, true, 1',
+        mqttSameAsPower: 'Samma som effekttopik, eller annan',
+      },
+    },
+    // SmartPlugCard
+    linkedTo: 'Länkad till:',
+    monitorOnly: 'Endast övervakning',
+    alerts: 'Larm',
+    scheduleOn: 'På {{time}}',
+    scheduleOff: 'Av {{time}}',
+    on: 'På',
+    off: 'Av',
+    power: 'Effekt',
+    kwhToday: 'kWh idag',
+    settings: 'Inställningar',
+    automationSettings: 'Automatiseringsinställningar',
+    showInSwitchbar: 'Visa i kontaktpanel',
+    quickAccessSidebar: 'Snabbåtkomst från sidofält',
+    enabled: 'Aktiverad',
+    enableAutomation: 'Aktivera automatisering för denna kontakt',
+    autoOn: 'Auto på',
+    autoOnDescription: 'Sätt på när utskrift startar',
+    autoOff: 'Auto av',
+    autoOffDescription: 'Stäng av när utskrift slutförs (engångs)',
+    autoOffPersistent: 'Håll aktiverad',
+    autoOffPersistentDescription: 'Förblir aktiverad mellan utskrifter istället för engångs',
+    controlsPrinterPower: 'Kontrollerar skrivarens ström',
+    controlsPrinterPowerDescription: 'Stäng av om denna kontakt endast förser en tillbehörsenhet (filterfläkt, belysning). Annars markeras skrivaren som offline när den stängs av.',
+    autoOffAfterDrying: 'Auto av efter torkning',
+    autoOffAfterDryingDescription: 'Stäng av när AMS-torkning slutförs',
+    delayAfterDryingMinutes: 'Torkningsfördröjning (minuter)',
+    turnOffDelayMode: 'Avstängningsfördröjningsläge',
+    time: 'Tid',
+    temp: 'Temp',
+    delayMinutes: 'Fördröjning (minuter)',
+    tempThreshold: 'Temperaturtröskelvärde (°C)',
+    tempThresholdDescription: 'Stäng av när munstycket svalnar under detta tröskelvärde',
+    edit: 'Redigera',
+    deleteConfirm: 'Är du säker på att du vill ta bort "{{name}}"? Detta kan inte ångras.',
+    turnOnConfirm: 'Är du säker på att du vill sätta på "{{name}}"?',
+    turnOffConfirm: 'Är du säker på att du vill stänga av "{{name}}"? Detta kommer att bryta strömmen till den anslutna enheten.',
+    failedToTurn: 'Kunde inte {{action}} "{{name}}"',
+    unknown: 'Okänd',
+    // AddSmartPlugModal
+    addTitle: 'Lägg till kontakt',
+    editTitle: 'Redigera kontakt',
+    stopScanning: 'Stoppa sökning',
+    discoverTasmota: 'Upptäck Tasmota-enheter',
+    foundDevices: 'Hittade {{count}} enhet(er) — klicka för att välja:',
+    noDevicesFound: 'Inga Tasmota-enheter hittade i ditt subnät',
+    haNotConfigured: 'Home Assistant är inte konfigurerad. Ställ in det i',
+    haSettingsPath: 'Inställningar → Nätverk → Home Assistant',
+    selectEntity: 'Välj entitet *',
+    ipAddress: 'IP-adress *',
+    nameLabel: 'Namn *',
+    username: 'Användarnamn',
+    password: 'Lösenord',
+    authHint: 'Lämna tomt om din Tasmota-enhet inte kräver autentisering',
+    linkToPrinter: 'Länka till skrivare',
+    noPrinter: 'Ingen skrivare (endast manuell kontroll)',
+    linkingDescription: 'Länkning aktiverar automatisk på/av när utskrifter startar/slutförs',
+    powerAlerts: 'Effektlarm',
+    alertAbove: 'Larma om över (W)',
+    alertBelow: 'Larma om under (W)',
+    alertDescription: 'Få en notis när effektförbrukningen överskrider dessa tröskelvärden. Lämna tomt för att inaktivera det villkoret.',
+    dailySchedule: 'Dagligt schema',
+    turnOnAt: 'Sätt på klockan',
+    turnOffAt: 'Stäng av klockan',
+    scheduleDescription: 'Sätt automatiskt på/av kontakten vid dessa tider dagligen. Lämna tomt för att hoppa över den åtgärden.',
+    showOnPrinterCard: 'Visa på skrivarkort',
+    displayOnPrinterCard: 'Visa knapp på skrivarkort',
+    connectedResult: 'Ansluten!',
+    deviceLabel: 'Enhet: {{name}} - ',
+    stateLabel: 'Status: {{state}}',
+    test: 'Test',
+    delete: 'Ta bort',
+    save: 'Spara',
+    add: 'Lägg till',
+    cancel: 'Avbryt',
+    failedToStartScan: 'Kunde inte starta sökning',
+    nameRequired: 'Namn krävs',
+    entityRequired: 'Entitet krävs för Home Assistant-kontakter',
+    mqttTopicRequired: 'Minst ett MQTT-ämne måste konfigureras för effekt, energi eller statusövervakning',
+    loadingEntities: 'Laddar entiteter...',
+    loading: 'Laddar...',
+    failedToLoadEntities: 'Kunde inte ladda entiteter: {{error}}',
+    noEntitiesMatching: 'Inga entiteter hittade som matchar "{{search}}"',
+    noEntitiesAvailable: 'Inga entiteter tillgängliga',
+    searchingEntities: 'Söker i alla entiteter ({{count}} hittade)',
+    showingEntities: 'Visar switch, light, input_boolean ({{count}} tillgängliga)',
+    energyMonitoringOptional: 'Energiövervakning (valfritt)',
+    energyMonitoringHint: 'Sök och välj sensorer som tillhandahåller effekt-/energidata.',
+    powerSensorW: 'Effektsensor (W)',
+    energyTodayKwh: 'Energi idag (kWh)',
+    totalEnergyKwh: 'Total energi (kWh)',
+    noMatchingSensors: 'Inga matchande sensorer',
+    none: 'Ingen',
+    mqttNotConfigured: 'MQTT-mäklare inte konfigurerad. Ställ in mäklaradress i',
+    mqttSettingsPath: 'Inställningar → Nätverk → MQTT-publicering',
+    mqttNotConfiguredSuffix: '(du behöver inte aktivera publicering, fyll bara i mäklaruppgifterna).',
+    mqttMonitorOnlyDescription: 'MQTT-kontakter tar emot effekt-/energidata via MQTT-prenumeration. På/av-kontroll är inte tillgänglig — använd din MQTT-mäklare eller hemautomatiseringssystem.',
+    powerMonitoring: 'Effektövervakning',
+    energyMonitoring: 'Energiövervakning',
+    stateMonitoring: 'Statusövervakning',
+    optional: 'valfritt',
+    topic: 'Topik',
+    jsonPath: 'JSON-sökväg',
+    multiplier: 'Multiplikator',
+    onValue: 'PÅ-värde',
+    mqttPowerHint: 'JSON-sökväg extraherar värde från JSON-nyttolast (t.ex. "power_l1"). Lämna tomt om ämnet publicerar råa numeriska värden.\nAnvänd multiplikator 0,001 för mW→W, 1000 för kW→W.',
+    mqttEnergyHint: 'JSON-sökväg extraherar värde från JSON-nyttolast. Lämna tomt för råa värden.\nAnvänd multiplikator 0,001 för Wh→kWh, 1000 för MWh→kWh.',
+    mqttStateHint: 'JSON-sökväg extraherar värde från JSON-nyttolast. Lämna tomt för råa värden.\nPÅ-värde: den exakta strängen som betyder "PÅ". Lämna tomt för auto-upptäckt (PÅ, true, 1).',
+    // REST kontakt
+    restControl: 'Kontroll',
+    restOnUrl: 'Sätt PÅ-URL',
+    restOffUrl: 'Sätt AV-URL',
+    restOnBody: 'PÅ-förfrågningsinnehåll',
+    restOffBody: 'AV-förfrågningsinnehåll',
+    restMethod: 'HTTP-metod',
+    restHeaders: 'Anpassade huvuden (JSON)',
+    restStatusUrl: 'Status-URL',
+    restStatusPath: 'Status JSON-sökväg',
+    restStatusOnValue: 'PÅ-värde',
+    restPowerUrl: 'Effekt-URL',
+    restPowerPath: 'Effekt JSON-sökväg',
+    restPowerMultiplier: 'Effektmultiplikator',
+    restEnergyUrl: 'Energi-URL',
+    restEnergyPath: 'Energi JSON-sökväg (idag)',
+    restEnergyTotalPath: 'Energi JSON-sökväg (livstid)',
+    restEnergyTotalMultiplier: 'Livstidsmultiplikator',
+    restEnergyTotalPathHint: 't.ex. aenergy.total',
+    restEnergyTotalHint:
+      'Många kontakter — varje Shelly bland dem — rapporterar endast en livstidsräknare som aldrig nollställs. Den hör hit, inte i fältet ovan: läs som dagens användning skulle den aldrig nollställas vid midnatt, och Igår och Totalt skulle förbli tomma. Bambuddy beräknar Idag och Igår utifrån den, vilket tar en eller två dagars avläsningar att fylla i. En Shelly rapporterar wattimmar, så använd en multiplikator på 0,001.',
+    restEnergyMultiplier: 'Energimultiplikator',
+    restUrlRequired: 'Minst en URL (PÅ eller AV) krävs för REST-kontakter',
+    restHeadersHint: 't.ex. {"Authorization": "Bearer din-token"}',
+    restBodyHint: 't.ex. PÅ, {"state": "on"}',
+    restStatusHint: 'URL för att hämta aktuell status',
+    restPathHint: 't.ex. state eller data.power.status',
+    restPowerUrlHint: 'Separat URL för effektdata (använder Status-URL om tom)',
+    restEnergyUrlHint: 'Separat URL för energidata (använder Status-URL om tom)',
+    restEnergyHint: 'Varje värde kan använda sin egen URL eller falla tillbaka till Status-URL. Använd multiplikatorer för enhetsomvandling (t.ex. 0,001 för att konvertera Wh till kWh).',
+    testConnection: 'Testa anslutning',
+    connectionSuccess: 'Anslutning lyckades',
+    noSwitchesInSwitchbar: 'Inga växlar i kontaktpanelen',
+    enableSwitchbarHint: 'Aktivera "Visa i kontaktpanel" i Inställningar > Kontakter',
+  },
+
+  // Notifications
+  notifications: {
+    // Provider types
+    providerTypes: {
+      callmebot: 'CallMeBot/WhatsApp',
+      ntfy: 'ntfy',
+      pushover: 'Pushover',
+      telegram: 'Telegram',
+      email: 'E-post',
+      discord: 'Discord',
+      webhook: 'Webhook',
+      homeassistant: 'Home Assistant',
+      bark: 'Bark',
+    },
+    // Provider descriptions
+    providerDescriptions: {
+      email: 'SMTP e-postnotiser',
+      telegram: 'Notiser via Telegram-bot',
+      discord: 'Skicka till Discord-kanal via webhook',
+      ntfy: 'Gratis, självhostade pushnotiser',
+      pushover: 'Enkla, pålitliga pushnotiser',
+      callmebot: 'Gratis WhatsApp-notiser via CallMeBot',
+      webhook: 'Generisk HTTP POST till valfri URL',
+      homeassistant: 'Permanenta notiser i Home Assistant-instrumentpanel',
+      bark: 'iOS push-notiser via Bark (självhostbar)',
+    },
+    // NotificationProviderCard
+    lastSuccess: 'Senast: {{date}}',
+    error: 'Fel',
+    printer: 'Skrivare:',
+    allPrinters: 'Alla skrivare',
+    sendTestNotification: 'Skicka testnotis',
+    eventSettings: 'Händelseinställningar',
+    enabled: 'Aktiverad',
+    sendFromProvider: 'Skicka notiser från denna leverantör',
+    // Event categories
+    printEvents: 'Utskriftshändelser',
+    printerStatus: 'Skrivarstatus',
+    amsAlarms: 'AMS-larm',
+    amsHtAlarms: 'AMS-HT-larm',
+    printQueue: 'Utskriftskö',
+    // Event tags (badges)
+    start: 'Start',
+    plateCheck: 'Plattkontroll',
+    complete: 'Slutförd',
+    failed: 'Misslyckad',
+    stopped: 'Stoppad',
+    progress: 'Förlopp',
+    offline: 'Offline',
+    lowFilament: 'Lågt filament',
+    maintenance: 'Underhåll',
+    amsHumidity: 'AMS-luftfuktighet',
+    amsTemp: 'AMS-temperatur',
+    amsDryingSuspended: 'Torkning pausad',
+    amsHtHumidity: 'AMS-HT-luftfuktighet',
+    amsHtTemp: 'AMS-HT-temperatur',
+    bedCooled: 'Byggplatta kyld',
+    firstLayer: 'Första skikt',
+    quiet: 'Tyst',
+    digest: 'Sammanfattning {{time}}',
+    // Event labels (expanded settings)
+    printStarted: 'Utskrift startad',
+    plateNotEmpty: 'Platta inte tom',
+    plateNotEmptyDescription: 'Objekt upptäckta före utskrift',
+    plateClearRequired: 'Platt-rensning krävs',
+    plateClearRequiredDescription: 'Utskrift slutförd, kön väntar på plattbekräftelse',
+    plateClear: 'Platta rensad',
+    printCompleted: 'Utskrift slutförd',
+    bedCooledLabel: 'Byggplatta kyld',
+    bedCooledDescription: 'Byggplattan kyld under tröskelvärdet efter utskrift',
+    firstLayerCompleteLabel: 'Första skikt klart',
+    firstLayerCompleteDescription: 'Notis med ögonblicksbild när första skiktet är klart',
+    missingSpoolAssignmentLabel: 'Rulltilldelning saknas',
+    billingChargeFailedLabel: 'Faktureringsavgift misslyckades',
+    billingChargeFailedDescription: 'Notis när utskriftskostnader inte kunde registreras',
+    missingSpoolAssignmentDescription: 'Notis när utskrift startar och nödvändiga fack saknar tilldelad rulle',
+    printFailed: 'Utskrift misslyckades',
+    printStopped: 'Utskrift stoppad',
+    progressMilestones: 'Förloppsmilstolpar',
+    progressMilestonesDescription: 'Notis vid 25%, 50%, 75%',
+    printerOffline: 'Skrivare offline',
+    printerError: 'Skrivarfel',
+    aiFailureDetection: 'AI-felsdetektering',
+    aiFailureDetectionDescription: 'Notis när Obico AI upptäcker ett möjligt utskriftsfel',
+    lowFilamentLabel: 'Lågt filament',
+    maintenanceDue: 'Underhåll förfallit',
+    maintenanceDueDescription: 'Notis när underhåll behövs',
+    amsHumidityHigh: 'Hög AMS-luftfuktighet',
+    amsHumidityHighDescription: 'AMS-luftfuktighet överskrider tröskelvärdet',
+    amsTemperatureHigh: 'Hög AMS-temperatur',
+    amsTemperatureHighDescription: 'AMS-temperatur överskrider tröskelvärdet',
+    amsDryingSuspendedTitle: 'Auto-torkning pausad',
+    amsDryingSuspendedDescription: 'Automatisk torkning avbröts för en AMS-enhet eftersom luftfuktigheten aldrig sjönk under tröskelvärdet',
+    amsHtHumidityHigh: 'Hög AMS-HT-luftfuktighet',
+    amsHtHumidityHighDescription: 'AMS-HT-luftfuktighet överskrider tröskelvärdet',
+    amsHtTemperatureHigh: 'Hög AMS-HT-temperatur',
+    amsHtTemperatureHighDescription: 'AMS-HT-temperatur överskrider tröskelvärdet',
+    // Inventory stock alert events
+    inventoryAlerts: 'Lagerlarm',
+    stockReorderAlert: 'Påfyllningslarm',
+    stockReorderAlertDescription: 'Artikel har nått sin påfyllningsnivå',
+    stockBreakAlert: 'Lagerslutslarm',
+    stockBreakAlertDescription: 'Lagret kommer att ta slut innan påfyllning ankommer',
+    // Queue events
+    jobAdded: 'Jobb tillagt',
+    jobAddedDescription: 'Jobb tillagt i kön',
+    jobAssigned: 'Jobb tilldelat',
+    jobAssignedDescription: 'Modellbaserat jobb tilldelat till skrivare',
+    jobStarted: 'Jobb startat',
+    jobStartedDescription: 'Köjobb startade utskrift',
+    jobWaiting: 'Jobb väntar',
+    jobWaitingDescription: 'Jobb väntar på filament eller skrivare',
+    jobSkipped: 'Jobb hoppades över',
+    jobSkippedDescription: 'Jobb hoppades över (föregående misslyckades)',
+    jobFailed: 'Jobb misslyckades',
+    jobFailedDescription: 'Jobb kunde inte starta',
+    queueComplete: 'Kö slutförd',
+    queueCompleteDescription: 'Alla köjobb slutförda',
+    // Quiet hours
+    quietHours: 'Tysta timmar',
+    noNotificationsDuring: 'Inga notiser under dessa timmar',
+    editProviderToChangeQuietHours: 'Redigera leverantör för att ändra tysta timmar',
+    // Daily digest
+    dailyDigest: 'Daglig sammanfattning',
+    batchNotifications: 'Samla notiser till en daglig sammanfattning',
+    sendAt: 'Skicka klockan {{time}}',
+    editProviderToChangeDigestTime: 'Redigera leverantör för att ändra sammanfattningstid',
+    // Actions
+    edit: 'Redigera',
+    deleteProvider: 'Ta bort notisleverantör',
+    deleteConfirm: 'Är du säker på att du vill ta bort "{{name}}"? Detta kan inte ångras.',
+    delete: 'Ta bort',
+    // AddNotificationModal
+    addTitle: 'Lägg till notisleverantör',
+    editTitle: 'Redigera notisleverantör',
+    nameLabel: 'Namn *',
+    namePlaceholder: 'Mina notiser',
+    providerTypeLabel: 'Leverantörstyp *',
+    configuration: 'Konfiguration',
+    testConfiguration: 'Testa konfiguration',
+    printerFilter: 'Skrivarfilter',
+    onlyFromPrinter: 'Skicka notiser endast för händelser från denna skrivare',
+    quietHoursDnd: 'Tysta timmar (Stör ej)',
+    quietStart: 'Start',
+    quietEnd: 'Slut',
+    dailyDigestLabel: 'Daglig sammanfattning',
+    sendDigestAt: 'Skicka sammanfattning klockan',
+    digestCollected: 'Händelser kommer att samlas och skickas som en sammanfattning vid denna tid',
+    notificationEvents: 'Notishändelser',
+    progressPercent: '(25%, 50%, 75%)',
+    bedCooledAfterPrint: '(efter utskrift slutförs)',
+    haSensorAlert: 'Sensorlarm',
+    haSensorAlertDescription: '(en kopplad Home Assistant-sensor behöver uppmärksamhet)',
+    locationHaSensorAlert: 'Sensorlarm för lagringsplats',
+    locationHaSensorAlertDescription: '(en Home Assistant-sensor som är kopplad till en lagringsplats behöver uppmärksamhet)',
+    // Per-event ntfy priority (#990)
+    eventPriority: {
+      sectionTitle: 'ntfy-prioritet',
+      helpNtfy: 'Välj en prioritet för varje aktiverad händelse. ntfy använder dessa för att eskalera larm (ljud, synlighet, push-beteende). Nivåer som inte sätts här använder ntfy-serverns standard.',
+      min: 'Min',
+      low: 'Låg',
+      default: 'Standard',
+      high: 'Hög',
+      urgent: 'Brådskande',
+    },
+    cancel: 'Avbryt',
+    save: 'Spara',
+    add: 'Lägg till',
+    nameRequired: 'Namn krävs',
+    fieldRequired: '{{field}} krävs',
+    haDataInvalid: 'Data-fältet måste vara ett giltigt JSON-objekt, t.ex. {"priority": "high", "ttl": 0}',
+    // Config field labels
+    phoneNumber: 'Telefonnummer',
+    apiKey: 'API-nyckel',
+    serverUrl: 'Server-URL',
+    topic: 'Ämne',
+    authToken: 'Autentiseringstoken',
+    userKey: 'Användarnyckel',
+    appToken: 'App-nyckel',
+    priority: 'Prioritet',
+    pushoverRetry: 'Nödåterförsök (s)',
+    pushoverExpire: 'Nödutgång (s)',
+    botToken: 'Bot-token',
+    chatId: 'Chat-ID',
+    telegramThreadId: 'Forumämnes-ID',
+    telegramThreadIdHelp: 'Valfritt. Skickar till ett enda ämne i en forumgrupp — det sista numret i ämneslänken (t.me/c/.../25). Lämna tomt för det allmänna ämnet.',
+    telegramThreadIdInvalid: 'Forumämnes-ID måste vara ett nummer.',
+    smtpServer: 'SMTP-server',
+    smtpPort: 'SMTP-port',
+    security: 'Säkerhet',
+    authentication: 'Autentisering',
+    username: 'Användarnamn',
+    password: 'Lösenord',
+    fromEmail: 'Från e-post',
+    toEmail: 'Till e-post',
+    webhookUrl: 'Webhook-URL',
+    payloadFormat: 'Nyttolastsformat',
+    authorization: 'Autorisation',
+    titleFieldName: 'Titel-fältnamn',
+    messageFieldName: 'Meddelande-fältnamn',
+    // NotificationTemplateEditor
+    editTemplate: 'Redigera mall: {{name}}',
+    titleLabel: 'Titel',
+    bodyLabel: 'Brödtext',
+    titlePlaceholder: 'Notistitel...',
+    bodyPlaceholder: 'Notisbrödtext...',
+    availableVariables: 'Tillgängliga variabler',
+    clickToInsert: 'Klicka för att infoga vid markörpositionen i brödtext',
+    livePreview: 'Live-förhandsvisning',
+    hide: 'Dölj',
+    show: 'Visa',
+    loadingPreview: 'Laddar förhandsvisning...',
+    enterTemplateContent: 'Ange mallinnehåll för att se förhandsvisning',
+    titlePreview: 'Titel:',
+    bodyPreview: 'Brödtext:',
+    resetToDefault: 'Återställ till standard',
+    titleRequired: 'Titel krävs',
+    bodyRequired: 'Brödtext krävs',
+    // NotificationLogViewer
+    notificationLog: 'Notislogg',
+    showFailedOnly: 'Visa endast misslyckade',
+    last24Hours: 'Senaste 24 timmarna',
+    last7Days: 'Senaste 7 dagarna',
+    last30Days: 'Senaste 30 dagarna',
+    last90Days: 'Senaste 90 dagarna',
+    justNow: 'Precis nu',
+    noFailedNotifications: 'Inga misslyckade notiser',
+    noNotificationsLogged: 'Inga notiser loggade',
+    unknownProvider: 'Okänd leverantör',
+    logTitle: 'Titel',
+    logMessage: 'Meddelande',
+    logError: 'Fel',
+    logProvider: 'Leverantör: {{type}}',
+    logTime: 'Tid: {{time}}',
+    refresh: 'Uppdatera',
+    clearOld: 'Rensa gamla',
+    statsSummary: 'Senaste {{days}} dagarna:',
+    statsNotifications: 'notiser',
+    statsSent: '{{count}} skickade',
+    statsFailed: '{{count}} misslyckade',
+    // Event type labels (for log viewer)
+    eventTypes: {
+      print_start: 'Utskrift startad',
+      print_complete: 'Utskrift slutförd',
+      print_failed: 'Utskrift misslyckades',
+      print_stopped: 'Utskrift stoppad',
+      print_progress: 'Förlopp',
+      printer_offline: 'Skrivare offline',
+      printer_error: 'Skrivarfel',
+      filament_low: 'Lågt filament',
+      maintenance_due: 'Underhåll förfallit',
+      test: 'Test',
+    },
+    // User email notification preferences
+    userEmail: {
+      title: 'Notiser',
+      emailNotifications: 'E-postnotiser',
+      emailNotificationsDesc: 'Ta emot e-postnotiser för dina egna utskriftsjobb. E-postmeddelanden skickas med hjälp av systemets SMTP-inställningar som konfigurerats i avancerad autentisering.',
+      sendingTo: 'Notiser kommer att skickas till',
+      noEmailWarning: 'Ditt konto har ingen e-postadress. Kontakta en administratör för att lägga till en.',
+      printJobNotifications: 'Utskriftsjobbnotiser',
+      printJobNotificationsDesc: 'Välj vilka händelser som utlöser e-postnotiser för utskriftsjobb som du skickar in.',
+      printJobStarts: 'Utskriftsjobb startar',
+      printJobStartsDesc: 'Få en notis när ditt utskriftsjobb börjar.',
+      printJobFinishes: 'Utskriftsjobb slutförs',
+      printJobFinishesDesc: 'Få en notis när ditt utskriftsjobb slutförs.',
+      printErrors: 'Utskriftsfel',
+      printErrorsDesc: 'Få en notis när ditt utskriftsjobb misslyckas eller stöter på ett fel.',
+      printJobStops: 'Utskriftsjobb stoppas',
+      printJobStopsDesc: 'Få en notis när ditt utskriftsjobb avbryts eller stoppas.',
+      saveSuccess: 'Notisinställningar sparade.',
+      saveError: 'Kunde inte spara notisinställningar.',
+    },
+  },
+
+  // Rich Text Editor
+  richTextEditor: {
+    bold: 'Fet',
+    italic: 'Kursiv',
+    underline: 'Understruken',
+    bulletList: 'Punktlista',
+    numberedList: 'Numrerad lista',
+    alignLeft: 'Vänsterjustera',
+    alignCenter: 'Centrera',
+    alignRight: 'Högerjustera',
+    addLink: 'Lägg till länk',
+    removeLink: 'Ta bort länk',
+  },
+
+  // External Links
+  externalLinks: {
+    title: 'Sidofältslänkar',
+    sidebarLayout: 'Sidofält',
+    sidebarLayoutDescription: 'Visa eller dölj inbyggda sidor, lägg till externa länkar och dra objekt för att omordna sidofältsnavigeringen.',
+    systemPages: 'Bambuddy-sidor',
+    externalLinks: 'Externa länkar',
+    visibleInSidebar: 'Synlig i sidofält',
+    hiddenFromSidebar: 'Dold från sidofält',
+    requiredInSidebar: 'Obligatorisk i sidofält',
+    hidePage: 'Dölj sida',
+    showPage: 'Visa sida',
+    settingsCannotBeHidden: 'Inställningar kan ej döljas',
+    noLinksConfigured: 'Inga externa länkar konfigurerade',
+    deleteLink: 'Ta bort länk',
+    removeCustomIcon: 'Ta bort anpassad ikon',
+    openInNewTab: 'Öppna i ny flik',
+    placeholders: {
+      linkName: 'Min länk',
+    },
+  },
+
+  // Keyboard Shortcuts Modal
+  keyboardShortcuts: {
+    title: 'Tangentbordsgenvägar',
+    navigation: 'Navigering',
+    archivesSection: 'Arkiv',
+    kProfilesSection: 'K-profiler',
+    generalSection: 'Allmänt',
+    shortcuts: {
+      goToPrinters: 'Gå till Skrivare',
+      goToArchives: 'Gå till Arkiv',
+      goToQueue: 'Gå till Kö',
+      goToStats: 'Gå till Statistik',
+      goToProfiles: 'Gå till Molnprofiler',
+      goToSettings: 'Gå till Inställningar',
+      focusSearch: 'Fokusera sökning',
+      openUploadModal: 'Öppna uppladdningsmodal',
+      clearSelection: 'Rensa val / ta bort fokus från inmatning',
+      contextMenu: 'Kontextmeny på kort',
+      refreshProfiles: 'Uppdatera profiler',
+      newProfile: 'Ny profil',
+      exitSelectionMode: 'Avsluta urvalsläge',
+      showHelp: 'Visa denna hjälp',
+    },
+    footer: 'Tryck på Esc eller klicka utanför för att stänga',
+  },
+
+  // Notification Log
+  notificationLog: {
+    title: 'Notislogg',
+    events: {
+      printStarted: 'Utskrift startad',
+      printComplete: 'Utskrift slutförd',
+      printFailed: 'Utskrift misslyckades',
+      printStopped: 'Utskrift stoppad',
+      progress: 'Förlopp',
+      printerOffline: 'Skrivare offline',
+      printerError: 'Skrivarfel',
+      lowFilament: 'Lågt filament',
+      maintenanceDue: 'Underhåll utebliven',
+      test: 'Test',
+    },
+    timeAgo: {
+      justNow: 'Precis nu',
+      minutesAgo: '{{minutes}}m sedan',
+      hoursAgo: '{{hours}}t sedan',
+    },
+  },
+
+  // Restore/Backup Modal
+  restoreBackup: {
+    title: 'Återställ säkerhetskopia',
+    restoring: 'Återställer...',
+    restoreComplete: 'Återställning slutförd',
+    restoreFailed: 'Kunde inte återställa',
+    importSettings: 'Importera inställningar från en säkerhetskopia',
+    pleaseWait: 'Vänligen vänta medan din data återställs',
+    clickToSelect: 'Klicka för att välja säkerhetskopia (.json eller .zip)',
+    howDuplicateHandling: 'Hur dubbletter hanteras:',
+    categories: {
+      printers: 'Skrivare',
+      smartPlugs: 'Kontakter',
+      notificationProviders: 'Notisleverantörer',
+      filaments: 'Filament',
+      archives: 'Arkiv',
+      pendingUploads: 'Väntande uppladdningar',
+      settingsTemplates: 'Inställningar & mallar',
+    },
+    matchingInfo: {
+      printers: 'matchade efter serienummer',
+      smartPlugs: 'matchade efter IP-adress',
+      notificationProviders: 'matchade efter namn',
+      filaments: 'matchade efter namn + typ + märke',
+      archives: 'matchade efter innehållshash',
+      pendingUploads: 'matchade efter filnamn',
+      settingsTemplates: 'skrivs alltid över',
+    },
+    replaceExisting: 'Ersätt befintlig data',
+    keepExisting: 'Behåll befintlig data',
+    replaceDescription: 'Skriv över objekt som redan finns med säkerhetskopia',
+    keepDescription: 'Återställ endast objekt som inte redan finns',
+    caution: 'Varning:',
+    cautionText: 'Att skriva över kommer att ersätta dina nuvarande konfigurationer med data från säkerhetskopian. Skrivaråtkomstkoder skrivs aldrig över av säkerhetsskäl.',
+    itemsRestored: 'Objekt återställda',
+    itemsSkipped: 'Objekt hoppade över',
+    restored: 'Återställd',
+    skipped: 'Hoppades över (finns redan)',
+    filesLabel: 'Filer (3MF, minibilder, etc.)',
+    newApiKeysGenerated: 'Nya API-nycklar genererade',
+    newApiKeysWarning: 'Dessa nycklar visas endast en gång. Kopiera dem nu!',
+    processingBackup: 'Bearbetar säkerhetskopia...',
+    noDataFound: 'Ingen data hittades att återställa i säkerhetskopian.',
+    failedToRestore: 'Kunde inte återställa säkerhetskopia. Kontrollera filformatet.',
+  },
+
+  // Backup Export Modal
+  backupExport: {
+    title: 'Exportera säkerhetskopia',
+    selectData: 'Välj data att inkludera',
+    selectAll: 'Markera alla',
+    selectNone: 'Avmarkera alla',
+    categoryDescriptions: {
+      settings: 'Språk, tema, uppdateringsinställningar',
+      notifications: 'ntfy, Pushover, Discord, etc.',
+      templates: 'Anpassade meddelandemallar',
+      smartPlugs: 'Tasmota-kontaktkonfigurationer',
+      externalLinks: 'Sidofältslänkar till externa tjänster',
+      printers: 'Skrivarinformation (åtkomstkoder exkluderade)',
+      plateDetection: 'Referensbilder för tomma plattor',
+      filaments: 'Filamenttyper och kostnader',
+      maintenance: 'Anpassade underhållsscheman',
+      archives: 'All utskriftsdata + filer (3MF, minibilder, foton)',
+      projects: 'Projekt, BOM-objekt och bilagor',
+      pendingUploads: 'Uppladdningar från virtuell skrivare som väntar på granskning',
+      apiKeys: 'Webhook API-nycklar (nya nycklar genereras vid import)',
+    },
+    requiresPrinters: 'Kräver att Skrivare är valda',
+    zipFileWarning: 'En ZIP-fil kommer att skapas.',
+    zipFileDescription: 'Inkluderar alla 3MF-filer, minibilder, timelapse och foton. Detta kan ta en stund och resultera i en stor fil.',
+    includeAccessCodes: 'Inkludera åtkomstkoder',
+    includeAccessCodesDescription: 'För överföring till en annan maskin',
+    includeAccessCodesWarning: 'Åtkomstkoder kommer att inkluderas i klartext. Håll denna säkerhetskopia säker!',
+    categoriesSelected: '{{selectedCount}} kategorier valda',
+  },
+
+  // Pending Uploads Panel
+  pendingUploads: {
+    placeholders: {
+      notes: 'Lägg till anteckningar om denna utskrift...',
+    },
+    discardUpload: 'Kassera uppladdning',
+    archiveAllUploads: 'Arkivera alla uppladdningar',
+    discardAllUploads: 'Kassera alla uppladdningar',
+    archive: 'Arkivera',
+    timeAgo: {
+      justNow: 'Precis nu',
+      minutesAgo: '{{minutes}}m sedan',
+      hoursAgo: '{{hours}}t sedan',
+      daysAgo: '{{days}}d sedan',
+    },
+  },
+
+  // API Browser
+  apiBrowser: {
+    placeholders: {
+      requestBody: 'JSON-förfrågningsinnehåll...',
+      searchEndpoints: 'Sök ändpunkter...',
+    },
+  },
+
+  // Configure AMS Slot Modal
+  configureAmsSlot: {
+    title: 'Konfigurera AMS-fack',
+    slotConfigured: 'Fack konfigurerat!',
+    configuringSlot: 'Konfigurerar fack:',
+    slotLabel: '{{ams}} fack {{slot}}',
+    searchPresets: 'Sök förinställningar...',
+    colorPlaceholder: 'Färgnamn eller hex (t.ex. brun, FF8800)',
+    clearCustomColor: 'Rensa anpassad färg',
+    noCloudPresets: 'Inga molnförinställningar. Logga in på Bambu Cloud för att synkronisera.',
+    noPresetsAvailable: 'Inga förinställningar tillgängliga. Logga in på Bambu Cloud eller importera lokala profiler.',
+    noMatchingPresets: 'Inga matchande förinställningar hittade.',
+    custom: 'Anpassad',
+    builtin: 'Inbyggd',
+    orcaCloud: 'Orca Cloud',
+    bambuCloud: 'Bambu Cloud',
+    settingsSentToPrinter: 'Inställningar skickade till skrivare',
+    filamentProfile: 'Filamentprofil',
+    kProfileLabel: 'K-profil (Tryckförskott)',
+    filteringFor: 'Filtrerar för: {{material}}',
+    noKProfile: 'Ingen K-profil (använd standard 0,020)',
+    noMatchingKProfiles: 'Inga matchande K-profiler hittade. Standard K=0,020 kommer att användas.',
+    otherKProfiles: 'Andra K-profiler på denna skrivare',
+    selectFilamentFirst: 'Välj en filamentprofil först',
+    kFromCalibration: 'K={{value}} från skrivarkalibrering',
+    customColorLabel: 'Anpassad färg (valfritt)',
+    presetColors: '{{name}}-färger:',
+    showLessColors: 'Visa färre färger',
+    showMoreColors: 'Visa fler färger',
+    clear: 'Rensa',
+    hexLabel: 'Hex: #{{hex}}',
+    resetting: 'Återställer...',
+    resetSlot: 'Återställ fack',
+    cancel: 'Avbryt',
+    configuring: 'Konfigurerar...',
+    configureSlot: 'Konfigurera fack',
+  },
+
+  // Git Backup Settings
+  githubBackup: {
+    title: 'Git-säkerhetskopia',
+    history: 'Historik',
+    downloadBackup: 'Ladda ner säkerhetskopia',
+    restoreBackup: 'Återställ säkerhetskopia',
+    noBackupsYet: 'Inga säkerhetskopior än',
+  },
+
+  // Email Settings
+  emailSettings: {
+    placeholders: {
+      fromName: 'Bambuddy',
+    },
+  },
+
+  // Tag Management Modal
+  tagManagement: {
+    searchTags: 'Sök taggar...',
+    renameTag: 'Döp om tagg',
+    deleteTag: 'Ta bort tagg',
+  },
+
+  // Notification Template Editor
+  notificationTemplates: {
+    placeholders: {
+      title: 'Notistitel...',
+      body: 'Notisbrödtext...',
+    },
+  },
+
+  // Batch Tag Modal
+  batchTag: {
+    placeholders: {
+      newTag: 'Ange ny tagg...',
+    },
+  },
+
+  // Photo Gallery Modal
+  photoGallery: {
+    deletePhoto: 'Ta bort foto',
+  },
+
+  // Filament Hover Card
+  filamentHoverCard: {
+    copySpoolUuid: 'Kopiera rullens UUID',
+  },
+
+  // K Profiles View
+  kProfilesView: {
+    hasNote: 'Har anteckning',
+    copyProfile: 'Kopiera profil',
+  },
+
+  // Layout/Navigation
+  layout: {
+    openMenu: 'Öppna meny',
+    noPermissionSystemInfo: 'Du har inte behörighet att visa systeminformation',
+  },
+
+  // Dashboard
+  dashboard: {
+    dragToReorder: 'Dra för att omordna',
+    hideWidget: 'Dölj widget',
+  },
+
+  // Notification Provider Card
+  notificationProviderCard: {
+    deleteNotificationProvider: 'Ta bort notisleverantör',
+  },
+
+  // File Manager Modal
+  fileManagerModal: {
+    closeFileManager: 'Stäng filhanterare',
+    sortFiles: 'Sortera filer',
+    goToParentFolder: 'Gå till överordnad mapp',
+    threeView: '3D-vy',
+  },
+
+  // Embedded Camera Viewer
+  embeddedCameraViewer: {
+    refreshStream: 'Uppdatera ström',
+    close: 'Stäng',
+    zoomOut: 'Zooma ut',
+    resetZoom: 'Återställ zoom',
+    zoomIn: 'Zooma in',
+    dragToResize: 'Dra för att ändra storlek',
+  },
+
+  // Timelapse Viewer
+  timelapseViewer: {
+    skipBack5s: 'Hoppa bakåt 5s',
+    skipForward5s: 'Hoppa framåt 5s',
+  },
+
+  // Notification Providers
+  notificationProviders: {
+    descriptions: {
+      email: 'SMTP e-postnotiser',
+      telegram: 'Notiser via Telegram-bot',
+      discord: 'Skicka till Discord-kanal via webhook',
+      ntfy: 'Gratis, självhostade push-notiser',
+      pushover: 'Enkla, pålitliga push-notiser',
+      callmebot: 'Gratis WhatsApp-notiser via CallMeBot',
+      webhook: 'Generisk HTTP POST till valfri URL',
+    },
+  },
+
+  // Log Viewer
+  logViewer: {
+    searchPlaceholder: 'Sök meddelande eller loggnamn...',
+    noLogEntries: 'Inga loggposter hittade',
+  },
+
+  // Switchbar Popover
+  switchbarPopover: {
+    noSwitchesInSwitchbar: 'Inga växlar i kontaktpanelen',
+  },
+
+  // Project Page Modal
+  projectPageModal: {
+    placeholders: {
+      title: 'Titel',
+      designer: 'Designer',
+      license: 'Licens',
+      description: 'Ange beskrivning...',
+      profileTitle: 'Profilnamn',
+      profileDescription: 'Profilbeskrivning...',
+    },
+  },
+
+  // Spoolman Settings
+  spoolmanSettings: {},
+
+  // Time
+  time: {
+    unknown: '-',
+    waiting: 'Väntar',
+    justNow: 'Precis nu',
+    now: 'Nu',
+    minsAgo: '{{count}}m sedan',
+    inMins: 'om {{count}}m',
+    hoursAgo: '{{count}}t sedan',
+    inHours: 'om {{count}}t',
+    daysAgo: '{{count}}d sedan',
+    inDays: 'om {{count}}d',
+  },
+
+  // SpoolBuddy Kiosk
+  spoolbuddy: {
+    nav: {
+      dashboard: 'Instrumentpanel',
+      ams: 'AMS',
+      inventory: 'Inventarium',
+      writeTag: 'Skriv tagg',
+      settings: 'Inställningar',
+    },
+    status: {
+      nfcReady: 'NFC redo',
+      nfcOff: 'NFC av',
+      offline: 'Offline',
+      online: 'Online',
+      noPrinters: 'Inga skrivare',
+      deviceOffline: 'Enhet offline',
+      waitingConnection: 'Väntar på enhetsanslutning...',
+      systemReady: 'System redo',
+      status: 'Status',
+    },
+    dashboard: {
+      readyToScan: 'Redo att skanna',
+      idleMessage: 'Placera en rulle på vågen för att identifiera den',
+      nfcHint: 'NFC-tagg kommer att läsas automatiskt',
+      device: 'Enhet',
+      syncWeight: 'Synkronisera vikt',
+      weightSynced: 'Synkroniserad!',
+      unknownTag: 'Okänd tagg',
+      newTag: 'Ny tagg upptäckt',
+      onScale: 'på våg',
+      linkSpool: 'Länka till rulle',
+      linkTagTitle: 'Länka tagg till rulle',
+      linkTag: 'Länka tagg',
+      selectSpool: 'Välj en rulle att länka denna tagg till:',
+      noUntagged: 'Inga rullar utan taggar hittade',
+      tagDetected: 'Tagg upptäckt',
+      noTag: 'Ingen tagg',
+      tagId: 'Tagg',
+      grossWeight: 'Bruttovikt',
+      spoolSize: 'Rullstorlek',
+      close: 'Stäng',
+      currentSpool: 'Aktuell rulle',
+      plateReady: 'Platta redo: {{name}}',
+      plateReadyLabel: 'Plattor redo att rensa',
+      plateClearAction: 'Rensa',
+      plateClearedToast: 'Platta markerad som rensad',
+      plateClearFailed: 'Kunde inte markera platta som rensad',
+    },
+    modal: {
+      spoolDetected: 'Rulle upptäckt',
+      assignToAms: 'Tilldela till AMS',
+      syncWeight: 'Synkronisera vikt',
+      weightSynced: 'Synkroniserad!',
+      syncing: 'Synkroniserar...',
+      newTagDetected: 'Ny tagg upptäckt',
+      addToInventory: 'Lägg till i inventarium',
+      assignToAmsTitle: 'Tilldela till AMS',
+      selectSlot: 'Välj ett fack',
+      assign: 'Tilldela',
+      assigning: 'Tilldelar...',
+      assignSuccess: 'Tilldelad!',
+      assignPendingInsert: 'Tilldelad. Facket kommer att konfigureras när du sätter in rullen.',
+      assignError: 'Kunde inte tilldela rulle. Försök igen.',
+      noPrinterSelected: 'Välj en skrivare...',
+      noAmsDetected: 'Ingen AMS upptäckt på denna skrivare',
+      slot: 'Fack',
+    },
+    weight: {
+      noReading: 'Ingen avläsning',
+      stable: 'Stabil',
+      measuring: 'Mäter...',
+      tare: 'Tara',
+      calibrate: 'Kalibrera',
+    },
+    spool: {
+      remaining: 'Återstående',
+      material: 'Material',
+      brand: 'Märke',
+      color: 'Färg',
+      coreWeight: 'Kärna',
+      labelWeight: 'Etikett',
+      scaleWeight: 'Våg',
+      netWeight: 'Nettovikt',
+      lastUsed: 'Senast använd',
+      unknownColor: 'Okänd färg',
+    },
+    ams: {
+      noData: 'Ingen AMS upptäckt',
+      connectAms: 'Anslut en AMS för att se filamentfack',
+      noPrinter: 'Ingen skrivare vald',
+      selectPrinter: 'Välj en skrivare från den övre menyn',
+      printerDisconnected: 'Skrivare frånkopplad',
+      humidity: 'Luftfuktighet',
+      level: 'Nivå',
+      active: 'Aktiv',
+      slot: 'Fack',
+      empty: 'Tomt',
+    },
+    inventory: {
+      search: 'Sök rullar...',
+      empty: 'Inga rullar i inventariet',
+      noResults: 'Inga matchande rullar',
+      spools: 'rullar',
+      addSpool: 'Lägg till rulle',
+    },
+    settings: {
+      // Tabs
+      tabDevice: 'Enhet',
+      tabDisplay: 'Skärm',
+      tabScale: 'Våg',
+      tabUpdates: 'Uppdateringar',
+      // Device tab
+      nfcReader: 'NFC-läsare',
+      type: 'Typ',
+      connection: 'Anslutning',
+      notConnected: 'Ej ansluten',
+      deviceInfo: 'Enhetsinformation',
+      hostname: 'Värdnamn',
+      uptime: 'Driftstid',
+      systemConfig: 'Backend & Autentisering',
+      backendUrl: 'Bambuddy Backend-URL',
+      apiToken: 'API-token',
+      apiTokenPlaceholder: 'Ange API-token',
+      saveConfig: 'Spara konfiguration',
+      systemQueued: 'Konfiguration köad.',
+      nfcDiagnostic: 'NFC-diagnostik',
+      scaleDiagnostic: 'Vågdiagnostik',
+      readTagDiagnostic: 'Läs tagg-diagnostik',
+      testNfc: 'Testa läsare',
+      testScale: 'Testa noggrannhet',
+      testReadTag: 'Läs tagg',
+      systemFieldsRequired: 'Backend-URL krävs.',
+      // Display tab
+      brightness: 'Ljusstyrka',
+      saved: 'Sparad',
+      noBacklight: 'Ingen DSI-bakgrundsbelysning upptäckt. Ljusstyrkekontroll kräver en DSI-display.',
+      screenBlank: 'Skärm avstängningstimeout',
+      screenBlankDesc: 'Skärmen stängs av efter inaktivitet. Tryck för att väcka.',
+      displayNote: 'Ljusstyrka tillämpas som ett mjukvarufilter.',
+      // Scale tab
+      scaleCalibration: 'Vågkalibrering',
+      currentWeight: 'Aktuell vikt',
+      tareOffset: 'Tara',
+      calFactor: 'Faktor',
+      knownWeight: 'Känd vikt',
+      calStep1: 'Ta bort alla föremål från vågen och tryck på Sätt noll.',
+      calStep2: 'Placera känd vikt på vågen.',
+      setZero: 'Sätt noll',
+      calibrateNow: 'Kalibrera',
+      calibrated: 'Kalibrerad',
+      tareSet: 'Tara-kommando skickad. Väntar på enhet...',
+      tareComplete: 'Tara slutförd!',
+      tareTimedOut: 'Tara timeout — körs SpoolBuddy-demon?',
+      tareFailed: 'Kunde inte skicka tarakommando',
+      zeroSet: 'Nollpunkt inställd. Placera känd vikt på vågen.',
+      calibrationDone: 'Kalibrering slutförd!',
+      calibrationFailed: 'Kalibrering misslyckades',
+      lastCalibrated: 'Senast kalibrerad',
+      stable: 'Stabil',
+      settling: 'Stabiliserar...',
+      firmware: 'Firmware',
+      scale: 'Våg',
+      noDevice: 'Ingen SpoolBuddy-enhet hittad',
+      // Updates tab
+      daemonVersion: 'Demonversion',
+      currentVersion: 'Aktuell',
+      versionPending: 'Väntar på demon...',
+      checking: 'Kontrollerar...',
+      checkUpdates: 'Sök efter uppdateringar',
+      updateAvailable: 'Uppdatering tillgänglig',
+      updateInstructions: 'Uppdatera via SSH: kör SpoolBuddy-installationsskriptet för att uppgradera.',
+      upToDate: 'Uppdaterad',
+      includeBeta: 'Inkludera betaversioner',
+    },
+    writeTag: {
+      tabExisting: 'Befintlig rulle',
+      tabNew: 'Ny rulle',
+      tabReplace: 'Ersätt tagg',
+      searchPlaceholder: 'Sök efter material, färg, märke...',
+      noUntaggedSpools: 'Inga rullar utan taggar',
+      noTaggedSpools: 'Inga rullar med taggar',
+      selectSpool: 'Välj en rulle, placera sedan en tom NTAG på läsaren',
+      placeTag: 'Placera en NTAG på läsaren',
+      tagReady: 'Tagg upptäckt — redo att skriva',
+      writeTag: 'Skriv tagg',
+      replaceTag: 'Ersätt tagg',
+      writing: 'Skriver tagg...',
+      waiting: 'Väntar på SpoolBuddy...',
+      writeSuccess: 'Tagg skriven!',
+      writeFailed: 'Kunde inte skriva tagg',
+      queueFailed: 'Kunde inte köa skrivkommando',
+      tryAgain: 'Försök igen',
+      cancel: 'Avbryt',
+      replaceWarning: 'Gamla taggen kommer att avlänkas. Ny tagg kommer att ersätta den.',
+      deviceOffline: 'SpoolBuddy är offline',
+      material: 'Material',
+      colorName: 'Färgnamn',
+      color: 'Färg',
+      brand: 'Märke',
+      weight: 'Vikt (g)',
+      createSpool: 'Skapa rulle',
+      creating: 'Skapar...',
+      spoolCreated: 'Rulle skapad! Redo att skriva.',
+      createFailed: 'Kunde inte skapa rulle',
+      incompleteDataWarning: 'Tagg skriven med ofullständig Spoolman-data',
+    },
+    quickMenu: {
+      printerPower: 'Skrivarström',
+      systemControls: 'System',
+      restartDaemon: 'Starta om demon',
+      restartBrowser: 'Starta om webbläsare',
+      reboot: 'Starta om',
+      shutdown: 'Stäng av',
+      swipeToClose: 'Svep ner för att stänga',
+      confirmTitle: 'Bekräfta',
+      confirmShutdown: 'Är du säker på att du vill stänga av SpoolBuddy? Du kommer att behöva fysisk åtkomst för att sätta på den igen.',
+      confirmReboot: 'Är du säker på att du vill starta om SpoolBuddy?',
+      confirmRestartDaemon: 'Starta om SpoolBuddy-demon? NFC och våg kommer att vara tillfälligt otillgängliga.',
+      confirmRestartBrowser: 'Starta om kiosk-webbläsaren? Skärmen kommer kort att bli tom.',
+      confirm: 'Bekräfta',
+      confirmPlugOn: 'Sätt på {{name}}?',
+      confirmPlugOff: 'Stäng av {{name}}?',
+      turnOn: 'Sätt på',
+      turnOff: 'Stäng av',
+    },
+  },
+
+  diagnostic: {
+    modalTitle: 'Anslutningsdiagnostik — {{name}}',
+    running: 'Kör diagnostik...',
+    runningElapsed: 'Kör diagnostik... ({{elapsed}}s)',
+    waitingForReportHint: 'Lyssnar efter att skrivaren ska publicera en statusrapport — detta kan ta upp till {{max}} sekunder.',
+    runFailed: 'Kunde inte köra diagnostik: {{error}}',
+    retry: 'Kör igen',
+    runButton: 'Kör diagnostik',
+    sectionTitle: 'Anslutningsdiagnostik',
+    sectionDescription: 'Kontrollera varför en skrivare inte ansluter eller inte skriver ut — portåtkomlighet, LAN-utvecklarläge, Docker-nätverksläge och inloggningsuppgifter.',
+    noPrinters: 'Inga skrivare konfigurerade.',
+    overall: {
+      ok: 'Inga problem hittade — skrivaranslutningen ser frisk ut.',
+      warnings: 'Skrivaren bör fungera, men vissa saker behöver uppmärksamhet.',
+      problems: 'Hittade problem som förklarar varför skrivaren inte ansluter eller skriver ut.',
+    },
+    check: {
+      port_mqtt: {
+        title: 'Kontrollport (MQTT 8883)',
+        pass: 'Åtkomlig — skrivaren accepterar kontrollanslutningar.',
+        fail: 'Port 8883 är otillgänglig. Skrivaren är avstängd, har en annan IP-adress, eller en brandvägg blockerar den. Verifiera skrivarens IP och att inget blockerar port 8883.',
+      },
+      port_ftps: {
+        title: 'Filöverföringsport (FTPS 990)',
+        pass: 'Åtkomlig — skickande av utskriftsfiler kommer att fungera.',
+        warn: 'Port 990 är otillgänglig. Övervakning kan fortfarande fungera, men skickande av utskrifter till skrivaren kommer att misslyckas. Se till att port 990 inte blockeras.',
+        warn_no_tls: 'Port 990 är öppen men skrivarens filservice slutför inte ett TLS-handskak. Utskriftsfiler, omslag och timelapse kan inte hämtas, så arkiv förblir tomma. Starta om skrivaren — att låsa upp porten kommer inte att hjälpa.',
+      },
+      external_storage: {
+        title: 'Lagra skickade filer på extern lagring (installationssteg 4)',
+        pass: 'Skrivaren rapporterar att detta alternativ är på — skickade filer kommer att lagras på SD-kortet och arkiv kommer att ha minibilder och slicer-inställningar.',
+        fail: 'Skrivaren rapporterar att detta alternativ är av. Aktivera "Lagra skickade filer på extern lagring" — på nyare firmware (P2S 01.02 / Bambu Studio 2.6+) finns växeln på skrivarens Utskriftsinställningar; på äldre versioner finns den i Bambu Studio / OrcaSlicers Enhetsflik. Utan det saknar varje arkiverad utskrift sin minibild och slicer-inställningar.',
+        skip: 'Kontrollerades inte — kräver en aktiv MQTT-anslutning. På äldre slicers där denna inställning endast finns i slicern rapporterar skrivaren aldrig det, så denna kontroll kommer att passera även när alternativet är av — verifiera installationssteg 4 manuellt.',
+        skip_unsupported_model: 'Denna modell har ett SD-kortfack men inget sätt att slå på alternativet — aktuell P1-serie-firmware exponerar inte växeln i Bambu Studio och skrivaren har ingen skärm. Inget att åtgärda här; arkiverade utskrifter kan sakna minibilder och slicer-inställningar tills Bambu Lab lägger till firmware-stöd.',
+        fail_no_media: 'Alternativet är aktiverat, men skrivaren rapporterar att det inte finns något kort eller sticka i sin kortplats, så det finns ingenstans för skickade filer att ta vägen. Sätt i ett och skriv ut igen – fram till dess kommer alla arkiverade utskrifter att sakna sina minibilder och slicing-metadata.',
+        warn_internal_storage: 'Alternativet är aktiverat och lagring finns, men den sista utskriften gick ändå till skrivarens interna lagring, som Bambuddy inte kan läsa. På H2-serien och P2S skickar Bambu Studios Skriv ut-knapp alltid dit det alternativ det är inställt på. Arkivet skrivs ut med namn och tidpunkt, men utan minibild eller metadata för slicern. För kompletta arkiv, starta utskrifter från Bambuddy eller slica i OrcaSlicer — eller i Bambu Studio, använd Skicka med Externt vald, och starta sedan utskriften.',
+        warn_internal_history: 'Alternativet är aktiverat och lagring finns, men den senaste utskriften kördes från en fil som redan fanns på skrivaren – en ny utskrift från dess skärm, en start från Handy eller en fil som skickades tidigare. Det biblioteket finns på den interna lagringen som Bambuddy inte kan läsa, och ingen inställning ändrar det, eftersom ingenting skickades för den utskriften. Den arkiverar fortfarande med sitt namn och tidpunkt, men utan en minibild eller slicer-metadata. För fullständiga arkiv, starta utskrifter från Bambuddy eller skicka dem från slicern.',
+      },
+      port_rtsps: {
+        title: 'Kameraport ({{protocol}} {{port}})',
+        pass: 'Åtkomlig — kameraströmmen kommer att fungera.',
+        warn: 'Port {{port}} är otillgänglig. Live-kameravyn kommer inte att fungera. Detta påverkar inte utskriften.',
+      },
+      macos_local_network: {
+        title: 'macOS lokala nätverksbehörighet',
+        pass: 'macOS tillåter Bambuddy att nå det lokala nätverket.',
+        warn_unsigned: 'Den Python som kör Bambuddy har ingen kodsignatur, så macOS har inget att koppla en lokal nätverksbehörighet till och släpper tyst varje anslutning till skrivaren - inget fel och ingen prompt. Kör Bambuddy-uppdateringen (install/update_macos.sh), som signerar den, starta sedan om Bambuddy. Tolk: {{executable}}',
+        warn_permission: 'Om skrivaren är påslagen och på den här adressen, öppna Systeminställningar > Sekretess & säkerhet > Lokalt nätverk och se till att den Python som kör Bambuddy är aktiverad. macOS släpper lokala anslutningar tyst när det inte är det, och uppdatering av Python kan lämna den gamla behörigheten bakom sig.',
+      },
+      network_mode: {
+        title: 'Docker-nätverksläge',
+        genericRuntime: 'en container',
+        pass: 'Körs i {{runtime}} med värdnätverk.',
+        warn: 'Bambuddy körs i {{runtime}} med bryggnätverk. Skrivaruppäckt och den virtuella skrivaren kräver värdnätverksläge — skapa containern igen i värdnätverksläge ("network_mode: host" i docker-compose, "--network=host" för Podman).',
+        skip: 'Körs inte i Docker — inte tillämpligt.',
+        skip_unknown: 'Bambuddy körs i {{runtime}}, men dess nätverksläge kunde inte fastställas. Om skrivarupptäckt eller den virtuella skrivaren inte fungerar, återskapa containern med värdnätverk.',
+        skip_system_container: 'Bambuddy körs i en {{runtime}} systemcontainer, som sitter på LAN som en virtuell maskin — inte tillämpligt.',
+      },
+      subnet: {
+        title: 'Nätverkssubnät',
+        pass: 'Skrivaren och Bambuddy är på samma subnät.',
+        warn: 'Skrivaren ({{printer_ip}}) och Bambuddy ({{host_ip}}) är på olika subnät. De kan inte nå varandra om inte routning mellan subnäten är konfigurerad.',
+        skip: 'Subnät kunde inte bestämmas — hoppade över.',
+      },
+      mqtt_auth: {
+        title: 'Skrivarens inloggningsuppgifter',
+        pass: 'Skrivaren accepterade anslutningen.',
+        fail: 'Skrivaren är åtkomlig men Bambuddy är inte ansluten till den. Åtkomstkoden eller serienumret är troligen fel — åtkomstkoden ändras varje gång LAN Only eller Utvecklarläge växlas, så kopiera den från skrivarens skärm igen. En skrivare som startar om, eller redan har nått sin gräns för samtidiga anslutningar, kan se ut på samma sätt.',
+        fail_auth_rejected: 'Skrivaren avvisade Bambuddys inloggningsuppgifter. Åtkomstkoden eller serienumret är fel — åtkomstkoden ändras varje gång LAN Only eller Utvecklarläge växlas, så kopiera den från skrivarens skärm och spara den i skrivarinställningarna.',
+        skip: 'Kontrollerades inte — skrivaren kunde inte nås.',
+      },
+      developer_mode: {
+        title: 'LAN-utvecklarläge',
+        pass: 'Utvecklarläge är aktiverat.',
+        fail: 'Utvecklarläge är AV på skrivaren. Aktivera det i skrivarens LAN-inställningar — och bekräfta med OK. Utan det kommer utskrifter inte att starta.',
+        skip: 'Kunde inte kontrolleras — kräver en aktiv anslutning till skrivaren.',
+      },
+      printer_publishing: {
+        title: 'Skrivaren publicerar status',
+        pass: 'Skrivaren publicerar statusuppdateringar — AMS, filament och K-profiler kommer att speglas korrekt till slicern.',
+        fail: 'MQTT-mäklaren accepterade anslutningen men skrivaren har inte publicerat några statusrapporter. Detta är nästan alltid ett felaktigt serienummer eller ett serienummer med felaktigt skiftläge — device/<serial>/report är skiftlägeskänsligt. Dubbelkolla serienumret i skrivarinställningarna mot skärmen på skrivaren.',
+        skip: 'Kunde inte kontrolleras — kräver en aktiv anslutning till skrivaren.',
+      },
+    },
+  },
+
+  systemHealth: {
+    sectionTitle: 'Systemhälsa',
+    sectionDescription: 'Söker i senaste loggar efter kända problem som du vanligtvis kan åtgärda själv, innan de blir till ett supportärende.',
+    rescan: 'Sök igen',
+    clean: 'Inga kända problem hittade i de senaste {{times}} loggposterna.',
+    logUnavailable: 'Filloggning är inaktiverad, så loggar kan inte sökas. Aktivera filloggning för att använda denna kontroll.',
+    learnMore: 'Hur du åtgärdar',
+    fixLabel: 'Åtgärd:',
+    occurrences: 'Set {{times}}× — senast {{lastSeen}}',
+    category: {
+      layer8: 'Du kan åtgärda detta',
+      environment: 'Miljö',
+      bug: 'Rapportera detta',
+    },
+    signature: {
+      'ftp-auth-rejected': {
+        name: 'Skrivaren avvisade åtkomstkoden',
+        cause: 'Skrivaren vägrade filöverföringsinloggningen. Åtkomstkoden är fel, eller den ändrades efter att Utvecklarläge växlats.',
+        fix: 'Kopiera åtkomstkoden från skrivarens skärm (LAN-inställningar) och uppdatera den i skrivarens inställningar i Bambuddy.',
+      },
+      'ftp-connection-timeout': {
+        name: 'Filöverföringsanslutning timeout',
+        cause: 'Bambuddy kunde inte nå skrivarens filöverföringsport (FTPS 990). Porten är blockerad, eller skrivaren är av eller på ett annat subnät.',
+        fix: 'Se till att inget blockerar port 990 mellan Bambuddy och skrivaren, och att båda är på samma nätverk.',
+      },
+      'ftp-ssl-error': {
+        name: 'Säker filöverförings-handskak misslyckades',
+        cause: 'Skrivarens filservice svarade på port 990 utan TLS. Dess filserver har fastnat — ett fel på skrivarsidan, inte ett brandväggs- eller firmware-problem.',
+        fix: 'Starta om skrivaren. Tills dess kan utskriftsfiler, omslag och timelapse inte hämtas; själva utskriften påverkas inte.',
+      },
+      'bambu-cloud-captcha': {
+        name: 'Bambu Cloud begär en CAPTCHA',
+        cause: 'Bambus anti-missbrukslager utmanar detta nätverk, så ingen Bambu Cloud-inloggning kan slutföras. Det är kopplat till den offentliga IP-adressen, inte till ditt konto eller denna installation.',
+        fix: 'Vänta — det löser sig normalt inom några timmar, och upprepade inloggningsförsök förlänger det. För att ansluta under tiden, logga in med en åtkomsttoken som tas från en webbläsarsession.',
+      },
+      'mqtt-connection-flapping': {
+        name: 'Skrivaranslutningen kopplas bort upprepade gånger',
+        cause: 'Kontrollanslutningen (MQTT 8883) kopplas bort och ansluter upprepade gånger — vanligtvis en svag nätväg eller en delvis blockerad port.',
+        fix: 'Kontrollera Wi-Fi-signalen vid skrivaren, föredra en trådbunden anslutning och se till att port 8883 är pålitligt åtkomlig.',
+      },
+      'camera-connection-refused': {
+        name: 'Kameraström otillgänglig',
+        cause: 'Live-kameran kunde inte nås på port RTSPS 322. Porten är blockerad, eller kameran eller LAN-livevy är av på skrivaren.',
+        fix: 'Aktivera kameran och LAN-livevy på skrivaren, och se till att port 322 inte blockeras. Detta påverkar inte utskriften.',
+      },
+      'database-locked': {
+        name: 'Databas-skrivkonflikt',
+        cause: 'SQLite-databasen får "databas är låst"-fel under belastning — vanligt när flera skrivare körs samtidigt.',
+        fix: 'Växla Bambuddy till en extern PostgreSQL-databas. Se PostgreSQL-guiden i dokumentationen.',
+      },
+    },
+  },
+
+  vpDiagnostic: {
+    title: 'Inställningskontroll — {{name}}',
+    runButton: 'Kör inställningskontroll',
+    running: 'Kör inställningskontroll...',
+    runFailed: 'Kunde inte köra inställningskontrollen: {{error}}',
+    retry: 'Kör igen',
+    overall: {
+      ok: 'Alla kontroller godkända — denna virtuella skrivare är korrekt konfigurerad.',
+      warnings: 'Den virtuella skrivaren bör fungera, men vissa saker behöver uppmärksamhet.',
+      problems: 'Hittade problem som förklarar varför slicern inte kan se eller använda denna virtuella skrivare.',
+    },
+    check: {
+      enabled: {
+        title: 'Virtuell skrivare aktiverad',
+        fail: 'Denna virtuella skrivare är avstängd. Växla på den för att göra den upptäckbar.',
+      },
+      running: {
+        title: 'Tjänster körs',
+        fail: 'Den virtuella skrivaren är aktiverad men dess tjänster körs inte. Kontrollera Bambuddy-loggen — en bind-IP-konflikt eller ett behörighetsfel stoppar vanligtvis dem.',
+      },
+      bind_interface: {
+        title: 'Bind nätverksgränssnitt',
+        fail: 'Bind-gränssnittet är inte inställt, eller existerar inte längre på denna värd. Välj ett aktuellt gränssnitt i rullisten Bind-gränssnitt.',
+      },
+      access_code: {
+        title: 'Åtkomstkod inställd',
+        fail: 'Ingen åtkomstkod är inställd. Slicern måste ges samma 8-teckens åtkomstkod som du ställt in här.',
+      },
+      target_printer: {
+        title: 'Målskrivare',
+        fail: 'Ingen målskrivare är vald. Proxyläge behöver en riktig skrivare att vidarebefordra till.',
+        warn: 'Målskrivaren är offline just nu — vidarebefordring kommer att återupptas när den ansluter igen.',
+      },
+      port_ftps: {
+        title: 'Filuppladdningstjänst (port {{port}})',
+        fail: 'Inget lyssnar på port {{port}} för bind-IP, så slicern kan inte ladda upp filer. En portkonflikt på detta gränssnitt är den vanliga orsaken.',
+      },
+      port_mqtt: {
+        title: 'Kontrolltjänst (port {{port}})',
+        fail: 'Inget lyssnar på port {{port}} för bind-IP, så slicern kan inte ansluta eller visa status.',
+      },
+      port_bind: {
+        title: 'Söktjänst (port {{port}})',
+        fail: 'Inget lyssnar på port {{port}} för bind-IP, så slicerns upptäcknings-handskak misslyckas.',
+      },
+      privileged_ports: {
+        title: 'Privilegerad portbindning',
+        fail: 'Port {{port}} är under 1024, och denna tjänst har inte behörighet att binda den — varför inget lyssnar ovan. Lägg till AmbientCapabilities=CAP_NET_BIND_SERVICE till /etc/systemd/system/bambuddy.service och starta om, eller kör "sudo setcap cap_net_bind_service=+ep $(readlink -f $(which python3))". För Docker, lägg till cap_add: [NET_BIND_SERVICE].',
+      },
+      certificate: {
+        title: 'TLS-certifikat',
+        pass: 'Certifikat redo. Se till att Bambuddy-CA-certifikatet (ovan) importeras till din slicerns betroddelagring.',
+        fail: 'TLS-certifikatet för denna virtuella skrivare saknas. Kontrollera att Bambuddy-datakatalogen är skrivbar.',
+      },
+    },
+  },
+
+  bugReport: {
+    title: 'Rapportera ett fel',
+    description: 'Beskrivning',
+    descriptionPlaceholder: 'Vad gick fel? Beskriv problemet...',
+    email: 'E-post (valfritt)',
+    emailPlaceholder: 'din@e-post.com',
+    emailPrivacy: 'Om den anges kommer din e-post att inkluderas i en ihopfälld sektion av GitHub-ärendet så att underhållaren kan följa upp.',
+    screenshot: 'Skärmdump',
+    uploadOrPaste: 'Ladda upp, klistra in eller dra en bild',
+    dataCollectedSummary: 'Vilken data inkluderas i rapporten?',
+    dataIncluded: 'Inkluderad:',
+    dataIncludedList: 'App-version, OS, arkitektur, Python-version, databasstatistik (endast räknare), skrivarmodeller, munstyckesantal, firmwareversioner, anslutningsstatus, integrationsstatus (Spoolman, MQTT, HA), icke-känsliga inställningar, nätverksgränssnittsantal, Docker-detaljer, beroendeversioner.',
+    dataNeverIncluded: 'Inkluderas aldrig:',
+    dataNeverIncludedList: 'Skrivarnamn, serienummer, åtkomstkoder, lösenord, IP-adresser, e-postadresser, API-nycklar, tokens, webhook-URL:er, värdnamn eller användarnamn.',
+    submit: 'Skicka in',
+    startLogging: 'Starta felsökningsloggning',
+    stepEnableLogging: 'Felsökningsloggning aktiverad',
+    stepReproduce: 'Återskapa problemet nu',
+    stepStopLogging: 'Stoppa och skicka in rapport',
+    stopAndSubmit: 'Stoppa och skicka in',
+    maxDuration: 'Stoppar automatiskt efter {{minutes}} min',
+    stoppingLogs: 'Samlar in loggar och skickar in...',
+    submitting: 'Skickar in felrapport...',
+    submittingStepConnection: 'Kör skrivaranslutningskontroller',
+    submittingStepVirtualPrinters: 'Kör inställningskontroller för virtuella skrivare',
+    submittingStepLogScan: 'Söker i senaste loggar efter kända problem',
+    submittingStepSubmit: 'Skickar in rapport till GitHub',
+    submitSuccess: 'Felrapport skickad in!',
+    submitFailed: 'Kunde inte skicka in felrapport',
+    diagnosticChecking: 'Kontrollerar skrivaranslutningar...',
+    diagnosticHealthy: 'Anslutningskontroll godkänd — inga problem hittade på dina skrivare.',
+    diagnosticSummary: '{{problems}} av {{total}} skrivare har anslutningsproblem',
+    diagnosticIntro: 'En eller flera skrivare har ett anslutningsproblem som kan orsaka ditt problem. Fäll ut en skrivare nedan för att se åtgärden — att lösa det kan lösa problemet utan en felrapport. Du kan fortfarande skicka in en rapport nedan.',
+    logHealthSummary: 'Kända problem hittade i dina loggar',
+    logHealthIntro: 'Senaste loggar matchar kända problem. Kontrollera åtgärderna nedan — att lösa dem kan lösa ditt problem utan en felrapport. Du kan fortfarande skicka in en rapport nedan.',
+    thankYou: 'Tack!',
+    submitted: 'Din felrapport har skickats in.',
+    viewIssue: 'Visa ärende',
+    closeKeepsRecording: 'Du kan stänga den här panelen medan du återskapar problemet – inspelningen fortsätter och om du öppnar den igen kommer du tillbaka hit.',
+    resumeRecording: 'Buggrapport spelar in — {{elapsed}}. Klicka för att avsluta.',
+    resumeReport: 'Återuppta rapportering',
+    unexpectedError: 'Ett oväntat fel uppstod',
+  },
+  failureDetection: {
+    title: 'AI-feldetektering',
+    description: 'Övervaka utskrifter med ett självhostat Obico ML-API och agera automatiskt på upptäckta fel.',
+    mlUrl: 'Obico ML-API-URL',
+    mlUrlHint: 'Bas-URL för din självhostade Obico ml_api-container (t.ex. http://192.168.1.10:3333).',
+    mlToken: 'ML-API-token (valfritt)',
+    mlTokenPlaceholder: 'Lämna tomt om servern körs utan ML_API_TOKEN',
+    mlTokenHint: 'Måste matcha ML_API_TOKEN-miljövariabeln för din Obico ml_api-container. Lämna tomt när containern körs utan en.',
+    test: 'Test',
+    testSuccess: 'ML-API åtkomlig och frisk.',
+    testSuccessTokenUnknown: 'ML-API åtkomlig och frisk. Token kunde inte kontrolleras.',
+    testFailed: 'Kunde inte nå ML-API:et.',
+    sensitivity: 'Känslighet',
+    sensitivityLow: 'Låg (färre falska larm)',
+    sensitivityMedium: 'Medium (balanserad)',
+    sensitivityHigh: 'Hög (upptäck tidigt, fler falska larm)',
+    sensitivityHint: 'Justerar konfidens-trösklarna som utlöser varningar och fel.',
+    action: 'Åtgärd vid upptäckt fel',
+    actionNotify: 'Notisera endast',
+    actionPause: 'Pausa utskrift',
+    actionPauseOff: 'Pausa och bryt ström',
+    pollInterval: 'Avläsningsintervall (sekunder)',
+    pollIntervalHint: 'Hur ofta varje skrivare ska kontrollera medan den skriver ut. Minimum 5s, maximum 120s.',
+    externalUrlMissing: 'Extern URL är inte inställd.',
+    externalUrlHint: 'ML-API:et hämtar kamerans ögonblicksbild via URL. Sätt den externa URL:en i Allmänna inställningar så att ML-API-containern kan nå Bambuddy.',
+    perPrinterTitle: 'Övervakade skrivare',
+    perPrinterHint: 'Välj vilka skrivare som övervakningstjänsten ska bevaka.',
+    monitorAll: 'Övervaka alla anslutna skrivare',
+    statusTitle: 'Status',
+    serviceRunning: 'Tjänst körs',
+    thresholds: 'Låga / Hög tröskelvärden',
+    activePrinters: 'Aktiva utskrifter',
+    noActivePrints: 'Inga utskrifter körs för närvarande.',
+    historyTitle: 'Senaste upptäckter',
+    noHistory: 'Inga upptäckter än.',
+  },
+
+  makerworld: {
+    title: 'MakerWorld',
+    description: 'Klistra in en MakerWorld-modell-URL för att importera och skriva ut den direkt från Bambuddy — utan att lämna för Bambu Handy-app.',
+    pasteUrlHeader: 'Importera från MakerWorld',
+    pasteUrlPlaceholder: 'https://makerworld.com/en/models/… eller klistra in valfri MakerWorld-länk',
+    resolveButton: 'Lös',
+    signInRequiredTitle: 'Bambu Cloud-inloggning krävs för nedladdning',
+    signInRequiredBody: 'Du kan bläddra bland modelldetaljer anonymt, men MakerWorld kräver ett Bambu Cloud-konto för att ladda ner 3MF-filer.',
+    signInExpiredTitle: 'Bambu Cloud-inloggning har löpt ut',
+    signInExpiredBody: 'Du är fortfarande inloggad på Bambuddy, men Bambu Lab har slutat acceptera den lagrade token, så nedladdningar kommer att misslyckas. Logga in på Bambu Cloud igen.',
+    openCloudSettings: 'Öppna molninställningar',
+    untitledModel: 'Namnlös modell',
+    byCreator: 'av {{name}}',
+    downloadsCount: '{{count}} nedladdningar',
+    licensePrefix: 'Licens',
+    alreadyImported: 'Redan importerad',
+    openOnMakerworld: 'Öppna på MakerWorld',
+    alreadyInLibrary: 'Denna modell finns redan i ditt bibliotek — hitta den i Filhanterare → MakerWorld',
+    importSuccess: 'Importerade {{filename}} — sparad i Filhanterare → MakerWorld',
+    platesHeader: 'Plattor ({{count}})',
+    plateDefaultName: 'Platta {{n}}',
+    materialCount: '{{count}} filament',
+    amsRequired: 'AMS krävs',
+    slicedFor: 'Slicad för {{printer}}',
+    alsoCompatible: 'Markerad som kompatibel med: {{printers}}',
+    importToLibrary: 'Spara',
+    sliceIn: 'Spara och slica i {{slicer}}',
+    disclaimer: 'MakerWorld-integration använder community-dokumenterade API-ändpunkter. Bambuddy är inte ansluten till eller godkänd av MakerWorld eller Bambu Lab.',
+    lastImportSuccess: 'Importerad till ditt bibliotek',
+    lastImportAlreadyInLibrary: 'Finns redan i ditt bibliotek',
+    viewInLibrary: 'Visa i Filhanterare',
+    openInBambuStudio: 'Öppna i Bambu Studio',
+    openInOrcaSlicer: 'Öppna i OrcaSlicer',
+    importTo: 'Importera till filhanterare',
+    recentImportsHeader: 'Senaste importen',
+    phaseResolving: 'Löser',
+    phaseDownloading: 'Laddar ner',
+    folderAuto: 'MakerWorld (standard)',
+    importAll: 'Importera alla',
+    importAllProgress: 'Importerar {{current}}/{{total}}',
+    openGallery: 'Öppna bildgalleri',
+    galleryPrev: 'Föregående bild',
+    galleryNext: 'Nästa bild',
+    deleteImport: 'Ta bort från bibliotek',
+    importDeleting: 'Tar bort...',
+    importDeleted: 'Borttagen från bibliotek',
+    confirmDelete: 'Ta bort {{filename}} från biblioteket? Detta tar bort den lokala filen men plattan kan importeras om från MakerWorld.',
+    errors: {
+      resolveFailed: 'Kunde inte lösa den MakerWorld-URL:en.',
+      downloadFailed: 'Kunde inte ladda ner. Försök igen.',
+      deleteFailed: 'Kunde inte ta bort filen från biblioteket.',
+    },
+  },
+  gcodeViewer: {
+    filamentSlot: 'Filament {{n}}',
+    loading: 'Läser verktygssökväg…',
+    loadFailed: 'Kunde inte ladda G-koden för denna fil.',
+    showTravel: 'Rörelse',
+    topLayer: 'Topplager',
+    bottomLayer: 'Bottenlager',
+    noSource: 'Ingen fil gavs för förhandsgranskning.',
+    view: {
+      filament: 'Filament',
+      feature: 'Särdrag',
+      height: 'Höjd',
+      width: 'Bredd',
+    },
+    feature: {
+      wall: 'Väggar',
+      sparseInfill: 'Gles utfyllnad',
+      solidInfill: 'Solid utfyllnad',
+      bridge: 'Brygga / överhäng',
+      support: 'Stöd',
+      skirt: 'Kant / brätte',
+      gapFill: 'Mellanrumsifyllnad',
+      ironing: 'Strykning',
+      primeTower: 'Primtorn',
+    },
+    back: 'Tillbaka',
+    backToArchives: 'Tillbaka till utskriftsarkiv',
+    backToFiles: 'Tillbaka till Filhanterare',
+    plates: 'Plattor',
+    plateN: 'Platta {{n}}',
+  },
+  libraryTrash: {
+    title: 'Papperskorgen',
+    headerButton: 'Papperskorgen',
+    headerTooltip: 'Visa filer som flyttats till papperskorgen',
+    backToFiles: 'Tillbaka till Filhanterare',
+    subtitleAdmin: 'Borttagna filer stannar här i {{days}} dagar, sedan raderas de automatiskt. Denna vy visar filer i papperskorgen för alla användare.',
+    subtitleUser: 'Borttagna filer stannar här i {{days}} dagar, sedan raderas de automatiskt.',
+    loading: 'Laddar papperskorgen…',
+    loadError: 'Kunde inte ladda papperskorgen.',
+    empty: 'Papperskorgen är tom.',
+    summary: '{{count}} filer · {{size}}',
+    emptyTrash: 'Töm papperskorgen',
+    restore: 'Återställ',
+    purgeNow: 'Ta bort nu',
+    autoPurgeIn: 'Raderas automatiskt om {{when}}',
+    days: 'dagar',
+    retentionLabel: 'Automatisk radering efter',
+    selectAll: 'Markera alla',
+    selectOne: 'Markera {{filename}}',
+    selectionCount: '{{count}} markerade',
+    bulkRestore: 'Återställ markerade',
+    bulkPurge: 'Ta bort markerade',
+    col: {
+      filename: 'Fil',
+      folder: 'Mapp',
+      size: 'Storlek',
+      deleted: 'Flyttad till papperskorgen',
+      autoPurge: 'Automatisk radering',
+      owner: 'Ägare',
+      actions: 'Åtgärder',
+    },
+    confirm: {
+      purgeTitle: 'Ta bort permanent?',
+      purgeBody: '{{filename}} kommer att tas bort från disken och kan inte återställas.',
+      emptyTitle: 'Töm papperskorgen?',
+      emptyBody: 'Alla {{count}} filer kommer att tas bort från disken. Detta kan inte ångras.',
+      bulkPurgeTitle: 'Ta bort markerade filer permanent?',
+      bulkPurgeBody: 'De {{count}} markerade filerna kommer att tas bort från disken och kan inte återställas.',
+      cta: 'Ta bort permanent',
+    },
+    toast: {
+      restored: 'Fil återställd.',
+      restoreFailed: 'Kunde inte återställa filen.',
+      purged: 'Fil borttagen permanent.',
+      purgeFailed: 'Kunde inte ta bort filen.',
+      emptied: 'Tog bort {{count}} fil(er) från papperskorgen.',
+      emptyFailed: 'Kunde inte tömma papperskorgen.',
+      retentionSaved: 'Automatisk radering inställd på {{days}} dagar.',
+      retentionFailed: 'Kunde inte spara inställningen för automatisk radering.',
+      bulkRestored: 'Återställde {{count}} fil(er).',
+      bulkPurged: 'Tog bort {{count}} fil(er).',
+    },
+  },
+  libraryPurge: {
+    title: 'Rensa gamla filer',
+    headerButton: 'Rensa gamla',
+    headerTooltip: 'Massflytta gamla filer till papperskorgen',
+    description: 'Rensa ut gamla filer från ditt bibliotek i ett svep. Filer med utskriftshistorik åldras efter deras senaste utskriftsdatum; filer som aldrig skrivits ut åldras efter deras uppladdningsdatum.',
+    ageLabel: 'Flytta filer äldre än',
+    days: 'dagar',
+    includeNeverPrinted: 'Inkludera filer som aldrig skrivits ut',
+    effectsTitle: 'Vad händer när du klickar på Rensa',
+    effect1: 'Matchande filer flyttas till Papperskorgen — de raderas inte från disken än.',
+    effect2: 'Du kan återställa dem från Papperskorgen när som helst tills behållningsfönstret löper ut.',
+    effect3: 'Efter behållningstiden rensar papperskorgen dem permanent från disken.',
+    effect4: 'Filer i externa (länkade) mappar hoppas över — Bambuddy raderar aldrig byte som den inte äger.',
+    previewLoading: 'Kontrollerar hur många filer som matchar…',
+    previewFailed: 'Kunde inte förhandsgranska rensningen.',
+    previewSummary: '{{count}} filer · {{size}} kommer att flyttas till papperskorgen',
+    andMore: '…och {{count}} till',
+    warning: 'Filer i papperskorgen räknas fortfarande mot lagringen tills behållningsfönstret löper ut. Töm Papperskorgen därefter för att frigöra diskutrymme omedelbart.',
+    confirmCta: 'Flytta {{count}} till papperskorgen',
+    purging: 'Flyttar till papperskorgen…',
+    toast: {
+      success: 'Flyttade {{count}} fil(er) till papperskorgen.',
+      failed: 'Kunde inte rensa filer.',
+    },
+  },
+  libraryAutoPurge: {
+    enableLabel: 'Auto-rensa gamla filer',
+    enableDescription: 'Kör den administrativa rensningen en gång per dag. Filer går till Papperskorgen först — de raderas inte omedelbart.',
+    ageLabel: 'Auto-rensa filer äldre än',
+    ageDescription: 'Minimum 7 dagar, maximum 10 år. Använder samma åldersregel som den manuella Rensa-knappen.',
+    days: 'dagar',
+    includeNeverPrinted: 'Inkludera filer som aldrig skrivits ut',
+    saveFailed: 'Kunde inte spara inställningar för auto-rensning.',
+  },
+  archivePurge: {
+    headerButton: 'Rensa gamla',
+    headerTooltip: 'Massradera gamla arkiv',
+    title: 'Rensa gamla arkiv',
+    description: 'Rensa ut gammal utskriftshistorik. Varje arkiv åldras efter dess senaste utskrifts slutförande — omutskrift av ett arkiv uppdaterar dess ålder, så aktivt arbete raderas aldrig.',
+    ageLabel: 'Radera arkiv som inte skrivits ut på',
+    days: 'dagar',
+    effectsTitle: 'Vad händer när du klickar på Rensa',
+    effect1: 'Varje matchande arkiv döljs från listorna och dess filer tas bort från disken (3MF, minibild, timelapse, käll-3MF, F3D-designfil, foton).',
+    effect2: 'Arkivraden förblir i databasen så att Snabbstatistik behåller filament-, tid-, kostnads- och energibidraget — samma som standard för radering av enskilt arkiv.',
+    effect3: 'Kryssa i "Ta också bort från statistik" nedan för att ta bort Snabbstatistik-bidraget också (matchar alternativet för radering av enskilt arkiv). Den vägen är oåterkallelig.',
+    effect4: 'Omutskrift av ett arkiv uppdaterar dess åldersklocka, så arkiv som du fortfarande använder är säkra.',
+    purgeStatsLabel: 'Ta också bort från statistik',
+    purgeStatsHint: 'Tar bort de matchande arkiven från Snabbstatistik (filament, tid, kostnad, energi). Utan detta behåller Snabbstatistik varje bidrag och endast filerna lämnar disken.',
+    previewLoading: 'Kontrollerar hur många arkiv som matchar…',
+    previewFailed: 'Kunde inte förhandsgranska rensningen.',
+    previewSummary: '{{count}} arkiv · {{size}} kommer att tas bort',
+    andMore: '…och {{count}} till',
+    warning: 'Filer tas bort från disken och kan inte återställas. Ladda ner eller markera som favorit allt du vill behålla innan du fortsätter.',
+    confirmCta: 'Ta bort {{count}} arkiv',
+    purging: 'Tar bort…',
+    toast: {
+      success: 'Tog bort {{count}} arkiv.',
+      failed: 'Kunde inte rensa arkiv.',
+    },
+  },
+  archiveAutoPurge: {
+    enableLabel: 'Auto-rensa gamla arkiv',
+    enableDescription: 'En gång per dag döljs arkiv från listorna och deras filer tas bort från disken när de inte har skrivits ut inom tröskelvärdet. Omutskrift av ett arkiv återställer klockan.',
+    ageLabel: 'Auto-radera arkiv som inte skrivits ut på',
+    ageDescription: 'Minimum 7 dagar, maximum 10 år. Baserat på det senaste utskrifts slutförandet — omutskrift av ett arkiv uppdaterar dess ålder. Tar bort 3MF, minibild, timelapse, käll-3MF, F3D och foton.',
+    days: 'dagar',
+    purgeStatsLabel: 'Ta också bort från statistik',
+    purgeStatsDescription: 'När aktiverat tar den dagliga rensaren också bort varje rensat arkiv från Snabbstatistik (filament, tid, kostnad, energi). Standard av — Snabbstatistik behåller bidraget, endast filerna lämnar disken.',
+    runNow: 'Rensa arkiv nu',
+    saveFailed: 'Kunde inte spara inställningar för auto-rensning.',
+  },
+  cameraTokens: {
+    scope: {
+      camera_stream: 'Kameraström',
+      camwall: 'Kameravägg',
+      overlay: 'Strömningsöverlägg',
+    },
+    title: 'Kamera-API-tokens',
+    navTitle: 'Kamera-API-tokens',
+    description:
+      'Långlivade tokens för att bädda in kameraströmmen i Home Assistant, Frigate, kiosker eller något annat verktyg som behöver en stabil URL. Välj omfång när du skapar en; en token kan återkallas när som helst.',
+    loading: 'Laddar…',
+    confirmRevoke: {
+      title: 'Återkalla denna token?',
+      body: 'All enheter som använder "{{name}}" kommer att förlora åtkomsten omedelbart. Detta kan inte ångras.',
+      cancel: 'Avbryt',
+      confirm: 'Återkalla',
+    },
+    create: {
+      scopeLabel: 'Omfång',
+      hintCameraStream:
+        'En kameraström-token kan endast hämta kameraströmmar och ögonblicksbilder. Använd den för Home Assistant, Frigate eller något som bäddar in en enda kamera.',
+      hintCamWall:
+        'En Kameravägg-token öppnar /camwall på en skärm utan inloggning. Den kan se alla skrivares namn och status, och deras kameraströmmar. Den kan inte se filnamn, adresser eller åtkomstkoder.',
+      hintOverlay:
+        'En Strömningsöverlägg-token öppnar /overlay/{printerId} på en skärm utan inloggning — för OBS eller någon livestream. Den kan se en skrivares kameraström plus dess live utskriftsstatus, inklusive filnamnet som visas på skärmen. Den kan inte se adresser eller åtkomstkoder.',
+      title: 'Skapa ny token',
+      nameLabel: 'Token-namn',
+      namePlaceholder: 't.ex. Home Assistant',
+      daysLabel: 'Dagar till utgång',
+      submit: 'Skapa',
+      hint:
+        'Maximal livstid är 365 dagar. Token-värdet visas endast en gång vid skapande — kopiera det nu.',
+    },
+    created: {
+      camWallUrlTitle: 'Kameravägg-URL för denna display',
+      camWallUrlHint:
+        'Öppna detta på skärmen. Vem som helst som kan läsa URL:en kan titta på väggen, så behandla den som en nyckel — återkalla token för att koppla bort display.',
+      overlayUrlTitle: 'Överläggs-URL för OBS',
+      overlayUrlHint:
+        'Lägg till detta som en Browser Source i OBS. Ändra /overlay/1 numret till din skrivares nummer (från dess URL på Skrivarsidan). Vem som helst som kan läsa URL:en kan titta på strömmen, så behandla den som en nyckel — återkalla token för att koppla bort den.',
+      title: 'Token skapad — kopiera den nu',
+      warning:
+        'Detta är det enda tillfället denna token kommer att visas. När du stänger denna dialogruta kan du aldrig visa den igen.',
+      copy: 'Kopiera',
+      dismiss: 'Jag har sparat den',
+    },
+    list: {
+      scope: 'Omfång',
+      myTitle: 'Mina tokens',
+      allTitle: 'Alla användare (admin-vy)',
+      empty: 'Inga tokens än.',
+      name: 'Namn',
+      owner: 'Ägare',
+      prefix: 'Prefix',
+      created: 'Skapad',
+      expires: 'Utgår',
+      lastUsed: 'Senast använd',
+      revoke: 'Återkalla',
+      expired: 'Utgången',
+    },
+    toast: {
+      created: 'Token skapad',
+      createFailed: 'Kunde inte skapa token',
+      revoked: 'Token återkallad',
+      revokeFailed: 'Kunde inte återkalla token',
+      loadFailed: 'Kunde inte ladda tokens',
+      copied: 'Kopierad till urklipp',
+      copyFailed: 'Kunde inte kopiera — markera och kopiera manuellt',
+    },
+  },
+  // Forecast & Inventory Intelligence
+  forecast: {
+    title: 'Prognos',
+    noSpools: 'Inga aktiva rullar hittade. Lägg till rullar till din inventering för att se prognosdata.',
+    noUsageData: 'Inga användningsdata tillgängliga — kan inte projicera lagertidslinje.',
+    // Table headers
+    sku: 'SKU',
+    material: 'Material',
+    stock: 'Lager',
+    dailyRate: 'Förbrukning',
+    daysLeft: 'Dagar kvar',
+    emptyBy: 'Tomt den',
+    reorderBy: 'Beställ senast',
+    actions: 'Åtgärder',
+    // Rate tier badges
+    trend: 'Trend',
+    estimated: 'Uppskattad',
+    noData: 'Ingen data',
+    // Timeframe
+    timeframe: 'Tidsram',
+    // Chart
+    chartTitle: 'Projicerat lager — Topp 5 material',
+    dashedLinesROP: 'Streckade linjer = beställningspunkter',
+    stockLevel: 'Lagernivå',
+    reorderPoint: 'Beställningspunkt',
+    safetyMargin: 'Säkerhetsmarginal',
+    // Legend labels
+    trendLegend: 'Trend (historikbaserad, 95% servicenivå)',
+    estimatedLegend: 'Uppskattad (viktskillnad)',
+    noDataLegend: 'Ingen data',
+    ropLabel: 'ROP',
+    ssLabel: 'SS',
+    safetyStockLegend: 'Reservlager',
+    stockArrivalLegend: 'Lagerankomst',
+    stockoutLegend: 'Lagerslut',
+    // Alerts toolbar
+    alertCount_one: '{{count}} varning',
+    alertCount_other: '{{count}} varningar',
+    order: 'Beställ',
+    // Settings
+    save: 'Spara',
+    cancel: 'Avbryt',
+    settingsSaved: 'Inställningar sparade',
+    failedSaveSettings: 'Kunde inte spara inställningar',
+    globalLeadTimeSaved: 'Global ledtid sparad',
+    globalLeadTime: 'Global ledtid',
+    globalLeadTimeHint: 'Global ledtidsbas — används i beräkning av beställningspunkt för alla SKU:er',
+    skuLeadTimeOverride: 'Åsidosätt ledtid',
+    skuLeadTimeHint: '0 = använd global ledtid. Sätt >0 för att åsidosätta för denna SKU.',
+    safetyMarginLabel: 'Säkerhetsmarginal',
+    effectiveLeadTime: 'Effektiv ledtid',
+    effectiveLeadTimeHint: 'max(global {{global}}d, SKU {{sku}}d)',
+    reorderPointHint: 'd̄ × LT + säkerhetsmarginal — beställ när lagret når denna nivå',
+    safetyMarginHint: 'Statistisk säkerhetslager (z=1,65 × σ × √LT) + användardefinierad buffert',
+    safetyMarginHintDays: 'Buffert som läggs till på den statistiska säkerhetslagret.{{approx}}',
+    safetyMarginHintDaysApprox: ' ≈ {{g}}g vid aktuell förbrukning.',
+    safetyMarginHintG: 'Fast viktbuffert som läggs till på den statistiska säkerhetslagret.{{approx}}',
+    safetyMarginHintGApprox: ' ≈ {{days}}d vid aktuell förbrukning.',
+    individualSpools: 'Enskilda rullar',
+    labelWeight: 'Etikett',
+    spoolCount_one: '{{count}} rulle',
+    spoolCount_other: '{{count}} rullar',
+    // Alerts
+    stockBreakRisk: 'Risk för lagerslut',
+    stockBreakDetail: '{{days}} dagar kvar, ledtid {{lt}} dagar.',
+    stockBreakBefore: 'Lagerslut före påfyllning',
+    reorderNow: 'Beställ nu',
+    reorderTriggerPassed: 'Utlösningsdatum {{date}} har passerat.',
+    // Shopping list
+    shoppingList: 'Inköpslista',
+    shoppingListItems_one: '({{count}} artikel)',
+    shoppingListItems_other: '({{count}} artiklar)',
+    shoppingListEmpty: 'Inköpslistan är tom. Klicka på varukorgsikonen på valfri rad för att lägga till artiklar.',
+    addToCart: 'Lägg till i inköpslista',
+    alertsSnoozed: 'Tysta varningar för denna SKU',
+    alertsEnabled: 'Aktivera varningar för denna SKU',
+    addedToCart: 'Lagt till i inköpslista',
+    failedAddItem: 'Kunde inte lägga till artikel',
+    listView: 'Lista',
+    logisticsView: 'Logistik',
+    qty: 'Antal',
+    weight: 'Vikt',
+    leadTime: 'Ledtid',
+    expectedRestock: 'Förväntad påfyllning',
+    status: 'Status',
+    note: 'Anteckning',
+    pending: 'Väntande',
+    purchased: 'Inköpt',
+    received: 'Mottagen',
+    markPurchased: 'Markera som inköpt',
+    markReceived: 'Markera som mottagen — lägger till rullar i Lagerinventering',
+    resetToPending: 'Återställ till väntande',
+    remove: 'Ta bort',
+    clearAll: 'Rensa alla',
+    downloadCsv: 'CSV',
+    // Add to cart modal
+    addToCartTitle: 'Lägg till i inköpslista',
+    byQuantity: 'Efter kvantitet',
+    byDuration: 'Efter varaktighet',
+    numberOfSpools: 'Antal rullar',
+    lastHowManyDays: 'Bör räcka hur många dagar?',
+    noUsageQty: 'Ingen användningsdata — kvantitet inställd på 1.',
+    noteOptional: 'Anteckning (valfritt)',
+    notePlaceholder: 't.ex. för projekt X, brådskande…',
+    addNSpools_one: 'Lägg till {{count}} rulle',
+    addNSpools_other: 'Lägg till {{count}} rullar',
+    // Cart logistics
+    onArrival: 'Vid ankomst',
+    stockBreakIn: 'Lagerslut om {{days}} dagar.',
+    stockRunsOutBefore: 'Lagret tar slut innan ledtiden {{lt}} dagar har passerat.',
+    atRate: 'Vid {{rate}}g/dag behöver du',
+    moreSpools_one: '{{count}} rulle till',
+    moreSpools_other: '{{count}} rullar till',
+    bridgeGap: 'för att överbrygga gapet.',
+    // Permissions
+    noReadAccess: 'Du har inte behörighet att visa lagerprognoser.',
+    noWriteAccess: 'Du har inte behörighet att modifiera prognosinställningar.',
+  },
+};