File size: 39,087 Bytes
557ee65
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
# src/domain/i18n.py
from typing import Dict, Any

# UI Localization Text
UI_TEXT = {
    "en": {
        "welcome": "Welcome to Runner Intelligence. Upload your first run and the system will begin building your training baseline and generating insights.",
        "title": "# 🏃 Runner Agentic Intelligence (Experimental)",
        "subtitle": '<span class="muted">Personalized coaching from your training data.</span>',
        "workflow": '<span class="muted"><b>Workflow:</b> Upload runs ➔ Get Insights ➔ Review Weekly Plan ➔ Chat with Coach</span><br/><span class="muted"><i>Supported formats: .fit, .fit.gz, .tcx, .tcx.gz, .gpx (max 50MB per file)</i></span><br/><span class="muted">Feedback: <a href="https://github.com/ideas-to-life/runner-agentic-intelligence/issues" target="_blank">GitHub Issues</a> or DM me</span>',
        "evolution_workflow": '<span class="muted">Track your evolution. Review your weekly check-in and progress vs last month.</span><br/><span class="muted">Upload new runs anytime — your dashboard updates automatically.</span><br/><span class="muted">Feedback: <a href="https://github.com/ideas-to-life/runner-agentic-intelligence/issues" target="_blank">GitHub Issues</a> or DM me</span>',
        "tab_analyse": "Analyse",
        "tab_results": "Results",
        "tab_coach": "Coach",
        "tab_home": "Home",
        "tab_intelligence": "Intelligence",
        "tab_positioning": "Positioning",
        "lbl_your_week": "Your Week",
        "lbl_current_state": "Current State",
        "lbl_key_insight": "Key Insight",
        "lbl_forward_focus": "This week's Focus",
        "lbl_details": "Details",
        "lbl_coach_brief": "Coach Brief",
        "lbl_parsed": "Parsed",
        "unit_weeks": "weeks",
        "lbl_across": "across",
        "lbl_current": "Current",
        "lbl_previous": "Previous",
        "lbl_distance": "Distance",
        "lbl_runs": "Runs",
        "lbl_avg_pace": "Avg Pace",
        "lbl_consistency": "Consistency",
        "goal_status_template": "Your goal trajectory is **{val}**.",
        "home_story_template": "You ran **{count}** {unit} this week for a {of} **{dist:.1f} km**.",
        "sec_evolution": "📈 Progress vs Last Month",
        "sec_checkin": "## 🧠 Weekly Check-In",
        "lbl_goal_traj_inline": "**🎯 Trajectory:**",
        "lbl_focus_inline": "**🎯 Focus:**",
        "sec_snapshot": "## 📅 Current Week Snapshot",
        "sec_upload": "🗂️ Upload your training data",
        "upload_hints": '<div class="muted" style="margin-bottom: 12px; font-size: 0.9rem;"><ul><li>Best results: upload 4–12 recent runs (or ~2–6 weeks).</li><li>Include HR data if you have it (helps fatigue/risk signals).</li><li>Then click ‘Analyse Data’ to populate Results + Coach context.</li></ul></div>',
        "upload_label": "Drag and drop or click to upload",
        "btn_analyse": "🚀 Analyse Data",
        "btn_reset": "Reset",
        "sec_insights": "Coaching Insights",
        "lbl_risk": "Safety/Risk Assessment",
        "lbl_lever": "Primary Lever",
        "sec_plan": "Weekly Training Plan",
        "sec_charts": "Trends & Analytics",
        "sec_chat": "Ask about your training",
        "chat_indicator_no": "⚠️ *Upload and analyze runs to enable chat context.*",
        "chat_indicator_yes": "✅ *Chat context enabled.*",
        "chat_tip": "Tip: try ‘Plot my pace’ or ‘Show HR chart’ to visualize your data.",
        "chat_placeholder": "e.g., How was my pace last week?",
        "btn_send": "Send",
        "btn_clear": "Clear History",
        "lang_label": "Language / Idioma",
        "starter_limiter": "Biggest limiter?",
        "starter_why": "Why this focus?",
        "starter_fatigue": "Fatigue risk?",
        "starter_keep": "What to keep doing?",
        "chat_starter_limiter": "What is my biggest training limiter?",
        "chat_starter_why": "Why did you suggest this training focus?",
        "chat_starter_fatigue": "Do you see any signs of overtraining or fatigue?",
        "chat_starter_keep": "What aspects of my training should I keep doing?",
        "analyse_progress": "Analysing training data...",
        "insights_primary_lever_heading": "Primary Lever",
        "insights_risk_signal_heading": "Risk Signal",
        "insights_key_observations_heading": "Key Observations",
        "insights_evidence_label": "Evidence",
        "insights_constraint_label": "Constraint",
        "insights_no_primary_lever": "No primary lever identified.",
        "insights_no_risk": "No elevated risk detected.",
        "insights_no_observations": "*No observations provided.*",
        "insights_analysis_failed": "*Analysis Failed*",
        "insights_analysis_pending": "*Analysis pending...*",
        "insights_raw_default": "Raw insights will appear here.",
        "plan_week_summary_label": "Week summary:",
        "plan_focus_label": "This week's focus:",
        "plan_pending": "*Plan will appear here after analysis.*",
        "progress_extracting": "Extracting features from run data...",
        "progress_generating": "Generating insights and training plan...",
        "pipeline_stage_1": "🏃 Uploading runs",
        "pipeline_stage_2": "📊 Building weekly snapshot",
        "pipeline_stage_3": "📈 Analyzing training trends",
        "pipeline_stage_4": "🧠 Generating coach insights",
        "pipeline_stage_5": "📋 Preparing training recommendation",
        "chat_context_indicator": "🧠 **Using your training insights as context**",
        "error_no_runs": "No runs to process.",
        "lbl_details": "Details (Risk & Observations)",
        "banner_title": "⚠️ Public Preview Information",
        "banner_session": "**Session Data**: All uploaded data and chat history are temporary and destroyed after the session.",
        "banner_persistence_disabled": "🟡 **Public Preview Mode** — No data is persisted. All uploads and derived metrics are temporary.",
        "banner_persistence_enabled": "🟢 **Training History Persistence Enabled** — Weekly snapshots and trends are stored locally.",
        "banner_medical": "**Medical Advice**: This system provides coaching insights, NOT medical advice. Consult a professional before starting any training plan.",
        "banner_full": "**Full Experience**: For full persistence and local storage, run the app locally from [GitHub](https://github.com/avfranco/runner-agentic-intelligence).",
        "insights_timestamp_label": "Insights generated on",
        "risk_level_low": "LOW",
        "risk_level_medium": "MEDIUM",
        "risk_level_high": "HIGH",
        "chat_error": "I'm sorry, I'm having trouble processing your request right now.",
        "plan_error": "Could not generate plan at this time.",
        "tab_profile": "Profile",
        "sec_profile": "## Runner Profile (Digital Twin v1)",
        "lbl_display_name": "Display Name",
        "lbl_age": "Age",
        "lbl_experience": "Experience Level",
        "lbl_injury_notes": "Injury History / Notes",
        "btn_save_profile": "Save Profile",
        "profile_saved": "Profile saved successfully!",
        "profile_save_error": "Error saving profile.",
        "lbl_baseline": "Baseline Weekly Distance (km)",
        "lbl_gender": "Gender",
        "sec_goal": "Active Goal",
        "lbl_goal_type": "Goal Type",
        "lbl_target": "Target Value",
        "lbl_unit": "Unit",
        "lbl_date": "Target Date",
        "btn_save_goal": "Set Goal",
        "goal_saved": "Goal updated!",
        "lbl_progress": "Progress",
        "lbl_total_distance": "Distance",
        "lbl_distance": "Distance",
        "lbl_avg_pace": "Avg Pace",
        "lbl_avg_hr": "Avg HR",
        "lbl_runs_count": "Runs",
        "goal_trajectory_title": "Goal Trajectory",
        "goal_status": "Status",
        "goal_progress": "Progress",
        "goal_next_milestone": "Next Milestone",
        "goal_status_ahead": "Ahead",
        "goal_status_on_track": "On Track",
        "goal_status_behind": "Behind",
        "lbl_latest_data": "Latest Data Found",
        "lbl_consistency": "Consistency",
        "lbl_metric": "Metric",
        "lbl_interpreted_delta": "Interpreted Δ",
        "performance_first_week_title": "This Week in Running",
        "performance_first_week_body": "This is your first recorded week. You’re building your performance baseline. As you log more runs, your trends will become clearer.",
        "performance_first_week_focus": "Keep logging your sessions to establish a consistent rhythm.",
        "error_insufficient_data": "*Not enough history for period comparison (8 weeks required).*",
        "goal_status_on_track": "On Track",
        "goal_status_slightly_behind": "Slightly Behind",
        "goal_status_behind": "Closing the Gap",
        "goal_type_race": "Race/Event",
        "goal_type_volume": "Weekly Volume",
        "goal_type_pace": "Target Pace",
        "unit_km": "km",
        "unit_runs": "runs",
        "unit_bpm": "bpm",
        "unit_pts": "pts",
        "unit_spkm": "s/km",
        "na": "N/A",
        "sec_structure": "Weekly Structure",
        "lbl_weekday_runs": "Weekday Runs",
        "lbl_long_run": "Long Run",
        "lbl_structure_status": "Structure Status",
        "lbl_km_remaining": "km remaining",
        "lbl_km_remaining_subtext": "{val} km",
        "coaching_advice": "Stay consistent this week to close the gap.",
        "strong_week": "Strong Week",
        "structured_but_light": "Structured but Imcomplete Volume",
        "rebuild_week": "Rebuild Week",
        "reset_week": "Reset Week",
        "status_pending": "Pending",
        "status_completed": "Completed",
        "current_week_label": "Current Week",
        "last_week_label": "Last Week",
        "lbl_snapshot_title": "Weekly Snapshot",
        "no_data_available": "*No runs logged yet this week.*",
        "home_no_goal_banner": "No active goal set. Set a goal to generate your weekly training plan.",
        "performance_card_header": "This Week in Running",
        "delta_vs_4w": "Δ vs 4W avg",
        "focus_label": "Forward Focus",
        "no_runs_message": "No runs recorded yet. Looking forward to your first activity!",
        "btn_download_card": "Download Performance Card",
        "next_run.title": "Next Recommended Run",
        "next_run.focus": "Focus",
        "next_run.session": "Suggested Session",
        "next_run.why": "Why",
        "next_run.upload_runs_prompt": "### 🏃 Next Run\n*Upload and analyze runs to see your next recommended session.*",
        "next_run.set_goal_prompt": "### 🏃 Next Run\n*Set a goal in your Profile to receive personalized training recommendations.*",
        "insights_risk_signal_heading": "Risk Signal",
        "insights_key_observations_heading": "Key Observations",
        "insights_primary_lever_heading": "Primary Lever",
        "lbl_home_week_range": "Current Week",
        "lbl_health_signal": "Health Signal",
        "lbl_goal_trajectory": "Goal Trajectory",
        "lbl_this_week": "This Week",
        "lbl_local_folder_path": "Local folder path (Server mode)",
        "btn_analyse_folder": "Analyse Folder",
        "btn_consult_coach": "Consult your Coach",
        "btn_starter_limiter": "Biggest limiter?",
        "btn_starter_why": "Why this focus?",
        "btn_starter_fatigue": "Fatigue risk?",
        "acc_knowledge_base": "Knowledge Base & Templates",
        "lbl_category": "Category",
        "lbl_template": "Template",
        "lbl_preview": "Preview",
        "btn_insert_message": "Insert into Message Box",
        "acc_adjustments": "Adjustments & Notes",
        "lbl_pace_trend": "Pace Trend Analysis",
        "lbl_hr_trend": "Heart Rate Analysis",
        "lbl_gender_male": "Male",
        "lbl_gender_female": "Female",
        "lbl_gender_pns": "Prefer not to say",
        "lbl_gender_none": "None",
        "lbl_exp_beginner": "Beginner",
        "lbl_exp_intermediate": "Intermediate",
        "lbl_exp_advanced": "Advanced",
        "lbl_focus_inline": "**Focus:**",
        "lbl_total_of": "total of",
        "lbl_more": "more",
        "lbl_less": "less",
        "lbl_faster": "faster",
        "lbl_slower": "slower",
        "lbl_that_is": "That's",
        "lbl_than_avg": "than your recent average.",
        "lbl_pace_was": "Your pace was",
        "runner_positioning_title": "Runner Positioning",
        "positioning_insufficient_data": "Insufficient data to determine positioning yet.",
        "positioning_no_data": "No training data available yet.",
        "positioning_context_title": "4-Week Context",
        "positioning_state_title": "Training State",
        "positioning_summary_title": "Summary",
        "positioning_focus_title": "Forward Focus",
        "positioning_current_state": "Training State",
        "positioning_health_signal": "Health Signal",
        "positioning_goal_trajectory": "Goal Trajectory",
        "analysis_pending": "Analysis pending...",
        "analysis_failed": "Analysis failed.",
        # Health signals
        "health_stable": "Stable",
        "health_overreaching": "Under High Load",
        "health_strain": "Strain Detected",
        # Position status
        "position_advancing": "Advancing",
        "position_stable": "Stable",
        "position_drifting": "Drifting",
        # Goal trajectory
        "trajectory_improving": "Progressing",
        "trajectory_maintaining": "Holding steady",
        "trajectory_declining": "Losing ground",
        # Focus guidance
        "focus_recovery": "Prioritize recovery and absorb recent load.",
        "focus_build": "Continue building volume gradually.",
        "focus_maintenance": "Maintain current structure and protect consistency.",
        "focus_reduce_load": "Reduce load to prevent strain.",
        # Positioning v1 Status Names
        "positioning_status_constructive_adaptation": "Constructive Adaptation",
        "positioning_status_productive_load": "Productive Load",
        "positioning_status_strain": "Compensatory Strain",
        "positioning_status_plateau": "Plateau",
        # Positioning v1 Headlines
        "positioning_headline_constructive_adaptation": "Your training is driving clear constructive adaptation.",
        "positioning_headline_productive_load": "You protected your baseline this week but did not drive new adaptation.",
        "positioning_headline_strain": "Current load is exceeding your capacity to absorb it safely.",
        "positioning_headline_plateau": "Training has stabilized after a reduction in volume and frequency. Intensity may now be insufficient to stimulate further adaptation.",
        # Rationales
        "positioning_rationale_constructive_adaptation": "Load is increasing while maintaining consistency.",
        "positioning_rationale_productive_load": "Maintaining load and protecting baseline.",
        "positioning_rationale_strain": "Load increase is outpacing cardiovascular adaptation.",
        "positioning_rationale_plateau": "Training has stabilized.",
        # Forward Focus
        "positioning_forward_focus_constructive_adaptation": "Maintain recent volume and allow adaptation to solidify.",
        "positioning_forward_focus_productive_load": "Reinforce frequency consistency this week.",
        "positioning_forward_focus_strain": "Prioritize active recovery and reduce non-essential session load.",
        "positioning_forward_focus_plateau": "Introduce localized intensity spikes to challenge the baseline.",
        "positioning_status_baseline": "Baseline Building",
        "positioning_headline_baseline": "Your training baseline is being established.",
        "positioning_rationale_baseline": "Initial week(s) of training detected. Collecting data to establish trends.",
        "positioning_forward_focus_baseline": "Establish consistent easy runs this week.",
        "positioning_trajectory_baseline": "Not enough history yet to assess training trends.",
        "trajectory_no_goal": "No active goal",
        "trajectory_establishing": "Establishing baseline",
        # Trajectory
        "positioning_trajectory_building": "Building: If this pattern continues, you are on track to exceed recent benchmarks.",
        "positioning_trajectory_stable": "Stable: You are maintaining your level, ideal for long-term health.",
        "positioning_trajectory_fatigue": "Fatigue Risk: If this pattern continues, performance may decline without recovery.",
        "positioning_trajectory_plateau": "Training load has stabilized and adaptation appears to have plateaued.",
        # Phases
        "positioning_phase_title": "Training Phase",
        "positioning_phase_base": "Base Phase",
        "positioning_phase_build": "Build Phase",
        "positioning_phase_peak": "Peak Phase",
        "positioning_phase_recovery": "Recovery Phase",
        "positioning_phase_plateau": "Plateau Phase",
        # Evidence
        "positioning_evidence_title": "Evidence Breakdown",
        "positioning_evidence_distance": "Distance",
        "positioning_evidence_hr": "HR variance",
        "positioning_evidence_frequency": "Frequency",
        "positioning_evidence_consistency": "Consistency",
        "positioning_not_enough_history": "Not enough training history to determine positioning yet.",
        "positioning_evidence_pace_improved": "Pace improved",
        "positioning_evidence_pace_worsened": "Pace worsened",
        # Training Recommendations
        "rec_title": "🎯 Training Recommendation",
        "rec_lbl_focus": "**Focus:**",
        "rec_lbl_session": "**Suggested Session:**",
        "rec_lbl_explanation": "**Explanation:**",
        "rec_focus_protect_recovery": "Protect Recovery",
        "rec_focus_build_endurance": "Build Endurance",
        "rec_focus_introduce_intensity": "Introduce Intensity",
        "rec_focus_maintain_consistency": "Maintain Consistency",
        "rec_session_easy_run": "Easy Recovery Run",
        "rec_session_long_run": "Aerobic Long Run",
        "rec_session_tempo_intervals": "Tempo Intervals",
        "rec_session_steady_run": "20-minute easy run",
        "rec_desc_protect_recovery": "Your indicators suggest accumulated fatigue. Prioritize low-intensity movement to allow cardiovascular and structural recovery.",
        "rec_desc_build_endurance": "Stability in your recent markers shows you are ready to expand your aerobic base. Focus on extending duration at a comfortable effort.",
        "rec_desc_introduce_intensity": "Your capacity for adaptation is high right now. Introducing controlled intensity will help break through current performance plateaus.",
        "rec_desc_maintain_consistency": "Focus on protecting your current training rhythm. Consistency is your most powerful lever right now.",
    },
    "pt-BR": {
        "welcome": "Bem-vindo ao Runner Intelligence. Envie sua primeira corrida e o sistema começará a construir sua base de treinamento e gerar insights.",
        "title": "# 🏃 Runner Inteligência Agêntica (Experimental)",
        "subtitle": '<span class="muted">Treinamento personalizado a partir dos seus dados.</span>',
        "workflow": '<span class="muted"><b>Fluxo:</b> Enviar corridas ➔ Ver Insights ➔ Plano Semanal ➔ Chat com Treinador</span><br/><span class="muted"><i>Formatos: .fit, .fit.gz, .tcx, .tcx.gz, .gpx (max 50MB)</i></span><br/><span class="muted">Feedback: <a href="https://github.com/ideas-to-life/runner-agentic-intelligence/issues" target="_blank">GitHub Issues</a></span>',
        "evolution_workflow": '<span class="muted">Acompanhe sua evolução. Revise seu check-in semanal e progresso vs mês passado.</span><br/><span class="muted">Envie novas corridas a qualquer momento — seu painel será atualizado automaticamente.</span><br/><span class="muted">Feedback: <a href="https://github.com/ideas-to-life/runner-agentic-intelligence/issues" target="_blank">GitHub Issues</a></span>',
        "tab_analyse": "Analisar",
        "tab_results": "Resultados",
        "tab_coach": "Treinador",
        "tab_home": "Início",
        "tab_intelligence": "Inteligência",
        "tab_positioning": "Posicionamento",
        "lbl_your_week": "Sua Semana",
        "lbl_coach_brief": "Resumo do Treinador",
        "lbl_parsed": "Processadas",
        "unit_weeks": "semanas",
        "lbl_across": "ao longo de",
        "lbl_current": "Atual",
        "lbl_previous": "Passada",
        "lbl_distance": "Distância",
        "lbl_runs": "Corridas",
        "lbl_avg_pace": "Ritmo Médio",
        "lbl_consistency": "Consistência",
        "goal_status_template": "Sua meta está **{val}**.",
        "home_story_template": "Você correu **{count}** {unit} esta semana, em um {of} **{dist:.1f} km**.",
        "lbl_current_state": "Estado Atual",
        "lbl_key_insight": "Insight Principal",
        "lbl_forward_focus": "Foco da Semana",
        "lbl_details": "Detalhes",
        "sec_evolution": "📈 Progresso vs Mês Passado",
        "sec_checkin": "Check-In Semanal",
        "lbl_goal_traj_inline": "**🎯 Trajetória:**",
        "lbl_focus_inline": "**🎯 Foco:**",
        "sec_snapshot": "Snapshot da Semana Atual",
        "sec_upload": "🗂️ Envie seus dados de treino",
        "upload_hints": '<div class="muted" style="margin-bottom: 12px; font-size: 0.9rem;"><ul><li>Melhores resultados: envie 4–12 corridas recentes (ou ~2–6 semanas).</li><li>Inclua dados de FC se tiver (ajuda com sinais de fadiga/risco).</li><li>Depois clique em ‘Analisar Dados’ para gerar Resultados e contexto.</li></ul></div>',
        "upload_label": "Arraste e solte ou clique para enviar",
        "btn_analyse": "🚀 Analisar Dados",
        "btn_reset": "Reiniciar",
        "sec_insights": "Insights do Treinador",
        "lbl_risk": "Avaliação de Risco/Segurança",
        "lbl_lever": "Alavanca Principal",
        "sec_plan": "Plano de Treino Semanal",
        "sec_charts": "Tendências e Análises",
        "sec_chat": "Pergunte sobre seu treino",
        "chat_indicator_no": "⚠️ *Envie e analise corridas para habilitar o contexto do chat.*",
        "chat_indicator_yes": "✅ *Contexto do chat habilitado.*",
        "chat_tip": "Dica: tente ‘Plotar meu ritmo’ ou ‘Mostrar gráfico de FC’ para visualizar seus dados.",
        "chat_placeholder": "ex: Como foi meu ritmo semana passada?",
        "btn_send": "Enviar",
        "btn_clear": "Limpar Histórico",
        "lang_label": "Language / Idioma",
        "starter_limiter": "Maior limitador?",
        "starter_why": "Por que este foco?",
        "starter_fatigue": "Risco de fadiga?",
        "starter_keep": "O que manter?",
        "chat_starter_limiter": "Qual é o meu maior limitador de treino?",
        "chat_starter_why": "Por que você sugeriu este foco de treinamento?",
        "chat_starter_fatigue": "Você vê algum sinal de excesso de treino ou fadiga?",
        "chat_starter_keep": "Quais aspectos do meu treino devo continuar fazendo?",
        "analyse_progress": "Análise dos dados de treino em andamento...",
        "insights_primary_lever_heading": "Alavanca Principal",
        "insights_risk_signal_heading": "Sinal de Risco",
        "insights_key_observations_heading": "Observações Principais",
        "insights_evidence_label": "Evidências",
        "insights_constraint_label": "Restrição",
        "insights_no_primary_lever": "Nenhuma alavanca principal identificada.",
        "insights_no_risk": "Nenhum risco elevado detectado.",
        "insights_no_observations": "*Nenhuma observação fornecida.*",
        "insights_analysis_failed": "*Falha na Análise*",
        "insights_analysis_pending": "*Análise pendente...*",
        "insights_raw_default": "Os insights brutos aparecerão aqui.",
        "plan_week_summary_label": "Resumo da semana:",
        "plan_focus_label": "Foco desta semana:",
        "plan_pending": "*O plano aparecerá aqui após a análise.*",
        "progress_extracting": "Extraindo características dos dados de corrida...",
        "progress_generating": "Gerando insights e plano de treinamento...",
        "pipeline_stage_1": "🏃 Enviando corridas",
        "pipeline_stage_2": "📊 Construindo snapshot semanal",
        "pipeline_stage_3": "📈 Analisando tendências de treino",
        "pipeline_stage_4": "🧠 Gerando insights do treinador",
        "pipeline_stage_5": "📋 Preparando recomendação de treino",
        "chat_context_indicator": "🧠 **Usando seus insights de treinamento como contexto**",
        "error_no_runs": "Nenhuma corrida para processar.",
        "lbl_details": "Detalhes (Risco e Observações)",
        "banner_title": "⚠️ Informações do Public Preview",
        "banner_session": "**Dados da Sessão**: Todos os dados enviados e histórico de chat são temporários e apagados após a sessão.",
        "banner_persistence_disabled": "🟡 **Modo Public Preview** — Nenhum dado é persistido. Todos os envios e métricas derivadas são temporários.",
        "banner_persistence_enabled": "🟢 **Persistência de Histórico Ativada** — Snapshots semanais e tendências são armazenados localmente.",
        "banner_medical": "**Aviso Médico**: Este sistema fornece insights de treinamento, NÃO aconselhamento médico. Consulte um profissional antes de iniciar qualquer plano de treino.",
        "banner_full": "**Experiência Completa**: Para persistência total e armazenamento local, execute o app localmente a partir do [GitHub](https://github.com/avfranco/runner-agentic-intelligence).",
        "insights_timestamp_label": "Insights gerados em",
        "risk_level_low": "BAIXO",
        "risk_level_medium": "MÉDIO",
        "risk_level_high": "ALTO",
        "chat_error": "Desculpe, estou com problemas para processar seu pedido agora.",
        "plan_error": "Não foi possível gerar o plano neste momento.",
        "tab_profile": "Perfil",
        "sec_profile": "## Perfil do Corredor (Gêmeo Digital v1)",
        "lbl_display_name": "Nome de Exibição",
        "lbl_age": "Idade",
        "lbl_experience": "Nível de Experiência",
        "lbl_injury_notes": "Histórico de Lesões / Notas",
        "btn_save_profile": "Salvar Perfil",
        "profile_saved": "Perfil salvo com sucesso!",
        "profile_save_error": "Erro ao salvar perfil.",
        "lbl_baseline": "Distância Semanal Base (km)",
        "lbl_gender": "Gênero",
        "sec_goal": "Objetivo Atual",
        "lbl_goal_type": "Tipo de Objetivo",
        "lbl_target": "Valor Alvo",
        "lbl_unit": "Unidade",
        "lbl_date": "Data Alvo",
        "btn_save_goal": "Definir Objetivo",
        "goal_saved": "Objetivo atualizado!",
        "lbl_progress": "Progresso",
        "lbl_total_distance": "Distância",
        "lbl_distance": "Distância",
        "lbl_avg_pace": "Ritmo Médio",
        "lbl_avg_hr": "FC Média",
        "lbl_runs_count": "Corridas",
        "goal_trajectory_title": "Trajetória da Meta",
        "goal_status": "Status",
        "goal_progress": "Progresso",
        "goal_next_milestone": "Próximo Marco",
        "goal_status_ahead": "Adiantado",
        "goal_status_on_track": "No Caminho",
        "goal_status_behind": "Atrasado",
        "lbl_latest_data": "Últimos Dados Encontrados",
        "lbl_consistency": "Consistência",
        "lbl_metric": "Métrica",
        "lbl_interpreted_delta": "Δ Interpretado",
        "performance_first_week_title": "Esta Semana nas Corridas",
        "performance_first_week_body": "Esta é a sua primeira semana registrada. Você está construindo sua base de performance. Conforme você registrar mais corridas, suas tendências ficarão mais claras.",
        "performance_first_week_focus": "Continue registrando suas sessões para estabelecer um ritmo consistente.",
        "error_insufficient_data": "*Histórico insuficiente para comparação (8 semanas necessárias).*",
        "goal_status_on_track": "No Caminho",
        "goal_status_slightly_behind": "Um Pouco Abaixo",
        "goal_status_behind": "Em Progresso para a Meta",
        "goal_type_race": "Prova/Evento",
        "goal_type_volume": "Volume Semanal",
        "goal_type_pace": "Ritmo Alvo",
        "unit_km": "km",
        "unit_runs": "corridas",
        "unit_bpm": "bpm",
        "unit_pts": "pts",
        "unit_spkm": "s/km",
        "na": "N/A",
        "sec_structure": "Estrutura Semanal",
        "lbl_weekday_runs": "Corridas Semanais",
        "lbl_long_run": "Longão",
        "lbl_structure_status": "Status da Estrutura",
        "lbl_km_remaining": "km restantes",
        "lbl_km_remaining_subtext": "{val} km",
        "coaching_advice": "Mantenha a consistência esta semana para fechar a meta.",
        "strong_week": "Semana Forte",
        "structured_but_light": "Estruturada, mas Leve",
        "rebuild_week": "Reconstrução",
        "reset_week": "Recuperação/Reset",
        "status_pending": "Pendente",
        "status_completed": "Concluído",
        "current_week_label": "Semana Atual",
        "last_week_label": "Semana Passada",
        "lbl_snapshot_title": "Snapshot da Semana Atual",
        "no_data_available": "*Nenhuma corrida registrada esta semana ainda.*",
        "home_no_goal_banner": "Nenhum objetivo ativo definido. Defina um objetivo para gerar seu plano de treino semanal.",
        "performance_card_header": "Esta Semana nas Corridas",
        "delta_vs_4w": "Δ vs méd. 4s",
        "focus_label": "Foco à Frente",
        "no_runs_message": "Nenhuma corrida registrada ainda. No aguardo da sua primeira atividade!",
        "btn_download_card": "Baixar Card de Performance",
        "next_run.title": "Próxima Corrida Recomendada",
        "next_run.focus": "Foco",
        "next_run.session": "Sessão Sugerida",
        "next_run.why": "Por quê",
        "next_run.upload_runs_prompt": "### 🏃 Próxima Corrida\n*Envie e analise suas corridas para ver sua próxima sessão recomendada.*",
        "next_run.set_goal_prompt": "### 🏃 Próxima Corrida\n*Defina um objetivo no seu Perfil para receber recomendações de treino personalizadas.*",
        "insights_risk_signal_heading": "Sinal de Risco",
        "insights_key_observations_heading": "Observações Principais",
        "insights_primary_lever_heading": "Alavanca Principal",
        "lbl_home_week_range": "Semana Atual",
        "lbl_health_signal": "Sinal de Saúde",
        "lbl_goal_trajectory": "Trajetória da Meta",
        "lbl_this_week": "Esta Semana",
        "lbl_local_folder_path": "Caminho da pasta local (Modo servidor)",
        "btn_analyse_folder": "Analisar Pasta",
        "btn_consult_coach": "Consultar seu Treinador",
        "btn_starter_limiter": "Maior limitador?",
        "btn_starter_why": "Por que este foco?",
        "btn_starter_fatigue": "Risco de fadiga?",
        "acc_knowledge_base": "Base de Conhecimento e Modelos",
        "lbl_category": "Categoria",
        "lbl_template": "Modelo",
        "lbl_preview": "Pré-visualização",
        "btn_insert_message": "Inserir na Caixa de Mensagem",
        "acc_adjustments": "Ajustes e Notas",
        "lbl_pace_trend": "Análise de Tendência de Ritmo",
        "lbl_hr_trend": "Análise de Frequência Cardíaca",
        "lbl_gender_male": "Masculino",
        "lbl_gender_female": "Feminino",
        "lbl_gender_pns": "Prefiro não dizer",
        "lbl_gender_none": "Nenhum",
        "lbl_exp_beginner": "Iniciante",
        "lbl_exp_intermediate": "Intermediário",
        "lbl_exp_advanced": "Avançado",
        "lbl_focus_inline": "**Foco:**",
        "lbl_total_of": "total de",
        "lbl_more": "mais",
        "lbl_less": "menos",
        "lbl_faster": "mais rápido",
        "lbl_slower": "mais lento",
        "lbl_that_is": "Isso é",
        "lbl_than_avg": "que sua média recente.",
        "lbl_pace_was": "Seu ritmo foi",
        "runner_positioning_title": "Posicionamento do Corredor",
        "positioning_insufficient_data": "Dados insuficientes para determinar o posicionamento ainda.",
        "positioning_no_data": "Nenhum dado de treino disponível ainda.",
        "positioning_context_title": "Contexto de 4 Semanas",
        "positioning_state_title": "Estado do Treino",
        "positioning_summary_title": "Resumo",
        "positioning_focus_title": "Foco Recomendado",
        "positioning_current_state": "Estado do Treino",
        "positioning_health_signal": "Sinal de Saúde",
        "positioning_goal_trajectory": "Trajetória do Objetivo",
        "positioning_trajectory": "Trajetória",
        "positioning_insights": "Insights",
        "analysis_pending": "Análise pendente...",
        "analysis_failed": "Falha na análise.",
        # Health signals
        "health_stable": "Estável",
        "health_overreaching": "Carga Elevada",
        "health_strain": "Sinais de Sobrecarga",
        # Position status
        "position_advancing": "Avançando",
        "position_stable": "Estável",
        "position_drifting": "Perdendo Ritmo",
        # Goal trajectory
        "trajectory_improving": "Progredindo",
        "trajectory_maintaining": "Mantendo",
        "trajectory_declining": "Regredindo",
        # Focus guidance
        "focus_recovery": "Priorize a recuperação e absorva a carga recente.",
        "focus_build": "Continue aumentando o volume gradualmente.",
        "focus_maintenance": "Mantenha a estrutura atual e proteja a consistência.",
        "focus_reduce_load": "Reduza a carga para evitar sobrecarga.",
        # Positioning v1 Status Names
        "positioning_status_constructive_adaptation": "Adaptação Construtiva",
        "positioning_status_productive_load": "Carga Produtiva",
        "positioning_status_strain": "Sobrecarga Compensatória",
        "positioning_status_plateau": "Platô",
        # Positioning v1 Headlines
        "positioning_headline_constructive_adaptation": "Seu treino está gerando uma adaptação construtiva clara.",
        "positioning_headline_productive_load": "Você protegeu sua base esta semana, mas não gerou nova adaptação.",
        "positioning_headline_strain": "A carga atual está excedendo sua capacidade de absorção segura.",
        "positioning_headline_plateau": "O treino estabilizou, mas a intensidade pode ser insuficiente para evolução.",
        # Rationales
        "positioning_rationale_constructive_adaptation": "A carga está aumentando enquanto a consistência se mantém.",
        "positioning_rationale_productive_load": "Mantendo a carga e protegendo a base.",
        "positioning_rationale_strain": "O aumento da carga está superando a adaptação cardiovascular.",
        "positioning_rationale_plateau": "O treinamento estabilizou.",
        # Forward Focus
        "positioning_forward_focus_constructive_adaptation": "Mantenha o volume recente e permita que a adaptação se consolide.",
        "positioning_forward_focus_productive_load": "Reforce a consistência de frequência esta semana.",
        "positioning_forward_focus_strain": "Priorize a recuperação ativa e reduza a carga de sessões não essenciais.",
        "positioning_forward_focus_plateau": "Introduza picos de intensidade localizados para desafiar sua base.",
        "positioning_status_baseline": "Construindo Base",
        "positioning_headline_baseline": "Sua base de treinamento está sendo estabelecida.",
        "positioning_rationale_baseline": "Semana(s) inicial(is) detectada(s). Coletando dados para estabelecer tendências.",
        "positioning_forward_focus_baseline": "Estabeleça corridas leves consistentes esta semana.",
        "positioning_trajectory_baseline": "Histórico insuficiente para avaliar tendências de treino.",
        "trajectory_no_goal": "Sem objetivo ativo",
        "trajectory_establishing": "Estabelecendo base",
        # Trajectory
        "positioning_trajectory_building": "Construção: Se este padrão continuar, você está no caminho para superar marcas recentes.",
        "positioning_trajectory_stable": "Estável: Você está mantendo seu nível, ideal para a saúde de longo prazo.",
        "positioning_trajectory_fatigue": "Risco de Fadiga: Se este padrão continuar, a performance pode cair sem recuperação.",
        "positioning_trajectory_plateau": "A carga de treino estabilizou e a adaptação parece ter atingido um platô.",
        # Phases
        "positioning_phase_title": "Fase de Treino",
        "positioning_phase_base": "Fase de Base",
        "positioning_phase_build": "Fase de Construção",
        "positioning_phase_peak": "Fase de Pico",
        "positioning_phase_recovery": "Fase de Recuperação",
        "positioning_phase_plateau": "Fase de Platô",
        # Evidence
        "positioning_evidence_title": "Detalhamento de Evidências",
        "positioning_evidence_distance": "Distância",
        "positioning_evidence_hr": "Variância de FC",
        "positioning_evidence_frequency": "Frequência",
        "positioning_evidence_consistency": "Consistência",
        "positioning_not_enough_history": "Histórico de treino insuficiente para determinar o posicionamento ainda.",
        "positioning_evidence_pace_improved": "Pace melhorou",
        "positioning_evidence_pace_worsened": "Pace piorou",
        # Training Recommendations
        "rec_title": "🎯 Recomendação de Treino",
        "rec_lbl_focus": "**Foco:**",
        "rec_lbl_session": "**Sessão Sugerida:**",
        "rec_lbl_explanation": "**Explicação:**",
        "rec_focus_protect_recovery": "Proteger Recuperação",
        "rec_focus_build_endurance": "Construir Resistência",
        "rec_focus_introduce_intensity": "Introduzir Intensidade",
        "rec_focus_maintain_consistency": "Manter Consistência",
        "rec_session_easy_run": "Corrida de Recuperação Leve",
        "rec_session_long_run": "Longão Aeróbico",
        "rec_session_tempo_intervals": "Intervalado de Tempo",
        "rec_session_steady_run": "Corrida Leve de 20 minutos",
        "rec_desc_protect_recovery": "Seus indicadores sugerem fadiga acumulada. Priorize movimentos de baixa intensidade para permitir a recuperação cardiovascular e estrutural.",
        "rec_desc_build_endurance": "A estabilidade nos seus marcadores recentes mostra que você está pronto para expandir sua base aeróbica. Foque em estender a duração em um esforço confortável.",
        "rec_desc_introduce_intensity": "Sua capacidade de adaptação está alta agora. Introduzir intensidade controlada ajudará a superar os patamares atuais de performance.",
        "rec_desc_maintain_consistency": "Foque em proteger seu ritmo de treino atual. A consistência é sua alavanca mais poderosa agora.",
    },
}

def get_text(key: str, language: str = "en") -> str:
    """Retrieves localized text for a given key and language."""
    lang_batch = UI_TEXT.get(language, UI_TEXT["en"])
    return lang_batch.get(key, UI_TEXT["en"].get(key, key))