Files
HealthLog/messages/en.json
T
Marc-André BombeckandClaude Opus 4.7 10a67ff6c8 feat(insights): RecommendationCard with expandable rationale + mini-chart of data window
Each recommendation now lives in its own collapsible card. Collapsed
state shows: severity badge + rec text + named slot for the future
B5d confidence-ring + chevron toggle. Expanding reveals the
Oura-style "Contributors" panel:

  - 3 rationale rows (Window / Compared to / Deviation)
  - mini-chart pinned to the rec's data window via HealthChart's
    new `mini` + `windowOverride` props (or MoodChart's mirror props
    for mood-typed metrics)
  - citation footnote (B5a) when referenceId resolves
  - named slot for the future B5e feedback-thumbs

Default state: collapsed. ChevronDown / ChevronUp toggle aria-expanded
and a 200ms ease-out animation reveals the rationale block.

Recs without rationale (legacy payloads) and plain-string recs render
as a non-expandable list item with the inline citation footnote
preserved — defence in depth so a stale cached payload still
surfaces its source even though the rationale block is empty.

InsightAdvisorCard renders the new component and surfaces the
legacyPayload CTA when the route flagged the cached blob as pre-B5c
shape — clicking the regenerate button is the single trigger; we
never auto-regenerate.

InsightRecommendation type widens to optionally carry rationale +
metricSource + severity + id (mirrors the strict
aiRecommendationSchema). Optional in the UI type because legacy
cached payloads predate them; the server-side schema enforces
presence on fresh generations.

Layout slots are deliberately named so B5d (confidence) and B5e
(feedback) plug into named positions without touching this file:

  - data-slot="rec-confidence-slot"  → B5d ConfidenceRing
  - data-slot="rec-feedback-slot"    → B5e RecommendationFeedback

11 new tests in `recommendation-card.test.tsx` pin the contract
(severity badge, default-collapsed, rationale row labels in both
locales, mini-chart routing for BP / mood, slot positions, legacy
fallback). Existing 6 citation-footnote tests still green via the
inline-footnote fallback path.

7 new EN+DE i18n keys under `insights.recommendation.*`:
  rationale, rationaleWindow, rationaleComparedTo, rationaleDeviation,
  rationaleExpand, rationaleCollapse, legacyPayloadCta.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-10 01:17:15 +02:00

2294 lines
100 KiB
JSON
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{
"common": {
"save": "Save",
"cancel": "Cancel",
"delete": "Delete",
"edit": "Edit",
"moreOptions": "More options",
"create": "Create",
"close": "Close",
"loading": "Loading...",
"error": "Error",
"success": "Success",
"saved": "Saved",
"confirm": "Confirm",
"back": "Back",
"next": "Next",
"yes": "Yes",
"no": "No",
"search": "Search",
"filter": "Filter",
"noData": "No data available",
"optional": "Optional",
"required": "Required",
"all": "All",
"active": "Active",
"inactive": "Inactive",
"enabled": "Enabled",
"disabled": "Disabled",
"networkError": "Network error",
"unknownError": "Unknown error",
"notLoggedIn": "Not logged in",
"noAccess": "Access denied",
"copied": "Copied!",
"or": "or",
"unknown": "Unknown",
"replace": "Replace",
"add": "Add",
"import": "Import",
"test": "Test",
"reset": "Reset",
"copy": "Copy",
"copyDetails": "Copy details",
"retry": "Retry",
"reportIssue": "Report issue",
"showPassword": "Show password",
"hidePassword": "Hide password"
},
"doctorReport": {
"title": "Health Report",
"subtitle": "HealthLog — Personal Health Report",
"patient": "Patient",
"dateOfBirth": "Date of birth",
"gender": "Gender",
"genderMale": "Male",
"genderFemale": "Female",
"genderOther": "Non-binary",
"height": "Height",
"period": "Reporting period",
"createdOn": "Created on",
"vitalsTitle": "Vital signs — Summary",
"colParameter": "Parameter",
"colCurrent": "Current",
"colAvgPeriod": "Avg. period",
"colMin": "Min",
"colMax": "Max",
"colN": "n",
"bpClassificationTitle": "Blood pressure — ESH classification (2023)",
"avgBp": "Average blood pressure",
"classification": "Classification",
"bmiTitle": "Body Mass Index (BMI)",
"bmiRow": "BMI: {bmi} kg/m² — Classification: {class} (WHO)",
"complianceTitle": "Medication compliance",
"colMedication": "Medication",
"colTaken": "Taken",
"colSkipped": "Skipped",
"colMissed": "Missed",
"colTotal": "Total",
"colComplianceRate": "Compliance rate",
"moodTitle": "Mood trajectory",
"moodSummary": "Average: {avg} / 5.0 · Entries: {count} · Range: {min}–{max}",
"colMood": "Mood",
"colCount": "Count",
"colShare": "Share",
"footerDisclaimer1": "This report was generated automatically from self-tracked data and is intended to support",
"footerDisclaimer2": "the doctor–patient conversation. It does not replace a medical diagnosis. Correlations do not imply causation.",
"footerSource": "Source: HealthLog | Timezone: Europe/Berlin | Created: {timestamp}",
"typeWeight": "Body weight",
"typeBpSys": "Systolic blood pressure",
"typeBpDia": "Diastolic blood pressure",
"typePulse": "Resting pulse",
"typeBodyFat": "Body fat",
"typeSleep": "Sleep duration",
"typeSteps": "Activity (steps)",
"typeTotalBodyWater": "Total body water",
"typeBoneMass": "Bone mass",
"typeOxygenSaturation": "Oxygen saturation",
"unitSteps": "steps",
"bmiUnderweight": "Underweight",
"bmiNormal": "Normal weight",
"bmiOverweight": "Overweight (pre-obese)",
"bmiObeseGrade1": "Obesity grade I",
"bmiObeseGrade2": "Obesity grade II",
"bmiObeseGrade3": "Obesity grade III",
"bpOptimal": "Optimal",
"bpNormal": "Normal",
"bpHighNormal": "High-normal",
"bpHypertensionGrade1": "Hypertension grade 1",
"bpHypertensionGrade2": "Hypertension grade 2",
"bpHypertensionGrade3": "Hypertension grade 3",
"moodAwful": "Very bad",
"moodBad": "Bad",
"moodNeutral": "Neutral",
"moodGood": "Good",
"moodGreat": "Very good",
"typeGlucoseFasting": "Glucose (fasting)",
"typeGlucosePostprandial": "Glucose (postprandial)",
"typeGlucoseRandom": "Glucose (random)",
"typeGlucoseBedtime": "Glucose (bedtime)",
"glucoseClassificationTitle": "Blood glucose — reference ranges (ADA 2024 / DDG)",
"glucoseRow": "{label}: avg {avg} {unit} (target {rangeMin}–{rangeMax}) — {class}",
"glucoseInTarget": "in target",
"glucoseBelowTarget": "below target",
"glucoseAboveTarget": "above target",
"practiceLabel": "Practice",
"dialog": {
"title": "Doctor report (PDF)",
"description": "Pick the reporting period and (optionally) the practice name; both are printed on the cover.",
"startLabel": "Start date",
"endLabel": "End date",
"practiceLabel": "Practice / clinic name (optional)",
"practicePlaceholder": "e.g. Dr. Müller — Family practice",
"preset90d": "Last 90 days",
"preset180d": "Last 6 months",
"preset365d": "Last 12 months",
"submit": "Generate PDF",
"cancel": "Cancel",
"errorEndBeforeStart": "End date must be on or after the start date.",
"errorRangeTooLong": "The reporting period cannot exceed 2 years.",
"errorInvalidDate": "Please select a valid start and end date."
}
},
"errorBoundary": {
"title": "Something went wrong",
"description": "An unexpected error occurred. You can retry, copy the technical details, or open a bug report."
},
"nav": {
"home": "Home",
"dashboard": "Dashboard",
"measurements": "Measurements",
"medications": "Medications",
"charts": "History",
"insights": "Insights",
"targets": "Targets",
"achievements": "Achievements",
"settings": "Settings",
"bugreport": "Bug Report",
"admin": "Admin Console",
"logout": "Sign out",
"login": "Sign in",
"notifications": "Notifications",
"theme": "Appearance",
"themeSystem": "System",
"themeDark": "Dark",
"themeLight": "Light",
"collapseSidebar": "Collapse",
"userMenu": "User menu",
"mood": "Mood",
"skipToContent": "Skip to content",
"sidebar": "Sidebar",
"mainNavigation": "Main navigation",
"mobileNavigation": "Mobile navigation",
"loadingScreen": "Loading…",
"more": "More",
"moreSheetTitle": "More",
"moreSheetDescription": "Pages that don't fit the bottom bar."
},
"auth": {
"login": "Sign in",
"register": "Sign up",
"loginTitle": "Sign In",
"registerTitle": "Sign Up",
"username": "Username",
"password": "Password",
"email": "Email address",
"emailPlaceholder": "name@example.com",
"emailOrUsername": "Email address or username",
"emailOrUsernamePlaceholder": "name@example.com or username",
"loginWithPasskey": "Sign in with Passkey",
"loginWithPassword": "Sign in with password",
"noAccount": "Don't have an account?",
"hasAccount": "Already have an account?",
"registerDisabled": "Registration is disabled.",
"loginFailed": "Login failed",
"passkeyFailed": "Passkey authentication cancelled or failed",
"registerFailed": "Registration failed",
"createAccount": "Create account",
"newAccount": "Create new account",
"backToPasskey": "Back to Passkey",
"passkeySetupLater": "You can set up passkeys at any time in Settings.",
"passwordMinLength": "Min. 12 characters",
"passwordTooShort": "Password must be at least {minLength} characters long.",
"passwordStrength": "Password strength",
"strengthWeak": "Very weak",
"strengthFair": "Weak",
"strengthGood": "Fair",
"strengthStrong": "Strong",
"strengthVeryStrong": "Very strong"
},
"dashboard": {
"title": "Dashboard",
"subtitle": "Your health overview",
"greeting": {
"morning": "Good morning",
"day": "Hello",
"evening": "Good evening"
},
"welcomeBack": "{greeting}, welcome back.",
"welcomeBackWithName": "{greeting} {name}, welcome back.",
"greetingSalutation": "Hi, {name}",
"streakLabel": "days in a row",
"weight": "Weight",
"bloodPressure": "Blood Pressure",
"bloodPressureSys": "Blood Pressure (Sys)",
"bloodPressureDia": "Blood Pressure (Dia)",
"pulse": "Pulse",
"bodyFat": "Body Fat",
"sleep": "Sleep",
"steps": "Steps",
"bpInTarget": "BP in Target",
"days30Short": "30d",
"medications": "Medications",
"lastMeasurement": "Last measurement",
"noMeasurements": "No measurements yet",
"trend": "Trend",
"trendUp": "rising",
"trendDown": "falling",
"trendStable": "stable",
"quickEntry": "Quick entry",
"quickAddMeasurement": "Log measurement",
"quickAddMood": "Log mood",
"addMeasurement": "Add measurement",
"compliance7d": "Compliance (7 days)",
"complianceGood": "Good",
"complianceLow": "Low",
"mood": "Mood",
"customizeTitle": "Dashboard layout",
"customizeSubtitle": "Choose which cards appear on your dashboard and in what order. Defaults work out of the box.",
"layoutReset": "Reset to defaults",
"layoutSaveSuccess": "Dashboard layout saved",
"layoutSaveError": "Could not save dashboard layout",
"layoutResetSuccess": "Reset to default layout",
"layoutUsingDefaults": "Using default layout",
"layoutCustomized": "Custom layout active",
"moveUp": "Move up",
"moveDown": "Move down",
"layoutTileColumn": "Tile",
"layoutChartColumn": "Chart",
"emptyTitle": "Your dashboard is empty",
"emptyDescription": "Log your first measurement or mood entry. Tiles and charts appear automatically as data lands.",
"emptyAddMeasurement": "Add your first measurement"
},
"measurements": {
"title": "Measurements",
"subtitle": "Weight, blood pressure, pulse & more",
"addMeasurement": "Add",
"editMeasurement": "Edit measurement",
"type": "Type",
"value": "Value",
"unit": "Unit",
"date": "Date",
"source": "Source",
"notes": "Notes",
"typeWeight": "Weight",
"typeBloodPressure": "Blood Pressure",
"typeBpSys": "Sys",
"typeBpDia": "Dia",
"typePulse": "Pulse",
"typeBodyFat": "Body Fat",
"typeSleep": "Sleep",
"typeSteps": "Steps",
"typeBloodGlucose": "Blood glucose",
"typeTotalBodyWater": "Total body water",
"typeBoneMass": "Bone mass",
"typeOxygenSaturation": "Oxygen saturation",
"glucoseContext": "Context",
"glucoseContextFasting": "Fasting (≥8h without food)",
"glucoseContextPostprandial": "Post-meal (2h after eating)",
"glucoseContextRandom": "Random / casual",
"glucoseContextBedtime": "Before bed",
"glucoseUnit": "Glucose display unit",
"glucoseUnitHint": "Stored canonically in mg/dL; display unit is your preference.",
"unitHours": "hours",
"unitSteps": "steps",
"sourceManual": "Manual",
"sourceWithings": "Withings",
"sourceImport": "Import",
"systolicLabel": "Systolic (mmHg)",
"diastolicLabel": "Diastolic (mmHg)",
"pulseLabel": "Pulse (bpm)",
"valueWithUnit": "Value ({unit})",
"timestamp": "Time",
"notesPlaceholder": "e.g. after a meal",
"formReset": "Reset form",
"saveError": "Error saving",
"deleteError": "Error deleting",
"invalidValue": "Please enter a valid value.",
"invalidTimestamp": "Please select a valid time.",
"loginRequired": "Please sign in to view measurements.",
"allTypes": "All types",
"measurementCount": "{count} measurements",
"noMeasurements": "No measurements found",
"emptyTitle": "No measurements yet",
"emptyDescription": "Log your weight, blood pressure, pulse, or other vitals to start tracking trends.",
"emptyFilteredTitle": "No measurements match this filter",
"emptyFilteredDescription": "Try a different type or clear the filter to see all measurements.",
"emptyAddFirst": "Add your first measurement",
"emptyResetFilter": "Show all types",
"comment": "Comment",
"actions": "Actions",
"deleteConfirmTitle": "Delete measurement?",
"deleteConfirmDescription": "This measurement will be permanently deleted.",
"pageInfo": "Page {page} of {total}",
"showing": "Showing",
"of": "of",
"entries": "entries"
},
"mood": {
"title": "Mood",
"subtitle": "Mood tracker & entries",
"addEntry": "Add",
"editEntry": "Edit entry",
"moodLevel": "Mood",
"tags": "Tags",
"tagsPlaceholder": "e.g. Exercise, Work, Family",
"tagsHelp": "Comma-separated",
"timestamp": "Time",
"date": "Date",
"source": "Source",
"levelSuperGut": "Amazing",
"levelGut": "Good",
"levelOkay": "Okay",
"levelSchlecht": "Bad",
"levelLausig": "Terrible",
"sourceManual": "Manual",
"sourceMoodlog": "moodLog",
"sourceWeb": "Web",
"sourceTelegram": "Telegram",
"sourceDaylio": "Daylio",
"allMoods": "All moods",
"entryCount": "{count} entries",
"noEntries": "No mood entries found",
"emptyTitle": "No mood entries yet",
"emptyDescription": "Log how you feel today to spot patterns over time.",
"emptyFilteredTitle": "No mood entries match this filter",
"emptyFilteredDescription": "Try a different mood level or clear the filter to see all entries.",
"emptyAddFirst": "Log your first mood",
"emptyResetFilter": "Show all moods",
"actions": "Actions",
"formReset": "Reset form",
"saveError": "Error saving",
"deleteError": "Error deleting",
"invalidTimestamp": "Please select a valid time.",
"deleteConfirmTitle": "Delete entry?",
"deleteConfirmDescription": "This mood entry will be permanently deleted.",
"pageInfo": "Page {page} of {total}",
"loginRequired": "Please sign in to view mood entries."
},
"medications": {
"title": "Medications",
"subtitle": "Medications, schedules & intake",
"loginRequired": "Please sign in to manage medications.",
"addMedication": "Add",
"editMedication": "Edit medication",
"newMedication": "New medication",
"firstMedication": "Add first medication",
"noMedicationsYet": "No medications added yet",
"emptyTitle": "No medications yet",
"emptyDescription": "Add medications, dosages, and reminder windows to track compliance.",
"loadFailed": "Could not load medications",
"retryLoad": "Retry",
"name": "Name",
"dose": "Dose",
"doseAmount": "Amount",
"doseUnit": "Unit",
"category": "Category",
"schedule": "Schedule",
"scheduleFrom": "From",
"scheduleTo": "To",
"scheduleLabel": "Label",
"scheduleDays": "Days",
"scheduleDaily": "Daily",
"active": "Active",
"inactive": "Paused",
"intakeHistory": "Intake history",
"showIntakeHistory": "Show intake history",
"hideIntakeHistory": "Hide intake history",
"markTaken": "Taken",
"markSkipped": "Skipped",
"deleteConfirm": "Delete medication?",
"deleteDescription": "The medication and all intake records will be permanently deleted.",
"noMedications": "No medications found.",
"compliance": "Compliance",
"import": "Import",
"importIntakes": "Import intakes",
"importDescription": "Paste a JSON array with intake data. Expected format:",
"importUploadFile": "Upload JSON file",
"importPaste": "Paste JSON here...",
"importSelected": "Selected: {name}",
"importFileLoaded": "File \"{name}\" loaded",
"importInvalidJson": "File does not contain valid JSON",
"importNoArray": "No array found",
"importResult": "{imported} intakes imported",
"importDuplicatesSkipped": "{count} duplicates skipped",
"importInvalidSkipped": "{count} invalid entries skipped",
"importFailed": "Import failed",
"importInvalidFormat": "Invalid JSON format",
"apiAccess": "API access",
"apiEndpointTitle": "API Endpoint: {name}",
"apiEndpointDescription": "Use this endpoint to record intakes via API (e.g., iPhone Shortcut or cron job).",
"apiEndpointActive": "API endpoint active",
"apiEndpointActivated": "API endpoint activated",
"apiEndpointDeactivated": "API endpoint deactivated",
"apiTokenCount": "Active ({count} tokens)",
"apiToken": "API Token",
"apiTokenActiveHint": "Endpoint is active. Existing tokens remain valid but cannot be shown in plain text again.",
"apiTokenActivateHint": "Activate the endpoint to create a new token.",
"apiTokenOnceHint": "The token is only shown in plain text once at creation.",
"requestExample": "Request example",
"statusLoadFailed": "Could not load status",
"changeFailed": "Change failed",
"categoryBloodPressure": "Blood Pressure",
"categoryCholesterol": "Cholesterol",
"categoryDiabetes": "Diabetes",
"categoryVitamin": "Vitamins",
"categoryThyroid": "Thyroid",
"categoryHormone": "Hormones",
"categorySupplement": "Supplement",
"categoryPainRelief": "Pain Relief",
"categoryAllergy": "Allergy",
"categoryDigestive": "Gastrointestinal",
"categorySkin": "Skincare",
"categorySleepAid": "Sleep Aid",
"categoryOther": "Other",
"daysSun": "Sun",
"daysMon": "Mon",
"daysTue": "Tue",
"daysWed": "Wed",
"daysThu": "Thu",
"daysFri": "Fri",
"daysSat": "Sat",
"intakeHistoryTitle": "Intake History",
"newIntake": "Add",
"editIntake": "Edit Intake",
"intakeScheduledFor": "Scheduled",
"intakeTakenAt": "Taken at",
"intakeStatus": "Status",
"intakeSource": "Source",
"intakeStatusTaken": "Taken",
"intakeStatusSkipped": "Skipped",
"intakeStatusMissed": "Missed",
"intakeDeleteConfirm": "Delete intake record?",
"intakeDeleteDescription": "This intake record will be permanently deleted.",
"intakeCount": "{count} intakes",
"viewHistory": "History",
"today": "Today",
"yesterday": "Yesterday",
"tomorrow": "Tomorrow",
"withoutNotification": "Without notification",
"pausedSince": "Paused since",
"takeNow": "Take now",
"overdue": "Overdue",
"veryOverdue": "Very overdue",
"compliance7d": "7-day compliance",
"compliance30d": "30-day compliance",
"lastIntake": "Last intake:",
"nextIntake": "Next intake:",
"dayStreak": "day streak",
"taken": "Taken",
"skipped": "Skipped",
"weekdaySunday": "Sunday",
"weekdayMonday": "Monday",
"weekdayTuesday": "Tuesday",
"weekdayWednesday": "Wednesday",
"weekdayThursday": "Thursday",
"weekdayFriday": "Friday",
"weekdaySaturday": "Saturday",
"weekdaySundayPlural": "Sundays",
"weekdayMondayPlural": "Mondays",
"weekdayTuesdayPlural": "Tuesdays",
"weekdayWednesdayPlural": "Wednesdays",
"weekdayThursdayPlural": "Thursdays",
"weekdayFridayPlural": "Fridays",
"weekdaySaturdayPlural": "Saturdays",
"formType": "Type",
"formDose": "Dose",
"formUnit": "Unit",
"formSchedule": "Schedule",
"newSchedule": "New schedule",
"removeSchedule": "Remove schedule",
"advancedEditing": "Advanced editing",
"advancedEditingHide": "Hide advanced editing",
"scheduleInterval": "Interval",
"scheduleEveryWeek": "every week",
"scheduleEveryNWeeks": "every {n} weeks",
"scheduleIntervalPrefix": "Interval:",
"nextSchedulePrefix": "Next schedule:",
"nextScheduleDaily": "daily",
"importIntakesAction": "Import intakes",
"apiEndpointAction": "API endpoint",
"pause": "Pause",
"activate": "Activate",
"disableNotifications": "Disable notifications",
"enableNotifications": "Enable notifications",
"purgeRecords": "Delete all records",
"formReset": "Reset form",
"createMedication": "Create medication",
"deleteConfirmDescription": "The medication and all intake history will be permanently deleted.",
"purgeConfirmTitle": "Delete all records?",
"purgeConfirmDescription": "All intake records for this medication will be permanently deleted. The medication itself will remain and start without history data.",
"saveError": "Error saving",
"deleteError": "Error deleting",
"purgeError": "Error deleting records",
"invalidTimestamp": "Please select a valid time.",
"noIntakesYet": "No intakes recorded yet",
"noIntakesForMedication": "No intakes yet for",
"deleteIntakeAriaLabel": "Delete intake",
"actions": "Actions",
"pageInfo": "Page {page} of {total}",
"loginRequiredIntakes": "Please sign in to view intakes.",
"clear": "Clear",
"phaseConfig": "Reminder phases",
"phaseConfigDescription": "Configure timing for reminders.",
"phaseGreen": "Green",
"phaseYellow": "Yellow",
"phaseOrange": "Orange",
"phaseRed": "Red",
"phaseMinutes": "Min",
"phasePercent": "%",
"phaseBeforeEnd": "before end",
"phaseAfterEnd": "after end",
"phaseResetDefaults": "Reset to defaults",
"phaseSaved": "Reminder phases saved",
"phaseReset": "Reset to defaults",
"sourceWeb": "Website",
"sourceApi": "External API",
"sourceReminder": "Telegram / Reminder",
"sourceImport": "CSV Import",
"unitDrops": "Drops",
"unitTablets": "Tablet(s)",
"unitCapsules": "Capsule(s)",
"unitPieces": "Piece(s)",
"namePlaceholder": "e.g. Ibuprofen",
"dosePlaceholder": "e.g. 400",
"labelPlaceholder": "e.g. Morning",
"defaultDose": "Default",
"dayDeactivate": "Deactivate {day}",
"dayActivate": "Activate {day}"
},
"charts": {
"title": "History",
"subtitle": "Visualization of your health data",
"timeRange": "Time range",
"days7": "7 days",
"days30": "30 days",
"days90": "90 days",
"days365": "1 year",
"daysAll": "All",
"weight": "Weight",
"bloodPressure": "Blood Pressure",
"pulse": "Pulse",
"bodyFat": "Body Fat",
"sleep": "Sleep",
"steps": "Steps",
"compliance": "Compliance",
"noData": "No data in selected time range",
"movingAverage": "Moving average",
"target": "Target range",
"bucketWeekly": "Weekly avg",
"bucketMonthly": "Monthly avg",
"points7Label": "7 pts",
"points7Title": "Last 7 data points",
"points30Label": "30 pts",
"points30Title": "Last 30 data points",
"points90Label": "90 pts",
"points90Title": "Last 90 data points",
"pointsAllLabel": "All",
"pointsAllTitle": "All available data points",
"systolic": "Systolic",
"diastolic": "Diastolic",
"bodyWater": "Body water",
"boneMass": "Bone mass",
"spo2": "SpO₂",
"movingAverage7d": "7-day trend",
"avg7dShort": "7d",
"avg30dShort": "30d",
"trend7dShort": "7-day trend",
"trend": "Trend",
"targetRanges": "Target ranges",
"perWeek": "/week",
"totalDelta": "Total",
"selectMedication": "Select medication",
"noComplianceData": "No compliance data available",
"history": "History",
"complianceDays90": "Compliance (90 days)",
"colorGreen": "Green:",
"colorOrange": "Orange:",
"colorRed": "Red:",
"mood": "Mood",
"moodScore": "Mood Score",
"moodMA": "7-day trend",
"moodLabel1": "Awful",
"moodLabel2": "Bad",
"moodLabel3": "Okay",
"moodLabel4": "Good",
"moodLabel5": "Great",
"weekdays": {
"mon": "Mon",
"wed": "Wed",
"fri": "Fri",
"sun": "Sun"
},
"months": {
"jan": "Jan",
"feb": "Feb",
"mar": "Mar",
"apr": "Apr",
"may": "May",
"jun": "Jun",
"jul": "Jul",
"aug": "Aug",
"sep": "Sep",
"oct": "Oct",
"nov": "Nov",
"dec": "Dec"
},
"heatmapOnTime": "on time",
"heatmapLate": "late",
"heatmapVeryLate": "very late",
"legendOnTime": "On time",
"legendLate": "Late",
"legendVeryLate": "Very late",
"legendMissed": "Missed",
"emptyStateTitle": "Add more measurements to see trends",
"emptyStateDescription": "Log at least 3 entries to unlock the trend line.",
"personalBaseline": "Your normal",
"deltaVsBaseline": "{delta} vs. your normal",
"deltaUnchanged": "matches your normal",
"targetWeight": "Target",
"deltaVsTarget": "{delta} vs. target"
},
"insights": {
"aiAnalysisTitle": "AI Health Analysis",
"noAnalysisYet": "No analysis yet.",
"emptyTitle": "Not enough data yet",
"emptyDescription": "Insights light up once you've logged a handful of measurements. Start with weight or blood pressure.",
"emptyAddMeasurement": "Add a measurement",
"bmiEmptyTitle": "Set your height to see BMI",
"bmiEmptyDescription": "BMI needs your height. Add it under Settings → Account.",
"bmiEmptyAction": "Open account settings",
"noProviderConfigured": "AI provider not configured.",
"startAnalysis": "Start analysis",
"refreshAnalysis": "Refresh analysis",
"keyTakeaway": "Key Takeaway",
"findingsTitle": "Findings",
"heroFindingPositive": "Top finding",
"heroFindingNeutral": "Top finding",
"heroFindingAttention": "Worth attention",
"heroFindingWarning": "Top alert",
"correlationsTitle": "Correlations",
"recommendationsTitle": "Recommendations",
"recommendation": {
"source": "Source",
"viewSource": "Open guideline in a new tab",
"rationale": "Why this recommendation",
"rationaleWindow": "Window",
"rationaleComparedTo": "Compared to",
"rationaleDeviation": "Deviation",
"rationaleExpand": "Show why",
"rationaleCollapse": "Hide why",
"legacyPayloadCta": "Insights updated — regenerate for new explainability features"
},
"dataFoundation": "Data coverage",
"dataGaps": "Data gaps:",
"lastUpdated": "Last updated",
"confidenceHoch": "High",
"confidenceMittel": "Medium",
"confidenceGering": "Low",
"loadError": "Failed to load insights",
"generationFailed": "The analysis couldn't be generated. Please try again.",
"title": "Insights",
"subtitle": "AI-powered analysis of your health data",
"overviewSubtitle": "Trends, risks, progress at a glance",
"navGeneral": "General",
"navBloodPressure": "Blood Pressure",
"navWeight": "Weight",
"navPulse": "Pulse",
"navMood": "Mood",
"navMedication": "Medication",
"navBmi": "BMI",
"measurementsOverDays": "{count} measurements over {days} days",
"healthStatus": "Health Status",
"noWeightData": "No weight data or height not set.",
"notEnoughBpData": "Not enough blood pressure data.",
"bpTargetRange": "BP Target Range",
"inTargetRange": "in target range",
"bpTarget": "Target: {range}",
"noDobSet": "Date of birth not set.",
"avg30dEsc": "30d average · ESH 2023",
"whoClassification": "WHO Classification",
"correlations": "Correlations",
"weightVsBp": "Weight vs. Blood Pressure (Systolic)",
"strengthStrong": "Strong correlation",
"strengthModerate": "Moderate correlation",
"strengthWeak": "Weak correlation",
"strengthNone": "No correlation",
"weightBpStrong": "There is a strong correlation between weight and blood pressure.",
"weightBpModerate": "There is a moderate correlation between weight and blood pressure.",
"weightBpWeak": "There is a weak correlation between weight and blood pressure.",
"weightBpNone": "No discernible correlation between weight and blood pressure.",
"notEnoughCorrelationData": "Not enough data for correlation analysis.",
"minCorrelationData": "At least 5 time-matched weight and blood pressure measurements needed.",
"bpMedContinuity": "BP Medication Continuity vs. Blood Pressure (Systolic)",
"continuityLabel": "Continuity",
"continuityBpLabel": "BP Medication Continuity (%)",
"weightKgLabel": "Weight (kg)",
"bpMedNegative": "Negative correlation: higher continuity tends to be associated with lower systolic blood pressure.",
"bpMedPositive": "Positive correlation: higher continuity tends to be associated with higher systolic blood pressure in your data.",
"bpMedNone": "No discernible correlation in your data.",
"bpMedCount": "{count} BP medications",
"notEnoughMedData": "Not enough data for this analysis.",
"notEnoughMedDataHint": "Tag medications as blood pressure medications and record sufficient intakes + blood pressure measurements.",
"medicationCompliance": "Medication Compliance",
"dayStreak": "{count} day streak",
"compliance7d": "7-day compliance",
"compliance30d": "30-day compliance",
"taken": "taken",
"skipped": "skipped",
"missed": "missed",
"complianceTrend": "Compliance Trend",
"generalStatusTitle": "General Health Status",
"generalStatusLoading": "Generating general status...",
"generalStatusNoKey": "The general status cannot be generated because no OpenAI key is configured.",
"generalStatusUnavailable": "The general status is currently unavailable.",
"generalStatusBadge": {
"good": "Good",
"watch": "Watch",
"critical": "Critical"
},
"assessmentTitle": "Assessment",
"bloodPressureSectionTitle": "Blood Pressure",
"bloodPressureMedicationListTitle": "Blood Pressure Medication & Compliance",
"bloodPressureMedicationListEmpty": "No active blood pressure medication configured.",
"bloodPressureStatusLoading": "Generating blood pressure summary...",
"bloodPressureStatusNoKey": "The blood pressure summary cannot be generated because no OpenAI key is configured.",
"bloodPressureStatusUnavailable": "The blood pressure summary is currently unavailable.",
"weightSectionTitle": "Weight",
"weightStatusLoading": "Generating weight summary...",
"weightStatusNoKey": "The weight summary cannot be generated because no OpenAI key is configured.",
"weightStatusUnavailable": "The weight summary is currently unavailable.",
"pulseSectionTitle": "Pulse",
"pulseStatusLoading": "Generating pulse summary...",
"pulseStatusNoKey": "The pulse summary cannot be generated because no OpenAI key is configured.",
"pulseStatusUnavailable": "The pulse summary is currently unavailable.",
"bmiSectionTitle": "BMI",
"bmiStatusLoading": "Generating BMI summary...",
"bmiStatusNoKey": "The BMI summary cannot be generated because no OpenAI key is configured.",
"bmiStatusUnavailable": "The BMI summary is currently unavailable.",
"medicationComplianceStatusLoading": "Generating medication compliance text...",
"medicationComplianceStatusNoKey": "The medication compliance text cannot be generated because no OpenAI key is configured.",
"medicationComplianceStatusUnavailable": "The medication compliance text is currently unavailable.",
"complianceNoData": "No compliance data available.",
"aiInsights": "AI Insights",
"configureApiKey": "Configure an OpenAI API key in Settings to get AI-powered insights.",
"alertsTitle": "Notes & Recommendations",
"showLess": "Show less",
"showMore": "+{count} more",
"generate": "Generate new analysis",
"generating": "Generating analysis...",
"lastGenerated": "Last analysis",
"noInsights": "No analysis available yet.",
"rateLimit": "Please wait before generating a new analysis.",
"noApiKey": "Please add an OpenAI API key in Settings first.",
"sendRawData": "Send raw data",
"minMoodCorrelationData": "At least 5 temporally matched mood and measurement data points required.",
"moodBpModerate": "There is a moderate correlation between mood and blood pressure.",
"moodBpNone": "No detectable correlation between mood and blood pressure.",
"moodBpStrong": "There is a strong correlation between mood and blood pressure.",
"moodBpWeak": "There is a weak correlation between mood and blood pressure.",
"moodScoreLabel": "Mood (avg)",
"moodSectionTitle": "Mood",
"moodStatusLoading": "Generating mood analysis...",
"moodStatusNoKey": "Mood summary cannot be generated because no OpenAI API key is configured.",
"moodStatusUnavailable": "Mood analysis unavailable",
"moodVsBp": "Mood vs. Blood Pressure (Systolic)",
"moodVsPulse": "Mood vs. Pulse",
"moodVsWeight": "Mood vs. Weight",
"moodWeightModerate": "There is a moderate correlation between mood and weight.",
"moodWeightNone": "No detectable correlation between mood and weight.",
"moodWeightStrong": "There is a strong correlation between mood and weight.",
"moodWeightWeak": "There is a weak correlation between mood and weight.",
"notEnoughMoodCorrelationData": "Not enough mood data for correlation analysis.",
"refreshButton": "Refresh",
"generateButton": "Generate",
"analyzing": "Analyzing health data...",
"confidence": "Confidence",
"confidence_niedrig": "low",
"confidence_mittel": "medium",
"confidence_hoch": "high",
"cached": "Cached",
"sectionChanged": "What has changed",
"sectionStable": "What is stable",
"sectionDrivers": "Possible correlations",
"sectionNextSteps": "Next steps",
"generatePrompt": "Click \"Generate\" for AI-powered insights about your health data."
},
"thresholds": {
"title": "Personal thresholds",
"subtitle": "Override the computed target range for any metric. Defaults stay in effect until you set a value here.",
"defaultLabel": "Default",
"overrideLabel": "Your override",
"autoModeLabel": "Auto",
"overrideModeLabel": "Override",
"resetAction": "Reset to default",
"resetAllAction": "Reset all to default",
"minLabel": "Min",
"maxLabel": "Max",
"unitSuffix": "({unit})",
"outOfBoundsHint": "Allowed range: {min}–{max} {unit}",
"overrideWarning": "Overriding with values outside guideline ranges may produce unhealthy targets. Only do this on doctor's advice.",
"saveSuccess": "Thresholds updated",
"saveError": "Could not save thresholds",
"resetSuccess": "Reset to default",
"sourceOverride": "User override",
"metricWeight": "Weight",
"metricBpSys": "Blood pressure (systolic)",
"metricBpDia": "Blood pressure (diastolic)",
"metricPulse": "Resting pulse",
"metricBodyFat": "Body fat",
"metricSleep": "Sleep duration",
"metricSteps": "Daily steps",
"metricGlucoseFasting": "Glucose — fasting",
"metricGlucosePostprandial": "Glucose — post-meal",
"metricGlucoseRandom": "Glucose — random",
"metricGlucoseBedtime": "Glucose — bedtime",
"metricBodyWater": "Body water",
"metricBoneMass": "Bone mass",
"metricOxygenSaturation": "Oxygen saturation (SpO₂)",
"unsetExplanation": "No override — using computed default.",
"loadError": "Could not load thresholds"
},
"onboarding": {
"welcome": "Welcome to HealthLog!",
"setupDescription": "Set up your profile to get started. You can change this later in Settings.",
"completeSetup": "Complete setup",
"skip": "Skip",
"medicationsTitle": "Do you take medications?",
"medicationsDescription": "Add your medications to enable reminders and compliance tracking.",
"medNamePlaceholder": "Name",
"medDosePlaceholder": "Dose",
"notificationsTitle": "Reminders",
"notificationsDescription": "HealthLog can remind you about your medications. Configure this later in Settings.",
"telegramHint": "Reminders via Telegram bot with snooze buttons",
"webPushHint": "Browser notifications directly to your device",
"notificationsLater": "You can set this up anytime in Settings.",
"targetsTitle": "Target Values",
"targetsDescription": "Set optional target values for blood pressure and weight.",
"targetSys": "Systolic (mmHg)",
"targetDia": "Diastolic (mmHg)",
"targetWeight": "Target weight (kg)",
"errorProfile": "Could not save your profile. Please try again.",
"errorMedication": "Could not add the medication \"{name}\". Please try again or add it later in Medications.",
"errorTargets": "Could not save your target values. Please try again.",
"errorGeneric": "Something went wrong while finishing setup. Please try again.",
"medScheduleHint": "We'll add a default reminder window (08:00–09:00 daily). You can adjust it anytime in Medications.",
"v2": {
"title": "Welcome to HealthLog",
"subtitle": "Three quick steps. You can finish anything later from Settings.",
"stepOf": "Step {current} of {total}",
"back": "Back",
"continue": "Continue",
"finish": "Finish setup",
"skipStep": "Skip this step — you can finish setup later from Settings.",
"step1": {
"title": "About you",
"description": "Used for blood-pressure targets, BMI, and the right reminders.",
"displayNameLabel": "Display name",
"displayNameHint": "Shown on the dashboard greeting and in reports.",
"languageLabel": "Language",
"languageHint": "We'll use this for the app, PDFs, and notifications."
},
"step2": {
"title": "Log your first measurement",
"description": "Weight, blood pressure, or pulse — whatever you have right now. The dashboard comes alive with one entry.",
"added": "Got it — you can add more anytime from the dashboard.",
"skipHint": "No measurement at hand? Skip and log one when you're ready."
},
"step3": {
"title": "Pick one notification channel",
"description": "We'll only send what you ask for. You can add more channels or fine-tune events later.",
"channelTelegramTitle": "Telegram bot",
"channelTelegramHint": "Reminders with snooze buttons inside Telegram.",
"channelWebPushTitle": "Web Push",
"channelWebPushHint": "Native browser notifications on this device.",
"channelNtfyTitle": "ntfy.sh",
"channelNtfyHint": "Open-source push to phone or desktop, no account.",
"channelNoneTitle": "Skip for now",
"channelNoneHint": "I'll set up notifications later from Settings.",
"openSettings": "Continue in Settings"
},
"doneToast": "You're all set — welcome aboard."
},
"tour": {
"stepOf": "Step {current} of {total}",
"next": "Next",
"back": "Back",
"skip": "Skip tour",
"done": "Got it",
"restart": "Restart onboarding tour",
"restartHint": "Replay the dashboard walkthrough from the start.",
"restartConfirmation": "Tour will restart on your next dashboard visit.",
"steps": {
"tileStrip": {
"title": "Your daily numbers",
"body": "The tile strip shows the latest reading and a 7-day trend for every metric you log — weight, blood pressure, pulse, mood. Hide what you don't need from Settings → Dashboard."
},
"quickAdd": {
"title": "Log anything in two taps",
"body": "Use the Add button to drop a measurement or mood entry without leaving the dashboard. The form remembers your last context and tags."
},
"insights": {
"title": "AI-assisted insights",
"body": "Insights turns your readings into a plain-English health summary, with classifications for blood pressure, weight trend and mood. Bring your own AI key or use the built-in default."
},
"integrations": {
"title": "Connect your devices",
"body": "Open Settings to link Withings (auto-sync weight, BP and pulse), moodLog, or your AI provider. Everything stays optional and encrypted."
},
"achievements": {
"title": "Earn streaks and badges",
"body": "The Achievements page tracks daily logging streaks, blood-pressure milestones and consistency badges. A small nudge to keep going."
}
}
}
},
"gettingStarted": {
"title": "Getting started",
"subtitle": "Quick wins to get the most out of HealthLog.",
"progress": "{done} of {total} done",
"dismiss": "Dismiss",
"dismissAll": "Hide checklist",
"dismissTooltip": "Hide this item",
"restoreHint": "You can restore the checklist from Settings.",
"items": {
"profileTitle": "Set your profile",
"profileDescription": "Height, date of birth and gender unlock personalised targets.",
"profileCta": "Open profile",
"measurementTitle": "Log your first measurement",
"measurementDescription": "One reading is enough to draw your first trend tile.",
"measurementCta": "Add measurement",
"medicationTitle": "Add a medication",
"medicationDescription": "Track compliance and get reminders right when you need them.",
"medicationCta": "Add medication",
"withingsTitle": "Connect Withings (optional)",
"withingsDescription": "Auto-sync weight, BP and pulse from your Withings devices.",
"withingsCta": "Connect",
"notificationsTitle": "Configure notifications",
"notificationsDescription": "Choose how HealthLog should remind you — Telegram, ntfy or Web Push.",
"notificationsCta": "Open notifications"
}
},
"trendHints": {
"title": "First trend after 5 readings",
"remainingOne": "1 more reading to go.",
"remainingMany": "{count} more readings to go."
},
"settings": {
"title": "Settings",
"subtitle": "Profile, Security & Connections",
"shell": {
"sectionsNav": "Settings sections"
},
"sections": {
"account": {
"title": "Account",
"description": "Profile, password, passkeys, and your onboarding tour."
},
"integrations": {
"title": "Integrations",
"description": "Withings, moodLog, and other connected services."
},
"notifications": {
"title": "Notifications",
"description": "Per-channel delivery — Telegram, ntfy, Web Push — plus the live channel-reliability board."
},
"dashboard": {
"title": "Dashboard",
"description": "Tile layout and order."
},
"thresholds": {
"title": "Personal targets",
"description": "Override target ranges for every metric."
},
"ai": {
"title": "AI Insights",
"description": "Provider, model, key."
},
"api": {
"title": "API & Tokens",
"description": "Bearer tokens for your own scripts and apps — log measurements or medication intake from anywhere."
},
"advanced": {
"title": "Advanced",
"description": "Account-wide danger zone — irreversibly wipe every health record while keeping your account."
},
"export": {
"title": "Export",
"description": "Download your health data as PDF, CSV, or a full JSON backup.",
"actions": {
"download": "Download"
},
"filters": {
"since": "From",
"until": "Until"
},
"cards": {
"doctorReport": {
"title": "Doctor Report",
"description": "Printable PDF for the doctor's appointment — vitals, BMI, BP classification, medication compliance, mood.",
"action": "Configure & generate"
},
"measurementsCsv": {
"title": "Measurements",
"description": "Weight, blood pressure, pulse, glucose, and every other measurement as comma-separated values."
},
"medicationsCsv": {
"title": "Medications",
"description": "Your medication list with dosage, schedules, and (optionally) the full intake history.",
"includeIntake": "Include intake history"
},
"moodCsv": {
"title": "Mood",
"description": "Daily mood entries with score, tags, and timestamps."
},
"fullBackup": {
"title": "Full backup",
"description": "Single JSON file with everything — same shape as the weekly auto-backup. Useful for self-restore via admin upload."
}
}
},
"about": {
"title": "About",
"description": "Version, license, links."
},
"placeholder": {
"coming_soon": "Moving here with the next release update."
}
},
"sectionsTitle": "Settings",
"categoryGeneral": "General",
"categoryNotifications": "Notifications",
"categoryAi": "AI",
"categoryPersonalization": "Personalization",
"categoryIntegration": "Integration",
"categoryApi": "API",
"profile": "Profile",
"security": "Security",
"language": "Language",
"languageDescription": "Choose the display language of the application.",
"languageSystem": "System (automatic)",
"username": "Username",
"height": "Height (cm)",
"dateOfBirth": "Date of birth",
"dateOfBirthHint": "Used for automatic blood pressure target calculations.",
"gender": "Gender",
"genderNone": "Not specified",
"genderMale": "Male",
"genderFemale": "Female",
"genderHint": "Used for gender-specific target values.",
"profileSaved": "Profile saved",
"changePassword": "Change password",
"changePasswordDescription": "Replace your current password with a new one.",
"passwordReset": "Password reset",
"currentPassword": "Current password",
"newPassword": "New password",
"confirmNewPassword": "Confirm new password",
"passwordMismatch": "New passwords do not match",
"passwordUpdated": "Password updated successfully",
"passkeys": "Passkeys",
"registeredPasskeys": "Registered Passkeys",
"passkeysDescription": "Passkeys allow secure login without a password.",
"passkeyName": "Name",
"passkeyDevice": "Device",
"passkeyBackup": "Backup",
"passkeyCreated": "Created",
"passkeyActions": "Actions",
"noPasskeys": "No passkeys registered.",
"addPasskey": "Add passkey",
"passkeyAdded": "Passkey added successfully!",
"passkeyOptionsError": "Could not load passkey options",
"passkeyRegistrationFailed": "Passkey registration failed",
"passkeyRegistrationCancelled": "Passkey registration cancelled",
"passkeyNotSupported": "Your browser or device doesn't support passkeys yet. Try a different browser or device.",
"passkeyAlreadyRegistered": "This device is already registered as a passkey for your account.",
"passkeySecurityBlocked": "Your browser blocked the passkey request for security reasons. Make sure you're on a trusted HTTPS origin and try again.",
"passkeyTimeout": "The passkey prompt timed out. Please try again.",
"passkeyUnknownError": "Passkey registration failed: {message}",
"deletePasskey": "Delete passkey?",
"deletePasskeyDescription": "The passkey will be permanently deleted.",
"singleDevice": "Single device",
"multiDevice": "Multi-device",
"backedUp": "backed up",
"telegram": "Telegram Notifications",
"telegramDescription": "Get reminders for missed medication intake via Telegram.",
"telegramSaved": "Telegram settings saved",
"botToken": "Bot Token",
"chatId": "Chat ID",
"enableNotifications": "Enable notifications",
"testMessage": "Test message",
"testSent": "Test message sent!",
"telegramStep1": "1. Create a bot via @BotFather in Telegram and copy the token.",
"telegramStep2": "2. Send /start to your bot to activate the chat.",
"telegramStep3": "3. Find your Chat ID via @userinfobot or the Bot API.",
"ntfy": "ntfy",
"ntfyDescription": "Notifications via ntfy (self-hosted or ntfy.sh).",
"ntfyEnable": "Enable ntfy",
"ntfyServer": "Server URL",
"ntfyTopic": "Topic",
"ntfyAuthToken": "Auth Token (optional)",
"ntfyAuthTokenHint": "Only needed for private topics with access control.",
"webPush": "Browser Push",
"webPushDescription": "Receive notifications directly in your browser, even when HealthLog is not open.",
"webPushNotSupported": "Your browser does not support push notifications.",
"webPushDenied": "Push notifications are blocked. Allow them in your browser settings.",
"webPushNotConfigured": "Web Push is not configured on the server.",
"webPushSubscribe": "Enable push",
"webPushUnsubscribe": "Disable push",
"webPushSubscribed": "Push notifications enabled!",
"webPushUnsubscribed": "Push notifications disabled.",
"webPushSubscribeFailed": "Activation failed",
"webPushActive": "Active",
"kiInsights": "AI Insights (OpenAI)",
"kiInsightsDescription": "Optional: Save your OpenAI key for daily, automatic AI evaluations in Insights.",
"kiInsightsBenefitsTitle": "Benefits with OpenAI key",
"kiInsightsBenefit1": "Daily summaries for general status, blood pressure, weight, pulse, BMI, and medication compliance.",
"kiInsightsBenefit2": "Better trend and correlation interpretation based on your latest 30 daily measurement points per area.",
"kiInsightsBenefit3": "Automatic background refresh so the Insights page always shows up-to-date assessments.",
"createApiKeyHint": "Create your API key at:",
"createApiKeyLinkLabel": "platform.openai.com/api-keys",
"apiKey": "API Key",
"apiKeyStored": "Key stored — enter new one to replace",
"apiKeySaved": "API key saved",
"apiKeyRemoved": "API key removed",
"codexConnected": "ChatGPT connected successfully! AI insights are now active.",
"codexDisconnected": "ChatGPT connection removed.",
"codexConnectionFailed": "ChatGPT connection failed. Please try again.",
"rawData": "Send raw data",
"rawDataOnDescription": "Aggregated metrics plus anonymized raw points from the last 30 days are sent. This includes per-metric measurements (for example weight, blood pressure, pulse) with time context so AI can detect patterns, outliers, and correlations more reliably. Name, email, and direct account identifiers are not transmitted.",
"rawDataOffDescription": "Only summarized metrics are sent (for example averages, trends, minimum/maximum). No individual points and no exact time context. This is more privacy-preserving, but AI can be less precise for short-term patterns and fluctuations.",
"rawDataWarning": "Raw mode enabled: AI receives additional anonymized points from the last 30 days for higher analysis accuracy.",
"regenerateInsights": "Regenerate reports",
"regenerateSuccess": "Reports regenerated successfully",
"regenerateRateLimit": "Please wait — you've hit the hourly limit for analyses.",
"lastGeneratedAt": "Last generated",
"ai": {
"title": "AI Insights",
"description": "Provider, model, key.",
"chatgptConnectedBadge": "ChatGPT connected",
"adminAiActiveBadge": "Admin AI active",
"connectionExpiredBadge": "Connection expired",
"chatgptConnectedHeading": "ChatGPT connected",
"chatgptConnectedBody": "Insights are generated through your ChatGPT subscription — no extra cost.",
"connectedSince": "Connected since {when}.",
"disconnect": "Disconnect",
"connectChatgptHeading": "Connect with ChatGPT",
"connectChatgptBody": "Link your ChatGPT Pro/Max account to get AI-powered health analyses based on current medical guidelines. No additional API costs.",
"connectChatgptCta": "Connect with ChatGPT",
"deviceCodeHeading": "Finish connecting on chatgpt.com",
"deviceCodeStep1": "Open this link on any device:",
"deviceCodeStep2": "Enter this one-time code:",
"deviceCodeStep3": "Approve the connection — this page updates automatically.",
"deviceCodeCopy": "copy",
"deviceCodeWaiting": "Waiting for approval…",
"deviceCodeCancel": "Cancel",
"oauthNotConfigured": "ChatGPT OAuth is not configured on this instance — use your own API key below instead.",
"adminFallback": "Alternatively, HealthLog will use the AI provider configured by the administrator.",
"personalProviderHeading": "AI provider (personal)",
"personalProviderBody": "Your own AI provider overrides the admin setting. Leave blank for the default. For ChatGPT Pro/Max OAuth use the connect button above.",
"providerLabel": "Provider",
"providerOptionDefault": "— Default (Admin/Codex) —",
"providerOptionOpenai": "OpenAI (API key)",
"providerOptionAnthropic": "Anthropic (Claude)",
"providerOptionLocal": "Local (OpenAI-compatible)",
"modelLabel": "Model",
"modelOptionDefault": "— Default —",
"modelOptionCustom": "Custom…",
"customModelLabel": "Custom model name",
"openaiKeyLabel": "OpenAI API key",
"openaiKeyHelp": "Your own key — not connected to your ChatGPT subscription. For the subscription use the connect button above.",
"anthropicKeyLabel": "Anthropic API key",
"baseUrlLabel": "Base URL",
"localKeyLabel": "API key (optional)",
"savedPreview": "(saved {preview})",
"savedShort": "(saved)",
"saveCta": "Save",
"testCta": "Test connection",
"removeKeyCta": "Remove saved key",
"keyRemoved": "Saved key removed",
"removeKeyConfirmTitle": "Remove saved API key?",
"removeKeyConfirmBody": "Insights for this provider will fall back to the admin/Codex provider until you save a new key.",
"saved": "Saved",
"saveFailed": "Save failed",
"testFailed": "Test failed",
"errorGeneric": "Error",
"providerChain": {
"heading": "AI provider fallback chain",
"activeLine": "Active provider: {provider}",
"cachedSuffix": "(cached: {provider})",
"chainLine": "Configured chain: {chain}",
"managementHint": "Reordering and on/off toggles arrive in the next release.",
"none": "none configured",
"types": {
"codex": "ChatGPT (Codex)",
"openai": "OpenAI (your key)",
"anthropic": "Anthropic (Claude)",
"local": "Local model",
"admin-openai": "Admin OpenAI"
},
"title": "Fallback chain",
"description": "If the primary provider fails, HealthLog walks the chain in order. Drag the rows to reorder, toggle the switch to disable a provider without removing it.",
"moveUp": "Move up",
"moveDown": "Move down",
"removeFromChain": "Remove from chain",
"addProvider": "Add provider",
"addNoneAvailable": "All providers already in chain",
"saveOrder": "Save chain order",
"saved": "Chain saved",
"saveFailed": "Saving the chain failed",
"resetDefaults": "Reset to defaults",
"resetConfirmTitle": "Reset chain to defaults?",
"resetConfirmBody": "The chain reverts to Codex → OpenAI → Anthropic → Local → Admin OpenAI. Your saved credentials are not touched."
},
"activeProviderHeading": "Active AI provider",
"activeProviderBody": "Pick the provider you want to use first. The form below configures only the selected provider; the fallback chain at the bottom decides what happens if it fails.",
"activeProviderLabel": "Primary provider",
"providerConfigTitle": "Provider configuration",
"providerSelect": {
"codex": "ChatGPT account (Codex)",
"openai": "OpenAI (your API key)",
"anthropic": "Anthropic (Claude)",
"local": "Local model (OpenAI-compatible)",
"admin-openai": "Admin-provided OpenAI"
},
"openai": {
"modelSelect": "Model",
"modelOptionCustom": "Custom slug…",
"modelCustomLabel": "Custom model slug",
"modelCustomPlaceholder": "gpt-5",
"baseUrlLabel": "Base URL (advanced)",
"baseUrlPlaceholder": "https://api.openai.com/v1",
"baseUrlHelp": "Override only when using an OpenAI-compatible gateway. Leave blank for OpenAI itself.",
"showAdvanced": "Show advanced",
"hideAdvanced": "Hide advanced",
"apiKey": "API key",
"apiKeyPlaceholder": "sk-…"
},
"codex": {
"statusConnected": "Connected",
"statusDisconnected": "Not connected",
"statusExpired": "Connection expired",
"connectButton": "Connect with ChatGPT",
"disconnectButton": "Disconnect",
"modelSlugLabel": "Model slug",
"modelSlugBody": "Codex uses the model your ChatGPT subscription routes to. The CODEX_MODEL environment variable lets ops override this on the instance.",
"lastInsight": "Last insight: {when}"
},
"adminOpenai": {
"title": "Admin OpenAI",
"body": "Operator-provided OpenAI key. Used as a last-ditch fallback when no personal provider is configured. There is nothing to configure on this row — visibility means the operator has set it up.",
"notConfigured": "The operator has not configured a shared OpenAI key on this instance."
},
"testProvider": "Test active provider",
"testSuccess": "OK — {provider} ({model})",
"testFailedShort": "Test failed: {message}"
},
"withings": "Withings",
"withingsDescription": "Connect your Withings scale and blood pressure monitors.",
"withingsCredentials": "API Credentials",
"withingsClientId": "Client ID",
"withingsClientSecret": "Client Secret",
"withingsCredentialsSaved": "Credentials saved",
"withingsCredentialsSavedPlaceholder": "Saved — enter new to replace",
"withingsCredentialsSavedPlaceholderSecret": "Saved — enter new to replace",
"withingsSaveCredentials": "Save credentials",
"withingsConnected": "Connected",
"configured": "Configured",
"withingsTokenExpired": "Token expired",
"withingsLastSync": "Last sync",
"withingsSync": "Sync now",
"withingsFullSync": "Sync all data",
"withingsFullSyncTitle": "Full synchronization?",
"withingsFullSyncDescription": "All available Withings data will be fully synchronized. This may take some time depending on your history.",
"withingsSyncResult": "{count} measurements synchronized",
"withingsFullSyncResult": "{count} measurements fully synchronized",
"withingsSyncFailed": "Sync failed",
"withingsSynchronize": "Synchronize",
"withingsDisconnect": "Disconnect",
"withingsDisconnectTitle": "Disconnect Withings?",
"withingsDisconnectDescription": "The connection to Withings will be disconnected. Previously synced data will be preserved.",
"withingsConnect": "Connect with Withings",
"withingsNoCredentials": "Please enter your API credentials above to connect Withings.",
"integrationStatus": {
"stateConnected": "Connected",
"stateError": "Error",
"stateReauthRequired": "Reconnect required",
"stateDisconnected": "Disconnected",
"consecutiveFailures": "{count}/{threshold} consecutive failures",
"lastSuccess": "Last successful sync",
"lastAttempt": "Last attempt"
},
"apiTokens": "API Tokens",
"apiTokensDescription": "Create API tokens for external medication intake (e.g., Shortcuts, automations).",
"tokenName": "Token name",
"tokenNamePlaceholder": "Token name (e.g., iPhone Shortcut)",
"tokenCreated": "Token created — copy it now! It won't be shown again.",
"tokenRevoke": "Revoke token?",
"tokenRevokeDescription": "The token will be permanently deactivated. Applications using it will lose access.",
"tokenRevoked": "Revoked",
"tokenExpired": "Expired",
"tokenActive": "Active",
"activeTokensTitle": "Active tokens",
"revokedTokensTitle": "Revoked tokens ({count})",
"tokenTableName": "Name",
"tokenTablePermissions": "Permissions",
"tokenTableStatus": "Status",
"tokenTableCreated": "Created",
"tokenTableLastUsed": "Last used",
"tokenTableActions": "Actions",
"noActiveTokens": "No active tokens available.",
"tokenNeverUsed": "Never",
"tokenLastUsed": "Last used:",
"tokenCreatedAt": "Created:",
"apiEndpoint": "API endpoint for medication intake:",
"apiEndpointsTitle": "API endpoints",
"apiEndpointsDescription": "Overview of currently available external endpoint(s) for token-based ingestion.",
"apiEndpointMethod": "Method",
"apiEndpointPath": "Path",
"apiEndpointAuth": "Authentication",
"apiEndpointExample": "Body example",
"export": "Data Export",
"exportDescription": "Export all your health data.",
"exportJson": "JSON Export",
"exportCsv": "CSV Export",
"doctorReport": "Doctor Report (PDF)",
"auditLog": "Activity Log",
"auditLogHidden": "Log hidden.",
"auditLogShowing": "Showing last {count} of {total} entries",
"auditNoActivities": "No activities found.",
"auditAction": "Action",
"auditCategory": "Category",
"auditIp": "IP",
"auditLocation": "Location",
"auditTimestamp": "Time",
"auditOther": "Other",
"auditCategoryAuth": "Auth",
"auditCategoryData": "Data",
"auditCategoryIntegration": "Integration",
"auditCategoryAI": "AI",
"auditCategoryAdmin": "Admin",
"auditActionAuthRegister": "Registration",
"auditActionAuthLogin": "Login",
"auditActionAuthLoginPasskey": "Passkey login",
"auditActionAuthLoginPassword": "Password login",
"auditActionAuthLoginFailed": "Failed login",
"auditActionAuthLogout": "Logout",
"auditActionAuthPasskeyRegister": "Passkey added",
"auditActionAuthPasskeyDelete": "Passkey deleted",
"auditActionAuthPasswordChange": "Password changed",
"auditActionMeasurementCreate": "Measurement created",
"auditActionMeasurementUpdate": "Measurement updated",
"auditActionMeasurementDelete": "Measurement deleted",
"auditActionMedicationCreate": "Medication created",
"auditActionMedicationUpdate": "Medication updated",
"auditActionMedicationDelete": "Medication deleted",
"auditActionMedicationIntake": "Intake recorded",
"auditActionMedicationIngestExternal": "External intake",
"auditActionWithingsConnect": "Withings connected",
"auditActionWithingsDisconnect": "Withings disconnected",
"auditActionExportDownload": "Export downloaded",
"auditActionInsightsGenerate": "AI insight generated",
"auditActionAdminUserUpdate": "Admin: User updated",
"auditActionAdminUserResetPassword": "Admin: Password reset",
"auditActionAdminSettingsUpdate": "Admin: Settings changed",
"collapse": "Collapse",
"expand": "Expand",
"dangerZoneTitle": "Danger Zone",
"dangerZone": "Delete All Data",
"dangerZoneDescription": "Deletes all your health data and integrations. Your user account will be preserved.",
"dangerZoneConfirm": "Delete all data?",
"dangerZoneConfirmDescription": "This will permanently delete all your health data and integrations. Your user account will be preserved.",
"dangerZoneSuccess": "All personal data has been deleted",
"dangerZoneDeleteFailed": "Deletion failed",
"finalDelete": "Delete permanently",
"saved": "Saved",
"savingError": "Error saving",
"adminAreaTitle": "Admin area",
"adminAreaDescription": "System-wide settings and user management are available in the admin console.",
"openAdminConsole": "Open admin console",
"moodLogTitle": "moodLog",
"moodLogDescription": "Import mood data from moodLog",
"moodLogUrl": "moodLog URL",
"moodLogUrlPlaceholder": "https://mood.example.com",
"moodLogApiKey": "API Key",
"moodLogApiKeyPlaceholder": "ml_...",
"moodLogWebhookSecret": "Webhook Secret",
"moodLogWebhookSecretHelp": "Enter this secret in moodLog as webhook secret",
"moodLogSync": "Start sync",
"moodLogFullSync": "Full sync",
"moodLogFullSyncTitle": "Full sync?",
"moodLogFullSyncDescription": "All available mood data will be fully synchronized.",
"moodLogDisconnect": "Disconnect",
"moodLogDisconnectTitle": "Disconnect moodLog?",
"moodLogDisconnectDescription": "The connection will be removed and all imported mood data will be deleted.",
"moodLogLastSync": "Last sync",
"moodLogEntries": "Entries",
"moodLogSyncResult": "{count} entries synchronized",
"moodLogSyncFailed": "Sync failed",
"moodLogSaved": "moodLog connection saved",
"moodLogDisconnected": "moodLog disconnected",
"about": {
"version": "App version",
"gitSha": "Build",
"builtAt": "Built {time}",
"license": "License",
"repository": "Source code",
"changelog": "Changelog",
"docs": "Documentation",
"linksHeading": "Sources & docs",
"updatesHeading": "Updates",
"checkUpdates": "Check now",
"checking": "Checking…",
"lastChecked": "Last checked: {time}",
"lastCheckedNever": "Not checked yet",
"upToDate": "You are up to date",
"newerAvailable": "Newer version: {tag}",
"checkFailed": "Could not reach GitHub — try again later"
},
"testConnection": {
"test": "Test connection",
"testing": "Testing…",
"ok": "Connected (latency {latency} ms)",
"errors": {
"credentials_rejected": "Credentials rejected — check your token",
"rate_limited": "Rate-limited by the upstream",
"timeout": "Request timed out",
"upstream_error": "Upstream returned an error",
"connection_failed": "Connection failed",
"not_configured": "Not configured",
"url_not_public": "URL is not a public endpoint",
"url_invalid": "URL is invalid",
"redirected": "Endpoint redirects — check the URL",
"endpoint_not_found": "Endpoint not found at the URL",
"credentials_unreadable": "Credentials cannot be decrypted",
"upstream_invalid_json": "Upstream sent invalid JSON",
"vapid_not_configured": "Web Push not configured (VAPID keys missing)",
"rate_limited_self": "Too many test requests",
"generic": "Test failed"
}
},
"notificationStatus": {
"title": "Channel reliability",
"description": "Live status of every notification channel — Auto-disabled means HealthLog stopped retrying after a permanent error.",
"emptyDescription": "No channels configured yet. Add a channel below to start tracking its delivery health.",
"stateActive": "Active",
"stateAutoDisabled": "Auto-disabled",
"stateSendingPaused": "Sending paused",
"stateManuallyDisabled": "Disabled",
"lastSuccess": "Last successful send",
"lastFailure": "Last failure",
"consecutiveFailures": "Consecutive failures",
"disabledReason": "Reason",
"nextRetry": "Next retry",
"reEnable": "Re-enable",
"sendTest": "Send test"
}
},
"admin": {
"title": "Administration",
"subtitle": "System status, users, and settings",
"settingsSaveError": "Failed to save settings",
"settingsSaveValidationError": "Please check the highlighted fields",
"sectionsTitle": "Admin",
"systemStatus": "System Status",
"version": "Version",
"database": "Database",
"databaseConnected": "Connected",
"databaseError": "Error",
"gitCommit": "Git Commit",
"startedAt": "Started",
"users": "Users",
"measurementsCount": "Measurements",
"activeTokens": "Active API Tokens",
"activeSessions": "Active Sessions",
"loadingStatus": "Loading status...",
"systemStatusLoadError": "Failed to load system status.",
"systemStatusRetry": "Retry",
"adminSettingsLoadError": "Failed to load admin settings. Toggles below may not reflect the live state — refresh the page.",
"hostMetrics": {
"title": "Host load",
"load1": "Load (1m)",
"memUsedPercent": "Memory",
"diskBusyPercent": "Disk I/O",
"diskReadBps": "Disk read",
"diskWriteBps": "Disk write",
"last2hours": "Last 2 hours",
"empty": "Sampling started — data appears in 1–2 minutes.",
"loadError": "Failed to load host metrics. Try refreshing the page."
},
"workerStatus": "Job Worker",
"workerRunning": "Running",
"workerStopped": "Stopped",
"lastReminderCheck": "Last Reminder Check",
"appSettings": "Application Settings",
"registrationEnabled": "Allow registration",
"registrationEnabledDescription": "When disabled, new users cannot register.",
"defaultLanguage": "Default language",
"defaultLanguageDescription": "Used for new users and as fallback.",
"servicesGlobal": "Services (global)",
"servicesGlobalDescription": "Disabled services are not available to any user.",
"telegramGlobal": "Allow Telegram notifications system-wide.",
"ntfyGlobal": "Allow ntfy notifications system-wide.",
"webPushGlobal": "Allow browser push notifications system-wide.",
"integrationWebPush": "Web Push",
"integrationBugReport": "Bug Report",
"apiGlobal": "Allow API endpoints and API tokens system-wide.",
"moodLogGlobal": "Allow moodLog integration system-wide.",
"sectionGeneral": "General",
"sectionIntegrations": "Integrations",
"sectionMedication": "Medications",
"sectionManagement": "Management",
"umamiTitle": "Umami",
"umamiDescription": "Web analytics with Umami",
"glitchtipTitle": "GlitchTip",
"glitchtipDescription": "Error tracking with GlitchTip",
"webPushVapidTitle": "Web Push VAPID",
"monitoring": "Monitoring (Umami/Glitchtip)",
"monitoringDescription": "Configuration for website analytics and error tracking.",
"umamiEnabled": "Enable Umami tracking.",
"umamiScriptUrl": "Umami script URL",
"umamiScriptUrlPlaceholder": "https://analytics.example.com/script.js",
"umamiWebsiteId": "Umami website ID",
"umamiWebsiteIdPlaceholder": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"glitchtipEnabled": "Enable Glitchtip error tracking.",
"glitchtipDsn": "Glitchtip DSN",
"glitchtipDsnPlaceholder": "https://<public-key>@glitchtip.example.com/<project-id>",
"glitchtipEnvironment": "Glitchtip environment",
"glitchtipEnvironmentPlaceholder": "production",
"webPushVapid": "Web Push (VAPID)",
"webPushVapidDescription": "Configure VAPID keys and subject here so browser push works without environment variables.",
"webPushVapidPublicKey": "VAPID public key",
"webPushVapidPublicKeyPlaceholder": "BElx... (Base64URL)",
"webPushVapidPrivateKey": "VAPID private key",
"webPushVapidPrivateKeyPlaceholder": "Optional: enter a new private key",
"webPushVapidSubject": "VAPID subject",
"webPushVapidSubjectPlaceholder": "mailto:you@example.com",
"configured": "Configured",
"notConfigured": "Not configured",
"monitoringTestUmami": "Send Umami test",
"monitoringTestGlitchtip": "Send Glitchtip test",
"monitoringTestSuccess": "Test event sent",
"monitoringTestFailed": "Monitoring test failed",
"monitoringSave": "Save monitoring",
"bugReportGithub": "Bug report (GitHub Issues)",
"bugReportGithubDescription": "Configure GitHub issue token and repository for incoming bug reports.",
"bugReportEnabledLabel": "Bug reports enabled",
"bugReportEnabledDescription": "When off, the in-app report button hides — token and repository stay configured.",
"bugReportRepo": "Repository",
"bugReportRepoPlaceholder": "owner/repo",
"bugReportToken": "Issue token",
"bugReportTokenPlaceholder": "ghp_...",
"bugReportConfigured": "Bug report is configured.",
"bugReportNotConfigured": "Bug report is not fully configured yet.",
"bugReportSave": "Save bug report settings",
"userManagement": "User Management",
"userEmail": "Email",
"userRole": "Role",
"userPasskeys": "Passkeys",
"userCreated": "Created",
"userActions": "Actions",
"editUser": "Edit user",
"editUserTitle": "Edit user: {name}",
"demoteToUser": "Demote to user",
"promoteToAdmin": "Promote to admin",
"toUser": "→ User",
"toAdmin": "→ Admin",
"ownRoleUnchangeable": "Cannot change own role",
"lastAdminError": "Cannot demote the last admin",
"resetPassword": "Reset password",
"resetPasswordTitle": "Reset password: {name}",
"newPassword": "New password",
"newPasswordPlaceholder": "At least 12 characters",
"passwordReset": "Password has been reset",
"reset": "Reset",
"loadingUsers": "Loading users...",
"apiTokens": "API Tokens",
"tokenUser": "User",
"tokenName": "Name",
"tokenPermissions": "Permissions",
"tokenStatus": "Status",
"tokenLastUsed": "Last used",
"tokenCreated": "Created",
"tokenNeverUsed": "Never",
"noTokens": "No API tokens found.",
"tokensEmptyTitle": "No API tokens yet",
"tokensEmptyDescription": "Tokens are issued when a native client signs in or via Settings → Account.",
"loginOverview": "Login Overview",
"allAuthEvents": "All auth events",
"failedOnly": "Failed only",
"noEntries": "No entries found.",
"loginEmptyTitle": "No authentication events yet",
"loginEmptyDescription": "Sign-ins, sign-outs, and passkey changes will show up here.",
"loginEmptyFailedTitle": "No failed sign-in attempts",
"loginEmptyFailedDescription": "That's the safe state. Switch to all events to see successful sign-ins.",
"loginEmptyResetFilter": "Show all events",
"showingEntries": "Showing {count} of {total} auth entries",
"status": "Status",
"action": "Action",
"ip": "IP",
"location": "Location",
"timestamp": "Time",
"dangerZone": "Danger Zone",
"deleteAllData": "Delete all data globally",
"deleteAllDescription": "Deletes all measurement, medication, integration, and log data for all users. User accounts will be preserved.",
"deleteAllConfirm": "Really delete all data?",
"deleteAllConfirmDescription": "This will permanently delete all measurements, medications, intake events, API tokens, Withings connections, open authentication challenges, notification channels (Telegram, ntfy, Web Push), push subscriptions, and queued Telegram message deletions for all users. User accounts, the audit log, and submitted feedback are preserved so the wipe itself remains traceable and bug reports stay triageable.",
"deleteButton": "Delete all data",
"finalDelete": "Delete permanently",
"deletedResult": "Deleted: {measurements} measurements, {medications} medications, {intakeEvents} intakes, {apiTokens} API tokens, {withingsConnections} Withings connections, {authChallenges} auth challenges, {notificationChannels} notification channels, {pushSubscriptions} push subscriptions, {telegramScheduledDeletions} queued Telegram deletions. Feedback rows preserved.",
"authRegister": "Registration",
"authLogin": "Login",
"authLoginPasskey": "Passkey login",
"authLoginPassword": "Password login",
"authLoginFailed": "Failed",
"authLogout": "Logout",
"authPasskeyRegister": "Passkey added",
"authPasskeyDelete": "Passkey deleted",
"medicationReminders": "Medication Reminders",
"medicationRemindersDescription": "Thresholds for reminder badge color transitions on medication cards.",
"reminderLateMinutes": "Late threshold (minutes)",
"reminderLateMinutesDescription": "Minutes after window end until the badge changes from yellow to orange.",
"reminderMissedMinutes": "Missed threshold (minutes)",
"reminderMissedMinutesDescription": "Minutes after window end until the intake is considered missed.",
"reminderThresholdsSave": "Save thresholds",
"notificationTest": "Test Notifications",
"notificationTestSend": "Send test notification",
"notificationTestSuccess": "Test notification sent",
"notificationTestFailed": "Failed to send test notification",
"reminderCheckRun": "Run reminder check",
"reminderCheckSuccess": "Reminder check completed",
"reminderCheckFailed": "Failed to run reminder check",
"reminderCheckResults": "Results",
"reminderCheckNotifOn": "Notifications on",
"reminderCheckNotifOff": "Notifications off",
"reminderCheckEventsToday": "Events today",
"reminderCheckNotifSent": "Sent",
"feedback": {
"title": "Feedback Inbox",
"description": "User-submitted feedback, bug reports, and feature requests.",
"tabOpen": "Open",
"tabAcknowledged": "Acknowledged",
"tabResolved": "Resolved",
"tabArchived": "Archived",
"subject": "Subject",
"category": "Category",
"user": "User",
"createdAt": "Submitted",
"actions": "Actions",
"details": "Details",
"noEntries": "No feedback in this category.",
"emptyTitle": "Inbox zero",
"emptyDescription": "No user feedback in this status. Submitted bugs, questions, and feature requests will appear here.",
"loading": "Loading feedback...",
"anonymous": "anonymous",
"categoryBug": "Bug",
"categoryFeature": "Feature",
"categoryQuestion": "Question",
"categoryOther": "Other",
"statusOpen": "Open",
"statusAcknowledged": "Acknowledged",
"statusResolved": "Resolved",
"statusArchived": "Archived",
"dialogTitle": "Feedback details",
"metadataHeading": "Metadata",
"metaUrl": "URL",
"metaLocale": "Locale",
"metaUserAgent": "User agent",
"metaAppVersion": "App version",
"screenshotHeading": "Screenshot",
"adminNote": "Admin note",
"adminNotePlaceholder": "Internal note (not visible to user)",
"saveNote": "Save note",
"noteSaved": "Note saved",
"actionAcknowledge": "Acknowledge",
"actionResolve": "Resolve",
"actionArchive": "Archive",
"actionPublishGithub": "Publish to GitHub",
"publishedToGithub": "Published to GitHub",
"viewIssue": "View issue",
"publishSuccess": "Issue created",
"publishFailed": "GitHub publish failed",
"updateFailed": "Update failed",
"archiveConfirm": "Archive this feedback entry?",
"submittedBy": "Submitted by",
"sectionTitle": "Feedback"
},
"shell": {
"overview": "Overview",
"sectionsNav": "Admin sections"
},
"overview": {
"welcomeTitle": "Welcome, {name}",
"welcomeSubtitle": "You are signed in as administrator. Pick a section from the sidebar to manage HealthLog.",
"snapshotTitle": "System snapshot",
"snapshotVersion": "Version",
"snapshotDatabase": "Database",
"snapshotWorker": "Worker",
"snapshotStarted": "Started",
"snapshotBuildSha": "Build SHA",
"snapshotBuiltAt": "Built at",
"snapshotLoadError": "Failed to load system snapshot.",
"snapshotLoading": "Loading snapshot...",
"auditTitle": "Recent activity",
"auditEmpty": "No recent audit entries.",
"auditLoadError": "Failed to load recent activity.",
"auditLoading": "Loading activity...",
"auditViewAll": "View all"
},
"section": {
"system-status": {
"title": "System Status",
"subtitle": "Worker, database, and integration health at a glance."
},
"general": {
"title": "General",
"subtitle": "Registration, default language, and other app-wide toggles."
},
"services": {
"title": "Services",
"subtitle": "Enable or disable notification channels system-wide."
},
"integrations": {
"title": "Integrations",
"subtitle": "Configure Umami, GlitchTip, Web Push, and bug reports."
},
"feedback": {
"title": "Feedback",
"subtitle": "Triage user-submitted feedback and bug reports."
},
"reminders": {
"title": "Reminders",
"subtitle": "Tune medication reminder thresholds and run a manual check."
},
"users": {
"title": "Users",
"subtitle": "Manage user accounts, roles, and active sessions.",
"filter": {
"all": "All",
"admin": "Admins",
"user": "Users"
},
"forceLogout": "Force logout",
"forceLogoutConfirmTitle": "Force logout {name}?",
"forceLogoutConfirmBody": "All active sessions for this user will be revoked. They will need to sign in again on every device.",
"forceLogoutSuccess": "Logged {name} out of {count} session(s)",
"forceLogoutFailed": "Failed to force logout",
"cannotLogoutSelf": "Cannot force-logout yourself",
"emptyTitle": "No users in this view",
"emptyDescription": "There are no users matching the current filter.",
"emptyResetFilter": "Show all users"
},
"api-tokens": {
"title": "API Tokens",
"subtitle": "Active bearer tokens issued to native clients and integrations."
},
"login-overview": {
"title": "Login Overview",
"subtitle": "Audit trail of authentication and admin events."
},
"auditLog": {
"title": "Audit log",
"filterActor": "Actor (user id or username)",
"filterAction": "Action",
"filterActionAll": "All actions",
"filterTarget": "Target (id or path)",
"filterSeverity": "Severity",
"filterDate": "Date range",
"range24h": "Last 24 hours",
"range7d": "Last 7 days",
"range30d": "Last 30 days",
"rangeAll": "All time",
"perPage": "Per page",
"prev": "Previous",
"next": "Next",
"pageOf": "Page {page} of {total}",
"export": "Export CSV",
"empty": "No audit entries match the current filters."
},
"app-logs": {
"title": "App Logs",
"subtitle": "Tail the most recent structured wide-events emitted by this process.",
"processNote": "Showing app-process logs only — worker-process logs go to Loki when LOKI_ENDPOINT is configured. Buffer is volatile and capped at 500 entries.",
"filterTraceId": "Trace ID",
"filterAction": "Action contains…",
"filterLevel": "Level",
"levelAll": "All levels",
"filterRange": "Time window",
"range15m": "Last 15 minutes",
"range1h": "Last hour",
"range6h": "Last 6 hours",
"rangeAll": "Whole buffer",
"colLevel": "Level",
"colTimestamp": "Timestamp",
"colAction": "Action",
"colDuration": "Duration",
"colTraceId": "Trace",
"showing": "Showing {count} of up to {bufferMax} buffered events",
"empty": "Buffer is empty",
"emptyDescription": "No events match the current filters yet. Hit refresh after triggering some traffic.",
"refresh": "Refresh",
"eventDetails": "Event details",
"closeDetails": "Close details"
},
"backups": {
"title": "Backups",
"subtitle": "Weekly per-user data snapshots stored in PostgreSQL.",
"description": "Each user gets one rolling snapshot per backup type. Sizes show the encrypted blob — payloads are not downloadable from this page.",
"runNow": "Backup now",
"runEnqueued": "Backup job enqueued",
"runFailed": "Failed to enqueue backup",
"loading": "Loading backups...",
"loadError": "Failed to load backups.",
"empty": "No backups recorded yet.",
"emptyTitle": "No backups yet",
"emptyDescription": "Backups run automatically every Sunday at 03:00 — or trigger one now to create the first snapshot.",
"colUser": "User",
"colType": "Type",
"colSize": "Size",
"colCreatedAt": "Last snapshot",
"colActions": "Actions",
"retentionLabel": "Retention: {days} days",
"download": "Download",
"downloadAria": "Download backup for {username}",
"downloadFailed": "Download failed",
"downloadStarted": "Download started",
"uploadTitle": "Upload backup",
"uploadDescription": "Validate a backup file and store it as a manual snapshot. Restoring is a separate step.",
"uploadButton": "Upload file",
"uploadHelp": "JSON file matching the current backup schema. Max 10 MB.",
"uploadSuccess": "Backup uploaded ({count} records)",
"uploadFailed": "Upload failed",
"restore": "Restore",
"restoreAria": "Restore from backup for {username}",
"restoreTitle": "Restore from backup",
"restoreDescription": "This will replace ALL current data for {username} with the snapshot from {when}. Existing measurements, medications, intake events, mood entries, notification channels, push subscriptions and queued Telegram deletions will be deleted.",
"restorePromptLabel": "Type RESTORE to continue",
"restoreConfirm": "Restore now",
"restoreInProgress": "Restoring...",
"restoreSuccess": "Restore complete",
"restoreFailed": "Restore failed",
"docsLink": "Documentation"
},
"danger-zone": {
"title": "Danger Zone",
"subtitle": "Destructive system-wide operations."
}
}
},
"achievements": {
"title": "Achievements",
"subtitle": "Unlock achievements from feature rollout onward through consistent health trends and medication habits.",
"loginRequired": "Please sign in to view achievements.",
"points": "Points",
"unlocked": "Unlocked",
"nextGoal": "Next goal",
"allCompleted": "All achievements unlocked!",
"completed": "Completed",
"inProgress": "In progress",
"progress": "Progress",
"goalReached": "Goal reached",
"remaining": "{count} remaining",
"remainingUnlocks": "{count} still unlockable",
"noneUnlockedYet": "No achievements unlocked yet.",
"pointsValue": "{points} points",
"metricCount": "{count}",
"metricDays": "{count} days",
"metricPercent": "{count}%",
"badges": {
"intakeTotal1": {
"title": "First intake",
"description": "Record your first taken medication event."
},
"intakeTotal10": {
"title": "Intake starter",
"description": "Record 10 taken medication events."
},
"intakeTotal50": {
"title": "Intake routine",
"description": "Record 50 taken medication events."
},
"intakeTotal150": {
"title": "Intake expert",
"description": "Record 150 taken medication events."
},
"intakeTotal300": {
"title": "Intake legend",
"description": "Record 300 taken medication events."
},
"overIntake1": {
"title": "Idiot",
"description": "Take medication at least once more than planned."
},
"skippedIntake1": {
"title": "Lazy Boy",
"description": "Skip at least one planned intake."
},
"passkeyCreated1": {
"title": "Passkey set up",
"description": "Create your first passkey."
},
"passkeyLogin1": {
"title": "Passkey login",
"description": "Sign in at least once with a passkey."
},
"passwordLogin1": {
"title": "Old school",
"description": "Sign in at least once with username and password."
},
"bugReport1": {
"title": "Bug hunter",
"description": "Submit a bug report."
},
"loginStreak7": {
"title": "Login streak 7d",
"description": "Sign in on 7 consecutive days."
},
"loginStreak30": {
"title": "Login streak 30d",
"description": "Sign in on 30 consecutive days."
},
"onTimePerfect1": {
"title": "On-time 1d",
"description": "Take all medications on time for 1 consecutive days."
},
"compliance801": {
"title": "80% adherence · 1d",
"description": "Reach at least 80% 30-day adherence for 1 consecutive days."
},
"bmiGreen1": {
"title": "BMI green · 1d",
"description": "Keep your BMI in the normal range for 1 consecutive days."
},
"bpGreen1": {
"title": "BP green · 1d",
"description": "Keep your blood pressure in the normal range for 1 consecutive days."
},
"pulseGreen1": {
"title": "Pulse green · 1d",
"description": "Keep your resting pulse in the normal range for 1 consecutive days."
},
"onTimePerfect7": {
"title": "On-time 7d",
"description": "Take all medications on time for 7 consecutive days."
},
"compliance807": {
"title": "80% adherence · 7d",
"description": "Reach at least 80% 30-day adherence for 7 consecutive days."
},
"bmiGreen7": {
"title": "BMI green · 7d",
"description": "Keep your BMI in the normal range for 7 consecutive days."
},
"bpGreen7": {
"title": "BP green · 7d",
"description": "Keep your blood pressure in the normal range for 7 consecutive days."
},
"pulseGreen7": {
"title": "Pulse green · 7d",
"description": "Keep your resting pulse in the normal range for 7 consecutive days."
},
"onTimePerfect30": {
"title": "On-time 30d",
"description": "Take all medications on time for 30 consecutive days."
},
"compliance8030": {
"title": "80% adherence · 30d",
"description": "Reach at least 80% 30-day adherence for 30 consecutive days."
},
"bmiGreen30": {
"title": "BMI green · 30d",
"description": "Keep your BMI in the normal range for 30 consecutive days."
},
"bpGreen30": {
"title": "BP green · 30d",
"description": "Keep your blood pressure in the normal range for 30 consecutive days."
},
"pulseGreen30": {
"title": "Pulse green · 30d",
"description": "Keep your resting pulse in the normal range for 30 consecutive days."
},
"onTimePerfect180": {
"title": "On-time 180d",
"description": "Take all medications on time for 180 consecutive days."
},
"compliance80180": {
"title": "80% adherence · 180d",
"description": "Reach at least 80% 30-day adherence for 180 consecutive days."
},
"bmiGreen180": {
"title": "BMI green · 180d",
"description": "Keep your BMI in the normal range for 180 consecutive days."
},
"bpGreen180": {
"title": "BP green · 180d",
"description": "Keep your blood pressure in the normal range for 180 consecutive days."
},
"pulseGreen180": {
"title": "Pulse green · 180d",
"description": "Keep your resting pulse in the normal range for 180 consecutive days."
},
"onTimePerfect360": {
"title": "On-time 360d",
"description": "Take all medications on time for 360 consecutive days."
},
"compliance80360": {
"title": "80% adherence · 360d",
"description": "Reach at least 80% 30-day adherence for 360 consecutive days."
},
"bmiGreen360": {
"title": "BMI green · 360d",
"description": "Keep your BMI in the normal range for 360 consecutive days."
},
"bpGreen360": {
"title": "BP green · 360d",
"description": "Keep your blood pressure in the normal range for 360 consecutive days."
},
"pulseGreen360": {
"title": "Pulse green · 360d",
"description": "Keep your resting pulse in the normal range for 360 consecutive days."
}
},
"nextProgressLabel": "Progress to unlock",
"completedOn": "Completed on {date}",
"locked": "Locked",
"criterionHint": "{current} / {target}",
"progressPercent": "{percent}%",
"categories": {
"medication": "Medication",
"vitals": "Vitals",
"security": "Account & security",
"engagement": "Engagement"
},
"dashboardCard": {
"title": "Recent unlocks",
"viewAll": "View all",
"empty": "No achievements yet — keep logging to unlock your first."
}
},
"bugreport": {
"title": "Bug Report",
"subtitle": "Send a bug report, feature request, or question. The server administrator will see your submission.",
"loginRequired": "Please sign in to report a bug.",
"bugTitle": "Title",
"description": "Description",
"descriptionPlaceholder": "Describe the bug in detail. What did you do? What happened? What did you expect?",
"screenshot": "Screenshot (optional)",
"screenshotPreview": "Screenshot preview",
"attachScreenshot": "Attach screenshot",
"imageOnly": "Only image files allowed",
"tooLarge": "Screenshot is too large (max 5 MB)",
"submit": "Send",
"success": "Thank you! Your bug report has been submitted successfully.",
"viewOnGithub": "View on GitHub",
"errorCreating": "Error creating report",
"notConfiguredTitle": "Bug reports not available yet",
"notConfiguredUser": "Bug reporting is disabled on this server. Please contact your administrator.",
"notConfiguredAdmin": "Bug reporting requires a GitHub integration (issue token + repository). Configure it in the admin panel under Settings → Bug reports.",
"openAdminSettings": "Open admin settings",
"category": "Type",
"categoryBug": "Bug report",
"categoryFeature": "Feature request",
"categoryQuestion": "Question",
"categoryOther": "Other feedback",
"bugTitlePlaceholder": "Short summary (optional)",
"githubEscalationNote": "Your feedback is stored locally. If the admin enables GitHub integration, it can be promoted to a public issue on request.",
"internalOnlyNote": "Your feedback is stored locally and only visible to the administrator of this server.",
"disabledTitle": "Bug reports are turned off",
"disabledBody": "The administrator has disabled bug reports on this server.",
"disabledError": "Bug reports are disabled by the administrator."
},
"notifications": {
"title": "Notifications",
"subtitle": "Choose which notifications you want to receive through which channel.",
"noChannels": "Configure a notification channel in Settings first.",
"goToSettings": "Go to Settings",
"channelDisabled": "Disabled",
"eventMedicationReminder": "Medication Reminder",
"eventMedicationReminderDesc": "Reminder when an intake is due.",
"eventMeasurementAnomaly": "Anomalous Measurement",
"eventMeasurementAnomalyDesc": "Warning for unusual measurements (e.g., high blood pressure).",
"eventComplianceLow": "Low Compliance",
"eventComplianceLowDesc": "Notification when medication compliance drops below a threshold.",
"eventWithingsSyncFailed": "Withings Sync Failed",
"eventWithingsSyncFailedDesc": "Alert when the automatic Withings data sync fails.",
"eventSystemAlert": "System Alert",
"eventSystemAlertDesc": "Important system messages and administrative notices."
},
"format": {
"dateShort": "{month}/{day}/{year}",
"timeShort": "{hours}:{minutes}",
"dateTime": "{month}/{day}/{year}, {hours}:{minutes}"
},
"classifications": {
"bmi": {
"Underweight": "Underweight",
"Normal": "Normal",
"Overweight": "Overweight",
"ObesityGradeI": "Obesity Grade I",
"ObesityGradeII": "Obesity Grade II",
"ObesityGradeIII": "Obesity Grade III"
},
"bp": {
"Optimal": "Optimal",
"Normal": "Normal",
"HighNormal": "High-normal",
"HypertensionGrade1": "Hypertension Grade 1",
"HypertensionGrade2": "Hypertension Grade 2",
"HypertensionGrade3": "Hypertension Grade 3"
},
"pulse": {
"Bradycardia": "Bradycardia",
"Normal": "Normal",
"Elevated": "Elevated",
"Tachycardia": "Tachycardia"
},
"pulseTarget": {
"SignificantlyLow": "Significantly low",
"SlightlyLow": "Slightly low",
"OnTarget": "On target",
"SlightlyElevated": "Slightly elevated",
"SignificantlyElevated": "Significantly elevated"
},
"sleep": {
"FarTooShort": "Far too short",
"TooShort": "Too short",
"OnTarget": "On target",
"SlightlyLong": "Slightly long",
"FarTooLong": "Far too long"
},
"bodyFat": {
"Essential": "Essential",
"Athletic": "Athletic",
"Fitness": "Fitness",
"Average": "Average",
"Obese": "Obese"
},
"steps": {
"VeryLow": "Very low",
"LowActive": "Low active",
"ModeratelyActive": "Moderately active",
"Active": "Active",
"VeryActive": "Very active"
},
"general": {
"Good": "Good",
"Moderate": "Moderate",
"Low": "Low",
"VeryGood": "Very good",
"VeryStable": "Very stable",
"Stable": "Stable",
"Fluctuating": "Fluctuating"
},
"alerts": {
"bmiBelowNormalTitle": "BMI below normal range",
"bmiBelowNormalMessage": "Your BMI of {bmi} is below the normal range (18.5–24.9).",
"bmiOverweightTitle": "BMI in overweight range",
"bmiOverweightMessage": "Your BMI of {bmi} is in the overweight range. Regular exercise and a balanced diet can help.",
"bmiObesityTitle": "BMI in obesity range",
"bmiObesityMessage": "Your BMI of {bmi} is in the obesity range.",
"bmiNormalTitle": "BMI in normal range",
"bmiNormalMessage": "Your BMI of {bmi} is in the healthy range.",
"bpDangerTitle": "Blood pressure significantly elevated",
"bpDangerMessage": "Your average blood pressure ({sys}/{dia}) is classified as \"{category}\".",
"bpWarningTitle": "Blood pressure slightly elevated",
"bpWarningMessage": "Your average blood pressure ({sys}/{dia}) is in the \"{category}\" range.",
"bpTargetGoodTitle": "Good blood pressure target adherence",
"bpTargetGoodMessage": "{pct}% of your readings are within the target range.",
"bpTargetBadTitle": "Blood pressure often outside target range",
"bpTargetBadMessage": "Only {pct}% of your readings are within the target range.",
"weightIncreasingTitle": "Weight increasing",
"weightIncreasingMessage": "Your weight is increasing by approx. {change} kg per week over the last 30 days.",
"weightDecreasingTitle": "Weight decreasing",
"weightDecreasingMessage": "Your weight is decreasing by approx. {change} kg per week over the last 30 days.",
"pulseOutliersTitle": "Pulse outliers detected",
"pulseOutliersMessage": "{count} unusual pulse readings in the last 30 days.",
"complianceLowTitle": "Low compliance: {name}",
"complianceLowMessage": "Your 7-day compliance for {name} is only {pct}%. Regular intake is important.",
"complianceGoodTitle": "Excellent compliance: {name}",
"complianceGoodMessage": "{pct}% compliance over the last 7 days. Keep it up!"
}
},
"targets": {
"title": "Targets",
"introText": "Your current values compared to recommended target ranges. Guideline sources are linked on each card.",
"weight": "Weight",
"bloodPressure": "Blood pressure",
"bloodPressureOnTarget": "Blood pressure on target",
"restingPulse": "Resting pulse",
"sleepDuration": "Sleep duration",
"bmi": "BMI",
"bodyFat": "Body fat",
"stepsPerDay": "Steps/day",
"medicationCompliance": "Medication compliance",
"mood": "Mood",
"moodStability": "Mood stability",
"steps": "steps",
"average30d": "30-day average:",
"currentValue": "Current: {value} {unit}",
"targetRangeValue": "Target: {min}–{max} {unit}",
"sourceLabel": "Source: {source}",
"inTarget": "Within target range",
"aboveTarget": "{delta} {unit} above target",
"belowTarget": "{delta} {unit} below target",
"diastolic": "Diastolic",
"noMeasurementYet": "No measurements yet",
"noMeasurementData": "No measurement data available. Add some measurements to see your targets.",
"profileIncomplete": "Profile incomplete",
"profileIncompleteHeight": "Add your height in profile settings to enable BMI targets.",
"profileIncompleteAge": "Add your date of birth in profile settings for age-specific targets.",
"profileIncompleteHeightAge": "Add your height and date of birth in profile settings for personalized targets.",
"compliancePerMedication": "Compliance per medication",
"glucoseFasting": "Glucose — fasting",
"glucosePostprandial": "Glucose — post-meal",
"glucoseRandom": "Glucose — random",
"glucoseBedtime": "Glucose — bedtime",
"loadError": "Failed to load targets"
},
"passwordStrength": {
"veryWeak": "Very weak",
"weak": "Weak",
"acceptable": "Acceptable",
"strong": "Strong",
"veryStrong": "Very strong",
"tooShort": "Too short",
"characters": "characters",
"minLength": "At least {count} characters required."
},
"telegram": {
"errorInvalidAction": "Invalid action.",
"errorMedicationNotFound": "Medication not found.",
"errorMedicationInactive": "Medication not found or inactive.",
"errorUnknownAction": "Unknown action.",
"snoozeOneHour": "1 hour",
"snoozeThreeHours": "3 hours",
"snoozedFor": "{name} snoozed for {duration}.",
"skipped": "{name} skipped.",
"alreadyRecorded": "{name} was already recorded.",
"recordedAsTaken": "{name} recorded as taken.",
"confirmed": "{name} confirmed.",
"genericConfirmed": "Confirmed.",
"cancelled": "Cancelled.",
"noActiveMedications": "No active medications found.",
"whichMedication": "<b>Which medication did you take?</b>",
"cancelButton": "Cancel",
"askMedicationName": "Please specify a medication, e.g. <b>taken Ramipril</b>.",
"medicationNotFoundExact": "Medication not found. Please send the name exactly as in HealthLog.",
"helpHeader": "<b>Available commands:</b>",
"helpBody": "/help — show this help\n/add — record an intake\n/start — start the bot\n\n<b>Text commands:</b>\ntaken &lt;name&gt; — confirm an intake\n\n<b>Buttons in reminders:</b>\n• Taken — confirm intake\n• 🕐 1h / 🕐 3h — postpone reminder\n• ⏭ Skip — skip intake\n• ✓ Confirm — confirm a missed intake"
},
"medicationReminders": {
"phaseGreenTitle": "🟢 Reminder: {medName}",
"phaseGreenMessage": "🟢 Reminder:\n<b>{medName}</b> ({doseInfo}, {timeWindow})\nWindow closes in {minutes} min.",
"phaseYellowTitle": "🟡 Due soon: {medName}",
"phaseYellowMessage": "🟡 Due soon:\n<b>{medName}</b> ({doseInfo}, {timeWindow})\n{minutes} min left.",
"phaseOrangeTitle": "🟠 Overdue: {medName}",
"phaseOrangeMessage": "🟠 Overdue:\n<b>{medName}</b> ({doseInfo}, {timeWindow})\nOverdue by {minutes} min.",
"phaseRedTitle": "🔴 Missed: {medName}",
"phaseRedMessage": "🔴 Missed:\n<b>{medName}</b> ({doseInfo}, {timeWindow})\nMarked as missed.",
"buttonTaken": "Taken",
"buttonConfirm": "✓ Confirm",
"buttonSnoozeOneHour": "🕐 1h",
"buttonSnoozeThreeHours": "🕐 3h",
"buttonSkip": "⏭ Skip"
}
}