import type { TranslationKey } from './de'; export const en: Record = { // ── Common ────────────────────────────────────────────────────────────────── 'common.save': 'Save', 'common.cancel': 'Cancel', 'common.delete': 'Delete', 'common.edit': 'Edit', 'common.add': 'Add', 'common.create': 'Create', 'common.close': 'Close', 'common.ok': 'OK', 'common.yes': 'Yes', 'common.no': 'No', 'common.search': 'Search…', 'common.loading': 'Loading…', 'common.all': 'All', 'common.none': 'None', 'common.auto': 'Auto', 'common.on': 'On', 'common.off': 'Off', 'common.confirm': 'Confirm', 'widget.confirm.defaultPrompt': 'Really switch?', 'common.duplicate': 'Duplicate', 'common.export': 'Export', 'common.move': 'Move', 'common.reset': 'Reset', 'common.remove': 'Remove', 'common.sizeSmall': 'Small', 'common.sizeMedium': 'Medium', 'common.sizeLarge': 'Large', 'common.seconds': 'sec', // ── Admin Navigation ───────────────────────────────────────────────────────── 'admin.nav.overview': 'Overview', 'admin.nav.editor': 'Dashboard Editor', 'admin.nav.layouts': 'Layouts', 'admin.nav.cssjs': 'CSS & JS', 'admin.nav.loadtimes': 'Load times', 'admin.nav.widgets': 'Widgets', 'admin.nav.widgetDesigner': 'Widget Designer', 'admin.nav.popups': 'Popups', 'admin.nav.design': 'Frontend Design', 'admin.nav.settings': 'Settings', 'admin.nav.openFrontend': 'Open Frontend', 'admin.nav.docs': 'Documentation', 'admin.nav.logout': 'Logout', 'admin.nav.lightMode': 'Light Mode', 'admin.nav.darkMode': 'Dark Mode', // ── Admin Save Bar ──────────────────────────────────────────────────────────── 'admin.save.unsaved': 'Unsaved Changes', 'admin.save.undo': 'Undo', 'admin.save.save': 'Save', 'admin.save.saved': 'All changes saved', 'admin.save.autoIn': 'Auto-saving in {s}s…', // ── Editor settings ─────────────────────────────────────────────────────────── 'settings.editor.title': 'Editor', 'settings.editor.autoSave': 'Auto-save', 'settings.editor.delay': 'Delay', 'settings.editor.ctrlS': 'Ctrl+S saves immediately', // ── Settings ────────────────────────────────────────────────────────────────── 'settings.title': 'Settings', 'settings.subtitle': 'Frontend, Grid, Security and Backup', 'settings.language.title': 'Language', 'settings.language.de': 'German', 'settings.language.en': 'English', 'settings.client.title': 'This Device', 'settings.client.hint': 'Each client gets a unique ID. Use {ns}.clients.{id}.navigate.url to control this device individually.', 'settings.client.name': 'Device Name', 'settings.client.namePh': 'e.g. Kitchen Tablet, Living Room TV…', 'settings.client.id': 'ioBroker Datapoint', 'settings.clients.title': 'Connected Devices', 'settings.clients.hint': 'All devices that have ever connected.', 'settings.clients.none': 'No devices registered yet.', 'settings.clients.thisDevice': 'This Device', 'settings.clients.copyId': 'Copy client ID', 'settings.clients.showIdBadge': 'Show ID badge on every device', 'settings.clients.justNow': 'just now', 'settings.clients.minsAgo': '{n} min ago', 'settings.clients.hoursAgo': '{n} h ago', 'settings.clients.daysAgo': '{n} d ago', 'settings.adminBaseUrl.title': 'Admin Base URL', 'settings.adminBaseUrl.description': 'Prepended to relative image paths in JSON Table widgets (e.g. /meteoalarm.admin/icons/...). Triggers on paths matching /.admin/...', 'settings.adminBaseUrl.hint': 'Empty = auto (same host, port 8081). Can be overridden per column in the JSON Table widget.', 'settings.frontend.title': 'Frontend', 'settings.behavior.title': 'Behavior', 'settings.frontend.layoutDrawer': 'Section Menu (Hamburger)', 'settings.frontend.layoutDrawerHint': 'Shown when the layout has more than one section (or always, if enabled below).', 'settings.frontend.layoutDrawerShowSingle': 'Show menu with a single section', 'settings.frontend.layoutDrawerShowSingleHint': 'Show the section menu even when the layout has only one section.', 'settings.frontend.layoutDrawerSize': 'Hamburger button size', 'settings.frontend.layoutDrawerAutoHide': 'Auto-hide', 'settings.frontend.layoutDrawerAutoHideHint': 'Button appears only when the mouse is near the top edge (or after a top-area touch). Applies only when the header is hidden.', 'settings.frontend.layoutDrawerPlacement': 'Placement', 'settings.frontend.layoutDrawerPlacementFloating': 'Floating', 'settings.frontend.layoutDrawerPlacementTabbar': 'In tab bar', 'settings.frontend.layoutDrawerPlacementSidebar': 'Docked sidebar', 'settings.frontend.layoutDrawerPlacementTop': 'Bar at top', 'settings.frontend.layoutDrawerPlacementBottom': 'Bar at bottom', 'settings.frontend.layoutDrawerPlacementHint': 'Floating/tab bar show a hamburger with an overlay (header hidden only). Docked sidebar is a permanently visible left menu. Bar at top/bottom is a horizontal section bar like the tab bar — at the top it sits above the tab bar.', 'settings.frontend.layoutDrawerWidth': 'Sidebar width', 'settings.frontend.layoutDrawerTopOffset': 'Top offset', 'settings.frontend.layoutDrawerBottomOffset': 'Bottom offset', 'settings.frontend.layoutDrawerShowTitle': 'Show menu title', 'settings.frontend.layoutDrawerHamburger': 'Hamburger button', 'settings.frontend.layoutDrawerEntryHeight': 'Entry height', 'settings.frontend.layoutDrawerPlacementDisabledHeader': 'Not relevant while the header is visible – the hamburger is then rendered in the header.', 'settings.frontend.layoutDrawerPlacementTabbarDisabledAutoHide': 'Not available when auto-hide is enabled.', 'settings.frontend.layoutDrawerTitle': 'Menu title', 'settings.frontend.layoutDrawerEntryStyle': 'Entry style', 'settings.frontend.layoutDrawerEntryStyleIconAndName': 'Icon + name', 'settings.frontend.layoutDrawerEntryStyleIconOnly': 'Icon only', 'settings.frontend.layoutDrawerEntryStyleNameOnly': 'Name only', 'settings.frontend.layoutDrawerEntryStyleBulletAndName': 'Bullet + name', 'settings.frontend.layoutDrawerIndicatorStyle': 'Selected style', 'settings.frontend.layoutDrawerFontSize': 'Font size', 'settings.frontend.layoutDrawerIconSize': 'Icon size', 'settings.frontend.layoutDrawerItems': 'Elements', 'settings.frontend.layoutDrawerItemPosTop': 'Top', 'settings.frontend.layoutDrawerItemPosBottom': 'Bottom', 'settings.frontend.layoutDrawerItemMarginTop': 'Space above', 'settings.frontend.layoutDrawerItemMarginBottom': 'Space below', 'settings.frontend.idleReturn': 'Auto-return to default tab', 'settings.frontend.idleReturnDelay': 'Delay', 'settings.frontend.idleReturnHint': "Switches to the layout's default section and its default tab after the specified idle time.", 'settings.frontend.optimisticUpdates': 'Instant feedback on control', 'settings.frontend.optimisticUpdatesHint': 'Reflect written values immediately without waiting for ioBroker to confirm. Fixes stale UI for datapoints that never echo a write back (e.g. plain 0_userdata variables).', 'settings.frontend.showHeader': 'Show Header', 'settings.frontend.dashboardTitle': 'Dashboard Title', 'settings.frontend.connectionBadge': 'Connection Status', 'settings.frontend.showAdminLink': 'Show Admin Link in Header', 'settings.frontend.headerClock': 'Clock/Date in Header', 'settings.frontend.headerClockDisplay': 'Display', 'settings.frontend.headerClockSeconds': 'Seconds', 'settings.frontend.headerClockDateLen': 'Date format', 'settings.frontend.headerClockCustom': 'Custom format (empty = default)', 'settings.frontend.headerDatapoint': 'Datapoint in Header', 'settings.frontend.headerDatapointPh': 'e.g. hm-rpc.0.NEQ123.1.ACTUAL_TEMPERATURE', 'settings.frontend.headerDatapointTemplate': 'HTML Template (optional)', 'settings.frontend.headerDatapointTemplatePh': '{dp} °C', 'settings.frontend.headerDatapointTemplateHint': '{dp} is replaced by the datapoint value · Example: {dp} kW', 'settings.tabBar.title': 'Tab Bar', 'settings.tabBar.height': 'Height', 'settings.tabBar.style': 'Tab Style', 'settings.tabBar.styleText': 'Colored', 'settings.tabBar.styleUnderline': 'Underline', 'settings.tabBar.styleFilled': 'Filled', 'settings.tabBar.stylePills': 'Pills', 'settings.tabBar.fontSize': 'Font Size', 'settings.tabBar.iconSize': 'Icon Size', 'settings.tabBar.fontSm': 'Small', 'settings.tabBar.fontMd': 'Medium', 'settings.tabBar.fontLg': 'Large', 'settings.tabBar.background': 'Background', 'settings.tabBar.activeColor': 'Active Color', 'settings.tabBar.inactiveColor': 'Inactive Color', 'settings.tabBar.items': 'Tab Bar Items', 'settings.tabBar.addItem': '+ Add Item', 'settings.tabBar.itemTypeClock': 'Clock', 'settings.tabBar.itemTypeDatapoint': 'Datapoint', 'settings.tabBar.itemTypeText': 'Text', 'settings.tabBar.posLeft': 'Left', 'settings.tabBar.posCenter': 'Center', 'settings.tabBar.posRight': 'Right', 'settings.tabBar.datapointId': 'Datapoint ID', 'settings.tabBar.datapointTemplate': 'Template (optional)', 'settings.tabBar.datapointTemplateHint': '{dp} = value. HTML is supported.', 'settings.tabBar.staticText': 'Text', 'settings.tabBar.clockDisplay': 'Display', 'settings.tabBar.clockSeconds': 'Seconds', 'settings.tabBar.clockDateLen': 'Date format', 'settings.tabBar.clockCustom': 'Custom format', 'settings.tabBar.tabsAlignment': 'Menu Position', 'settings.tabBar.alignLeft': 'Left', 'settings.tabBar.alignCenter': 'Center', 'settings.tabBar.alignRight': 'Right', 'settings.tabBar.hideMobileScrollbar': 'Hide scroll bar (mobile)', 'settings.tabBar.showSingle': 'Show bar with a single tab', 'settings.tabBar.position': 'Position', 'settings.tabBar.positionTop': 'Top', 'settings.tabBar.positionBottom': 'Bottom (footer)', 'settings.tabBar.clearAll': '↩ Reset all', 'settings.grid.title': 'Grid & Mobile', 'settings.grid.rowHeight': 'Grid size (row)', 'settings.grid.snapX': 'Grid size (column)', 'settings.grid.mobileBreak': 'Mobile Breakpoint', 'settings.grid.wizardMaxDp': 'Wizard Max Datapoints', 'settings.grid.mobileOff': 'Off', 'settings.grid.hideScrollbar': 'Hide scroll bar', 'settings.grid.hideScrollbarHint': 'Hides the draggable scroll bar over the dashboard on touch devices.', 'settings.pin.title': 'Admin PIN', 'settings.pin.newPin': 'New PIN (min. 4 chars)', 'settings.pin.confirm': 'Confirm PIN', 'settings.pin.save': 'Save PIN', 'settings.pin.tooShort': 'At least 4 characters', 'settings.pin.mismatch': "PINs don't match", 'settings.pin.success': 'PIN changed successfully', 'settings.pin.wrong': 'Wrong PIN', 'settings.backup.title': 'Backup & Restore', 'settings.backup.description': 'Dashboard ({count} Tab{s}), Theme and Config as JSON.', 'settings.backup.download': 'Download Backup', 'settings.backup.import': 'Import Backup', 'settings.backup.invalidFile': 'Invalid backup file', 'settings.autobackup.title': 'Automatic Backup', 'settings.autobackup.description': 'Written as a file under {ns}.backups/ on every save.', 'settings.autobackup.lastBackup': 'Last backup', 'settings.autobackup.noBackup': 'No backup yet', 'settings.autobackup.download': 'Download backup', 'settings.autobackup.restore': 'Restore from backup', 'settings.autobackup.restoreConfirm': 'Restore now?', 'settings.autobackup.restoring': 'Restoring …', 'settings.autobackup.success': 'Restored', 'settings.autobackup.error': 'Restore failed', 'settings.autobackup.noData': 'Backup contains no data', 'settings.autobackup.count': 'Number of backups', 'settings.autobackup.latest': 'latest', 'settings.autobackup.changed': 'Changed', 'settings.autobackup.store.aura-dashboard': 'Dashboard', 'settings.autobackup.store.aura-theme': 'Theme', 'settings.autobackup.store.aura-groups': 'Groups', 'settings.autobackup.store.aura-config': 'App config', 'settings.autobackup.store.aura-global-settings': 'Global settings', 'settings.autobackup.store.aura-group-defs': 'Group contents', 'settings.autobackup.store.aura-popup-config': 'Popups', 'settings.autobackup.store.aura-widget-presets': 'Widget presets', 'settings.autobackup.change.widget-added': 'Widget “{label}” added', 'settings.autobackup.change.widget-added.n': '{count} widgets added', 'settings.autobackup.change.widget-removed': 'Widget “{label}” removed', 'settings.autobackup.change.widget-removed.n': '{count} widgets removed', 'settings.autobackup.change.widget-moved': 'Widget “{label}” moved', 'settings.autobackup.change.widget-moved.n': '{count} widgets moved', 'settings.autobackup.change.widget-edited': 'Widget “{label}” edited', 'settings.autobackup.change.widget-edited.n': '{count} widgets edited', 'settings.autobackup.change.widget-dp': 'Widget “{label}”: datapoint changed', 'settings.autobackup.change.widget-dp.n': '{count}× datapoint changed', 'settings.autobackup.change.widget-renamed': 'Widget renamed to “{label}”', 'settings.autobackup.change.widget-renamed.n': '{count} widgets renamed', 'settings.autobackup.change.series-added': 'Chart “{label}”: series added', 'settings.autobackup.change.series-added.n': '{count}× series added', 'settings.autobackup.change.series-removed': 'Chart “{label}”: series removed', 'settings.autobackup.change.series-removed.n': '{count}× series removed', 'settings.autobackup.change.widget-item-added': 'Widget “{label}”: item added', 'settings.autobackup.change.widget-item-added.n': '{count}× item added', 'settings.autobackup.change.widget-item-removed': 'Widget “{label}”: item removed', 'settings.autobackup.change.widget-item-removed.n': '{count}× item removed', 'settings.autobackup.change.tab-added': 'Tab “{label}” added', 'settings.autobackup.change.tab-added.n': '{count} tabs added', 'settings.autobackup.change.tab-removed': 'Tab “{label}” removed', 'settings.autobackup.change.tab-removed.n': '{count} tabs removed', 'settings.autobackup.change.tab-renamed': 'Tab “{label}” renamed', 'settings.autobackup.change.tab-renamed.n': '{count} tabs renamed', 'settings.autobackup.change.layout-added': 'Layout “{label}” added', 'settings.autobackup.change.layout-added.n': '{count} layouts added', 'settings.autobackup.change.layout-removed': 'Layout “{label}” removed', 'settings.autobackup.change.layout-removed.n': '{count} layouts removed', 'settings.autobackup.change.layout-renamed': 'Layout “{label}” renamed', 'settings.autobackup.change.layout-renamed.n': '{count} layouts renamed', 'settings.autobackup.change.section-added': 'Section “{label}” added', 'settings.autobackup.change.section-added.n': '{count} sections added', 'settings.autobackup.change.section-removed': 'Section “{label}” removed', 'settings.autobackup.change.section-removed.n': '{count} sections removed', 'settings.autobackup.change.section-renamed': 'Section “{label}” renamed', 'settings.autobackup.change.section-renamed.n': '{count} sections renamed', 'settings.expert.title': 'Expert', 'settings.expert.locked': 'Access with Admin PIN', 'settings.expert.unlocked': 'Unlocked', 'settings.expert.unlock': 'Unlock', 'settings.expert.lock': 'Lock', 'settings.reset.title': 'Reset All', 'settings.reset.description': 'Deletes all dashboards, widgets, themes and settings. Irreversible.', 'settings.reset.button': 'Reset…', 'settings.reset.confirm': 'Yes, delete all', // ── Dashboard Overview ──────────────────────────────────────────────────────── 'dashboard.title': 'Overview', 'dashboard.subtitle': 'Status and Statistics', 'dashboard.stats.layouts': 'Layouts', 'dashboard.stats.tabs': 'Total Tabs', 'dashboard.stats.widgets': 'Total Widgets', 'dashboard.stats.connected': 'Connected', 'dashboard.stats.disconnected': 'Disconnected', 'dashboard.tabs.title': 'Tabs & Widgets', 'dashboard.tabs.widgets': 'Widgets', 'dashboard.aura.title': 'What does AURA mean?', 'dashboard.aura.adaptive': 'Adapts flexibly to devices, rooms and layouts', 'dashboard.aura.unified': 'All datapoints and rooms in a unified interface', 'dashboard.aura.room': 'Room-based organization – each tablet its own layout', 'dashboard.aura.automation': 'Control and visualize ioBroker automations live', 'dashboard.nav.title': 'Tablet Navigation via ioBroker', 'dashboard.nav.description': 'Set the following datapoint from an ioBroker script or automation to navigate the tablet to a specific tab or external URL. The datapoint is automatically reset after navigation.', 'dashboard.nav.datapoint': 'Datapoint', 'dashboard.nav.tabSlugs': 'Tab Slugs (value for the datapoint)', 'dashboard.nav.example': 'Example (JavaScript script)', 'dashboard.nav.externalUrl': 'For external URLs specify the full URL (https://…).', 'dashboard.nav.copy': 'Copy', 'dashboard.orphans.title': '{count} orphaned DP(s) in ioBroker', 'dashboard.orphans.titleClean': 'No orphaned DPs in ioBroker', 'dashboard.orphans.hint': 'These objects exist in ioBroker but no longer belong to any widget. Cleaning up removes them from the object tree.', 'dashboard.orphans.hintClean': 'Every {ns}.timers.* and {ns}.lists.* datapoint belongs to an existing widget.', 'dashboard.orphans.timerLabel': 'Timer DPs without a widget', 'dashboard.orphans.listLabel': 'List DPs without a widget', 'dashboard.orphans.refresh': 'Refresh', 'dashboard.orphans.cleanup': 'Clean up', 'dashboard.brokenDps.title': '{count} widget reference(s) to missing DPs', 'dashboard.brokenDps.titleClean': 'All widget DP references are valid', 'dashboard.brokenDps.hint': 'The following widgets reference datapoints that do not exist in ioBroker. Update the datapoint in the widget or recreate it in the adapter.', 'dashboard.brokenDps.hintClean': 'Every datapoint used by a widget exists in ioBroker.', 'dashboard.brokenDps.colWidget': 'Widget', 'dashboard.brokenDps.colLocation': 'Location', 'dashboard.brokenDps.colField': 'Field', 'dashboard.brokenDps.colDp': 'Datapoint', // ── Layouts ─────────────────────────────────────────────────────────────────── 'layouts.title': 'Layouts', 'layouts.subtitle': 'Each layout has its own tabs and widgets — ideal for different tablets or rooms.', 'layouts.newLayout': 'New Layout', 'layouts.placeholder': 'Layout name, e.g. Bedroom Tablet', 'layouts.create': 'Create', 'layouts.urlSchema': 'URL Schema', 'layouts.default': 'Default Layout (first layout)', 'layouts.specific': 'Specific Layout', 'layouts.specificTab': 'Specific Layout + Tab', 'layouts.duplicateName': 'Copy name:', 'layouts.duplicate': 'Duplicate', 'layouts.open': 'Open in Frontend', 'layouts.edit': 'Edit', 'layouts.delete': 'Delete Layout', 'layouts.export': 'Export Layout', 'layouts.import': 'Import Layout', 'layouts.importInvalidFile': 'Invalid layout file', 'layouts.changeIcon': 'Change icon', 'layouts.dragToReorder': 'Drag to reorder', 'layouts.defaultTab': 'Default tab', 'layouts.setDefaultTab': 'Set as default tab (opened when no tab is specified in URL)', 'layouts.designSettings': 'Open Frontend Design', 'layouts.designHint': 'Theme, typography, header, menu and tab bar are configured under Frontend Design.', 'layouts.designHintLink': 'Open Frontend Design →', // ── Sections ("Bereiche") — the left-hand menu level inside a layout ── 'sections.title': 'Sections', 'sections.subtitle': 'A section is an entry in the left-hand menu of a layout and holds its own tabs.', 'sections.manage': 'Manage sections', 'sections.newSection': 'New section', 'sections.placeholder': 'Section name, e.g. Overview', 'sections.one': 'Section', 'sections.count': '{count} sections', 'sections.countOne': '1 section', 'sections.delete': 'Delete section', 'sections.export': 'Export section', 'sections.import': 'Import section', 'sections.importInvalidFile': 'Invalid section file', 'sections.moveTitle': 'Move / copy area to layout', 'sections.moveTargetLabel': 'Target layout', 'sections.moveTargetPlaceholder': 'Choose target layout…', 'sections.move': 'Move', 'sections.copy': 'Copy', 'sections.moveLastHint': "A layout's only section cannot be moved away", 'sections.hideFromMenu': 'Hide from menu', 'sections.hideFromMenuHint': 'Remove this section from the left-hand menu. Still reachable via its direct URL.', 'sections.hideMenuHere': 'Hide menu here', 'sections.hideMenuHereHint': 'Hide the section menu while this section is open – e.g. for a fixed tablet.', 'sections.defaultSection': 'Layout default', 'sections.setDefaultSection': "Make this the layout's default section – it opens here and idle-return comes back to it.", 'sections.isDefault': 'Default', 'sections.makeDefault': 'Set default', 'design.title': 'Frontend Design', 'design.subtitle': 'Theme, typography, grid and tab bar — global or per layout.', 'design.frameGroup': 'Global frame', 'design.header.hint': 'Frontend header bar: title, clock, status badge and an optional datapoint. Configurable globally or per layout.', 'design.menu.hint': 'Left-hand navigation menu for switching between the sections of a layout (hamburger button or docked sidebar). Configurable globally or per layout.', 'design.nav.hint': 'Automatically return to the layout default after a period of inactivity. Configurable globally or per layout.', 'layouts.subtab.theme': 'Theme & CSS Vars', 'layouts.subtab.typo': 'Typography & Spacing', 'layouts.subtab.grid': 'Grid & Mobile', 'layouts.subtab.guidelines': 'Guidelines & Resolution', 'guidelines.hint': 'The current screen resolution is being shown. To turn this off: Admin → Design → Guidelines & Resolution.', 'guidelines.hintKeep': 'Got it', 'guidelines.resolutionLabel': 'Resolution', 'layouts.subtab.css': 'Custom CSS', 'layouts.subtab.tabbar': 'Tab bar', 'layouts.subtab.tabbarHiddenHint': 'Tab bar is configured per layout. Pick a layout in the context picker above.', 'layouts.subtab.header': 'Header', 'layouts.subtab.menu': 'Section menu', 'layouts.subtab.nav': 'Navigation', 'layouts.scope.title': 'Scope', 'layouts.scope.global': 'Global', 'layouts.scope.globalHint': 'Defaults for all sections', 'layouts.scope.layoutHint': 'Overrides global values', 'layouts.scope.resetToGlobal': 'Reset to global', 'layouts.scope.reset': 'Reset', 'layouts.scope.resetHint': 'Clear this scope’s overrides and inherit again.', 'layouts.context.label': 'Context', 'layouts.context.global': 'Global', 'layouts.context.hintGlobal': 'Defaults for all sections. Sections can override individual values.', 'layouts.context.hintLayout': 'Values override the global default. ↩ Global resets a value.', // ── Layout drawer (Hamburger) ───────────────────────────────────────────────── 'layoutDrawer.title': 'Sections', 'layoutDrawer.open': 'Open section menu', // ── Endpoints ───────────────────────────────────────────────────────────────── 'endpoints.title': 'Endpoints & Groups', 'endpoints.subtitle': 'Group datapoints together – e.g. "All Lights". Groups can be inserted as a list widget in the dashboard.', 'endpoints.newGroup': 'New Group (e.g. All Lights)', 'endpoints.createGroup': 'Create', 'endpoints.noGroups': 'No groups yet', 'endpoints.noGroupsHint': 'Create a group and add datapoints', 'endpoints.dp.count': '{count} Datapoints', 'endpoints.dp.add': 'Add Datapoint', 'endpoints.dp.empty': 'No datapoints yet – add some.', 'endpoints.dp.label': 'Label', 'endpoints.dp.type': 'Type', 'endpoints.dp.typeBoolean': 'Boolean (Switch / Display)', 'endpoints.dp.typeNumber': 'Number (Value)', 'endpoints.dp.typeText': 'Text', 'endpoints.dp.unit': 'Unit', 'endpoints.dp.unitPh': 'e.g. °C, %, W', 'endpoints.dp.writable': 'Writable', 'endpoints.dp.asSwitch': 'As Switch', 'endpoints.dp.typeSwitch': 'Switch', 'endpoints.dp.typeBool': 'Bool', 'endpoints.dp.typeNum': 'Number', 'endpoints.dp.toggle': 'Toggle Switch', 'endpoints.dp.settable': 'Value can be set', 'endpoints.dp.readOnly': 'Display only', 'endpoints.picker.title': 'Select Datapoints', 'endpoints.picker.load': 'Load devices from ioBroker', 'endpoints.picker.loading': 'Loading…', 'endpoints.picker.search': 'Search…', 'endpoints.picker.all': 'All', 'endpoints.picker.none': 'Nothing selected', 'endpoints.picker.selected': '{count} selected', 'endpoints.picker.add': 'Add', 'endpoints.picker.cancel': 'Cancel', // ── Login ───────────────────────────────────────────────────────────────────── 'login.setup.title': 'Setup Admin', 'login.setup.subtitle': 'Set a PIN for the admin area', 'login.title': 'Admin Area', 'login.subtitle': 'Enter PIN to continue', 'login.newPin': 'New PIN (min. 4 chars)', 'login.pin': 'PIN', 'login.pinConfirm': 'Confirm PIN', 'login.setPin': 'Set PIN & Login', 'login.login': 'Login', 'login.back': 'Back to Dashboard', 'login.tooShort': 'At least 4 characters', 'login.mismatch': "PINs don't match", 'login.wrong': 'Wrong PIN', // ── Theme ───────────────────────────────────────────────────────────────────── 'theme.title': 'Theme & CSS', 'theme.subtitle': 'Global design for Frontend', 'theme.preset.title': 'Theme Preset', 'theme.preset.active': 'Active ✓', 'theme.preset.desc': 'A preset sets all design variables at once: page and card backgrounds, borders, shadows, corner radius, text colors and the accent colors (blue/green/yellow/red) used by widgets. The colored dots show each theme’s card and accent colors. After picking a preset you can fine-tune individual variables below.', 'theme.vars.title': 'Customize CSS Variables', 'theme.vars.resetAll': 'Reset All', 'theme.vars.app': 'App', 'theme.vars.widget': 'Widget Card', 'theme.vars.text': 'Text', 'theme.vars.colors': 'Colors', 'theme.vars.bg': 'Background', 'theme.vars.surface': 'Surface', 'theme.vars.border': 'Border', 'theme.vars.borderWidth': 'Border Width', 'theme.vars.radius': 'Corner Radius', 'theme.vars.shadow': 'Shadow', 'theme.vars.primary': 'Primary', 'theme.vars.secondary': 'Secondary', 'theme.vars.accent': 'Accent', 'theme.vars.green': 'Green', 'theme.vars.yellow': 'Yellow', 'theme.vars.red': 'Red', // Element-specific variables (Issue #313) 'theme.vars.elSwitch': 'Switch', 'theme.vars.elBlind': 'Blind', 'theme.vars.elHeader': 'Header', 'theme.vars.elGroup': 'Widget in group', 'theme.vars.elSlider': 'Slider', 'theme.vars.elButton': 'Button', 'theme.vars.elGauge': 'Gauge', 'theme.vars.elClimate': 'Climate', 'theme.vars.elChip': 'Chips', 'theme.vars.elBadge': 'Status badges', 'theme.vars.elLight': 'Light', 'theme.vars.elNav': 'Navigation', 'theme.vars.elOnBg': 'On background', 'theme.vars.elOffBg': 'Off background', 'theme.vars.elThumb': 'Thumb', 'theme.vars.elIndicator': 'Indicator', 'theme.vars.elUpColor': 'Up icon', 'theme.vars.elUpBg': 'Up background', 'theme.vars.elUpBorder': 'Up border', 'theme.vars.elStopColor': 'Stop icon', 'theme.vars.elStopBg': 'Stop background', 'theme.vars.elStopBorder': 'Stop border', 'theme.vars.elDownColor': 'Down icon', 'theme.vars.elDownBg': 'Down background', 'theme.vars.elDownBorder': 'Down border', 'theme.vars.elText': 'Text', 'theme.vars.elTrack': 'Track', 'theme.vars.elFill': 'Fill', 'theme.vars.elArc': 'Arc', 'theme.vars.elHeat': 'Heat', 'theme.vars.elCool': 'Cool', 'theme.vars.elActive': 'Active', 'theme.vars.elOn': 'On', 'theme.vars.elOff': 'Off', 'theme.typography.title': 'Typography', 'theme.typography.subtitle': 'Scales all text sizes in the frontend proportionally. The admin interface remains unchanged.', 'theme.typography.fontSize': 'Font Size', 'theme.typography.reference': 'Size reference at {percent} %', 'theme.typography.example': 'Example', 'theme.typography.reset': 'Reset (100 %)', 'theme.typography.value': 'Value / Clock', 'theme.typography.heading': 'Heading', 'theme.typography.subheading': 'Subheading', 'theme.typography.body': 'Body text', 'theme.typography.small': 'Small / Label', 'theme.layout.title': 'Layout & Spacing', 'theme.layout.gap': 'Gap between widgets', 'theme.layout.padding': 'Widget inner padding', 'theme.css.title': 'Global CSS', 'theme.css.subtitle': 'Applied directly to the frontend. CSS variables, animations, font overrides, etc.', 'theme.css.lines': '{count} lines', 'theme.css.empty': 'No Custom CSS', 'theme.css.enabled': 'CSS active', 'theme.css.inEditor': 'Also apply in dashboard editor', 'theme.js.title': 'Global JavaScript', 'theme.js.subtitle': "Helper functions for widget onClick handlers. API: window.aura.setState / getState / subscribeState / getObject / getObjectView / sendTo. Load external scripts via @import url('…'); at the top.", 'theme.js.warning': '⚠ Script runs with your frontend permissions and can read/write all ioBroker datapoints. Only paste code you trust.', 'theme.js.lines': '{count} lines', 'theme.js.empty': 'No Custom JS', 'theme.js.enabled': 'JS active', 'theme.js.inEditor': 'Also run in dashboard editor', 'theme.js.importHint': '💡 Order: put all @import lines at the very top, then your JS code (function, const, …). @import between code lines is treated as a syntax error.', 'cssjs.title': 'CSS & JS', 'cssjs.subtitle': 'Inject custom CSS and JavaScript globally or per layout.', 'cssjs.tab.css': 'Custom CSS', 'cssjs.tab.js': 'Custom JS', // ── Widgets page ────────────────────────────────────────────────────────────── 'widgets.fromIoBroker': 'Select from ioBroker', 'widgets.close': 'Close', 'widgets.edit': 'Edit', 'widgets.openInEditor': 'Open in dashboard editor', 'widgets.delete': 'Delete', 'widgets.noneSelected': 'Nothing selected', 'widgets.resetDefault': 'Reset to Default', 'widgets.title': 'Widget Management', 'widgets.subtitle': '{widgets} Widgets · {tabs} Tabs', 'widgets.search': 'Search widgets (name, datapoint, tab, type)…', 'widgets.import': 'Import', 'widgets.noTitle': 'No title', 'widgets.noWidgets': 'No widgets', 'widgets.noWidgetsHint': 'Create widgets in the Dashboard Editor or here.', 'widgets.createFirst': 'Create First Widget', 'widgets.noResults': 'No widgets found for "{search}"', 'widgets.groups': 'Groups', 'widgets.groupsSection': 'Groups & Datapoints', 'widgets.newGroup': 'New Group', 'widgets.groupPlaceholder': 'Group name, e.g. All Lights', 'widgets.noGroupsHint': 'No groups yet – create one to group datapoints.', 'widgets.defaultSizes': 'Default Sizes', 'widgets.defaultSizesHint': 'Width × Height in grid units when creating new widgets', 'widgets.targetTab': 'Target Tab', 'widgets.calendarHint': 'Please create Calendar widgets via the Dashboard Editor (iCal URL required).', 'widgets.copyTarget': 'Target:', // ── Editor ──────────────────────────────────────────────────────────────────── 'editor.dockedMenuPreview.hint': 'The section menu is docked as a sidebar and takes up this space in the frontend. It is shown here so the design area matches.', 'editor.dockedMenuPreview.link': 'Change menu setting', 'editor.manual.title': 'Add Widget Manually', 'editor.manual.template': 'Quick Select', 'editor.manual.type': 'Type', 'editor.manual.titleField': 'Title', 'editor.manual.icalUrl': 'iCal URL *', 'editor.manual.calName': 'Calendar Name', 'editor.manual.moreCalendars': 'Add more calendars after adding in the widget editor.', 'editor.manual.group': 'Group *', 'editor.manual.noGroups': 'No groups yet – first create one under "Endpoints"', 'editor.manual.selectGroup': '– Select group –', 'editor.manual.datapointId': 'Datapoint ID (optional)', 'editor.manual.unit': 'Unit (optional)', 'editor.manual.add': 'Add', 'editor.manual.cancel': 'Cancel', 'editor.manual.recentlyUsed': 'Recently used', 'editor.tab.addDevice': '+ Devices', 'editor.tab.addManual': '+ Manual', 'editor.tab.addTab': '+ Tab', 'editor.tab.noWidgets': 'No tab selected or tab is empty.', 'editor.layouts.standard': 'Default', 'editor.layouts.default': 'Default', 'editor.layouts.card': 'Card', 'editor.layouts.compact': 'Compact', 'editor.layouts.minimal': 'Minimal', 'editor.layouts.agenda': 'Agenda', 'editor.layouts.custom': 'Custom', 'editor.mobile.title': 'Mobile Order', 'editor.peekHint': 'Hold Ctrl+Alt = preview without edit buttons', 'editor.mobile.top': 'Top', 'editor.mobile.bottom': 'Bottom', 'editor.mobile.hidden': 'Hidden', 'editor.tabMgmt.title': 'Tab Management', 'editor.tabMgmt.settings': 'Tab Settings', 'editor.tabMgmt.name': 'Name', 'editor.tabMgmt.hideLabel': 'Hide Label', 'editor.tabMgmt.disabled': 'Tab disabled', 'editor.tabMgmt.hidden': 'Hide from tab bar', 'editor.tabMgmt.conditions': 'Conditions', 'editor.tabMgmt.icon': 'Icon', 'editor.tabMgmt.slug': 'URL Slug', 'editor.tabMgmt.slugTaken': 'Already taken', 'editor.tabMgmt.selectIcon': 'Select icon…', 'editor.tabMgmt.remove': 'Remove', 'editor.tabMgmt.delete': 'Delete Tab', // ── WidgetFrame menu & edit modal ───────────────────────────────────────────── 'wf.menu.edit': 'Edit', 'wf.menu.conditions': 'Conditions', 'wf.menu.badges': 'Badges', 'wf.menu.export': 'Export', 'wf.menu.saveAsPreset': 'Save as preset', 'preset.save.title': 'Save as widget preset', 'preset.save.subtitle': 'Saves this widget as a reusable template in the Widget Designer.', 'preset.save.name': 'Name', 'preset.save.icon': 'Icon', 'preset.save.category': 'Category', 'preset.save.categoryNone': 'None', 'preset.save.submit': 'Save', 'preset.save.saved': 'Saved ✓', 'preset.mine': 'My presets', 'preset.insert.title': 'Map datapoints', 'preset.insert.subtitle': 'This preset needs the following datapoints:', 'preset.insert.autoNote': 'Battery/status datapoints are detected automatically from siblings.', 'preset.insert.submit': 'Insert', 'preset.insert.noSlots': 'This preset needs no datapoints.', 'widgetDesigner.title': 'Widget Designer', 'widgetDesigner.subtitle': 'Manage, share and reuse your own widget presets.', 'widgetDesigner.empty': 'No presets yet. Save a widget via the widget menu “Save as preset”.', 'widgetDesigner.import': 'Import', 'widgetDesigner.importError': 'Import failed – invalid file', 'widgetDesigner.edit': 'Edit', 'preset.edit.save': 'Apply', 'widgetDesigner.export': 'Export', 'widgetDesigner.rename': 'Rename', 'widgetDesigner.delete': 'Delete', 'widgetDesigner.deleteConfirm': 'Delete this preset?', 'widgetDesigner.count': '{count} presets', 'wf.menu.copy': 'Copy', 'wf.menu.copyHere': 'Duplicate here', 'wf.menu.duplicateInGroup': 'Duplicate in group', 'wf.menu.dragToGroup': 'Drag into group', 'wf.menu.dragOutOfGroup': 'Drag out of group', 'wf.menu.move': 'Move', 'wf.menu.popupViews': 'Popup views', 'wf.menu.delete': 'Delete', 'wf.menu.confirm': 'Confirm', 'wf.menu.hidden': 'Hidden', 'wf.menu.options': 'Widget Options', 'wf.menu.clickAction': 'Click action', 'wf.edit.title': 'Edit Widget', 'wf.edit.name': 'Name', 'wf.edit.hideName': 'Hide Name', 'wf.edit.titlePosition': 'Title Position', 'wf.edit.showLastChange': 'Show Last Change', 'wf.edit.group.autoShrink': 'Shrink when widgets are hidden', 'wf.edit.group.autoShrinkHint': 'When child widgets are hidden by a condition, the group shrinks to fit the visible content (frontend only).', 'wf.edit.group.defaultCollapsed': 'Collapsed by default', 'wf.edit.group.defaultCollapsedHint': 'The group initially shows only its header; clicking it expands the content (frontend only).', 'wf.edit.group.mobileKeepGrid': 'Keep grid layout on mobile', 'wf.edit.group.mobileKeepGridHint': 'By default widgets are stacked in a single column on mobile. When enabled, the side-by-side arrangement from the normal view is kept, just scaled down.', 'wf.edit.position': 'Position', 'wf.edit.posLeft': 'Left', 'wf.edit.posCenter': 'Center', 'wf.edit.posRight': 'Right', 'wf.edit.style': 'Style', 'wf.edit.styleReset': 'Reset', 'wf.edit.widgetType': 'Widget Type', 'wf.edit.layout': 'Layout', 'wf.edit.icon': 'Icon', 'wf.edit.datapointId': 'Datapoint ID', 'wf.edit.jsonPath': 'JSON path (optional)', 'wf.edit.jsonPathHint': 'e.g. soc or devices.0.soc', 'wf.edit.jsonPathDesc': 'Read a nested value from an object/JSON state.', 'wf.edit.jsonPathClear': 'Clear path', 'wf.edit.fromIoBroker': 'Select from ioBroker', 'wf.edit.unit': 'Unit', 'wf.edit.conditions': 'Conditions', 'wf.dpTypeMismatch.title': 'Change widget type?', 'wf.dpTypeMismatch.message': 'The selected datapoint matches "{suggested}" better. Current widget type: "{current}".', 'wf.dpTypeMismatch.switch': 'Switch to "{suggested}"', 'wf.dpTypeMismatch.keep': 'Keep "{current}"', 'wf.edit.style.bg': 'Background', 'wf.edit.style.border': 'Border Color', 'wf.edit.style.borderWidth': 'Border Width', 'wf.edit.style.accent': 'Accent Color', 'wf.edit.style.text': 'Text', 'wf.edit.style.textSec': 'Secondary Text', 'wf.edit.style.radius': 'Corner Radius', 'wf.edit.header.subtitle': 'Subtitle (optional)', 'wf.edit.header.style': 'Style', 'wf.edit.header.default': 'Default (Accent line + Title)', 'wf.edit.header.compact': 'Compact (Left line)', 'wf.edit.header.minimal': 'Minimal (Divider + Text)', 'wf.edit.layout.standard': 'Default', 'wf.edit.layout.card': 'Card', 'wf.edit.layout.compact': 'Compact', 'wf.edit.layout.minimal': 'Minimal', 'wf.edit.layout.agenda': 'Agenda', // Clock config 'wf.clock.display': 'Display', 'wf.clock.timeOnly': 'Time only', 'wf.clock.datetime': 'Time + Date', 'wf.clock.dateOnly': 'Date only', 'wf.clock.showSeconds': 'Show Seconds', 'wf.clock.dateFormat': 'Date Format', 'wf.clock.short': 'Short (04/07/2026)', 'wf.clock.long': 'Long (Monday, April 7, 2026)', 'wf.clock.customFormat': 'Custom Format', 'wf.clock.timeFontSize': 'Time font size (px)', 'wf.clock.dateFontSize': 'Date font size (px)', 'wf.clock.customFontSize': 'Custom font size (px)', 'wf.clock.fontSizeAuto': 'auto', 'wf.clock.showWeek': 'Show calendar week', 'wf.clock.showCity': 'Show city', 'wf.clock.showSunrise': 'Show sunrise', 'wf.clock.showSunset': 'Show sunset', 'wf.clock.extrasFontSize': 'Extras font size (px)', 'wf.value.fontSize': 'Value font size (px)', // History (chart) 'wf.history.title': 'Historical Data', 'wf.history.checking': 'Checking adapter…', 'wf.history.noAdapter': 'No history adapter active for this datapoint.', 'wf.history.instance': 'Adapter Instance', 'wf.history.liveData': '– Live Data (no history) –', 'wf.history.timeRange': 'Time Range', 'wf.history.lockRange': 'Lock time range (hide selector in frontend)', 'wf.history.showYAxis': 'Show Y-axis', 'wf.history.yAxisCompact': 'Compact (7000 → 7K)', 'wf.history.showXAxis': 'Show X-axis', // Calendar config 'wf.cal.addCalendar': 'Add Calendar', 'wf.cal.calUrl': 'iCal URL…', 'wf.cal.calName': 'Name (optional)', 'wf.cal.changeColor': 'Change color', 'wf.cal.showName': 'Show name', 'wf.cal.add': 'Add', 'wf.cal.refreshInterval': 'Refresh Interval', 'wf.cal.daysAhead': 'Days Ahead', 'wf.cal.maxEntries': 'Max. Entries', // Gauge config 'wf.gauge.strokeWidth': 'Arc Width', 'wf.gauge.minStatic': 'Min (static)', 'wf.gauge.maxStatic': 'Max (static)', 'wf.gauge.minDynamic': 'Min Datapoint (dynamic)', 'wf.gauge.maxDynamic': 'Max Datapoint (dynamic)', 'wf.gauge.dynamicMax': 'Dynamic Maximum', 'wf.gauge.dynamicMaxHint': 'Automatically extend max to current value', 'wf.gauge.unit': 'Unit', 'wf.gauge.decimals': 'Decimal Places', 'wf.gauge.colorZones': 'Color Zones', 'wf.gauge.greenTo': 'Green up to', 'wf.gauge.yellowTo': 'Yellow up to', 'wf.gauge.showMinMax': 'Show Min/Max', // Thermostat config 'wf.thermo.actualDp': 'Actual Temperature Datapoint', 'wf.thermo.minTemp': 'Min °C', 'wf.thermo.maxTemp': 'Max °C', 'wf.thermo.step': 'Step Size', 'wf.thermo.presets': 'Quick Select (separate with ;)', // Group config 'wf.group.transparent': 'Transparency Mode', 'wf.group.transparentHint': 'Remove background, border and shadow', // Weather config 'wf.weather.dataSource': 'Data Source', 'wf.weather.dsOnline': 'Online', 'wf.weather.dsAdapter': 'ioBroker Adapter', 'wf.weather.dsOnlineHint': 'Fetched directly from api.open-meteo.com (requires internet)', 'wf.weather.dsAdapterHint': 'Read from the installed open-meteo-weather adapter (works offline)', 'wf.weather.adapterPath': 'Adapter location', 'wf.weather.adapterPathHint': 'e.g. open-meteo-weather.0.Berlin — pick any sub-state, the prefix is detected automatically', 'wf.weather.customSection': 'Custom layout: forecast bar', 'wf.weather.barFontSize': 'Min/Max font size (rem)', 'wf.weather.barFontSizeHint': 'Font size of the min/max values next to the temperature bar (tempBar cells)', 'wf.weather.barHeight': 'Bar height (rem)', 'wf.weather.barHeightHint': 'Thickness of the temperature bar (tempBar / tempBarOnly cells)', 'wf.weather.locationSearch': 'Search Location', 'wf.weather.cityPlaceholder': 'Enter city or address', 'wf.weather.search': 'Search', 'wf.weather.searching': '…', 'wf.weather.notFound': 'No location found', 'wf.weather.searchError': 'Search error', 'wf.weather.latitude': 'Latitude', 'wf.weather.longitude': 'Longitude', 'wf.weather.locationName': 'Location Name', 'wf.weather.locationPh': 'e.g. Munich', 'wf.weather.refreshMin': 'Refresh (min.)', 'wf.weather.showWeather': 'Show weather data', 'wf.weather.showForecast': 'Show Forecast', 'wf.weather.forecastDays': 'Forecast Days', 'wf.weather.showToday': 'Show Today', 'wf.weather.localTemp': 'Local temperature sensor (datapoint)', 'wf.weather.localTempPh': 'e.g. hm-rpc.0.xxx.TEMPERATURE', 'wf.weather.showWarnings': 'Show weather warnings (DWD)', 'wf.weather.warningsHint': 'Requires lat/lon • Germany only', 'wf.weather.warningsScale': 'Warnings size', 'wf.weather.warningsScaleHint': '1 = default. >1 enlarges the warnings independently.', 'wf.weather.showRainProb': 'Show rain probability', 'wf.weather.showRainAmount': 'Show rain amount (mm)', 'wf.weather.showCloudCover': 'Show cloud cover', 'wf.weather.tempThresholds': 'Temperature color scale (bars)', 'wf.weather.tempThresholdsAdd': 'Add', 'wf.weather.tempThresholdsPreset': 'Default', 'wf.weather.tempThresholdsFrom': 'from', 'wf.weather.tempThresholdsHint': 'From temperature → color · sort ascending', 'wf.weather.tempThresholdsEmpty': 'No thresholds configured', 'wf.weather.showCondition': 'Show weather condition text', 'wf.weather.showHumidityLabel': 'Show "humidity" label', 'wf.weather.feelsLikeStyle': '"Feels like" display', 'wf.weather.feelsLikeStyleText': 'Text ("Feels like …")', 'wf.weather.feelsLikeStyleIcon': 'Icon (🌡️ …)', 'wf.weather.feelsLikeStyleHidden': 'Value only', 'wf.weather.tempFontSize': 'Temperature font size (rem)', 'wf.weather.tempFontSizeHint': '0 = same as condition. Larger = prominent.', 'wf.weather.fontScale': 'Widget font size (multiplier)', 'wf.weather.fontScaleHint': '1 = automatic. >1 enlarges all text.', 'wf.weather.forecastRowGap': 'Forecast row spacing (rem)', 'wf.weather.forecastRowGapHint': '0 = default. Larger = more space between days.', 'wf.weather.forecastWrap': 'Forecast two-line (wrap)', // Camera config 'wf.camera.streamUrl': 'Stream URL', 'wf.camera.refresh': 'Refresh (sec., 0 = MJPEG)', 'wf.camera.fitMode': 'Image Fit', 'wf.camera.cover': 'Cover (fill)', 'wf.camera.contain': 'Contain (fit)', 'wf.camera.timestamp': 'Show Timestamp', // ── Last-change timestamps ──────────────────────────────────────────────────── 'lc.lessThan10s': 'updated less than 10 sec ago', 'lc.lessThan20s': 'updated less than 20 sec ago', 'lc.lessThan30s': 'updated less than 30 sec ago', 'lc.halfMinute': 'half a minute ago', 'lc.lessThan1Min': 'less than 1 minute ago', 'lc.1Min': '1 minute ago', 'lc.nMin': 'about {n} minutes ago', 'lc.1Hour': 'about 1 hour ago', 'lc.nHours': 'about {n} hours ago', 'lc.1Day': 'about 1 day ago', 'lc.nDays': '{n} days ago', 'lc.1Month': 'about 1 month ago', 'lc.nMonths': '{n} months ago', 'lc.1Year': 'about 1 year ago', 'lc.nYears': '{n} years ago', // ── TabBar ──────────────────────────────────────────────────────────────────── 'tabBar.settings': 'Tab Settings', 'tabBar.name': 'Name', 'tabBar.hideLabel': 'Hide Label', 'tabBar.disabled': 'Tab disabled', 'tabBar.hidden': 'Hide from tab bar', 'tabBar.conditions': 'Conditions', 'tabBar.badges': 'Badges', 'tabBar.hideTabOnCond': 'Hide tab when condition matches', 'tabBar.icon': 'Icon', 'tabBar.selectIcon': 'Select icon…', 'tabBar.remove': 'Remove', 'tabBar.addTab': '+ Tab', 'tabBar.exportTab': 'Export Tab', 'tabBar.moveTitle': 'Move / copy to section', 'tabBar.moveTargetPlaceholder': 'Choose target section…', 'tabBar.moveCurrentSuffix': 'current', 'tabBar.move': 'Move', 'tabBar.copy': 'Copy', 'tabBar.importTab': 'Import Tab', 'tabBar.importInvalidFile': 'Invalid tab file', // ── Frontend Dashboard ──────────────────────────────────────────────────────── 'frontend.noWidgets': 'No widgets configured.', 'frontend.addWidgets': 'No widgets yet – add via "+ Devices".', // ── DatapointPicker ─────────────────────────────────────────────────────────── 'dp.picker.title': 'Select Datapoint', 'dp.picker.refresh': 'Refresh', 'dp.picker.search': 'Search ID or name…', 'dp.picker.allAdapters': 'All Adapters', 'dp.picker.allRooms': 'All Rooms', 'dp.picker.allFuncs': 'All Functions', 'dp.picker.allRoles': 'All Roles', 'dp.picker.allTypes': 'All Types', 'dp.picker.typeHint': '{type} only', 'dp.picker.loading': 'Loading datapoints…', 'dp.picker.showing': 'Showing {max} of {count}', 'dp.picker.count': '{count} datapoints', 'dp.picker.noResults': 'No results', 'dp.picker.allUnits': 'All Units', 'dp.picker.historyOnly': 'With History', 'dp.picker.showInactive': 'Show inactive', 'dp.picker.showInactiveHint': 'Also show states of disabled/uninstalled adapters and orphaned or imported states', 'dp.picker.col.name': 'Name / ID', 'dp.picker.col.value': 'Value', 'dp.picker.col.unit': 'Unit', 'dp.picker.col.type': 'Type', 'dp.picker.col.history': 'History', // ── File Picker ────────────────────────────────────────────────────────────── 'fs.picker.title': 'File Picker', 'fs.picker.tab.dp': 'Datapoint', 'fs.picker.tab.files': 'Files', 'fs.picker.search': 'Search…', 'fs.picker.empty': 'Directory is empty', 'fs.picker.previewNone': 'No Preview', 'fs.picker.noRoots': 'No directories configured', 'fs.picker.roots': 'Roots', 'fs.picker.select': 'Select', // ── ConditionEditor ─────────────────────────────────────────────────────────── 'cond.equal': '= Equal', 'cond.notEqual': '≠ Not Equal', 'cond.greater': '> Greater', 'cond.greaterEq': '≥ Greater or equal', 'cond.less': '< Less', 'cond.lessEq': '≤ Less or equal', 'cond.contains': '∋ Contains', 'cond.isTrue': '✓ Is true', 'cond.isFalse': '✗ Is false', 'cond.colorAccent': 'Accent', 'cond.colorBg': 'Background', 'cond.colorBorder': 'Border', 'cond.colorText': 'Text', 'cond.colorText2': 'Text 2', 'cond.when': 'WHEN', 'cond.datapointId': 'Datapoint ID', 'cond.fromIoBroker': 'Select from ioBroker', 'cond.value': 'Value', 'cond.toStatic': 'Switch to static value', 'cond.toDatapoint': 'Compare with datapoint', 'cond.removeClause': 'Remove clause', 'cond.addClause': 'Add clause', 'cond.activeStyle': 'Style when active', 'cond.effect': 'Effect', 'cond.noEffect': 'No effect', 'cond.pulse': 'Pulse', 'cond.blink': 'Blink', 'cond.hideWidget': 'Hide Widget', 'cond.hideWidgetHint': 'Widget becomes invisible when condition is met', 'cond.controlVisibility': 'Control visibility', 'cond.controlVisibilityHint': 'Show or hide the widget depending on the condition', 'cond.controlTabVisibility': 'Control visibility', 'cond.controlTabVisibilityHint': 'Show or hide the tab depending on the condition', 'cond.mode': 'Mode', 'cond.hideOnMatch': 'Hide on match', 'cond.showOnMatch': 'Show on match', 'cond.hideOnMatchHint': 'Widget is visible and disappears as soon as the condition is met', 'cond.showOnMatchHint': 'Widget is hidden and appears only when the condition is met', 'cond.hideOnMatchTabHint': 'Tab is visible and disappears as soon as the condition is met', 'cond.showOnMatchTabHint': 'Tab is hidden and appears only when the condition is met', 'cond.pushOthers': 'Push other widgets up', 'cond.pushOthersHint': 'Widget is removed from the grid, others fill the space', 'cond.rules': 'Condition Rules', 'cond.rulesHint': 'Colors change when conditions are met', 'cond.noRules': 'No rules yet. Create a rule to get started.', 'cond.newRule': 'New Rule', // ── Badges ─────────────────────────────────────────────────────────────────── 'badge.rules': 'Badges', 'badge.rulesHint': 'Small indicators on the element edge', 'badge.noRules': 'No badges yet. Add one to get started.', 'badge.newRule': 'New Badge', 'badge.style': 'Style', 'badge.styleDot': 'Dot', 'badge.styleCount': 'Count (datapoint)', 'badge.styleLabel': 'Label', 'badge.corner': 'Corner', 'badge.cornerTL': 'Top left', 'badge.cornerTR': 'Top right', 'badge.cornerBL': 'Bottom left', 'badge.cornerBR': 'Bottom right', 'badge.sizePx': 'Size (px)', 'badge.color': 'Color', 'badge.datapoint': 'Datapoint', 'badge.label': 'Label', 'badge.icon': 'Icon', 'badge.visibility': 'Visible', 'badge.visAlways': 'Always', 'badge.visNonzero': 'When value > 0', 'badge.visNonzeroHint': 'Shown while the datapoint is active (> 0, true, or non-empty)', 'badge.visCondition': 'When condition met', 'badge.tabAggregate': 'Aggregate count', 'badge.tabAggregateHint': 'Show how many widgets on this tab currently have a badge', 'badge.sectionAggregate': 'Aggregate count', 'badge.sectionAggregateHint': 'Show how many widgets across all tabs of this section currently have a badge', // ── EChartConfig ───────────────────────────────────────────────────────────── 'echart.deleteSeries': 'Delete Series', 'echart.line': 'Line', 'echart.area': 'Area', 'echart.bar': 'Bar', 'echart.scatter': 'Scatter', 'echart.series': 'Series', 'echart.addSeries': 'Add Series', 'echart.noSeries': 'No series yet. Click "Add Series".', 'echart.name': 'Name', 'echart.datapoint': 'Datapoint', 'echart.dpPlaceholder': 'e.g. hm-rpc.0....', 'echart.fromIoBroker': 'Select from ioBroker', 'echart.chartType': 'Chart Type', 'echart.color': 'Color', 'echart.yAxis': 'Y Axis', 'echart.yLeft': 'Left', 'echart.yRight': 'Right', 'echart.smooth': 'Smooth', 'echart.lineWidth': 'Line width: {value}px', 'echart.history': 'Historical Data', 'echart.selectDpFirst': 'Select datapoint first.', 'echart.checking': 'Checking adapter…', 'echart.detect': 'Detect Adapter', 'echart.noAdapter': 'No history adapter active.', 'echart.instance': 'Adapter Instance', 'echart.liveData': '– Live Data –', 'echart.timeRange': 'Time Range', 'echart.globalSettings': 'Global Settings', 'echart.showLegend': 'Show Legend', 'echart.yAxisLeft': 'Y Axis Left', 'echart.unitLeft': 'Unit (e.g. °C)', 'echart.min': 'Min', 'echart.max': 'Max', 'echart.yAxisRight': 'Y Axis Right', 'echart.unitRight': 'Unit (e.g. %)', 'echart.jsonOverride': 'JSON Override', 'echart.jsonOverrideHint': 'Merged with auto-generated ECharts option (deep merge). Arrays are replaced.', 'echart.active': 'active', 'echart.mode': 'Mode', 'echart.modeTimeseries': 'Time Series', 'echart.modeComparison': 'Comparison', 'echart.aggregation': 'Aggregation', 'echart.aggAverage': 'Average (default)', 'echart.aggMinmax': 'Min/Max (true extremes — e.g. rain counter)', 'echart.aggMax': 'Maximum', 'echart.aggMin': 'Minimum', 'echart.aggTotal': 'Total', 'echart.visibleRanges': 'Time ranges shown in frontend', 'echart.dayNavToggle': 'Day navigation in frontend (◀ Today ▶)', 'echart.today': 'Today', 'echart.dayPrevTitle': 'Previous day', 'echart.dayTodayTitle': 'Go to current day', 'echart.dayNextTitle': 'Next day', 'echart.dateLocale': 'en-GB', 'echart.moveUp': 'Move up', 'echart.moveDown': 'Move down', 'echart.templateInstancePlaceholder': 'empty = instance of the triggering widget', 'echart.templateInstanceHint': 'Template datapoint – leave empty to inherit the history instance from the triggering widget.', 'echart.showYAxis': 'Show Y axis', 'echart.showXAxis': 'Show X axis', 'echart.gridLines': 'Horizontal grid lines', 'echart.showCurrentValue': 'Show current value', 'echart.unitHoursShort': 'Hrs', 'echart.unitDaysShort': 'Days', 'echart.daySingular': 'day', 'echart.dayPlural': 'days', 'echart.lockRangeToggle': 'Lock time range in frontend', 'echart.decimals': 'Decimal places (tooltip)', 'echart.globalActive': 'Global setting active – click to set a custom value', 'echart.resetToGlobal': 'Reset to global setting', 'echart.noData': 'No data', 'echart.preview': 'Preview', 'echart.historyInstance': 'History instance', // ── Device Wizard ───────────────────────────────────────────────────────────── 'wizard.device.title': 'Devices from ioBroker', 'wizard.device.loading': 'Loading devices…', 'wizard.device.hint': 'Load all available devices and datapoints', 'wizard.device.load': 'Load Devices', 'wizard.device.search': 'Search…', 'wizard.device.allAdapters': 'All Adapters', 'wizard.device.allRooms': 'All Rooms', 'wizard.device.allFuncs': 'All Functions', 'wizard.device.allRoles': 'All Roles', 'wizard.device.devices': 'Devices', 'wizard.device.noneSelected': 'None selected', 'wizard.device.widget': 'Widget', 'wizard.device.widgets': 'Widgets', 'wizard.device.cancel': 'Cancel', 'wizard.device.add': 'Add to Dashboard', 'wizard.device.tempDp': 'Actual temperature datapoint (optional)', // ── Tab Wizard ──────────────────────────────────────────────────────────────── 'wizard.tab.title': 'Tab Wizard', 'wizard.tab.selectTheme': 'Choose a theme for the new tab.', 'wizard.tab.themeAll': 'All Datapoints', 'wizard.tab.themeAllHint': 'All available datapoints from all adapters', 'wizard.tab.themeBattery': 'Battery Status', 'wizard.tab.themeBatteryHint': 'Battery level overview of all devices', 'wizard.tab.themeWindow': 'Window Status', 'wizard.tab.themeWindowHint': 'Open/closed status of windows and doors', 'wizard.tab.themePower': 'Power Consumption', 'wizard.tab.themePowerHint': 'Power and energy consumption of all devices', 'wizard.tab.showAllDp': 'Show all datapoints', 'wizard.tab.showThemeOnly': 'Show theme only', 'wizard.tab.widget': 'Widget', 'wizard.tab.widgets': 'Widgets', 'wizard.tab.selectLayout': 'Select Layout', 'wizard.tab.cancel': 'Cancel', 'wizard.tab.back': 'Back', 'wizard.tab.next': 'Next', 'wizard.tab.create': 'Create Tab', // ── Widget Registry labels ──────────────────────────────────────────────────── 'widget.switch': 'Switch', 'widget.shutter': 'Shutter', 'widget.dimmer': 'Dimmer', 'widget.thermostat': 'Thermostat', 'widget.value': 'Value Display', 'widget.gauge': 'Gauge', 'widget.chart': 'Chart (Simple)', 'widget.echart': 'Chart (Advanced (ECharts))', 'widget.echartsPreset': 'eCharts', 'widget.list': 'Static List', 'widget.autolist': 'Dynamic List', 'widget.fill': 'Fill Level', 'widget.windowcontact': 'Window/Door Contact', 'widget.binarysensor': 'Binary Sensor', 'widget.stateimage': 'State Image', 'widget.clock': 'Clock', 'widget.weather': 'Weather', 'widget.calendar': 'Calendar', 'widget.evcc': 'evcc', 'widget.camera': 'Camera', 'widget.image': 'Image', 'widget.trash': 'Waste Collection', 'widget.trashSchedule': 'Waste Collection Schedule', 'widget.iframe': 'iFrame', 'widget.jsontable': 'JSON Table', 'widget.html': 'HTML', 'widget.header': 'Section Title', 'widget.group': 'Group', 'widget.httpRequest': 'HTTP Action', 'widget.button': 'Button', 'widget.climate': 'Room Climate', 'widget.enum': 'Selection Field', 'widget.carousel': 'Carousel', 'widget.input': 'Input field', 'widget.map': 'Map', 'widget.energiebilanz': 'Chart (Distribution)', // ── Weather Widget ──────────────────────────────────────────────────────────── 'weather.sunny': 'Sunny', 'weather.mainlyClear': 'Mainly Clear', 'weather.partlyCloudy': 'Partly Cloudy', 'weather.cloudy': 'Cloudy', 'weather.overcast': 'Overcast', 'weather.fog': 'Fog', 'weather.drizzle': 'Drizzle', 'weather.rain': 'Rain', 'weather.snow': 'Snow', 'weather.showers': 'Showers', 'weather.thunderstorm': 'Thunderstorm', 'weather.unknown': 'Unknown', 'weather.today': 'Today', 'weather.humidity': 'Humidity', 'weather.feelsLike': 'Feels like {feel} · 💨 {wind} km/h', 'weather.noData': 'Weather data not available', 'weather.warnings': 'Weather Warnings', 'weather.noWarnings': 'No warnings', 'weather.warnSeverity.minor': 'Minor', 'weather.warnSeverity.moderate': 'Moderate', 'weather.warnSeverity.severe': 'Severe', 'weather.warnSeverity.extreme': 'Extreme', // ── Calendar Widget ─────────────────────────────────────────────────────────── 'calendar.title': 'Calendar', 'calendar.configure': 'Configure Calendar', 'calendar.noEvents': 'No events', 'calendar.loading': 'Loading…', 'calendar.events': 'Events', 'calendar.today': 'Today', 'calendar.tomorrow': 'Tomorrow', 'calendar.todayAt': 'Today, {time}', 'calendar.tomorrowAt': 'Tomorrow, {time}', 'calendar.more': '+{count} more', 'calendar.updated': 'Updated: {time}', 'calendar.noDays': 'No events in the next {days} days', 'cal.day.0': 'Sun', 'cal.day.1': 'Mon', 'cal.day.2': 'Tue', 'cal.day.3': 'Wed', 'cal.day.4': 'Thu', 'cal.day.5': 'Fri', 'cal.day.6': 'Sat', 'cal.month.0': 'Jan', 'cal.month.1': 'Feb', 'cal.month.2': 'Mar', 'cal.month.3': 'Apr', 'cal.month.4': 'May', 'cal.month.5': 'Jun', 'cal.month.6': 'Jul', 'cal.month.7': 'Aug', 'cal.month.8': 'Sep', 'cal.month.9': 'Oct', 'cal.month.10': 'Nov', 'cal.month.11': 'Dec', // ── Clock Widget ────────────────────────────────────────────────────────────── 'clock.day.0': 'Sunday', 'clock.day.1': 'Monday', 'clock.day.2': 'Tuesday', 'clock.day.3': 'Wednesday', 'clock.day.4': 'Thursday', 'clock.day.5': 'Friday', 'clock.day.6': 'Saturday', 'clock.month.0': 'January', 'clock.month.1': 'February', 'clock.month.2': 'March', 'clock.month.3': 'April', 'clock.month.4': 'May', 'clock.month.5': 'June', 'clock.month.6': 'July', 'clock.month.7': 'August', 'clock.month.8': 'September', 'clock.month.9': 'October', 'clock.month.10': 'November', 'clock.month.11': 'December', 'clock.kw': 'CW ', // ── AutoListConfig ──────────────────────────────────────────────────────────── 'autolist.trueText': 'Text for ON / true / 1', 'autolist.falseText': 'Text for OFF / false / 0', 'autolist.idContains': 'ID contains', 'autolist.found': '{count} found · {selected} selected', 'autolist.apply': 'Apply {count} entries', 'autolist.settings': 'Settings', 'autolist.invalidEntry': 'invalid entry (no datapoint) — remove', 'autolist.auto': 'Automatic', 'autolist.roles': 'Roles', 'autolist.room': 'Room', 'autolist.func': 'Function', 'autolist.idPh': 'e.g. hm-rpc, shelly', 'autolist.search': 'Search', 'autolist.noneFound': 'No datapoints found', 'autolist.datapoints': 'Datapoints', 'autolist.manualPh': 'Datapoint ID manually…', 'autolist.syncMin': 'Auto-Sync (minutes)', 'autolist.showRoom': 'Show Room', // ── ImportWidget ────────────────────────────────────────────────────────────── 'import.titleGeneral': 'Import Widget or Tab', 'import.title': 'Import Widget', 'import.titleTab': 'Import Tab', 'import.fileLabel': 'Load JSON File', 'import.or': 'or', 'import.pasteJson': 'Paste JSON', 'import.invalidWidget': 'Not a valid widget (field "type" missing)', 'import.invalidTab': 'Not a valid tab file', 'import.tabNotSupported': 'Tab import not supported here', 'import.tabWidgetCount': '{count} Widget(s)', 'import.importTab': 'Import Tab', // ── Export anonymisation ────────────────────────────────────────────────────── 'exportAnon.title': 'Export', 'exportAnon.subtitle': 'Choose which data to anonymise on export. With nothing selected everything is exported as-is.', 'exportAnon.selectAll': 'Anonymise everything', 'exportAnon.selectNone': 'Clear selection', 'exportAnon.datapoints': 'Datapoints', 'exportAnon.datapointsHint': 'Replace ioBroker IDs with placeholders (links stay intact)', 'exportAnon.titles': 'Titles & free text', 'exportAnon.titlesHint': 'Titles, labels and texts (may contain room / person names)', 'exportAnon.urls': 'URLs & credentials', 'exportAnon.urlsHint': 'Camera streams, HTTP addresses, links (often carry tokens)', 'exportAnon.geoAndCode': 'Geo & custom code', 'exportAnon.geoAndCodeHint': 'Remove coordinates and custom JavaScript/CSS', 'exportAnon.export': 'Export', // ── Layout Presets (Tab Wizard) ─────────────────────────────────────────────── 'layout.compact': 'Compact', 'layout.compactDesc': 'More widgets at a glance – smaller tiles', 'layout.standard': 'Standard', 'layout.standardDesc': 'Balanced layout with well-readable widgets', 'layout.spacious': 'Spacious', 'layout.spaciousDesc': 'Large tiles – ideal for wall tablets', // ── Thermostat Widget ──────────────────────────────────────────────────────── 'thermo.heating': 'Heating', 'thermo.cooling': 'Cooling', 'thermo.standby': 'Standby', 'thermo.setPoint': 'Target', 'thermo.actual': 'Actual', // ── Group Widget ────────────────────────────────────────────────────────────── 'group.addWidget': 'Add widget', 'group.mobileOrder': 'Mobile order', 'group.noWidgets': 'No widgets yet', 'group.dropHere': 'Drop widget here', 'group.masterPlaceholder': 'Group switch enabled – appears once controllable datapoints are configured', 'group.masterPlaceholderShort': 'needs DPs', 'group.fitHeight': 'Fit height to content', // ── Panels Widget (slide of widgets) ────────────────────────────────────────── 'panels.noSlides': 'No panels', 'panels.dropHere': 'Drop widget here', 'panels.empty.editHint': 'Add widgets below or drag & drop them here', 'panels.empty.viewHint': 'No panels configured', 'panels.removeSlide': 'Remove panel', 'panels.prev': 'Previous', 'panels.next': 'Next', 'panels.slide': 'Panel', 'panels.addSlide': 'Add panel', 'panels.pickWidget': 'Pick widget', 'panels.opt.loop': 'Infinite loop', 'panels.opt.showDots': 'Pagination dots', 'panels.opt.showArrows': 'Arrow buttons', 'panels.opt.autoplay': 'Autoplay', 'panels.opt.interval': 'Interval', // ── Carousel Widget (chip strip) ────────────────────────────────────────────── 'carousel.items.title': 'Items', 'carousel.items.add': '+ Add item', 'carousel.items.label': 'Label', 'carousel.items.dp': 'Write DP — value is written to this DP on click', 'carousel.items.value': 'Active value (written on click, lights up when DP matches)', 'carousel.items.activeValue': 'Active value — item lights up when active-DP matches (empty = write value)', 'carousel.items.action': 'Click action (overrides DP write)', 'carousel.opt.snap': 'Snap scrolling', 'carousel.opt.gap': 'Spacing between items (px)', 'carousel.opt.maxItemWidth': 'Max item width (text marquees on overflow)', 'carousel.opt.labelAlign': 'Label alignment', 'carousel.opt.hideScrollbar': 'Hide scrollbar', 'carousel.opt.shakeOnOpen': 'Shake on tab open (hints more items)', 'carousel.opt.mode': 'Mode', 'carousel.opt.mode.carousel': 'Carousel (chip strip)', 'carousel.opt.mode.single': 'Single (one per width)', 'carousel.opt.autoRotate': 'Auto-rotate items slowly', 'carousel.opt.autoRotateSpeed': 'Rotation speed', 'carousel.opt.autoRotateInterval': 'Step interval', 'carousel.items.bgColor': 'Background color', 'carousel.items.textColor': 'Text color', 'carousel.items.colors': 'Colors', 'carousel.items.iconSize': 'Icon size', 'carousel.items.resetIconSize': 'Auto-size', 'carousel.items.colorsActive': 'Active', 'carousel.items.colorsInactive': 'Inactive', 'carousel.items.resetColor': 'Reset', 'carousel.items.inactiveValue': 'Inactive value (e.g. false)', 'carousel.items.showLastChange': 'Show last change (second line)', 'carousel.action.none': 'DP toggle (default)', 'carousel.action.popupWidget': 'Popup: widget content', 'carousel.action.popupView': 'Popup: view', 'carousel.action.linkTab': 'Jump to tab', // ── EVCC Widget ─────────────────────────────────────────────────────────────── 'evcc.solar': 'Solar', 'evcc.house': 'House', 'evcc.grid': 'Grid', 'evcc.feedIn': 'Feed-in', 'evcc.gridLabel': 'Grid', 'evcc.loadpoint': 'Loadpoint {n}', 'evcc.vehicle': 'Vehicle', 'evcc.charging': 'Charging', 'evcc.heating': 'Heating', 'evcc.targetSoc': 'Target:', 'evcc.adjustTarget': 'Adjust target SoC', 'evcc.noConnection': 'No connection', 'evcc.prefix': 'evcc Prefix', 'evcc.loadpoints': 'Loadpoints', 'evcc.showBattery': 'Show Battery', 'evcc.showLoadpoints': 'Show Loadpoints', // ── Mediaplayer Widget ──────────────────────────────────────────────────────── 'mp.dp.title': 'Title DP', 'mp.dp.artist': 'Artist DP', 'mp.dp.album': 'Album DP', 'mp.dp.cover': 'Cover Art DP (URL)', 'mp.dp.source': 'Source / Player Name DP', 'mp.dp.playState': 'Play State DP', 'mp.dp.volume': 'Volume DP', 'mp.dp.mute': 'Mute DP', 'mp.dp.play': 'Play DP', 'mp.dp.pause': 'Pause DP', 'mp.dp.stop': 'Stop DP', 'mp.dp.next': 'Next Track DP', 'mp.dp.prev': 'Previous Track DP', 'mp.dp.shuffle': 'Shuffle DP', 'mp.dp.repeat': 'Repeat DP', 'mp.dp.mediaProgress': 'Position DP (seconds)', 'mp.dp.mediaLength': 'Duration DP (seconds)', 'mp.dp.mediaProgressStr': 'Position DP (text, e.g. 03:42)', 'mp.dp.mediaLengthStr': 'Duration DP (text, e.g. 05:45)', 'mp.vol.min': 'Min', 'mp.vol.max': 'Max', 'mp.vol.step': 'Step', 'mp.chips.title': 'Quick Access Chips', 'mp.chips.add': '+ Add chip', 'mp.chips.label': 'Label', 'mp.chips.value': 'Value (empty = true)', 'mp.autodetect': 'Auto-Detect', 'mp.displayDps': 'Display DPs', 'mp.controlDps': 'Control DPs', 'mp.volumeRange': 'Volume Range', // ── Slider Widget ───────────────────────────────────────────────────────────── 'sl.range.min': 'Min', 'sl.range.max': 'Max', 'sl.range.step': 'Step', 'sl.range.unit': 'Unit', 'sl.style.orientation': 'Orientation', 'sl.style.horizontal': 'Horizontal', 'sl.style.vertical': 'Vertical', 'sl.style.barStyle': 'Bar style', 'sl.style.barSize': 'Bar width (%)', 'sl.style.thickness': 'Track thickness (px)', 'sl.style.color': 'Slider color', 'sl.style.commitOnRelease': 'Write value only on release', 'sl.style.readOnly': 'Read-only (progress bar)', 'sl.actions.title': 'Action buttons', 'sl.actions.add': '+ Add button', 'sl.actions.icon': 'Icon', 'sl.actions.label': 'Label (optional)', 'sl.actions.dp': 'Datapoint', 'sl.actions.value': 'Value (empty = true)', // ── Chips Widget ───────────────────────────────────────────────────────────── 'cw.layout.title': 'Layout', 'cw.layout.mode': 'Arrangement', 'cw.layout.row': 'Row (horizontal, scrollable)', 'cw.layout.wrap': 'Wrapped', 'cw.layout.column': 'Column', 'cw.layout.grid': 'Grid (fixed columns)', 'cw.layout.align': 'Alignment', 'cw.layout.valign': 'Vertical position', 'cw.layout.chipSize': 'Chip size', 'cw.layout.chipStyle': 'Chip style', 'cw.layout.chipRadius': 'Corner radius', 'cw.layout.wrapCols': 'Columns', 'cw.layout.gap': 'Gap (px)', 'cw.layout.bgColor': 'Background colour', 'cw.layout.textColor': 'Text colour', // Menu widget (navigation) 'menu.mode.title': 'Menu type', 'menu.mode.section': 'Section menu', 'menu.mode.tab': 'Tab menu', 'menu.variant.title': 'Variant', 'menu.variant.hbar': 'Horizontal bar', 'menu.variant.vlist': 'Vertical list', 'menu.variant.grid': 'Grid', 'menu.variant.pills': 'Pills', 'menu.indicator.title': 'Active style', 'menu.items': 'Menu items', 'menu.showIcons': 'Show icons', 'menu.showLabels': 'Show labels', 'menu.iconSize': 'Icon size', 'menu.align': 'Alignment', 'menu.align.left': 'Left', 'menu.align.center': 'Center', 'menu.align.right': 'Right', 'menu.gridCols': 'Columns', 'menu.empty': 'No menu items', 'cw.radius.full': 'Pill', 'cw.style.filled': 'Filled', 'cw.style.outlined': 'Outlined', 'cw.style.ghost': 'Ghost', 'cw.size.sm': 'Small', 'cw.size.md': 'Medium', 'cw.size.lg': 'Large', 'cw.checkDp': 'Active state DP (optional)', 'cw.chips.title': 'Chips', 'cw.chips.add': '+ Add chip', 'cw.chips.label': 'Label', 'cw.chips.value': 'Write value (empty = true)', 'cw.chips.activeValue': 'Active value (optional)', 'cw.chips.bg': 'Background colour', 'cw.chips.fg': 'Text colour', 'cw.confirm.enable': 'Require confirmation before action', 'cw.confirm.text': 'Confirmation text (optional)', // ── Climate Widget ──────────────────────────────────────────────────────────── 'climate.actualTemp': 'Actual Temperature Datapoint', 'climate.targetTemp': 'Target Temperature Datapoint (optional)', 'climate.humidity': 'Humidity Datapoint (optional)', 'climate.unit': 'Temperature Unit', 'climate.humidityUnit': 'Humidity Unit', 'climate.lineColor': 'Chart Color', // ── Alarm Widget ────────────────────────────────────────────────────────────── 'alarm.title': 'Alarm system', 'alarm.state.deactivated': 'Disarmed', 'alarm.state.sharp': 'Armed', 'alarm.state.sharpInside': 'Armed (inside)', 'alarm.state.burglary': 'Burglary', 'alarm.state.nightRest': 'Night', 'alarm.state.getsActivated': 'Arming…', 'alarm.state.activationFail': 'Arming failed', 'alarm.state.activationAbort': 'Arming aborted', 'alarm.state.silentAlarm': 'Silent alarm', 'alarm.nightRest': 'Night rest', 'alarm.presence': 'Presence simulation', 'alarm.presence.on': 'Present', 'alarm.presence.off': 'Away', 'alarm.mode.off': 'Off', 'alarm.mode.sharp': 'Arm', 'alarm.mode.inside': 'Inside', 'alarm.mode.night': 'Night', 'alarm.enableDelay': 'With delay', 'alarm.panic': 'Panic', 'alarm.panicConfirm': 'Trigger panic alarm?', 'alarm.confirm': 'Confirm', 'alarm.cancel': 'Cancel', 'alarm.activatingIn': 'Arming in', 'alarm.silentIn': 'Silent alarm in', 'alarm.openCircuits': 'Open', 'alarm.changesPending': 'Monitored circuit changed', 'alarm.quit': 'Acknowledge', 'alarm.quitChanges': 'Acknowledge changes', 'alarm.today': 'Today', 'alarm.zone.one': 'Zone 1', 'alarm.zone.two': 'Zone 2', 'alarm.zone.three': 'Zone 3', 'alarm.pinPlaceholder': 'Enter PIN', 'alarm.wrongPin': 'Wrong PIN', 'alarm.send': 'Send', 'alarm.cfg.prefix': 'Alarm instance (prefix)', 'alarm.cfg.sections': 'Visible sections', 'alarm.cfg.behavior': 'Behavior', 'alarm.cfg.showHeader': 'Status header', 'alarm.cfg.showModes': 'Mode buttons', 'alarm.cfg.showModeOff': '"Off" button', 'alarm.cfg.showModeSharp': '"Armed" button', 'alarm.cfg.showModeInside': '"Inside" button', 'alarm.cfg.showModeNight': '"Night" button', 'alarm.cfg.showDelay': '"With delay" button', 'alarm.cfg.showCountdown': 'Countdown display', 'alarm.cfg.showCircuits': 'Open circuits / warnings', 'alarm.cfg.showZones': 'Zone toggles', 'alarm.cfg.showLog': "Today's log", 'alarm.cfg.showPanic': 'Panic button', 'alarm.cfg.showPanic.hint': 'Triggers behind a confirmation dialog', 'alarm.cfg.showPresence': 'Presence simulation', 'alarm.cfg.requirePin': 'Disarm only with PIN', 'alarm.cfg.requirePin.hint': 'Writes use.disable_password instead of use.disable', 'alarm.cfg.panicConfirm': 'Panic requires confirmation', 'alarm.cfg.compactMode': 'Compact mode', 'alarm.cfg.compactMode.hint': 'Mode buttons in 2 columns instead of 4', 'alarm.cfg.logLines': 'Log entries (max.)', 'alarm.cfg.sizeScale': 'Global scale', // ── Widget Previews ─────────────────────────────────────────────────────────── 'preview.feelsLike': 'Feels like {temp}°', 'preview.device': 'Device', 'preview.cal.dentist': 'Dentist', 'preview.cal.birthday': 'Birthday Lisa', };