import React, { useEffect, useMemo, useState } from 'react';
import { createRoot } from 'react-dom/client';
import './style.css';

const TODAY = () => new Date().toLocaleDateString('en-CA');
const BASE = {
  settings:{start:110,target:99,height:186,weekly:4,calories:2200,protein:160,deadline:'2026-12-31'},
  weights:[{id:1,date:'2026-10-22',weight:110,waist:113,note:'Mesure de départ'}],
  meals:[],workouts:[]
};
const pages = [
  ['dashboard','◈','Dashboard'],['progress','↗','Progression'],['nutrition','◉','Nutrition'],
  ['training','✦','Entraînement'],['coach','✧','Coach IA'],['settings','⚙','Objectifs & données']
];
const fmt = (v,d=1) => Number(v).toLocaleString('fr-FR',{minimumFractionDigits:d,maximumFractionDigits:d});
const esc = (s='') => String(s).replace(/[&<>"']/g,c=>({'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;',"'":'&#39;'}[c]));
function readState(){try{const v=JSON.parse(localStorage.getItem('goldenFitnessV1'));return v&&v.settings&&Array.isArray(v.weights)?v:structuredClone(BASE)}catch{return structuredClone(BASE)}}
function App(){
 const [state,setState]=useState(readState),[page,setPage]=useState('dashboard'),[toast,setToast]=useState('');
 const [weightForm,setWeightForm]=useState({date:TODAY(),weight:'',waist:'',note:''});
 const [mealForm,setMealForm]=useState({date:TODAY(),type:'Petit-déjeuner',name:'',calories:'',protein:''});
 const [workForm,setWorkForm]=useState({date:TODAY(),type:'Tapis de marche',minutes:'',intensity:'Modérée',note:''});
 const [coachTopic,setCoachTopic]=useState('general'),[coachOutput,setCoachOutput]=useState('');
 const [settingsForm,setSettingsForm]=useState(state.settings);
 useEffect(()=>{localStorage.setItem('goldenFitnessV1',JSON.stringify(state));setSettingsForm(state.settings)},[state]);
 useEffect(()=>{if(toast){const t=setTimeout(()=>setToast(''),2300);return()=>clearTimeout(t)}},[toast]);
 const latest=[...state.weights].sort((a,b)=>b.date.localeCompare(a.date))[0]||{weight:state.settings.start,waist:null,date:'—'};
 const weekStart=()=>{const d=new Date();d.setHours(0,0,0,0);d.setDate(d.getDate()-((d.getDay()+6)%7));return d.toLocaleDateString('en-CA')};
 const weekWorkouts=state.workouts.filter(x=>x.date>=weekStart()&&x.date<=TODAY());
 const monthWorkouts=state.workouts.filter(x=>x.date.slice(0,7)===TODAY().slice(0,7));
 const weightSorted=[...state.weights].sort((a,b)=>a.date.localeCompare(b.date));
 const loss=Number(state.settings.start)-Number(latest.weight),remaining=Math.max(0,Number(latest.weight)-Number(state.settings.target));
 const goalSpan=Number(state.settings.start)-Number(state.settings.target);
 const goalPct=goalSpan>0?Math.max(0,Math.min(100,loss/goalSpan*100)):0;
 const mealsToday=state.meals.filter(x=>x.date===TODAY());
 const caloriesToday=mealsToday.reduce((a,x)=>a+Number(x.calories),0),proteinToday=mealsToday.reduce((a,x)=>a+Number(x.protein||0),0);
 function patch(k,id){setState(s=>({...s,[k]:s[k].filter(x=>x.id!==id)}));setToast('Entrée supprimée')}
 function addWeight(e){e.preventDefault();setState(s=>({...s,weights:[...s.weights,{id:Date.now(),date:weightForm.date,weight:Number(weightForm.weight),waist:weightForm.waist?Number(weightForm.waist):null,note:weightForm.note.trim()}]}));setWeightForm({date:TODAY(),weight:'',waist:'',note:''});setToast('Mesure enregistrée')}
 function addMeal(e){e.preventDefault();setState(s=>({...s,meals:[...s.meals,{id:Date.now(),...mealForm,calories:Number(mealForm.calories),protein:Number(mealForm.protein||0)}]}));setMealForm({date:TODAY(),type:'Petit-déjeuner',name:'',calories:'',protein:''});setToast('Repas enregistré')}
 function addWorkout(e){e.preventDefault();setState(s=>({...s,workouts:[...s.workouts,{id:Date.now(),...workForm,minutes:Number(workForm.minutes)}]}));setWorkForm({date:TODAY(),type:'Tapis de marche',minutes:'',intensity:'Modérée',note:''});setToast('Séance enregistrée')}
 function saveSettings(e){e.preventDefault();setState(s=>({...s,settings:{...settingsForm,start:Number(settingsForm.start),target:Number(settingsForm.target),height:Number(settingsForm.height),weekly:Number(settingsForm.weekly),calories:Number(settingsForm.calories),protein:Number(settingsForm.protein)}}));setToast('Objectifs enregistrés')}
 function download(name,content,type){const a=document.createElement('a');a.href=URL.createObjectURL(new Blob([content],{type}));a.download=name;a.click();setTimeout(()=>URL.revokeObjectURL(a.href),1000)}
 function exportJson(){download('golden-fitness-sauvegarde.json',JSON.stringify(state,null,2),'application/json')}
 function exportCsv(){const rows=[['date','poids_kg','tour_taille_cm','notes'],...state.weights.map(x=>[x.date,x.weight,x.waist||'',x.note||''])];download('golden-mesures.csv',rows.map(r=>r.map(x=>'"'+String(x).replace(/"/g,'""')+'"').join(';')).join('\r\n'),'text/csv;charset=utf-8')}
 function importJson(e){const f=e.target.files?.[0];if(!f)return;const reader=new FileReader();reader.onload=()=>{try{const x=JSON.parse(reader.result);if(!x.settings||!Array.isArray(x.weights)||!Array.isArray(x.meals)||!Array.isArray(x.workouts))throw Error();setState(x);setToast('Sauvegarde importée')}catch{alert('Fichier invalide ou incompatible')}};reader.readAsText(f);e.target.value=''}
 function reset(){if(confirm('Effacer toutes les données locales ? Cette action est irréversible.')){setState(structuredClone(BASE));setToast('Données réinitialisées')}}
 function coach(){let txt='',s=state.settings,w=weekWorkouts;
 if(coachTopic==='general')txt=`BILAN PERSONNEL\nPoids actuel : ${fmt(latest.weight)} kg. Objectif : ${fmt(s.target)} kg.\nÉcart au poids de départ : ${fmt(s.start-latest.weight)} kg.\nCette semaine : ${w.length}/${s.weekly} séances.\n\nProchain pas : choisis une action simple et répétable — marche, repas planifié ou heure de coucher régulière.`;
 if(coachTopic==='nutrition')txt=`NUTRITION\nRepas enregistrés aujourd'hui : ${mealsToday.length}, soit environ ${caloriesToday} kcal sur une cible indicative de ${s.calories} kcal.\n\nPrivilégie des repas rassasiants avec une source de protéines, des légumes ou fruits, et une portion adaptée de féculents. Les calories restent des estimations.`;
 if(coachTopic==='training')txt=`ENTRAÎNEMENT\nSéances cette semaine : ${w.length}/${s.weekly}. Temps enregistré : ${w.reduce((a,x)=>a+Number(x.minutes),0)} minutes.\n\nSi tu reprends après une pause, recommence à une intensité confortable et augmente progressivement. La récupération compte aussi.`;
 if(coachTopic==='motivation')txt=`REPRISE SANS CULPABILITÉ\nUne pause n'annule pas tes progrès. Pour les prochaines 24 h :\n1. Prépare un repas simple et équilibré.\n2. Marche 15–25 minutes si tu te sens bien.\n3. Bois régulièrement et dors suffisamment.\n4. Reprends sans jugement, au prochain repas ou entraînement.`;
 if(coachTopic==='goal'){const days=s.deadline?Math.ceil((new Date(s.deadline+'T12:00:00')-new Date())/86400000):null;const rate=days>0?remaining/(days/7):null;txt=`OBJECTIF DE POIDS\nIl reste ${fmt(remaining)} kg pour atteindre ${fmt(s.target)} kg.${days!==null?`\nJours jusqu'à la date cible : ${Math.max(0,days)}.`:''}${rate!==null?`\nRythme théorique nécessaire : environ ${fmt(rate)} kg/semaine.`:''}\n\nUn rythme progressif et durable est préférable. Si le rythme théorique est supérieur à environ 1 kg/semaine, revois la date ou l'objectif avec un professionnel de santé.`}
 setCoachOutput(txt)}
 function Chart({items,keyName,suffix='',label}){const arr=[...items].sort((a,b)=>a.date.localeCompare(b.date)).slice(-14);if(!arr.length)return <div className="empty">Ajoute plusieurs mesures pour afficher la courbe.</div>;const vals=arr.map(x=>Number(x[keyName])).filter(Number.isFinite);if(!vals.length)return <div className="empty">Pas encore de données.</div>;let min=Math.min(...vals),max=Math.max(...vals);if(max-min<1){min-=1;max+=1}const W=600,H=210,L=43,R=12,T=16,B=30,iw=W-L-R,ih=H-T-B;const pts=arr.map((x,i)=>({x:L+(arr.length===1?iw/2:i*iw/(arr.length-1)),y:T+(max-Number(x[keyName]))/(max-min)*ih,v:x[keyName],d:x.date}));const path=pts.map((p,i)=>(i?'L':'M')+p.x.toFixed(1)+' '+p.y.toFixed(1)).join(' ');const labels=[...new Set([0,Math.floor((arr.length-1)/2),arr.length-1])];return <svg className="chart" viewBox={`0 0 ${W} ${H}`} role="img" aria-label={label}>{[0,.5,1].map(t=><g key={t}><line className="gridline" x1={L} x2={W-R} y1={T+ih*t} y2={T+ih*t}/><text x="2" y={T+ih*t+4}>{fmt(max-(max-min)*t)}</text></g>)}<path className="area" d={`${path} L ${pts.at(-1).x} ${T+ih} L ${pts[0].x} ${T+ih} Z`}/><path className="line" d={path}/>{pts.map((p,i)=><circle key={i} cx={p.x} cy={p.y} r="4" fill="#f1d99c"><title>{p.d}: {p.v}{suffix}</title></circle>)}{labels.map(i=><text key={i} x={pts[i].x} y={H-7} textAnchor="middle">{arr[i].date.slice(5)}</text>)}</svg>}
 function Field({label,children}){return <label className="field"><span>{label}</span>{children}</label>}
 const input=(value,onChange,type='text',props={})=><input type={type} value={value??''} onChange={e=>onChange(e.target.value)} {...props}/>;
 const select=(value,onChange,options)=><select value={value} onChange={e=>onChange(e.target.value)}>{options.map(o=><option key={o} value={o}>{o}</option>)}</select>;
 const title=pages.find(x=>x[0]===page)?.[2]||'Dashboard';
 return <div className="app">
  <aside className="sidebar"><div className="brand">GOLDEN<small>FITNESS OS · YOUR JOURNEY</small></div><nav>{pages.map(([id,icon,name])=><button key={id} className={page===id?'active':''} onClick={()=>setPage(id)}><span>{icon}</span>{name}</button>)}</nav><div className="side-note">VERSION 1.0<br/>Données locales sur cet appareil<br/><b>Discipline over motivation.</b></div></aside>
  <main className="main"><header className="top"><div><div className="eyebrow">Votre espace personnel</div><h1>{title}</h1><div className="date">{new Date().toLocaleDateString('fr-FR',{weekday:'long',day:'numeric',month:'long',year:'numeric'})}</div></div><button className="btn" onClick={()=>setPage('progress')}>＋ Saisir une mesure</button></header>
  {page==='dashboard'&&<><div className="grid stats">
    <div className="card"><div className="stat-label">POIDS ACTUEL</div><div className="stat-value">{fmt(latest.weight)} <small>kg</small></div><div className="sub">Mesuré le {latest.date}</div></div>
    <div className="card"><div className="stat-label">OBJECTIF</div><div className="stat-value gold">{fmt(state.settings.target)} <small>kg</small></div><div className="sub">{fmt(remaining)} kg avant l’objectif</div><div className="bar"><span style={{width:goalPct+'%'}}/></div></div>
    <div className="card"><div className="stat-label">TOUR DE TAILLE</div><div className="stat-value">{latest.waist?fmt(latest.waist):'—'} <small>cm</small></div><div className="sub">Dernière mesure</div></div>
    <div className="card"><div className="stat-label">SÉANCES CE MOIS</div><div className="stat-value">{monthWorkouts.length}</div><div className="sub">Objectif hebdomadaire : {state.settings.weekly}</div></div>
   </div><div className="grid two">
    <div className="card"><div className="card-head"><h2>Évolution du poids</h2><button className="btn secondary" onClick={()=>setPage('progress')}>Détails ↗</button></div><Chart items={state.weights} keyName="weight" suffix=" kg" label="Évolution du poids"/><div className="between"><span className="sub">Départ : {fmt(state.settings.start)} kg</span><span className="pill">{loss>0?'−'+fmt(loss)+' kg':loss<0?'+'+fmt(-loss)+' kg':'Point de départ'}</span></div></div>
    <div className="card"><h2>Objectifs de la semaine</h2><div className="between"><span>🏃 Séances de sport</span><b className="gold">{weekWorkouts.length} / {state.settings.weekly}</b></div><div className="bar"><span style={{width:Math.min(100,weekWorkouts.length/state.settings.weekly*100)+'%'}}/></div><div className="between"><span>⚖️ Mesures enregistrées</span><b>{state.weights.length}</b></div><hr/><h3>Actions rapides</h3><div className="quick"><button onClick={()=>setPage('progress')}><b>＋</b>Poids</button><button onClick={()=>setPage('nutrition')}><b>＋</b>Repas</button><button onClick={()=>setPage('training')}><b>＋</b>Sport</button></div></div>
   </div><div className="grid two lower"><div className="card"><h2>Résumé nutrition</h2><div className="listrow"><div>Apport calorique cible<span>Repère journalier personnalisable</span></div><b className="gold">{Number(state.settings.calories).toLocaleString('fr-FR')} kcal</b></div><div className="listrow"><div>Protéines cibles<span>À adapter selon tes besoins</span></div><b className="gold">{state.settings.protein} g</b></div><div className="listrow"><div>Repas enregistrés aujourd'hui<span>Sur cet appareil</span></div><b>{mealsToday.length}</b></div></div><div className="card coach"><div className="coach-mark">✧</div><h2>Votre focus du jour</h2><p>{weekWorkouts.length>=state.settings.weekly?'Objectif sport atteint : garde un rythme soutenable et pense à récupérer.':`Une marche de 15 à 30 minutes peut être un bon prochain pas. Tu es à ${weekWorkouts.length}/${state.settings.weekly} séances cette semaine.`}</p><button className="btn secondary" onClick={()=>setPage('coach')}>Parler au coach →</button></div></div></>}
  {page==='progress'&&<><div className="grid two"><div className="card"><h2>Ajouter une mesure</h2><form onSubmit={addWeight} className="formgrid"><Field label="Date">{input(weightForm.date,v=>setWeightForm({...weightForm,date:v}),'date',{required:true})}</Field><Field label="Poids (kg)">{input(weightForm.weight,v=>setWeightForm({...weightForm,weight:v}),'number',{min:30,max:350,step:.1,required:true,placeholder:'110.0'})}</Field><Field label="Tour de taille (cm)">{input(weightForm.waist,v=>setWeightForm({...weightForm,waist:v}),'number',{min:30,max:250,step:.5,placeholder:'113'})}</Field><Field label="Notes">{input(weightForm.note,v=>setWeightForm({...weightForm,note:v},'text'))}</Field><div className="form-actions full"><button className="btn">Enregistrer la mesure</button></div></form></div><div className="card"><h2>Indicateurs clés</h2><div className="listrow"><div>Variation depuis le départ</div><b className="gold">{loss>0?'−':loss<0?'+':''}{fmt(Math.abs(loss))} kg</b></div><div className="listrow"><div>IMC estimé</div><b>{fmt(latest.weight/Math.pow(state.settings.height/100,2))}</b></div><div className="listrow"><div>Objectif restant</div><b>{fmt(remaining)} kg</b></div><p className="notice">L’IMC est un indicateur général et ne distingue pas masse grasse et masse musculaire.</p></div></div><div className="grid two lower"><div className="card"><h2>Courbe de poids</h2><Chart items={state.weights} keyName="weight" suffix=" kg" label="Courbe de poids"/></div><div className="card"><h2>Tour de taille</h2><Chart items={state.weights.filter(x=>x.waist)} keyName="waist" suffix=" cm" label="Tour de taille"/></div></div><div className="card lower"><div className="card-head"><h2>Historique des mesures</h2><button className="btn secondary" onClick={exportCsv}>Exporter CSV</button></div><div className="tablewrap"><table><thead><tr><th>Date</th><th>Poids</th><th>Tour de taille</th><th>Notes</th><th/></tr></thead><tbody>{weightSorted.slice().reverse().map(x=><tr key={x.id}><td>{x.date}</td><td>{fmt(x.weight)} kg</td><td>{x.waist?fmt(x.waist)+' cm':'—'}</td><td>{x.note||'—'}</td><td><button className="textbtn" onClick={()=>patch('weights',x.id)}>Supprimer</button></td></tr>)}</tbody></table></div></div></>}
  {page==='nutrition'&&<><div className="grid two"><div className="card"><h2>Enregistrer un repas</h2><form onSubmit={addMeal} className="formgrid"><Field label="Date">{input(mealForm.date,v=>setMealForm({...mealForm,date:v}),'date',{required:true})}</Field><Field label="Repas">{select(mealForm.type,v=>setMealForm({...mealForm,type:v}),['Petit-déjeuner','Déjeuner','Collation','Dîner'])}</Field><Field label="Description">{input(mealForm.name,v=>setMealForm({...mealForm,name:v}),'text',{required:true,placeholder:'Poulet, riz, légumes…'})}</Field><Field label="Calories estimées (kcal)">{input(mealForm.calories,v=>setMealForm({...mealForm,calories:v}),'number',{min:0,max:10000,required:true,placeholder:'550'})}</Field><Field label="Protéines (g, facultatif)">{input(mealForm.protein,v=>setMealForm({...mealForm,protein:v}),'number',{min:0,placeholder:'35'})}</Field><div className="form-actions full"><button className="btn">Ajouter le repas</button></div></form></div><div className="card"><h2>Aujourd'hui</h2><div className="stat-value gold">{caloriesToday.toLocaleString('fr-FR')} <small>/ {Number(state.settings.calories).toLocaleString('fr-FR')} kcal</small></div><div className="bar"><span style={{width:Math.min(100,caloriesToday/state.settings.calories*100)+'%'}}/></div><div className="listrow"><div>Protéines enregistrées</div><b>{fmt(proteinToday,0)} g</b></div><div className="listrow"><div>Repas enregistrés</div><b>{mealsToday.length}</b></div><p className="notice">Les calories sont des estimations ; les portions et marques peuvent faire varier les valeurs.</p></div></div><div className="card lower"><div className="card-head"><h2>Journal alimentaire</h2><button className="btn secondary" onClick={()=>{if(confirm('Supprimer tous les repas ?'))setState(s=>({...s,meals:[]}))}}>Vider les repas</button></div><div className="tablewrap"><table><thead><tr><th>Date</th><th>Repas</th><th>Description</th><th>Calories</th><th>Protéines</th><th/></tr></thead><tbody>{[...state.meals].sort((a,b)=>b.date.localeCompare(a.date)).map(x=><tr key={x.id}><td>{x.date}</td><td>{x.type}</td><td>{x.name}</td><td>{x.calories} kcal</td><td>{x.protein||0} g</td><td><button className="textbtn" onClick={()=>patch('meals',x.id)}>Supprimer</button></td></tr>)}</tbody></table></div></div></>}
  {page==='training'&&<><div className="grid two"><div className="card"><h2>Enregistrer une séance</h2><form onSubmit={addWorkout} className="formgrid"><Field label="Date">{input(workForm.date,v=>setWorkForm({...workForm,date:v}),'date',{required:true})}</Field><Field label="Activité">{select(workForm.type,v=>setWorkForm({...workForm,type:v}),['Tapis de marche','Marche extérieure','Musculation','Vélo','Course','Autre'])}</Field><Field label="Durée (minutes)">{input(workForm.minutes,v=>setWorkForm({...workForm,minutes:v}),'number',{min:1,max:600,required:true,placeholder:'40'})}</Field><Field label="Intensité">{select(workForm.intensity,v=>setWorkForm({...workForm,intensity:v}),['Modérée','Légère','Élevée'])}</Field><Field label="Notes (facultatif)">{input(workForm.note,v=>setWorkForm({...workForm,note:v}),'text',{placeholder:'Inclinaison, sensations…'})}</Field><div className="form-actions full"><button className="btn">Enregistrer la séance</button></div></form></div><div className="card"><h2>Volume d’entraînement</h2><div className="stat-value gold">{weekWorkouts.reduce((a,x)=>a+Number(x.minutes),0)} <small>min cette semaine</small></div><div className="listrow"><div>Séances cette semaine</div><b>{weekWorkouts.length}</b></div><div className="listrow"><div>Objectif hebdomadaire</div><b>{state.settings.weekly} séances</b></div><p className="notice">Reprends progressivement et adapte l’effort à ta condition physique. Arrête en cas de douleur inhabituelle ou de malaise.</p></div></div><div className="card lower"><div className="card-head"><h2>Historique du sport</h2><button className="btn secondary" onClick={()=>{if(confirm('Supprimer toutes les séances ?'))setState(s=>({...s,workouts:[]}))}}>Vider les séances</button></div><div className="tablewrap"><table><thead><tr><th>Date</th><th>Activité</th><th>Durée</th><th>Intensité</th><th>Notes</th><th/></tr></thead><tbody>{[...state.workouts].sort((a,b)=>b.date.localeCompare(a.date)).map(x=><tr key={x.id}><td>{x.date}</td><td>{x.type}</td><td>{x.minutes} min</td><td>{x.intensity}</td><td>{x.note||'—'}</td><td><button className="textbtn" onClick={()=>patch('workouts',x.id)}>Supprimer</button></td></tr>)}</tbody></table></div></div></>}
  {page==='coach'&&<div className="grid two"><div className="card coach"><div className="eyebrow">GOLDEN INTELLIGENCE</div><h2>Coach personnel</h2><p>Conseils de départ basés sur les données saisies. Ils ne remplacent pas un professionnel de santé.</p><Field label="Qu’est-ce que tu veux travailler ?"><select value={coachTopic} onChange={e=>setCoachTopic(e.target.value)}><option value="general">Mon bilan général</option><option value="nutrition">Nutrition et repas</option><option value="training">Sport et régularité</option><option value="motivation">Motivation après une pause</option><option value="goal">Mon objectif de poids</option></select></Field><div className="form-actions"><button className="btn" onClick={coach}>Générer mon bilan</button></div><div className="coach-output">{coachOutput||'Choisis un thème pour obtenir des conseils à partir des données enregistrées.'}</div></div><div className="card"><h2>Ta fiche actuelle</h2><div className="listrow"><div>Dernier poids</div><b className="gold">{fmt(latest.weight)} kg</b></div><div className="listrow"><div>Objectif</div><b>{fmt(state.settings.target)} kg</b></div><div className="listrow"><div>Dernière mesure</div><b>{latest.date}</b></div><div className="listrow"><div>Séances cette semaine</div><b>{weekWorkouts.length}</b></div><p className="notice">Le coach de cette version fonctionne localement avec des règles prédéfinies. Il n’appelle pas encore de modèle d’IA externe.</p></div></div>}
  {page==='settings'&&<div className="grid two"><div className="card"><h2>Mes objectifs</h2><form onSubmit={saveSettings} className="formgrid"><Field label="Poids de départ (kg)">{input(settingsForm.start,v=>setSettingsForm({...settingsForm,start:v}),'number',{step:.1,min:30,max:350,required:true})}</Field><Field label="Poids cible (kg)">{input(settingsForm.target,v=>setSettingsForm({...settingsForm,target:v}),'number',{step:.1,min:30,max:350,required:true})}</Field><Field label="Taille (cm)">{input(settingsForm.height,v=>setSettingsForm({...settingsForm,height:v}),'number',{min:100,max:250,required:true})}</Field><Field label="Séances / semaine">{input(settingsForm.weekly,v=>setSettingsForm({...settingsForm,weekly:v}),'number',{min:1,max:14,required:true})}</Field><Field label="Calories cibles / jour">{input(settingsForm.calories,v=>setSettingsForm({...settingsForm,calories:v}),'number',{min:800,max:6000,required:true})}</Field><Field label="Protéines cibles / jour (g)">{input(settingsForm.protein,v=>setSettingsForm({...settingsForm,protein:v}),'number',{min:0,max:400,required:true})}</Field><Field label="Date cible">{input(settingsForm.deadline,v=>setSettingsForm({...settingsForm,deadline:v}),'date')}</Field><div className="form-actions full"><button className="btn">Enregistrer les objectifs</button></div></form></div><div className="card"><h2>Gestion des données</h2><p className="sub">Les données sont stockées dans le navigateur, sur cet appareil. Elles ne se synchronisent pas automatiquement entre iPhone et ordinateur.</p><div className="form-actions wrap"><button className="btn secondary" onClick={exportJson}>Exporter mes données (JSON)</button><label className="btn secondary filebtn">Importer une sauvegarde<input type="file" accept=".json,application/json" onChange={importJson} hidden/></label></div><hr/><button className="btn danger" onClick={reset}>Réinitialiser toutes les données</button><p className="notice">Exporte régulièrement une sauvegarde. Effacer les données du navigateur peut supprimer les informations locales.</p></div></div>}
  <footer className="notice footer">GOLDEN · Fitness OS — prototype personnel. Les objectifs nutritionnels sont des repères, pas une prescription médicale.</footer>
  </main><nav className="mobile-nav">{pages.map(([id,icon,name])=><button key={id} className={page===id?'active':''} onClick={()=>setPage(id)}><span>{icon}</span><small>{name==='Tableau de bord'?'Accueil':name}</small></button>)}</nav>{toast&&<div className="toast">{toast}</div>}
 </div>
}
createRoot(document.getElementById('root')).render(<App/>);
