Raí Santos commited on
Commit
8a34622
·
1 Parent(s): 47fa0d6
Files changed (5) hide show
  1. README.md +21 -1
  2. public/app.js +93 -17
  3. public/styles.css +107 -37
  4. public/sw.js +12 -3
  5. scripts/download-videos.js +8 -0
README.md CHANGED
@@ -171,7 +171,27 @@ MIT License - Veja o arquivo LICENSE para mais detalhes.
171
 
172
  ## 🐛 Correções Recentes
173
 
174
- ### v3.10.0 (Atual) - PREMIUM OPTIMIZATION + BUG FIXES 🎥⚡💎🐛
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
175
  ✅ **3 Critical Bugs Fixed**: Memory leaks resolvidos (94% reduction)
176
  ✅ **Local Videos**: Vídeos baixados durante build (31 MB) para performance máxima
177
  ✅ **Smart Fallback**: Se local falhar, usa CDN automaticamente
 
171
 
172
  ## 🐛 Correções Recentes
173
 
174
+ ### v3.10.2 (Atual) - SESSION LOGIC + AUTO-UPDATE 🎯🔄✨
175
+ ✅ **Thematic Sections**: 5 organized sessions (Abdômen, Massagem Facial, Cintura, Pernas, Postura/Mobilidade)
176
+ ✅ **Session Isolation**: Skip stays within session only
177
+ ✅ **Green Marking**: Completed sessions marked ✅ automatically
178
+ ✅ **Auto-Return**: Returns to personalized view after completion
179
+ ✅ **PWA Auto-Update**: skipWaiting + clients.claim (zero user action)
180
+ ✅ **Rounded Header**: Beautiful workout header with shadow
181
+ ✅ **20 Reps Update**: 3 key exercises updated to 20 reps × 3 sets
182
+ ✅ **Bug Fixes**: 4 bugs found and fixed
183
+ ✅ **Performance**: 60fps, 56.5KB bundle, 0 memory leaks
184
+
185
+ ### v3.10.1 - NEW EXERCISES + PREMIUM UI 🆕💎✨
186
+ ✅ **6 Novos Exercícios**: Mobilidade/Alongamento adicionados
187
+ ✅ **Play Button Removed**: Vídeos auto-play (experiência seamless)
188
+ ✅ **Premium Exercise Screen**: Glass morphism + gradient text
189
+ ✅ **Seção Costas/Mobilidade**: 7 exercícios (30 reps × 6 sets)
190
+ ✅ **Gasto Calórico**: 9-15 cal por exercício novo
191
+ ✅ **Download Script**: 6 novos vídeos incluídos
192
+ ✅ **UI Refinements**: Floating effects + animations premium
193
+
194
+ ### v3.10.0 - PREMIUM OPTIMIZATION + BUG FIXES 🎥⚡💎🐛
195
  ✅ **3 Critical Bugs Fixed**: Memory leaks resolvidos (94% reduction)
196
  ✅ **Local Videos**: Vídeos baixados durante build (31 MB) para performance máxima
197
  ✅ **Smart Fallback**: Se local falhar, usa CDN automaticamente
public/app.js CHANGED
@@ -1540,6 +1540,11 @@ class FitnessApp {
1540
  e.stopPropagation();
1541
  document.getElementById('completionModal').classList.remove('active');
1542
  this.playCuteSound('tap');
 
 
 
 
 
1543
  // Volta para a lista de exercícios, não para home
1544
  if (this.currentCategory) {
1545
  this.goBack();
@@ -1691,11 +1696,11 @@ class FitnessApp {
1691
  // If personalized, organize by sections
1692
  if (category === 'personalized') {
1693
  const sections = {
1694
- 'Abdômen': exercises.slice(0, 5),
1695
- 'Rosto': exercises.slice(5, 9),
1696
- 'Cintura': exercises.slice(9, 12),
1697
- 'Pernas': exercises.slice(12, 13),
1698
- 'Costas/Flexibilidade': exercises.slice(13, 14)
1699
  };
1700
 
1701
  // Store sections info for workout management
@@ -1709,6 +1714,15 @@ class FitnessApp {
1709
  // Add section header
1710
  const sectionHeader = document.createElement('div');
1711
  sectionHeader.className = 'section-header';
 
 
 
 
 
 
 
 
 
1712
  sectionHeader.innerHTML = `<h3>${sectionName}</h3>`;
1713
  fragment.appendChild(sectionHeader); // Add to fragment
1714
 
@@ -2220,12 +2234,31 @@ class FitnessApp {
2220
  });
2221
  });
2222
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2223
  // Update streak
2224
  this.updateStreak();
2225
 
2226
  this.saveProgress();
2227
 
2228
- // 🔥 FIX: Atualiza todos os stats após completar treino
2229
  this.updateAllStats();
2230
 
2231
  // Play completion sounds
@@ -2260,6 +2293,15 @@ class FitnessApp {
2260
 
2261
  document.getElementById('completionModal').classList.add('active');
2262
 
 
 
 
 
 
 
 
 
 
2263
  // Check for achievements
2264
  this.checkAchievements();
2265
 
@@ -3524,10 +3566,10 @@ class FitnessApp {
3524
  const exercises = {
3525
  personalized: [
3526
  // 🔥 Abdômen com vídeos do Hugging Face
3527
- { name: 'Prancha com Balanço Lateral', emoji: '🔥', video: this.VIDEO_BASE_URL + 'Prancha%20com%20balan%C3%A7o%20lateral.mp4', sets: 3, reps: '10', rest: 30, calories: 8 },
3528
- { name: 'Prancha com Elevação de Perna', emoji: '🔥', video: this.VIDEO_BASE_URL + 'Prancha%20com%20eleva%C3%A7%C3%A3o%20de%20perna.mp4', sets: 3, reps: '12', rest: 30, calories: 10 },
3529
  { name: 'Tesoura (Scissor Kicks)', emoji: '✂️', video: this.VIDEO_BASE_URL + 'Scissor%20Kicks.mp4', sets: 3, reps: '15', rest: 30, calories: 9 },
3530
- { name: 'Elevação Alternada de Pernas', emoji: '🦵', video: this.VIDEO_BASE_URL + 'Alternating%20Leg%20Lifts.mp4', sets: 3, reps: '12', rest: 30, calories: 8 },
3531
  { name: 'Prancha Lateral com Rotação', emoji: '🔄', video: this.VIDEO_BASE_URL + 'prancha%20lateral%20com%20rota%C3%A7%C3%A3o.mp4', sets: 3, reps: '10 cada', rest: 30, calories: 10 },
3532
 
3533
  // 😊 Rosto com vídeos do Hugging Face
@@ -3544,14 +3586,20 @@ class FitnessApp {
3544
  // 🏋️‍♀️ Pernas/Glúteos com vídeo do Hugging Face
3545
  { name: 'Agachamento com Rotação', emoji: '🏋️‍♀️', video: this.VIDEO_BASE_URL + 'agachamento%20rota%C3%A7%C3%A3o.mp4', sets: 3, reps: '12', rest: 35, calories: 12 },
3546
 
3547
- // 🧘‍♀️ Costas/Flexibilidade com vídeo do Hugging Face
3548
- { name: 'Flexão e Extensão do Tronco', emoji: '🧘‍♀️', video: this.VIDEO_BASE_URL + 'flexao%2C%20extens%C3%A3o%20e%20hiperextenxao%20do%20tronco%20com%20baco%20estendido.mp4', sets: 3, reps: '10', rest: 30, calories: 8 }
 
 
 
 
 
 
3549
  ],
3550
  abs: [
3551
- { name: 'Prancha com Balanço Lateral', emoji: '🔥', video: this.VIDEO_BASE_URL + 'Prancha%20com%20balan%C3%A7o%20lateral.mp4', sets: 3, reps: '10', rest: 30, calories: 8 },
3552
- { name: 'Prancha com Elevação de Perna', emoji: '🔥', video: this.VIDEO_BASE_URL + 'Prancha%20com%20eleva%C3%A7%C3%A3o%20de%20perna.mp4', sets: 3, reps: '12', rest: 30, calories: 10 },
3553
  { name: 'Tesoura (Scissor Kicks)', emoji: '✂️', video: this.VIDEO_BASE_URL + 'Scissor%20Kicks.mp4', sets: 3, reps: '15', rest: 30, calories: 9 },
3554
- { name: 'Elevação Alternada de Pernas', emoji: '🦵', video: this.VIDEO_BASE_URL + 'Alternating%20Leg%20Lifts.mp4', sets: 3, reps: '12', rest: 30, calories: 8 },
3555
  { name: 'Prancha Lateral com Rotação', emoji: '🔄', video: this.VIDEO_BASE_URL + 'prancha%20lateral%20com%20rota%C3%A7%C3%A3o.mp4', sets: 3, reps: '10 cada', rest: 30, calories: 10 }
3556
  ],
3557
  legs: [
@@ -3691,11 +3739,39 @@ class FitnessApp {
3691
  document.addEventListener('DOMContentLoaded', () => {
3692
  window.app = new FitnessApp();
3693
 
3694
- // Register Service Worker for PWA and caching
3695
  if ('serviceWorker' in navigator) {
3696
  navigator.serviceWorker.register('/sw.js')
3697
- .then(reg => console.log('Service Worker registered:', reg.scope))
3698
- .catch(err => console.error('Service Worker registration failed:', err));
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3699
  }
3700
  });
3701
 
 
1540
  e.stopPropagation();
1541
  document.getElementById('completionModal').classList.remove('active');
1542
  this.playCuteSound('tap');
1543
+ // 🎯 Return to personalized view if completing a session
1544
+ if (this.currentSectionName && this.currentCategory === 'personalized') {
1545
+ this.showCategoryExercises('personalized');
1546
+ return;
1547
+ }
1548
  // Volta para a lista de exercícios, não para home
1549
  if (this.currentCategory) {
1550
  this.goBack();
 
1696
  // If personalized, organize by sections
1697
  if (category === 'personalized') {
1698
  const sections = {
1699
+ 'Abdômen': exercises.slice(0, 5), // 5 exercícios
1700
+ 'Massagem Facial': exercises.slice(5, 9), // 4 exercícios
1701
+ 'Cintura': exercises.slice(9, 12), // 3 exercícios
1702
+ 'Pernas': exercises.slice(12, 13), // 1 exercício
1703
+ 'Postura e Mobilidade': exercises.slice(13, 20) // 7 exercícios (yoga/alongamento)
1704
  };
1705
 
1706
  // Store sections info for workout management
 
1714
  // Add section header
1715
  const sectionHeader = document.createElement('div');
1716
  sectionHeader.className = 'section-header';
1717
+
1718
+ // ✅ Mark as completed if done today
1719
+ const today = new Date().toDateString();
1720
+ if (this.progress.completedSections &&
1721
+ this.progress.completedSections[today] &&
1722
+ this.progress.completedSections[today].includes(sectionName)) {
1723
+ sectionHeader.classList.add('completed');
1724
+ }
1725
+
1726
  sectionHeader.innerHTML = `<h3>${sectionName}</h3>`;
1727
  fragment.appendChild(sectionHeader); // Add to fragment
1728
 
 
2234
  });
2235
  });
2236
 
2237
+ // Track completed sections for green marking
2238
+ if (this.currentSectionName && this.currentCategory === 'personalized') {
2239
+ if (!this.progress.completedSections) {
2240
+ this.progress.completedSections = {};
2241
+ }
2242
+ const today = new Date().toDateString();
2243
+ if (!this.progress.completedSections[today]) {
2244
+ this.progress.completedSections[today] = [];
2245
+ }
2246
+ if (!this.progress.completedSections[today].includes(this.currentSectionName)) {
2247
+ this.progress.completedSections[today].push(this.currentSectionName);
2248
+ }
2249
+ }
2250
+
2251
+ // Keep only last 50 exercises (cleanup old data)
2252
+ if (this.progress.completedExercises.length > 50) {
2253
+ this.progress.completedExercises = this.progress.completedExercises.slice(-50);
2254
+ }
2255
+
2256
  // Update streak
2257
  this.updateStreak();
2258
 
2259
  this.saveProgress();
2260
 
2261
+ // FIX: Atualiza todos os stats após completar treino
2262
  this.updateAllStats();
2263
 
2264
  // Play completion sounds
 
2293
 
2294
  document.getElementById('completionModal').classList.add('active');
2295
 
2296
+ // 🎯 AUTO-CLOSE: Close modal and return to personalized sections after 3 seconds
2297
+ if (this.currentSectionName && this.currentCategory === 'personalized') {
2298
+ setTimeout(() => {
2299
+ document.getElementById('completionModal').classList.remove('active');
2300
+ // Return to personalized view to choose next session
2301
+ this.showCategoryExercises('personalized');
2302
+ }, 3000);
2303
+ }
2304
+
2305
  // Check for achievements
2306
  this.checkAchievements();
2307
 
 
3566
  const exercises = {
3567
  personalized: [
3568
  // 🔥 Abdômen com vídeos do Hugging Face
3569
+ { name: 'Prancha com Balanço Lateral', emoji: '🔥', video: this.VIDEO_BASE_URL + 'Prancha%20com%20balan%C3%A7o%20lateral.mp4', sets: 3, reps: '20', rest: 30, calories: 10 },
3570
+ { name: 'Prancha com Elevação de Perna', emoji: '🔥', video: this.VIDEO_BASE_URL + 'Prancha%20com%20eleva%C3%A7%C3%A3o%20de%20perna.mp4', sets: 3, reps: '20', rest: 30, calories: 12 },
3571
  { name: 'Tesoura (Scissor Kicks)', emoji: '✂️', video: this.VIDEO_BASE_URL + 'Scissor%20Kicks.mp4', sets: 3, reps: '15', rest: 30, calories: 9 },
3572
+ { name: 'Elevação Alternada de Pernas', emoji: '🦵', video: this.VIDEO_BASE_URL + 'Alternating%20Leg%20Lifts.mp4', sets: 3, reps: '20', rest: 30, calories: 10 },
3573
  { name: 'Prancha Lateral com Rotação', emoji: '🔄', video: this.VIDEO_BASE_URL + 'prancha%20lateral%20com%20rota%C3%A7%C3%A3o.mp4', sets: 3, reps: '10 cada', rest: 30, calories: 10 },
3574
 
3575
  // 😊 Rosto com vídeos do Hugging Face
 
3586
  // 🏋️‍♀️ Pernas/Glúteos com vídeo do Hugging Face
3587
  { name: 'Agachamento com Rotação', emoji: '🏋️‍♀️', video: this.VIDEO_BASE_URL + 'agachamento%20rota%C3%A7%C3%A3o.mp4', sets: 3, reps: '12', rest: 35, calories: 12 },
3588
 
3589
+ // 🧘‍♀️ Costas/Mobilidade/Flexibilidade com vídeos do Hugging Face
3590
+ { name: 'Flexão e Extensão do Tronco', emoji: '🧘‍♀️', video: this.VIDEO_BASE_URL + 'flexao%2C%20extens%C3%A3o%20e%20hiperextenxao%20do%20tronco%20com%20baco%20estendido.mp4', sets: 6, reps: '30', rest: 30, calories: 15 },
3591
+ { name: 'Alcance Cruzado por Trás das Costas', emoji: '💪', video: this.VIDEO_BASE_URL + 'Alcance%20cruzado%20por%20tr%C3%A1s%20das%20costas%20(pegada%20alternada).mp4', sets: 6, reps: '30', rest: 30, calories: 12 },
3592
+ { name: 'Alongamento de Peitoral', emoji: '💆‍♀️', video: this.VIDEO_BASE_URL + 'Alongamento%20de%20Peitoral%20com%20M%C3%A3os%20Entrela%C3%A7adas%20Atr%C3%A1s%20do%20Corpo.mp4', sets: 6, reps: '30', rest: 30, calories: 10 },
3593
+ { name: 'Circundução Orbital com Garrafa', emoji: '🔄', video: this.VIDEO_BASE_URL + 'Circundu%C3%A7%C3%A3o%20%20%C3%B3rbita%20com%20a%20garrafa%20ao%20redor%20da%20nuca%20com%20reverso.mp4', sets: 6, reps: '30', rest: 30, calories: 14 },
3594
+ { name: 'Mobilidade de Ombro com Apoio', emoji: '🏋️‍♀️', video: this.VIDEO_BASE_URL + 'MobilidadeAlongamento%20de%20Ombro%20com%20Apoio%20(Garrafa%20ou%20Outro%20Objeto.mp4', sets: 6, reps: '30', rest: 30, calories: 11 },
3595
+ { name: 'Scapular Winging Exercise', emoji: '✨', video: this.VIDEO_BASE_URL + 'Scapular%20winging%20exercise%20ou%20Elbow%20fly%20stretch.mp4', sets: 6, reps: '30', rest: 30, calories: 13 },
3596
+ { name: 'Overhead Triceps Stretch', emoji: '💪', video: this.VIDEO_BASE_URL + 'Overhead%20triceps%20stretch.mp4', sets: 6, reps: '30', rest: 30, calories: 9 }
3597
  ],
3598
  abs: [
3599
+ { name: 'Prancha com Balanço Lateral', emoji: '🔥', video: this.VIDEO_BASE_URL + 'Prancha%20com%20balan%C3%A7o%20lateral.mp4', sets: 3, reps: '20', rest: 30, calories: 10 },
3600
+ { name: 'Prancha com Elevação de Perna', emoji: '🔥', video: this.VIDEO_BASE_URL + 'Prancha%20com%20eleva%C3%A7%C3%A3o%20de%20perna.mp4', sets: 3, reps: '20', rest: 30, calories: 12 },
3601
  { name: 'Tesoura (Scissor Kicks)', emoji: '✂️', video: this.VIDEO_BASE_URL + 'Scissor%20Kicks.mp4', sets: 3, reps: '15', rest: 30, calories: 9 },
3602
+ { name: 'Elevação Alternada de Pernas', emoji: '🦵', video: this.VIDEO_BASE_URL + 'Alternating%20Leg%20Lifts.mp4', sets: 3, reps: '20', rest: 30, calories: 10 },
3603
  { name: 'Prancha Lateral com Rotação', emoji: '🔄', video: this.VIDEO_BASE_URL + 'prancha%20lateral%20com%20rota%C3%A7%C3%A3o.mp4', sets: 3, reps: '10 cada', rest: 30, calories: 10 }
3604
  ],
3605
  legs: [
 
3739
  document.addEventListener('DOMContentLoaded', () => {
3740
  window.app = new FitnessApp();
3741
 
3742
+ // Register Service Worker for PWA functionality with auto-update
3743
  if ('serviceWorker' in navigator) {
3744
  navigator.serviceWorker.register('/sw.js')
3745
+ .then(reg => {
3746
+ console.log(' Service Worker registered');
3747
+
3748
+ // AUTO-UPDATE: Listen for updates
3749
+ reg.addEventListener('updatefound', () => {
3750
+ const newWorker = reg.installing;
3751
+ console.log(' New Service Worker found, installing...');
3752
+
3753
+ newWorker.addEventListener('statechange', () => {
3754
+ if (newWorker.state === 'activated') {
3755
+ console.log(' New Service Worker activated!');
3756
+ }
3757
+ });
3758
+ });
3759
+ })
3760
+ .catch(err => console.error(' Service Worker registration failed:', err));
3761
+
3762
+ // Listen for Service Worker updates
3763
+ navigator.serviceWorker.addEventListener('controllerchange', () => {
3764
+ console.log(' Service Worker controller changed - app updated!');
3765
+ // Show subtle notification
3766
+ this.showToast('');
3767
+ });
3768
+
3769
+ // Listen for messages from Service Worker
3770
+ navigator.serviceWorker.addEventListener('message', (event) => {
3771
+ if (event.data && event.data.type === 'SW_UPDATED') {
3772
+ console.log(` Service Worker updated to ${event.data.version}`);
3773
+ }
3774
+ });
3775
  }
3776
  });
3777
 
public/styles.css CHANGED
@@ -776,6 +776,9 @@ body {
776
  justify-content: space-between;
777
  align-items: center;
778
  color: var(--white);
 
 
 
779
  }
780
 
781
  .btn-close-workout {
@@ -809,23 +812,42 @@ body {
809
 
810
  .exercise-display {
811
  text-align: center;
 
812
  }
813
 
814
  .exercise-name {
815
- font-size: 1.5rem;
816
  font-weight: 700;
817
  color: var(--text-primary);
818
- margin-bottom: var(--spacing-sm);
 
 
 
 
 
 
819
  }
820
 
821
  .exercise-count {
822
- font-size: 0.9rem;
 
823
  color: var(--text-secondary);
824
- margin-bottom: var(--spacing-lg);
 
 
 
 
 
 
 
 
 
825
  }
826
 
827
  .exercise-demo {
828
  margin: var(--spacing-xl) 0;
 
 
829
  }
830
 
831
  .demo-placeholder {
@@ -833,12 +855,35 @@ body {
833
  max-width: 700px;
834
  margin: 0 auto;
835
  background: transparent;
836
- border-radius: var(--radius-lg); /* Premium: consistência */
837
  display: flex;
838
  align-items: center;
839
  justify-content: center;
840
  overflow: hidden;
841
  position: relative;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
842
  }
843
 
844
  .demo-icon {
@@ -858,33 +903,9 @@ body {
858
  transform: translateZ(0);
859
  }
860
 
861
- .video-play-button {
862
- position: absolute;
863
- top: 50%;
864
- left: 50%;
865
- transform: translate(-50%, -50%);
866
- background: rgba(255, 107, 157, 0.95);
867
- color: white;
868
- border: 3px solid white;
869
- border-radius: var(--radius-full);
870
- padding: 16px 32px;
871
- font-size: 1.2rem;
872
- font-weight: 700;
873
- cursor: pointer;
874
- transition: all 0.3s ease;
875
- box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3);
876
- z-index: 10;
877
- animation: pulse 2s infinite;
878
- }
879
-
880
- .video-play-button:hover {
881
- background: rgba(255, 107, 157, 1);
882
- transform: translate(-50%, -50%) scale(1.1);
883
- }
884
-
885
- .video-play-button:active {
886
- transform: translate(-50%, -50%) scale(0.95);
887
- }
888
 
889
  @keyframes pulse {
890
  0%, 100% {
@@ -900,15 +921,44 @@ body {
900
  }
901
 
902
  .reps-info {
903
- font-size: 1.1rem;
904
- font-weight: 600;
905
- color: var(--primary);
906
- margin-bottom: var(--spacing-sm);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
907
  }
908
 
909
  .rest-info {
910
- font-size: 0.9rem;
 
911
  color: var(--text-secondary);
 
 
 
 
 
 
 
 
 
 
 
 
912
  }
913
 
914
  .series-tracker {
@@ -1457,6 +1507,26 @@ body {
1457
  border-left: 4px solid var(--primary);
1458
  }
1459
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1460
  .btn-edit-profile {
1461
  width: 100%;
1462
  padding: 16px;
 
776
  justify-content: space-between;
777
  align-items: center;
778
  color: var(--white);
779
+ /* 💫 PREMIUM: Rounded bottom corners */
780
+ border-radius: 0 0 var(--radius-xl) var(--radius-xl);
781
+ box-shadow: 0 4px 20px rgba(255, 107, 157, 0.2);
782
  }
783
 
784
  .btn-close-workout {
 
812
 
813
  .exercise-display {
814
  text-align: center;
815
+ animation: fadeIn 0.4s ease;
816
  }
817
 
818
  .exercise-name {
819
+ font-size: 1.75rem;
820
  font-weight: 700;
821
  color: var(--text-primary);
822
+ margin-bottom: var(--spacing-md);
823
+ letter-spacing: -0.5px;
824
+ /* 💫 PREMIUM: Text gradient */
825
+ background: var(--gradient-primary);
826
+ -webkit-background-clip: text;
827
+ -webkit-text-fill-color: transparent;
828
+ background-clip: text;
829
  }
830
 
831
  .exercise-count {
832
+ font-size: 1rem;
833
+ font-weight: 600;
834
  color: var(--text-secondary);
835
+ margin-bottom: var(--spacing-xl);
836
+ /* 💫 PREMIUM: Glass morphism badge */
837
+ background: rgba(255, 255, 255, 0.9);
838
+ backdrop-filter: blur(10px);
839
+ -webkit-backdrop-filter: blur(10px);
840
+ padding: var(--spacing-sm) var(--spacing-lg);
841
+ border-radius: var(--radius-full);
842
+ display: inline-block;
843
+ box-shadow: var(--shadow-sm);
844
+ border: 1px solid rgba(255, 107, 157, 0.1);
845
  }
846
 
847
  .exercise-demo {
848
  margin: var(--spacing-xl) 0;
849
+ /* 💫 PREMIUM: Container animation */
850
+ animation: scaleIn 0.5s cubic-bezier(0.4, 0, 0.2, 1);
851
  }
852
 
853
  .demo-placeholder {
 
855
  max-width: 700px;
856
  margin: 0 auto;
857
  background: transparent;
858
+ border-radius: var(--radius-lg);
859
  display: flex;
860
  align-items: center;
861
  justify-content: center;
862
  overflow: hidden;
863
  position: relative;
864
+ /* 💫 PREMIUM: Floating effect */
865
+ box-shadow:
866
+ 0 20px 60px rgba(255, 107, 157, 0.15),
867
+ 0 0 0 1px rgba(255, 255, 255, 0.5) inset;
868
+ transition: all 0.3s ease;
869
+ }
870
+
871
+ .demo-placeholder:hover {
872
+ transform: translateY(-4px);
873
+ box-shadow:
874
+ 0 24px 80px rgba(255, 107, 157, 0.2),
875
+ 0 0 0 1px rgba(255, 255, 255, 0.6) inset;
876
+ }
877
+
878
+ @keyframes scaleIn {
879
+ 0% {
880
+ opacity: 0;
881
+ transform: scale(0.9);
882
+ }
883
+ 100% {
884
+ opacity: 1;
885
+ transform: scale(1);
886
+ }
887
  }
888
 
889
  .demo-icon {
 
903
  transform: translateZ(0);
904
  }
905
 
906
+ /* 💫 REMOVED: Video play button (user requested)
907
+ Videos auto-play on exercise screen for seamless experience
908
+ */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
909
 
910
  @keyframes pulse {
911
  0%, 100% {
 
921
  }
922
 
923
  .reps-info {
924
+ font-size: 1.25rem;
925
+ font-weight: 700;
926
+ color: var(--text-primary);
927
+ margin-bottom: var(--spacing-md);
928
+ /* 💫 PREMIUM: Glass card */
929
+ background: rgba(255, 255, 255, 0.95);
930
+ backdrop-filter: blur(10px);
931
+ -webkit-backdrop-filter: blur(10px);
932
+ padding: var(--spacing-md) var(--spacing-lg);
933
+ border-radius: var(--radius-lg);
934
+ box-shadow: var(--shadow-md);
935
+ border: 2px solid rgba(255, 107, 157, 0.15);
936
+ display: inline-block;
937
+ /* 💫 PREMIUM: Icon before */
938
+ }
939
+
940
+ .reps-info::before {
941
+ content: '💪';
942
+ margin-right: var(--spacing-sm);
943
+ font-size: 1.3rem;
944
  }
945
 
946
  .rest-info {
947
+ font-size: 1rem;
948
+ font-weight: 600;
949
  color: var(--text-secondary);
950
+ margin-bottom: var(--spacing-xl);
951
+ /* 💫 PREMIUM: Subtle badge */
952
+ background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
953
+ padding: var(--spacing-sm) var(--spacing-lg);
954
+ border-radius: var(--radius-full);
955
+ display: inline-block;
956
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
957
+ }
958
+
959
+ .rest-info::before {
960
+ content: '⏱️';
961
+ margin-right: var(--spacing-xs);
962
  }
963
 
964
  .series-tracker {
 
1507
  border-left: 4px solid var(--primary);
1508
  }
1509
 
1510
+ .section-header {
1511
+ background: rgba(255, 107, 157, 0.1);
1512
+ padding: var(--spacing-md);
1513
+ margin: var(--spacing-md) 0;
1514
+ border-radius: var(--radius-md);
1515
+ border-left: 4px solid var(--primary-color);
1516
+ transition: all 0.3s ease;
1517
+ }
1518
+
1519
+ /* ✅ COMPLETED SECTION - Green marking */
1520
+ .section-header.completed {
1521
+ background: rgba(76, 175, 80, 0.15);
1522
+ border-left: 4px solid #4CAF50;
1523
+ }
1524
+
1525
+ .section-header.completed h3::before {
1526
+ content: '✅ ';
1527
+ margin-right: var(--spacing-xs);
1528
+ }
1529
+
1530
  .btn-edit-profile {
1531
  width: 100%;
1532
  padding: 16px;
public/sw.js CHANGED
@@ -1,6 +1,8 @@
1
  // 🌟 PREMIUM PWA SERVICE WORKER v3.10.0
2
- // Local videos first, CDN fallback, advanced caching
3
- const VERSION = '3.10.0';
 
 
4
  const CACHE_NAME = `fitness-app-${VERSION}`;
5
  const STATIC_CACHE = `static-${VERSION}`;
6
  const DYNAMIC_CACHE = `dynamic-${VERSION}`;
@@ -39,6 +41,11 @@ const STATIC_ASSETS = [
39
 
40
  // 🚀 Install event - Premium caching strategy
41
  self.addEventListener('install', (event) => {
 
 
 
 
 
42
  console.log('🌟 [SW] Installing Premium Service Worker v' + VERSION);
43
 
44
  event.waitUntil(
@@ -56,7 +63,7 @@ self.addEventListener('install', (event) => {
56
  caches.open(FONT_CACHE)
57
  ]).then(() => {
58
  console.log('✅ [SW] Installation complete!');
59
- return self.skipWaiting();
60
  }).catch(err => {
61
  console.error('❌ [SW] Installation failed:', err);
62
  })
@@ -65,6 +72,8 @@ self.addEventListener('install', (event) => {
65
 
66
  // 🔄 Activate event - Smart cache management
67
  self.addEventListener('activate', (event) => {
 
 
68
  console.log('🔄 [SW] Activating Premium Service Worker v' + VERSION);
69
 
70
  const currentCaches = [
 
1
  // 🌟 PREMIUM PWA SERVICE WORKER v3.10.0
2
+ // Service Worker - Enhanced Version v3.10.2
3
+ // Premium PWA with 100% offline capability + Auto-update
4
+
5
+ const VERSION = '3.10.2';
6
  const CACHE_NAME = `fitness-app-${VERSION}`;
7
  const STATIC_CACHE = `static-${VERSION}`;
8
  const DYNAMIC_CACHE = `dynamic-${VERSION}`;
 
41
 
42
  // 🚀 Install event - Premium caching strategy
43
  self.addEventListener('install', (event) => {
44
+ console.log('🚀 [SW] Installing v3.10.2...');
45
+
46
+ // 💥 AUTO-UPDATE: Skip waiting to activate immediately
47
+ self.skipWaiting();
48
+
49
  console.log('🌟 [SW] Installing Premium Service Worker v' + VERSION);
50
 
51
  event.waitUntil(
 
63
  caches.open(FONT_CACHE)
64
  ]).then(() => {
65
  console.log('✅ [SW] Installation complete!');
66
+ return self.clients.claim();
67
  }).catch(err => {
68
  console.error('❌ [SW] Installation failed:', err);
69
  })
 
72
 
73
  // 🔄 Activate event - Smart cache management
74
  self.addEventListener('activate', (event) => {
75
+ console.log('✅ [SW] Activating v3.10.2...');
76
+
77
  console.log('🔄 [SW] Activating Premium Service Worker v' + VERSION);
78
 
79
  const currentCaches = [
scripts/download-videos.js CHANGED
@@ -29,6 +29,14 @@ const FILES_TO_DOWNLOAD = [
29
  'flexao, extensão e hiperextenxao do tronco com baco estendido.mp4',
30
  'prancha lateral com rotação.mp4',
31
 
 
 
 
 
 
 
 
 
32
  // Áudios
33
  'background_yoga.mp3',
34
  'start_yoga.mp3',
 
29
  'flexao, extensão e hiperextenxao do tronco com baco estendido.mp4',
30
  'prancha lateral com rotação.mp4',
31
 
32
+ // 🆕 Novos vídeos de mobilidade/alongamento
33
+ 'Alcance cruzado por trás das costas (pegada alternada).mp4',
34
+ 'Alongamento de Peitoral com Mãos Entrelaçadas Atrás do Corpo.mp4',
35
+ 'Circundução órbita com a garrafa ao redor da nuca com reverso.mp4',
36
+ 'MobilidadeAlongamento de Ombro com Apoio (Garrafa ou Outro Objeto.mp4',
37
+ 'Scapular winging exercise ou Elbow fly stretch.mp4',
38
+ 'Overhead triceps stretch.mp4',
39
+
40
  // Áudios
41
  'background_yoga.mp3',
42
  'start_yoga.mp3',