RENILCE DIAS
PAINEL PROFISSIONAL
SAIR

PERSONALIZADO

Prescrição individualizada criada a partir da lista do aluno.

VER ALUNOS

PERFORMANCE

Preparação física individual vinculada ao atleta.

VER ATLETAS

Visão geral

—Alunos ativos
—Treinos hoje
—Realizados
—Feedbacks
`).join('')||`
Nenhum exercício encontrado.
`} function selectExercise(name){window._pending={name,series:'3',reps:'10',load:'',rest:'60s',obs:''};render()} function saveExercise(){ const p=window._pending;if(!p)return; p.series=document.querySelector('#rxSeries')?.value||'';p.reps=document.querySelector('#rxReps')?.value||'';p.load=document.querySelector('#rxLoad')?.value||'';p.rest=document.querySelector('#rxRest')?.value||'';p.obs=document.querySelector('#rxObs')?.value||''; if(pickerTarget.kind==='general')workoutDraft.general.push({...p}); else if(pickerTarget.kind==='specific')workoutDraft.specific.push({...p}); else {ensureBlocks();workoutDraft.blocks[pickerTarget.index].push({...p})} window._pending=null;pickerTarget=null;render() } function removeExercise(kind,index,item){ if(kind==='general')workoutDraft.general.splice(item,1); else if(kind==='specific')workoutDraft.specific.splice(item,1); else workoutDraft.blocks[index].splice(item,1);render() } function addedList(arr,kind,index=-1){return arr.map((e,i)=>`
${e.name}
${e.series||'-'} séries • ${e.reps||'-'} reps${e.load?' • '+e.load:''}${e.rest?' • intervalo '+e.rest:''}${e.obs?`${e.obs}`:''}
`).join('')} function pickerModal(){ if(!pickerTarget)return ''; if(window._pending){const p=window._pending;return ``} return `` } let students=[ {name:'Ana Silva',phone:'(11) 99999-0001',email:'ana@email.com',birth:'1990-05-12',objective:'Força + Emagrecimento',secondary:'Melhorar condicionamento',level:'Intermediário',frequency:'3x/semana',availability:'Segunda, quarta e sexta',modalities:'Musculação e corrida',history:'Treina regularmente há 2 anos.',restrictions:'Sem restrições atuais.',notes:'Priorizar progressão de força.',status:'Ativo'}, {name:'Carlos Lima',phone:'',email:'',birth:'',objective:'Condicionamento',secondary:'',level:'Base',frequency:'2x/semana',availability:'',modalities:'',history:'',restrictions:'',notes:'',status:'Ativo'}, {name:'Mariana Costa',phone:'',email:'',birth:'',objective:'Qualidade de movimento',secondary:'',level:'Base',frequency:'2x/semana',availability:'',modalities:'',history:'',restrictions:'',notes:'',status:'Ativo'} ]; let studentIndex=0; function newStudent(){studentIndex=-1;go('studentform')} function editStudent(i){studentIndex=i;go('studentform')} function saveStudent(){ const ids=['name','phone','email','birth','objective','secondary','level','frequency','availability','modalities','history','restrictions','notes','status']; let s={}; ids.forEach(id=>s[id]=document.querySelector('#s_'+id)?.value||''); if(!s.name){alert('Informe o nome do aluno.');return} if(studentIndex<0){students.push(s);studentIndex=students.length-1}else students[studentIndex]=s; go('studentprofile') } function val(s,k){return (s&&s[k])||''} let assessments={}; const evalItems=[ ['MOBILIDADE','Tornozelo'],['MOBILIDADE','Quadril'],['MOBILIDADE','Torácica'],['MOBILIDADE','Ombro'], ['ESTABILIDADE / CONTROLE','Core'],['ESTABILIDADE / CONTROLE','Lombo-pélvico'],['ESTABILIDADE / CONTROLE','Escápula'], ['PADRÕES DE MOVIMENTO','Dominância de Joelho'],['PADRÕES DE MOVIMENTO','Dominância de Quadril'],['PADRÕES DE MOVIMENTO','Empurrar'],['PADRÕES DE MOVIMENTO','Puxar'], ['CAPACIDADES','Força'],['CAPACIDADES','Equilíbrio'],['CAPACIDADES','Coordenação'] ]; function assessmentKey(){return students[studentIndex]?.name||'aluno'} function currentAssessment(){let k=assessmentKey();if(!assessments[k])assessments[k]={date:new Date().toISOString().slice(0,10),objective:'',pain:'',notes:'',items:{}};return assessments[k]} function setEval(item,status){currentAssessment().items[item]=status;render()} function saveAssessment(){ let a=currentAssessment();a.date=document.querySelector('#a_date')?.value||a.date;a.objective=document.querySelector('#a_objective')?.value||'';a.pain=document.querySelector('#a_pain')?.value||'';a.notes=document.querySelector('#a_notes')?.value||'';alert('Avaliação salva no protótipo.');render() } function evalColor(s){return s==='Adequado'?'green':s==='Atenção'?'yellow':s==='Prioridade'?'red':''} let onlineA={goal:'',experience:'Intermediário',place:'Academia',minutes:'45',equipment:'',health:'',surgery:'',meds:'',restriction:'',pain:'Não',painArea:'',painScore:'0',painTime:'',painWorse:'',limitations:'',training:'',breaktime:'',familiar:'',sleep:'Bom',energy:'Boa',routine:'',sports:'',videos:'Não solicitados',decision:'Pendente',notes:''}; let oaStep=1; function oaSet(k,v){onlineA[k]=v;render()} function nextOA(){if(oaStep<6){oaStep++;render();scrollTo(0,0)}else saveOA()} function prevOA(){if(oaStep>1){oaStep--;render();scrollTo(0,0)}else go('studentprofile')} function saveStepFields(){ const ids=['goal','equipment','minutes','health','surgery','meds','restriction','painArea','painScore','painTime','painWorse','limitations','training','breaktime','familiar','routine','sports']; ids.forEach(k=>{let e=document.querySelector('#w_'+k);if(e)onlineA[k]=e.value}) } function nextSave(){saveStepFields();nextOA()} function prevSave(){saveStepFields();prevOA()} function choice(k,v){saveStepFields();onlineA[k]=v;render()} function choiceButtons(k,vals){return `
${vals.map(v=>``).join('')}
`} function saveOA(){ ['goal','experience','place','minutes','equipment','health','surgery','meds','restriction','pain','painArea','painScore','painTime','painWorse','limitations','training','breaktime','familiar','sleep','energy','routine','sports','videos'].forEach(k=>{let e=document.querySelector('#oa_'+k);if(e)onlineA[k]=e.value}); go('onlineReview') } function oaAlerts(){let a=[];if(onlineA.pain==='Sim')a.push(`Dor/desconforto: ${onlineA.painArea||'região não informada'} • ${onlineA.painScore}/10`);if(onlineA.restriction.trim())a.push('Recomendação/restrição profissional informada');if(onlineA.surgery.trim())a.push('Cirurgia ou lesão anterior informada');if(onlineA.health.trim())a.push('Informação de saúde para revisão');return a} function decision(d){onlineA.decision=d;render()} let selectedStudentIndex=0; function selectBuilderStudent(i){selectedStudentIndex=Number(i);studentIndex=selectedStudentIndex;render()} function builderContext(){let s=students[selectedStudentIndex]||students[0],a=onlineA;return {s,a,alerts:oaAlerts()}} function publishWorkout(){let c=builderContext(),total=workoutDraft.general.length+workoutDraft.specific.length+workoutDraft.blocks.reduce((n,b)=>n+b.length,0);if(!total){alert('Adicione pelo menos um exercício.');return}alert(`Treino publicado para ${c.s.name} • ${selectedType} • ${total} exercícios.`)} let libFilter='TODOS'; function setLibFilter(f){libFilter=f;render()} function filteredExercises(){ let f=libFilter.toUpperCase(); if(f==='TODOS')return exerciseDB; return exerciseDB.filter(e=>(e.cat+' '+e.group+' '+e.level+' '+e.name).toUpperCase().includes(f)) } function duplicateExercise(kind,bi,item){ let arr=kind==='general'?workoutDraft.general:kind==='specific'?workoutDraft.specific:workoutDraft.blocks[bi]; arr.splice(item+1,0,{...arr[item]});render() } function moveExercise(kind,bi,item,dir){ let arr=kind==='general'?workoutDraft.general:kind==='specific'?workoutDraft.specific:workoutDraft.blocks[bi],ni=item+dir; if(ni<0||ni>=arr.length)return;[arr[item],arr[ni]]=[arr[ni],arr[item]];render() } function duplicateBlock(i){ensureBlocks();workoutDraft.blocks.splice(i+1,0,workoutDraft.blocks[i].map(x=>({...x})));blocks++;render()} function removeBlock(i){if(blocks<=1)return;workoutDraft.blocks.splice(i,1);blocks--;render()} let workoutTemplates=[ {name:'MMII • BASE',type:'MMII',level:'Base',general:[],specific:[],blocks:[[]]}, {name:'MMII • INTERMEDIÁRIO',type:'MMII',level:'Intermediário',general:[],specific:[],blocks:[[]]}, {name:'MMSS • BASE',type:'MMSS',level:'Base',general:[],specific:[],blocks:[[]]}, {name:'FULL BODY • INTERMEDIÁRIO',type:'FULL BODY',level:'Intermediário',general:[],specific:[],blocks:[[]]} ]; function cloneItems(a){return a.map(x=>({...x}))} function loadTemplate(i){ let t=workoutTemplates[i];selectedType=t.type;workoutDraft={general:[],specific:[],blocks:t.blocks.map(cloneItems)};blocks=Math.max(1,workoutDraft.blocks.length);go('builder') } function saveAsTemplate(){ let n=prompt('Nome do modelo:',''+selectedType+' • NOVO MODELO');if(!n)return; workoutTemplates.push({name:n,type:selectedType,level:'Personalizado',general:[],specific:[],blocks:workoutDraft.blocks.map(cloneItems)}); alert('Modelo salvo.');go('templates') } function deleteTemplate(i){if(confirm('Excluir este modelo?')){workoutTemplates.splice(i,1);render()}} let studentWorkoutLog={done:{},load:{},reps:{},rpe:'',pain:'Não',painArea:'',note:'',finished:false}; function demoWorkout(){ let has=workoutDraft.general.length+workoutDraft.specific.length+workoutDraft.blocks.reduce((n,b)=>n+b.length,0); if(has)return workoutDraft; let pick=n=>({name:n,series:'3',reps:'10',load:'',rest:'60s',obs:''}); return {general:[pick('ESTEIRA')],specific:[pick('MOBILIDADE DE QUADRIL')],blocks:[[pick('AGACHAMENTO'),pick('TERRA KTB')],[pick('REMADA NO TRX'),pick('PRANCHA BÁSICA')]]} } function toggleDone(k){studentWorkoutLog.done[k]=!studentWorkoutLog.done[k];render()} function setLog(k,t,v){studentWorkoutLog[t][k]=v} function finishStudentWorkout(){studentWorkoutLog.finished=true;go('workoutFeedback')} function studentExCard(e,k){ let d=studentWorkoutLog.done[k]; return `
${e.name}
${e.series||'-'} séries • ${e.reps||'-'} reps
${e.rest?`Descanso ${e.rest}`:''}
▶ VÍDEO / EXECUÇÃO DO EXERCÍCIO
${e.obs?`
💬 ${e.obs}
`:''}
` } let studentWarmups={}; function warmupFor(i=selectedStudentIndex){ if(!studentWarmups[i]) studentWarmups[i]={general:[],specific:[]}; return studentWarmups[i]; } function warmAddedList(arr,kind){ return arr.map((e,i)=>`
${e.name}
${e.series||'-'} séries • ${e.reps||'-'} reps${e.rest?' • intervalo '+e.rest:''}
`).join('') } function moveWarm(kind,i,d){let a=warmupFor()[kind],n=i+d;if(n<0||n>=a.length)return;[a[i],a[n]]=[a[n],a[i]];render()} function removeWarm(kind,i){warmupFor()[kind].splice(i,1);render()} function openWarmPicker(kind){pickerTarget='warm_'+kind;pickerOpen=true;searchTerm='';render()} function saveWarmup(){alert(`Aquecimento padrão salvo para ${(students[selectedStudentIndex]||students[0]).name}. Ele será usado em todos os treinos deste aluno.`);go('builder')} let workoutHistory=[ {date:'18/09/2026',name:'Treino A',type:'MMII',rpe:7,pain:'Não',done:100,note:'',loads:'Agachamento 20 kg'}, {date:'16/09/2026',name:'Treino B',type:'MMSS',rpe:6,pain:'Não',done:100,note:'Treino confortável',loads:'Remada 18 kg'}, {date:'14/09/2026',name:'Treino A',type:'MMII',rpe:8,pain:'Sim',painArea:'Joelho',done:92,note:'Desconforto leve no final',loads:'Agachamento 18 kg'} ]; function saveFeedback(){ workoutHistory.unshift({date:new Date().toLocaleDateString('pt-BR'),name:'Treino do dia',type:selectedType||'FULL BODY',rpe:Number(studentWorkoutLog.rpe||5),pain:studentWorkoutLog.pain,painArea:studentWorkoutLog.painArea,done:100,note:studentWorkoutLog.note,loads:Object.values(studentWorkoutLog.load).filter(Boolean).join(' • ')}); studentWorkoutLog={done:{},load:{},reps:{},rpe:'',pain:'Não',painArea:'',note:'',finished:false};go('evolution') } function avgRpe(){return workoutHistory.length?(workoutHistory.reduce((s,x)=>s+(Number(x.rpe)||0),0)/workoutHistory.length).toFixed(1):'—'} function coachStudent(){return students[studentIndex]||students[0]} function coachHistory(){return workoutHistory} function attendanceRate(){let h=coachHistory();return h.length?Math.round(h.reduce((s,x)=>s+(Number(x.done)||0),0)/h.length):0} function painFlags(){return coachHistory().filter(x=>x.pain==='Sim')} function recentLoads(){return coachHistory().filter(x=>x.loads).slice(0,5)} const SERVICE_TYPES={ 'TREINO':{label:'TREINO',desc:'Aulas em Grupo'}, 'PERSONALIZADO':{label:'PERSONALIZADO',desc:'Treinamento individualizado'}, 'PERFORMANCE':{label:'PERFORMANCE',desc:'Preparação física e desempenho'} }; let studentServiceFilter='TODOS'; students.forEach((s,i)=>{if(!s.service)s.service=i%3===0?'TREINO':(i%3===1?'PERSONALIZADO':'PERFORMANCE')}); function serviceCount(type){return students.filter(s=>s.service===type).length} function serviceLabel(s){return (SERVICE_TYPES[s.service]||SERVICE_TYPES.TREINO).label} function setServiceFilter(x){studentServiceFilter=x;go('serviceStudents')} let prescriptionMode='PERSONALIZADO'; let groupClass={name:'Treino Coletivo 01',students:[],blocks:[]}; let performanceSport='CORRIDA',performanceGoal='PROVA / DESEMPENHO'; function openPrescription(type){prescriptionMode=type;go('prescriptionHub')} function selectGroupStudent(i){let p=groupClass.students.indexOf(i);p>=0?groupClass.students.splice(p,1):groupClass.students.push(i);render()} let monthlyPrograms=[ {id:1,month:'SETEMBRO',year:2026,status:'PUBLICADO',students:[],workouts:[ {name:'TREINO A',type:'FULL BODY',focus:'Força geral'}, {name:'TREINO B',type:'FULL BODY',focus:'Condicionamento'}, {name:'TREINO C',type:'FULL BODY',focus:'Força + core'} ]} ]; let activeMonthlyProgram=0; function monthLabel(p){return `${p.month} ${p.year}`} function newMonthlyProgram(){ let now=new Date(), months=['JANEIRO','FEVEREIRO','MARÇO','ABRIL','MAIO','JUNHO','JULHO','AGOSTO','SETEMBRO','OUTUBRO','NOVEMBRO','DEZEMBRO']; monthlyPrograms.unshift({id:Date.now(),month:months[now.getMonth()],year:now.getFullYear(),status:'RASCUNHO',students:[],workouts:[{name:'TREINO A',type:'FULL BODY',focus:''}]});activeMonthlyProgram=0;go('monthlyEditor') } function duplicateMonthly(i){let x=JSON.parse(JSON.stringify(monthlyPrograms[i]));x.id=Date.now();x.status='RASCUNHO';monthlyPrograms.unshift(x);activeMonthlyProgram=0;go('monthlyEditor')} function addMonthlyWorkout(){let p=monthlyPrograms[activeMonthlyProgram];let letter=String.fromCharCode(65+p.workouts.length);p.workouts.push({name:'TREINO '+letter,type:'FULL BODY',focus:''});render()} function removeMonthlyWorkout(i){monthlyPrograms[activeMonthlyProgram].workouts.splice(i,1);render()} function toggleMonthlyStudent(i){let a=monthlyPrograms[activeMonthlyProgram].students,p=a.indexOf(i);p>=0?a.splice(p,1):a.push(i);render()} let activeWorkoutContext={scope:'MONTHLY',programIndex:0,workoutIndex:0}; function ensureWorkoutData(w){ if(!w.blocks) w.blocks=[{name:'BLOCO 1',exercises:[]}]; return w; } function editMonthlyWorkout(i){ activeWorkoutContext={scope:'MONTHLY',programIndex:activeMonthlyProgram,workoutIndex:i}; ensureWorkoutData(monthlyPrograms[activeMonthlyProgram].workouts[i]);go('connectedWorkoutEditor') } function currentConnectedWorkout(){ if(activeWorkoutContext.scope==='MONTHLY') return ensureWorkoutData(monthlyPrograms[activeWorkoutContext.programIndex].workouts[activeWorkoutContext.workoutIndex]); if(activeWorkoutContext.scope==='V24') return ensureWorkoutData(v24Program(activeWorkoutContext.studentIndex).workouts[activeWorkoutContext.workoutIndex]); return null; } function addConnectedBlock(){let w=currentConnectedWorkout();w.blocks.push({name:'BLOCO '+(w.blocks.length+1),exercises:[]});render()} function deleteConnectedBlock(i){let w=currentConnectedWorkout();if(w.blocks.length>1)w.blocks.splice(i,1);render()} function addDemoExerciseToBlock(b){ let w=currentConnectedWorkout(), pool=(typeof exerciseDB!=='undefined'&&exerciseDB.length)?exerciseDB:[{name:'AGACHAMENTO'},{name:'REMADA NO CABO'},{name:'TERRA KTB'}]; let ex=pool[(w.blocks[b].exercises.length)%pool.length], name=ex.name||ex.exercise||'EXERCÍCIO'; w.blocks[b].exercises.push({name,sets:'3',reps:'10',load:'',rest:'60s',note:''});render() } function removeConnectedExercise(b,e){currentConnectedWorkout().blocks[b].exercises.splice(e,1);render()} function moveConnectedExercise(b,e,d){let a=currentConnectedWorkout().blocks[b].exercises,n=e+d;if(n<0||n>=a.length)return;[a[e],a[n]]=[a[n],a[e]];render()} function saveConnectedWorkout(){alert(currentConnectedWorkout().name+' salvo com '+currentConnectedWorkout().blocks.length+' bloco(s).');go('monthlyEditor')} let connectedPickerBlock=0,connectedLibraryQuery='',connectedLibraryFilter='TODOS'; function openConnectedLibrary(b){connectedPickerBlock=b;connectedLibraryQuery='';connectedLibraryFilter='TODOS';go('connectedLibrary')} function exText(x){return String(x.name||x.exercise||x.nome||'EXERCÍCIO')} function exMeta(x){return [x.cat||x.category||x.padrao||'',x.level||x.nivel||'',x.base||'',x.equipment||x.equipamento||''].filter(Boolean).join(' • ')} function connectedFilteredExercises(){ let q=connectedLibraryQuery.toUpperCase(),f=connectedLibraryFilter; return exerciseDB.filter(x=>{ let all=(exText(x)+' '+exMeta(x)).toUpperCase(); return (!q||all.includes(q))&&(f==='TODOS'||all.includes(f)); }).slice(0,120) } function chooseConnectedExercise(i){ let list=connectedFilteredExercises(),x=list[i]; if(!x)return; currentConnectedWorkout().blocks[connectedPickerBlock].exercises.push({name:exText(x),meta:exMeta(x),sets:'3',reps:'10',load:'',rest:'60s',note:''}); go('connectedWorkoutEditor') } let studentDemoIndex=0,studentActiveProgram=null,studentActiveWorkout=0; let studentMonthlyLogs={}; function publishedProgramForStudent(si){ return monthlyPrograms.find((p)=>p.status==='PUBLICADO' && (p.students.includes(si)|| (p.students.length===0 && students[si]?.service==='TREINO'))); } function openStudentMonthly(si=0){studentDemoIndex=si;studentActiveProgram=publishedProgramForStudent(si);go('studentMonthly')} function monthlyLogKey(pi,wi){return (studentActiveProgram?.id||'x')+'_'+studentDemoIndex+'_'+wi} function getMonthlyLog(wi){let k=monthlyLogKey(0,wi);if(!studentMonthlyLogs[k])studentMonthlyLogs[k]={done:{},load:{},reps:{},rpe:'',pain:'Não',painArea:'',note:'',finished:false};return studentMonthlyLogs[k]} function workoutExerciseCount(w){return (w.blocks||[]).reduce((n,b)=>n+(b.exercises||[]).length,0)} function workoutDoneCount(w,wi){let l=getMonthlyLog(wi);return Object.values(l.done).filter(Boolean).length} function monthlyProgress(w,wi){let n=workoutExerciseCount(w);return n?Math.round(workoutDoneCount(w,wi)/n*100):0} function openStudentMonthlyWorkout(i){studentActiveWorkout=i;go('studentMonthlyWorkout')} function finishMonthlyWorkout(){let l=getMonthlyLog(studentActiveWorkout);l.finished=true;go('studentMonthlyFeedback')} function saveMonthlyFeedback(){let l=getMonthlyLog(studentActiveWorkout),w=studentActiveProgram.workouts[studentActiveWorkout];workoutHistory.unshift({date:new Date().toLocaleDateString('pt-BR'),name:w.name,type:w.type,rpe:Number(l.rpe||5),pain:l.pain,painArea:l.painArea,done:100,note:l.note,loads:Object.values(l.load).filter(Boolean).join(' • ')});go('studentMonthly')} // ===== V24: PERSONALIZADO + PERFORMANCE COMPLETOS ===== let v24IndividualPrograms={}; let v24Exec={student:0,workout:0}; let v24Logs={}; function v24Program(si){ if(!v24IndividualPrograms[si]) v24IndividualPrograms[si]={workouts:[],phase:'',competitionDate:'',sportNotes:''}; return v24IndividualPrograms[si]; } function v24NewWorkout(si){ let p=v24Program(si), letter=String.fromCharCode(65+p.workouts.length); p.workouts.push({name:'TREINO '+letter,type:'FULL BODY',focus:'',blocks:[{name:'BLOCO 1',exercises:[]}],published:false}); activeWorkoutContext={scope:'V24',studentIndex:si,workoutIndex:p.workouts.length-1};go('connectedWorkoutEditor') } function v24EditWorkout(si,wi){activeWorkoutContext={scope:'V24',studentIndex:si,workoutIndex:wi};go('connectedWorkoutEditor')} function v24Publish(si,wi){v24Program(si).workouts[wi].published=true;render()} function v24LogKey(si,wi){return 'v24_'+si+'_'+wi} function v24Log(si,wi){let k=v24LogKey(si,wi);if(!v24Logs[k])v24Logs[k]={done:{},load:{},reps:{},rpe:'',pain:'Não',painArea:'',note:'',finished:false};return v24Logs[k]} function v24OpenStudent(si){studentDemoIndex=si;go('v24StudentProgram')} function v24OpenExec(si,wi){v24Exec={student:si,workout:wi};go('v24StudentExec')} function v24Finish(){go('v24StudentFeedback')} function v24SaveFeedback(){ let si=v24Exec.student,wi=v24Exec.workout,l=v24Log(si,wi),w=v24Program(si).workouts[wi];l.finished=true; workoutHistory.unshift({date:new Date().toLocaleDateString('pt-BR'),name:w.name,type:w.type,rpe:Number(l.rpe||5),pain:l.pain,painArea:l.painArea,done:100,note:l.note,loads:Object.values(l.load).filter(Boolean).join(' • ')}); go('v24StudentProgram') } // ===== V25: VÍDEOS NA BIBLIOTECA DE EXERCÍCIOS ===== let exerciseVideos={}; let v25ExerciseIndex=0,v25ReturnPage='library'; function v25VideoData(i){if(!exerciseVideos[i])exerciseVideos[i]={url:'',technical:'',attention:''};return exerciseVideos[i]} function v25OpenVideoAdmin(i,back='library'){v25ExerciseIndex=i;v25ReturnPage=back;go('v25VideoAdmin')} function v25OpenVideoStudentByName(name,back){ let i=exerciseDB.findIndex(x=>(x.name||'').toUpperCase()===String(name||'').toUpperCase()); if(i<0){alert('Este exercício ainda não possui vídeo cadastrado.');return} v25ExerciseIndex=i;v25ReturnPage=back||page;go('v25VideoStudent') } function v25YoutubeEmbed(url){ let m=String(url||'').match(/(?:youtu\.be\/|youtube\.com\/(?:watch\?v=|shorts\/|embed\/))([^?&/]+)/i); return m?'https://www.youtube.com/embed/'+m[1]:''; } function v25SaveVideo(){ let d=v25VideoData(v25ExerciseIndex); let u=document.getElementById('v25url'); if(u)d.url=u.value.trim(); let t=document.getElementById('v25tech'); if(t)d.technical=t.value.trim(); let a=document.getElementById('v25att'); if(a)d.attention=a.value.trim(); alert('Vídeo e orientações salvos para este exercício.');go(v25ReturnPage) } function v25VideoButton(name,back){ let i=exerciseDB.findIndex(x=>(x.name||'').toUpperCase()===String(name||'').toUpperCase()); if(i<0)return ''; let d=v25VideoData(i); return `${d.url?` VÍDEO`:` SEM VÍDEO`}`; } // ===== V26: PERSISTÊNCIA LOCAL DO PROTÓTIPO ===== const V26_STORAGE_KEY='renilce_dias_app_v26'; let v26SaveTimer=null; function v26Snapshot(){ return { version:26,savedAt:new Date().toISOString(), students:typeof students!=='undefined'?students:[], monthlyPrograms:typeof monthlyPrograms!=='undefined'?monthlyPrograms:[], studentWarmups:typeof studentWarmups!=='undefined'?studentWarmups:{}, workoutHistory:typeof workoutHistory!=='undefined'?workoutHistory:[], exerciseVideos:typeof exerciseVideos!=='undefined'?exerciseVideos:{}, v24IndividualPrograms:typeof v24IndividualPrograms!=='undefined'?v24IndividualPrograms:{}, v24Logs:typeof v24Logs!=='undefined'?v24Logs:{}, studentMonthlyLogs:typeof studentMonthlyLogs!=='undefined'?studentMonthlyLogs:{}, studentIndividualWorkouts:typeof studentIndividualWorkouts!=='undefined'?studentIndividualWorkouts:{}, v27Session:typeof v27Session!=='undefined'?v27Session:{} }; } function v26Save(silent=true){ try{ localStorage.setItem(V26_STORAGE_KEY,JSON.stringify(v26Snapshot())); let b=document.getElementById('persistBadge');if(b){b.textContent='✓ DADOS SALVOS';b.classList.add('ok')} if(!silent)alert('Dados salvos neste dispositivo.'); }catch(e){if(!silent)alert('Não foi possível salvar neste navegador.')} } function v26Restore(){ try{ let raw=localStorage.getItem(V26_STORAGE_KEY);if(!raw)return false; let d=JSON.parse(raw); if(d.students)students.splice(0,students.length,...d.students); if(d.monthlyPrograms)monthlyPrograms.splice(0,monthlyPrograms.length,...d.monthlyPrograms); if(d.studentWarmups)studentWarmups=d.studentWarmups; if(d.workoutHistory)workoutHistory.splice(0,workoutHistory.length,...d.workoutHistory); if(d.exerciseVideos)exerciseVideos=d.exerciseVideos; if(d.v24IndividualPrograms)v24IndividualPrograms=d.v24IndividualPrograms; if(d.v24Logs)v24Logs=d.v24Logs; if(d.studentMonthlyLogs)studentMonthlyLogs=d.studentMonthlyLogs; if(d.studentIndividualWorkouts)studentIndividualWorkouts=d.studentIndividualWorkouts; if(d.v27Session)v27Session=d.v27Session; return true; }catch(e){return false} } function v26AutoSave(){ clearTimeout(v26SaveTimer); v26SaveTimer=setTimeout(()=>v26Save(true),250); } function v26Export(){ let blob=new Blob([JSON.stringify(v26Snapshot(),null,2)],{type:'application/json'}); let a=document.createElement('a');a.href=URL.createObjectURL(blob);a.download='Renilce_Dias_Backup_'+new Date().toISOString().slice(0,10)+'.json';a.click();setTimeout(()=>URL.revokeObjectURL(a.href),500); } function v26Import(input){ let f=input.files&&input.files[0];if(!f)return; let r=new FileReader();r.onload=()=>{try{localStorage.setItem(V26_STORAGE_KEY,r.result);v26Restore();alert('Backup restaurado com sucesso.');render()}catch(e){alert('Arquivo de backup inválido.')}};r.readAsText(f) } function v26Clear(){ if(confirm('Apagar os dados salvos neste dispositivo e voltar aos dados do protótipo?')){localStorage.removeItem(V26_STORAGE_KEY);location.reload()} } // ===== V27: CONTAS + ARQUITETURA DE BACKEND ===== let v27Session={role:'PROFESSIONAL',studentIndex:0,email:'renilce@demo.app'}; function v27LoginProfessional(){v27Session={role:'PROFESSIONAL',studentIndex:0,email:'renilce@demo.app'};v26AutoSave();go('admin')} function v27LoginStudent(si){v27Session={role:'STUDENT',studentIndex:Number(si)||0,email:'aluno@demo.app'};studentDemoIndex=Number(si)||0;v26AutoSave();let st=students[studentDemoIndex]||students[0];go(st.service==='TREINO'?'studentMonthly':'v24StudentProgram')} function v27Logout(){v27Session={role:'',studentIndex:0,email:''};go('v27Login')} function v27OpenMyArea(){if(v27Session.role==='PROFESSIONAL')go('admin');else v27LoginStudent(v27Session.studentIndex)} function render(){ if(page==='login') A.innerHTML=`
RENILCE DIAS
TREINAMENTO FÍSICO & PERFORMANCE
Fundadora do DUO Centro de Treinamento Integrado
`; else if(page==='home') A.innerHTML=`
RENILCE DIAS
TREINAMENTO FÍSICO & PERFORMANCE
Olá, Ana 👋
Vamos treinar?
TREINO DE HOJE • MMII
Força — Membros Inferiores
45 min • Intermediário
🏋️Meus treinosFicha atual
📈EvoluçãoResultados
🧍AvaliaçãoAvaliação funcional
👤Renilce DiasSua treinadora
${nav('home')}
`; else if(page==='workout') A.innerHTML=`
TREINO A • MMII
Força — Membros Inferiores
AQUECIMENTO GERAL
01
Esteira5 min • intensidade leve/moderada
AQUECIMENTO ESPECÍFICO
01
Mobilidade de tornozelo2 × 10
02
Agachamento com peso corporal2 × 10
BLOCO 1
01
Agachamento Goblet3 × 10
02
Terra KTB3 × 10
BLOCO 2
03
Step Up3 × 10
${nav('workout')}
`; else if(page==='admin') A.innerHTML=`
RENILCE DIAS
PAINEL PROFISSIONAL
${adminTabs('admin')}
Visão geral
32Alunos ativos
18Treinos hoje
14Realizados
3Feedbacks

GRUPOS DE ALUNOS

${Object.keys(SERVICE_TYPES).map(k=>`
${serviceCount(k)} aluno(s)
${k}
${SERVICE_TYPES[k].desc}
`).join('')}
`; else if(page==='students') A.innerHTML=`
ALUNOS
PAINEL RENILCE
${adminTabs('students')}${students.map((s,i)=>`
${s.name[0]}
${s.name}${s.frequency||'Frequência não definida'} • ${s.level||'Nível não definido'}${s.service||'TREINO'}
›
`).join('')}
`; else if(page==='studentform'){let s=studentIndex>=0?students[studentIndex]:{};A.innerHTML=`
${studentIndex<0?'NOVO ALUNO':'EDITAR ALUNO'}
CADASTRO COMPLETO

DADOS PESSOAIS

PLANO / GRUPO

TREINO = aulas em grupo • PERSONALIZADO = prescrição individual • PERFORMANCE = preparação física e desempenho

OBJETIVOS E TREINAMENTO

`} else if(page==='studentprofile'){let s=students[studentIndex]||students[0];A.innerHTML=`
${s.name}
PERFIL DO ALUNO
${s.status} ${s.service||'TREINO'}
${s.objective||'Objetivo não definido'}
${s.level} • ${s.frequency}
Objetivo secundário

${s.secondary||'—'}

Disponibilidade

${s.availability||'—'}

Modalidades

${s.modalities||'—'}

Restrições / limitações

${s.restrictions||'—'}

Observações

${s.notes||'—'}

`} else if(page==='onlineAssessment'){let s=students[studentIndex]||students[0],a=onlineA;let pct=Math.round(oaStep/6*100);let content=''; if(oaStep===1)content=`
Vamos conhecer seu objetivo

Leva menos de 2 minutos. Você poderá atualizar essas informações depois.

${choiceButtons('experience',['Iniciante','Intermediário','Avançado'])}${choiceButtons('place',['Academia','Casa','DUO','Outro'])}
`; if(oaStep===2)content=`
Saúde e segurança

Essas informações ajudam Renilce a decidir se o treino precisa de algum cuidado ou adaptação.

`; if(oaStep===3)content=`
Dor ou limitação

Queremos saber como você está hoje.

${choiceButtons('pain',['Não','Sim'])}${a.pain==='Sim'?`
${a.painScore}
`:`
Ótimo.

Você informou que não sente dor ou desconforto atualmente.

`}`; if(oaStep===4)content=`
Sua experiência com treino
`; if(oaStep===5)content=`
Como está sua rotina?
${choiceButtons('sleep',['Bom','Regular','Ruim'])}${choiceButtons('energy',['Boa','Regular','Baixa'])}
`; if(oaStep===6)content=`
Última etapa 🎯
VÍDEOS

Você não precisa gravar nada agora.

Se Renilce precisar observar algum movimento, ela solicitará um vídeo específico e enviará as orientações de gravação.

${choiceButtons('videos',['Não solicitados','Solicitados','Enviados'])}
Pronto para enviar

Revise suas respostas usando o botão Voltar. Ao finalizar, Renilce receberá as informações para análise.

`; A.innerHTML=`
AVALIAÇÃO ONLINE${oaStep} de 6
${s.name}
${content}
`} else if(page==='onlineReview'){let s=students[studentIndex]||students[0],a=onlineA,alerts=oaAlerts();A.innerHTML=`
REVISÃO PROFISSIONAL
${s.name}
RESUMO
${a.goal||s.objective||'Objetivo não informado'}
${a.experience} • ${a.minutes} min • ${a.place}
PONTOS PARA REVISÃO${alerts.length?alerts.map(x=>`
⚠️ ${x}
`).join(''):`

Nenhum alerta identificado pelas respostas preenchidas. A prescrição permanece sujeita à revisão profissional.

`}
DECISÃO DA RENILCE${['Liberar para treinamento','Liberar com adaptações','Solicitar mais informações','Orientar avaliação profissional quando indicado'].map(d=>``).join('')}
`} else if(page==='studentassessment'){let s=students[studentIndex]||students[0],a=currentAssessment();A.innerHTML=`
AVALIAÇÃO
${s.name}
${['MOBILIDADE','ESTABILIDADE / CONTROLE','PADRÕES DE MOVIMENTO','CAPACIDADES'].map(group=>`
${group}${evalItems.filter(x=>x[0]===group).map(x=>{let st=a.items[x[1]]||'';return `
${x[1]}
`}).join('')}
`).join('')}
RESUMO
${Object.values(a.items).filter(x=>x==='Adequado').length} adequados
${Object.values(a.items).filter(x=>x==='Atenção').length} pontos de atenção
${Object.values(a.items).filter(x=>x==='Prioridade').length} prioridades
`} else if(page==='library') A.innerHTML=`
BIBLIOTECA DUO
${exerciseDB.length} EXERCÍCIOS IMPORTADOS DO EXCEL
${adminTabs('library')}
${exerciseDB.slice(0,220).map(e=>`
${e.cat}
${e.name}
${e.level} • ${e.group}
`).join('')}
`; else if(page==='builder'){ensureBlocks();let c=builderContext();A.innerHTML=`
CRIAR TREINO
PRESCRIÇÃO INDIVIDUAL
${adminTabs('builder')}
${c.s.name}
Objetivo: ${c.a.goal||c.s.objective||'não informado'} • ${c.a.experience||c.s.level} • ${c.a.minutes||'—'} min
${c.alerts.length?`
⚠️ ATENÇÃO NA PRESCRIÇÃO${c.alerts.map(x=>`
${x}
`).join('')}
Decisão: ${c.a.decision||'Pendente'}
`:`
AVALIAÇÃO ONLINE
Sem alertas registrados • Decisão: ${c.a.decision||'Pendente'}
`}
${['MMII','MMSS','FULL BODY'].map(t=>``).join('')}
AQUECIMENTO PADRÃO DO ALUNO
Único e aplicado automaticamente a todos os treinos.
Geral: ${warmupFor().general.length} exercício(s) • Específico: ${warmupFor().specific.length} exercício(s)
${Array.from({length:blocks},(_,i)=>`

BLOCO ${i+1}

${addedList(workoutDraft.blocks[i]||[],'block',i)}
`).join('')}
${pickerModal()}
`} else if(page==='templates'){A.innerHTML=`
MODELOS DE TREINO
CRIE UMA VEZ • ADAPTE PARA CADA ALUNO
${adminTabs('templates')}

Use um modelo como ponto de partida. Depois ajuste exercícios, séries, repetições e cargas para o aluno.

${workoutTemplates.map((t,i)=>`
${t.type}

${t.name}

${t.level} • ${t.blocks.length} bloco(s)
`).join('')}
`} else if(page==='warmupEditor'){let s=students[selectedStudentIndex]||students[0],w=warmupFor();A.innerHTML=`
AQUECIMENTO PADRÃO
${s.name}
REGRA

Este aquecimento é único para o aluno e aparece automaticamente antes de todos os Treinos A, B, C, D...

AQUECIMENTO GERAL

Preparação global
${warmAddedList(w.general,'general')}

AQUECIMENTO ESPECÍFICO

Mobilidade, estabilidade, ativação e preparação
${warmAddedList(w.specific,'specific')}
${pickerModal()}
`} else if(page==='todayWorkout'){let w=demoWorkout(),wu=warmupFor(selectedStudentIndex),all=[];(wu.general.length?wu.general:w.general).forEach((e,i)=>all.push(['AQUECIMENTO GERAL',e,'g'+i]));(wu.specific.length?wu.specific:w.specific).forEach((e,i)=>all.push(['AQUECIMENTO ESPECÍFICO',e,'s'+i]));w.blocks.forEach((b,bi)=>b.forEach((e,i)=>all.push(['BLOCO '+(bi+1),e,'b'+bi+'_'+i])));let done=all.filter(x=>studentWorkoutLog.done[x[2]]).length;A.innerHTML=`
TREINO DE HOJE
${selectedType||'FULL BODY'}
HOJE

${selectedType||'FULL BODY'}

${done} de ${all.length} exercícios concluídos
${['AQUECIMENTO GERAL','AQUECIMENTO ESPECÍFICO',...w.blocks.map((_,i)=>'BLOCO '+(i+1))].map(sec=>{let xs=all.filter(x=>x[0]===sec);return xs.length?`${xs.map(x=>studentExCard(x[1],x[2])).join('')}`:''}).join('')}
`} else if(page==='workoutFeedback'){A.innerHTML=`
TREINO CONCLUÍDO
COMO FOI HOJE?
✓

Bom trabalho!

Seu registro ajuda Renilce a acompanhar sua evolução e ajustar os próximos treinos.

${studentWorkoutLog.rpe||5}
${studentWorkoutLog.pain==='Sim'?`
`:''}
`} else if(page==='prescriptionHub'){let desc=SERVICE_TYPES[prescriptionMode]?.desc||'';A.innerHTML=`
${prescriptionMode}
${desc.toUpperCase()}
${prescriptionMode==='TREINO'?`
👥

Prescrição para aula em grupo

Uma programação é criada e vinculada a vários alunos da categoria TREINO.
Selecionar turmaSelecionar alunosMontar blocosPublicar aula
`:prescriptionMode==='PERFORMANCE'?`
🏃

Prescrição de performance

A programação parte da modalidade, objetivo esportivo e calendário do atleta.
AtletaModalidadeObjetivo / provaTreinoEvolução
`:`
👤

Prescrição personalizada

Treino individual baseado na avaliação, aquecimento padrão e evolução do aluno.
AlunoAvaliaçãoAquecimento padrãoTreinos A/B/C/D
`}
`} else if(page==='studentMonthly'){let st=students[studentDemoIndex]||students[0],p=studentActiveProgram||publishedProgramForStudent(studentDemoIndex);studentActiveProgram=p;A.innerHTML=`
RENILCE DIAS
MEUS TREINOS
PROGRAMAÇÃO ATUAL

${p?monthLabel(p):'SEM PROGRAMAÇÃO'}

${st.name} • ${st.service||'TREINO'}
${p?p.workouts.map((w,i)=>{let pr=monthlyProgress(w,i),log=getMonthlyLog(i);return `
${w.name}
${w.type} • ${w.focus||'Treinamento físico'}
${log.finished?'CONCLUÍDO':pr+'%'}
`}).join(''):`
Nenhum treino publicado.
Quando Renilce publicar a programação mensal, ela aparecerá aqui.
`}
`} else if(page==='studentMonthlyWorkout'){let p=studentActiveProgram,w=p.workouts[studentActiveWorkout],log=getMonthlyLog(studentActiveWorkout),counter=0;A.innerHTML=`
${w.name}
${monthLabel(p)} • ${w.type}
${(w.blocks||[]).map((b,bi)=>`

${b.name}

${(b.exercises||[]).map((e,ei)=>{let key=bi+'_'+ei;return `
${e.name}
${e.sets||'—'} séries • ${e.reps||'—'} reps • intervalo ${e.rest||'—'}
${e.note?`
💬 ${e.note}
`:''}${v25VideoButton(e.name,'studentMonthlyWorkout')}
`}).join('')||'
Bloco sem exercícios.
'}`).join('')}
`} else if(page==='studentMonthlyFeedback'){let l=getMonthlyLog(studentActiveWorkout),w=studentActiveProgram.workouts[studentActiveWorkout];A.innerHTML=`
TREINO CONCLUÍDO
${w.name} • FEEDBACK
ESFORÇO PERCEBIDO
DOR / DESCONFORTO${l.pain==='Sim'?``:''}
`} else if(page==='connectedLibrary'){let list=connectedFilteredExercises();A.innerHTML=`
BIBLIOTECA
${exerciseDB.length} EXERCÍCIOS • BLOCO ${connectedPickerBlock+1}
${['TODOS','DJ','DQ','EMP','PX','ANTI','POT','PLIO','BASE','INTERMEDIÁRIO','AVANÇADO'].map(f=>``).join('')}
${list.length} resultado(s) exibidos${connectedFilteredExercises().length>=120?' • refine a busca para localizar mais rápido':''}
${list.map((x,i)=>`
${exText(x)}
${exMeta(x)||'EXERCÍCIO DA BIBLIOTECA'}
`).join('')||`
Nenhum exercício encontrado. Tente outro termo ou filtro.
`}
`} else if(page==='connectedWorkoutEditor'){let w=currentConnectedWorkout();A.innerHTML=`
${w.name}
EDITOR CONECTADO • ${w.type}
TREINO INDEPENDENTE
${w.blocks.map((b,bi)=>`
${b.name}
${b.exercises.map((e,ei)=>`
${e.name}
`).join('')||'
Nenhum exercício neste bloco.
'}
`).join('')}
`} else if(page==='monthlyPrograms'){A.innerHTML=`
TREINO
PROGRAMAÇÕES MENSAIS
COMO FUNCIONA
Monte uma programação para o mês, inclua quantos treinos desejar e publique para os alunos da categoria TREINO. Não há vínculo com turma ou horário.
${monthlyPrograms.map((p,i)=>`
${monthLabel(p)}
${p.workouts.length} treino(s) • ${p.students.length} aluno(s)
${p.status}
`).join('')}
`} else if(page==='monthlyEditor'){let p=monthlyPrograms[activeMonthlyProgram],eligible=students.map((x,i)=>({x,i})).filter(o=>o.x.service==='TREINO');A.innerHTML=`
${monthLabel(p)}
PROGRAMAÇÃO MENSAL • TREINO
PERÍODO

TREINOS DO MÊS

${p.workouts.map((w,i)=>`
${w.name}
`).join('')}

ENVIAR PARA ALUNOS

Selecione os alunos da categoria TREINO que receberão toda esta programação mensal.
${eligible.map(o=>``).join('')||'
Nenhum aluno cadastrado em TREINO.
'}
`} else if(page==='groupBuilderLegacy'){let eligible=students.map((x,i)=>({x,i})).filter(o=>o.x.service==='TREINO');A.innerHTML=`
AULA EM GRUPO
TREINO
NOME DA AULA / TURMA
ALUNOS DA AULA
Selecione vários alunos. A mesma aula será publicada para todos.
${eligible.map(o=>``).join('')||'
Nenhum aluno cadastrado em TREINO.
'}
ESTRUTURA DA AULA
Aquecimento da aula + blocos coletivos. Cargas e adaptações podem ser registradas individualmente durante a execução.
`} else if(page==='performanceBuilder'){let perf=students.map((x,i)=>({x,i})).filter(o=>o.x.service==='PERFORMANCE');A.innerHTML=`
PERFORMANCE
PREPARAÇÃO FÍSICA & DESEMPENHO
ATLETA
CONTEXTO ESPORTIVO
MODALIDADE
FOCO
PRESCRIÇÃO
O treino continua usando sua biblioteca e seus blocos, mas fica identificado pela modalidade e objetivo esportivo.
`} else if(page==='services'){A.innerHTML=`
ALUNOS
POR CATEGORIA DE SERVIÇO
${Object.keys(SERVICE_TYPES).map(k=>`
${serviceCount(k)} aluno(s)
${SERVICE_TYPES[k].label}
${SERVICE_TYPES[k].desc}
`).join('')}
`} else if(page==='serviceStudents'){let list=studentServiceFilter==='TODOS'?students:students.filter(s=>s.service===studentServiceFilter);A.innerHTML=`
${studentServiceFilter==='TODOS'?'TODOS OS ALUNOS':studentServiceFilter}
${studentServiceFilter==='TODOS'?'CADASTROS ATIVOS':SERVICE_TYPES[studentServiceFilter].desc.toUpperCase()}
${Object.keys(SERVICE_TYPES).map(k=>``).join('')}
${list.map(s=>{let idx=students.indexOf(s);return `
${s.name}
${s.objective||'Objetivo não informado'}
${serviceLabel(s)}
`}).join('')||`
Nenhum aluno nesta categoria.
`}
`} else if(page==='coachStudentDashboard'){let s=coachStudent(),h=coachHistory(),pf=painFlags(),loads=recentLoads();A.innerHTML=`
ACOMPANHAMENTO
PAINEL PROFISSIONAL
ALUNO

${s.name}

${s.objective||'Objetivo não informado'} • ${s.level||'Nível não informado'}
${serviceLabel(s)}
${h.length}TREINOS
${avgRpe()}RPE MÉDIO
${attendanceRate()}%CONCLUSÃO
${pf.length?`
⚠️ ALERTAS RECENTES${pf.slice(0,3).map(x=>`
${x.painArea||'Dor/desconforto'}
${x.date} • ${x.name} • RPE ${x.rpe}/10
${x.note?`
${x.note}
`:''}
`).join('')}
`:`
ALERTAS
Nenhum relato recente de dor/desconforto.
`}
CARGAS REGISTRADAS${loads.length?loads.map(x=>`
${x.date} • ${x.name}${x.loads}
`).join(''):`
Ainda sem cargas registradas.
`}
ÚLTIMOS TREINOS
${h.slice(0,5).map(x=>`
${x.name} • ${x.type}
${x.date} • ${x.done}% concluído • RPE ${x.rpe}/10
`).join('')}
CATEGORIA DO ALUNO
${Object.keys(SERVICE_TYPES).map(k=>``).join('')}
${(SERVICE_TYPES[s.service]||SERVICE_TYPES.TREINO).desc}
AÇÕES RÁPIDAS
`} else if(page==='evolution'){let pains=workoutHistory.filter(x=>x.pain==='Sim').length;let completed=workoutHistory.length;A.innerHTML=`
MINHA EVOLUÇÃO
HISTÓRICO DE TREINOS
TREINOS${completed}
registrados
RPE MÉDIO${avgRpe()}
esforço percebido
${pains?`
⚠️ ${pains} treino(s) com registro de dor/desconforto. Essas informações ficam disponíveis para revisão profissional.
`:''}${workoutHistory.map((h,i)=>`
${h.name} • ${h.type}
${h.date} • ${h.done}% concluído • RPE ${h.rpe}/10
${h.loads?`
🏋 ${h.loads}
`:''}${h.pain==='Sim'?`
⚠️ Dor/desconforto: ${h.painArea||'não informado'}
`:''}${h.note?`
💬 ${h.note}
`:''}
`).join('')}
O QUE ACOMPANHAMOS

Frequência, conclusão dos treinos, esforço percebido, cargas registradas e relatos de dor/desconforto.

`} else if(page==='profile') A.innerHTML=`

Renilce Dias

TREINAMENTO FÍSICO & PERFORMANCE

Fundadora do DUO Centro de Treinamento Integrado

SOBRE MIM

Profissional de Educação Física, fundadora do DUO Centro de Treinamento Integrado, com atuação voltada ao treinamento físico, qualidade do movimento, força, condicionamento e performance.

FORMAÇÃO

Graduação em Educação Física.

Pós-graduação em Exercício Físico para Grupos Especiais.

Pós-graduação em Lesões Musculoesqueléticas e Traumáticas — Prevenção e Reabilitação.

Cursos de Treinamento Físico Funcional, do básico ao avançado, e Preparação Física.

${nav('profile')}
`; else A.innerHTML=`
RENILCE DIAS
${page==='evo'?'Minha evolução':'Avaliação'}

Módulo preparado para a próxima etapa da construção.

${nav(page)}
`; } render();
SALVAMENTO LOCAL ATIVO
⚙ NUVEM AGUARDANDO CONFIGURAÇÃO
TREINAMENTO FÍSICO & PERFORMANCE
Acesso profissional
Entre com a conta criada no Supabase.