/* global React, ReactDOM */
const { useState, useEffect, useMemo, useRef } = React;

/* ============================================================
   Diario del Ciclo — Dra. Carolina Nazario Josoy, ND
   Brand-aligned (cream · bronze · olive · periwinkle · clay)
   Persiste en localStorage (sobrevive recargas).
   ============================================================ */

const PHASES = {
  menstrual: { key:"menstrual", es:"Menstruación", color:"#B6566A", soft:"#F4E2E5", ink:"#7E2E40", icon:"drop",
    desc:"Días de sangrado. El cuerpo libera el revestimiento uterino." },
  folicular: { key:"folicular", es:"Fase folicular", color:"#7D8744", soft:"#E9ECD7", ink:"#4F5826", icon:"sprout",
    desc:"Después del sangrado. Sube la energía y el estrógeno." },
  ovulacion: { key:"ovulacion", es:"Ovulación", color:"#C98A2B", soft:"#F6E9CF", ink:"#84591A", icon:"sun",
    desc:"Liberación del óvulo. Ventana fértil y pico de energía." },
  lutea:     { key:"lutea", es:"Fase lútea", color:"#818AC0", soft:"#E6E8F3", ink:"#4A507F", icon:"moon",
    desc:"Antes de la menstruación. Pueden aparecer síntomas premenstruales." },
};

function phaseForDay(day, cycleLength = 28, periodLength = 5) {
  if (day < 1) return PHASES.menstrual;
  const ovulationDay = cycleLength - 14;
  if (day <= periodLength) return PHASES.menstrual;
  if (day < ovulationDay - 1) return PHASES.folicular;
  if (day >= ovulationDay - 1 && day <= ovulationDay + 1) return PHASES.ovulacion;
  return PHASES.lutea;
}

const MOODS = [
  { k:"radiante", e:"☀️", es:"Radiante" }, { k:"estable", e:"🙂", es:"Estable" },
  { k:"cansada", e:"😴", es:"Cansada" }, { k:"irritable", e:"😤", es:"Irritable" },
  { k:"ansiosa", e:"😟", es:"Ansiosa" }, { k:"triste", e:"🌧️", es:"Triste" },
  { k:"sensible", e:"🤍", es:"Sensible" },
];
const FLOW = [
  { k:"manchado", es:"Manchado", dots:1 }, { k:"ligero", es:"Ligero", dots:2 },
  { k:"moderado", es:"Moderado", dots:3 }, { k:"abundante", es:"Abundante", dots:4 },
];
const BLOOD_COLORS = [
  { k:"rosado", es:"Rosado", c:"#E8A6B4" }, { k:"rojo_brillante", es:"Rojo brillante", c:"#C8324B" },
  { k:"rojo_oscuro", es:"Rojo oscuro", c:"#8E1F33" }, { k:"marron", es:"Marrón", c:"#6E4326" },
];
const DISCHARGE = [
  { k:"seca", es:"Seca / nada" }, { k:"pegajosa", es:"Pegajosa" }, { k:"cremosa", es:"Cremosa" },
  { k:"clara_huevo", es:"Clara de huevo (elástica)" }, { k:"acuosa", es:"Acuosa" },
];
const LUTEAL_SX = [
  { k:"senos", es:"Senos sensibles" }, { k:"cabeza", es:"Dolor de cabeza" }, { k:"fatiga", es:"Fatiga" },
  { k:"hinchazon", es:"Hinchazón" }, { k:"antojos", es:"Antojos" }, { k:"acne", es:"Acné" },
  { k:"insomnio", es:"Insomnio" }, { k:"calambres", es:"Calambres" },
];
const OVU_SIDE = [
  { k:"izquierdo", es:"Lado izquierdo" }, { k:"centro", es:"Centro" }, { k:"derecho", es:"Lado derecho" },
];

/* ---------- storage (localStorage, namespaced) ---------- */
const NS = "cnj-cycle:";
const store = {
  get(k){ try { const v = localStorage.getItem(NS+k); return v==null?null:JSON.parse(v); } catch(e){ return null; } },
  set(k,v){ try { localStorage.setItem(NS+k, JSON.stringify(v)); } catch(e){} },
  del(k){ try { localStorage.removeItem(NS+k); } catch(e){} },
  clearDays(){ try { Object.keys(localStorage).filter(x=>x.startsWith(NS+"day:")).forEach(x=>localStorage.removeItem(x)); } catch(e){} },
};

/* ---------- tiny inline icons ---------- */
function Icon({ name, s=22 }){
  const p = { width:s, height:s, viewBox:"0 0 24 24", fill:"none", stroke:"currentColor",
    strokeWidth:1.6, strokeLinecap:"round", strokeLinejoin:"round" };
  const paths = {
    drop:<path d="M12 3c4 4.5 6.5 7.8 6.5 11A6.5 6.5 0 0 1 5.5 14C5.5 10.8 8 7.5 12 3Z"/>,
    sprout:<g><path d="M12 21v-7"/><path d="M12 14c0-3 2-5 5-5 0 3-2 5-5 5Z"/><path d="M12 16c0-2.4-1.7-4-4-4 0 2.4 1.7 4 4 4Z"/></g>,
    sun:<g><circle cx="12" cy="12" r="4.2"/><path d="M12 2.5v2.6M12 18.9v2.6M2.5 12h2.6M18.9 12h2.6M5.2 5.2l1.8 1.8M17 17l1.8 1.8M18.8 5.2 17 7M7 17l-1.8 1.8"/></g>,
    moon:<path d="M20 13.4A8 8 0 1 1 10.6 4 6.3 6.3 0 0 0 20 13.4Z"/>,
    thermo:<g><path d="M14 14.8V5a2 2 0 0 0-4 0v9.8a4 4 0 1 0 4 0Z"/><path d="M12 9v6"/></g>,
    pill:<g><rect x="3" y="9" width="18" height="6" rx="3" transform="rotate(-45 12 12)"/><path d="M8.5 8.5 15.5 15.5"/></g>,
    note:<g><path d="M5 4h11l3 3v13H5Z"/><path d="M9 11h6M9 15h4"/></g>,
    print:<g><path d="M6 9V3h12v6"/><path d="M6 18H4a2 2 0 0 1-2-2v-3a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v3a2 2 0 0 1-2 2h-2"/><rect x="6" y="14" width="12" height="7"/></g>,
    reset:<g><path d="M3 12a9 9 0 1 0 3-6.7"/><path d="M3 4v4h4"/></g>,
    spark:<path d="M12 3v4M12 17v4M3 12h4M17 12h4M6 6l2.5 2.5M15.5 15.5 18 18M18 6l-2.5 2.5M8.5 15.5 6 18"/>,
    check:<path d="M20 6 9 17l-5-5"/>,
    heart:<path d="M12 21s-7-4.4-9.2-9C1.3 8.5 3 5.5 6.2 5.5c2 0 3.2 1.3 3.8 2.4.6-1.1 1.8-2.4 3.8-2.4 3.2 0 4.9 3 3.4 6.5C19 16.6 12 21 12 21Z"/>,
    download:<g><path d="M12 3v12"/><path d="m7 11 5 5 5-5"/><path d="M5 21h14"/></g>,
    info:<g><circle cx="12" cy="12" r="9"/><path d="M12 11v5M12 7.6h.01"/></g>,
  };
  return <svg {...p}>{paths[name]||null}</svg>;
}

/* ---------- cycle wheel (signature visual) ---------- */
function polar(cx, cy, r, deg){ const a = deg*Math.PI/180; return [cx + r*Math.sin(a), cy - r*Math.cos(a)]; }
function seg(cx, cy, rO, rI, a0, a1){
  const [x0o,y0o]=polar(cx,cy,rO,a0), [x1o,y1o]=polar(cx,cy,rO,a1);
  const [x1i,y1i]=polar(cx,cy,rI,a1), [x0i,y0i]=polar(cx,cy,rI,a0);
  const lg = (a1-a0) > 180 ? 1 : 0;
  return `M${x0o} ${y0o} A${rO} ${rO} 0 ${lg} 1 ${x1o} ${y1o} L${x1i} ${y1i} A${rI} ${rI} 0 ${lg} 0 ${x0i} ${y0i} Z`;
}
function CycleWheel({ cycleLength, periodLength, day, entries, onPick }){
  const C=170, RO=158, RI=120, step=360/cycleLength, gap=Math.min(1.6, step*0.12);
  const ph = phaseForDay(day, cycleLength, periodLength);
  return (
    <div className="wheel">
      <svg viewBox="0 0 340 340" width="100%" height="100%" role="img" aria-label={`Día ${day}, ${ph.es}`}>
        {Array.from({length:cycleLength}).map((_,i)=>{
          const d=i+1, p=phaseForDay(d,cycleLength,periodLength), cur=d===day, logged=!!entries[d];
          const a0=i*step+gap/2, a1=(i+1)*step-gap/2;
          const [mx,my]=polar(C,C,(RO+RI)/2,(a0+a1)/2);
          return (
            <g key={d} className="wseg" onClick={()=>onPick(d)} style={{cursor:"pointer"}}>
              <path d={seg(C,C,cur?RO+6:RO,RI,a0,a1)} fill={cur?p.color:p.soft}
                stroke={cur?p.ink:"#fff"} strokeWidth={cur?1.5:1}/>
              {logged && <circle cx={mx} cy={my} r={3} fill={cur?"#fff":p.ink} opacity={cur?1:.55}/>}
            </g>
          );
        })}
      </svg>
      <div className="wheel-center" style={{ "--pc":ph.color, "--pi":ph.ink }}>
        <span className="wc-icon" style={{color:ph.color}}><Icon name={ph.icon} s={26}/></span>
        <div className="wc-day">{day}</div>
        <div className="wc-sub">día del ciclo</div>
        <div className="wc-phase" style={{color:ph.ink, background:ph.soft}}>{ph.es}</div>
      </div>
    </div>
  );
}

/* ---------- subcomponents ---------- */
function Chip({ on, tone, children, onClick, swatch, emoji }){
  return (
    <button type="button" className={"chip"+(on?" on "+(tone||""):"")} onClick={onClick}>
      {swatch && <span className="swatch" style={{background:swatch}}/>}
      {emoji && <span className="emoji">{emoji}</span>}
      {children}
    </button>
  );
}
function Field({ icon, label, req, hint, children }){
  return (
    <div className="field">
      <div className="flabel">{icon && <span className="fic"><Icon name={icon} s={18}/></span>}<span>{label}</span>{req && <span className="req">clave</span>}</div>
      {children}
      {hint && <div className="fhint">{hint}</div>}
    </div>
  );
}
function Seg({ value, options, onChange }){
  return (
    <div className="seg">
      {options.map(o=>(
        <button key={o.v} type="button" className={value===o.v?"on":""} onClick={()=>onChange(o.v)}>{o.t}</button>
      ))}
    </div>
  );
}

function App(){
  const [cycleLength, setCycleLength] = useState(28);
  const [periodLength, setPeriodLength] = useState(5);
  const [day, setDay] = useState(1);
  const [entries, setEntries] = useState({});
  const [savedFlash, setSavedFlash] = useState(false);
  const [setupOpen, setSetupOpen] = useState(false);
  const saveTimer = useRef(null);
  const cardRef = useRef(null);

  // load once
  useEffect(()=>{
    const cfg = store.get("config");
    if (cfg){ if(cfg.cycleLength) setCycleLength(cfg.cycleLength); if(cfg.periodLength) setPeriodLength(cfg.periodLength); if(cfg.lastDay) setDay(cfg.lastDay); }
    const loaded = {};
    try {
      Object.keys(localStorage).filter(x=>x.startsWith(NS+"day:")).forEach(x=>{
        const d = parseInt(x.split(":")[2],10);
        const v = store.get("day:"+d);
        if (v) loaded[d]=v;
      });
    } catch(e){}
    setEntries(loaded);
  },[]);

  const phase = useMemo(()=>phaseForDay(day,cycleLength,periodLength),[day,cycleLength,periodLength]);
  const entry = entries[day] || {};
  const loggedCount = Object.keys(entries).length;

  function persist(next){
    const merged = { ...entries, [day]: next };
    setEntries(merged);
    if (saveTimer.current) clearTimeout(saveTimer.current);
    saveTimer.current = setTimeout(()=>{
      store.set("day:"+day, next);
      store.set("config", { cycleLength, periodLength, lastDay: day });
      setSavedFlash(true); setTimeout(()=>setSavedFlash(false),1500);
    }, 400);
  }
  const up = (patch)=>persist({ ...entry, ...patch });
  function toggleArr(field,val){
    const cur = Array.isArray(entry[field])?entry[field]:[];
    up({ [field]: cur.includes(val)?cur.filter(x=>x!==val):[...cur,val] });
  }
  function saveConfig(cl,pl){ setCycleLength(cl); setPeriodLength(pl); store.set("config",{cycleLength:cl,periodLength:pl,lastDay:day}); }
  function goDay(d){ setDay(d); store.set("config",{cycleLength,periodLength,lastDay:d}); }

  function exportXlsx(){
    if (!window.XLSX){ alert("No se pudo cargar el exportador de Excel. Revisa tu conexión a internet e inténtalo de nuevo."); return; }
    const map = (arr)=>Object.fromEntries(arr.map(o=>[o.k,o.es]));
    const moodMap=map(MOODS), dischMap=map(DISCHARGE), flowMap=map(FLOW), bloodMap=map(BLOOD_COLORS), sideMap=map(OVU_SIDE), lutMap=map(LUTEAL_SX);
    const clotsMap={no:"No",pequenos:"Pequeños",grandes:"Grandes"};
    const days=Object.keys(entries).map(n=>+n).sort((a,b)=>a-b);
    if (days.length===0){ alert("Aún no hay días registrados para exportar. Registra al menos un día primero."); return; }
    const rows=days.map(d=>{
      const e=entries[d]||{}; const ph=phaseForDay(d,cycleLength,periodLength);
      return {
        "Día del ciclo": d,
        "Fase": ph.es,
        "Temp. basal (°F)": e.temp!=null ? e.temp : "",
        "Ánimo": (e.mood||[]).map(k=>moodMap[k]||k).join(", "),
        "Relaciones sexuales": e.sex ? "Sí" : "",
        "Protección": e.sex ? (e.sexProtection==="protegida"?"Con protección": e.sexProtection==="sin"?"Sin protección":"") : "",
        "Descarga vaginal": e.discharge ? (dischMap[e.discharge]||e.discharge) : "",
        "Sangrado": e.flow ? (flowMap[e.flow]||e.flow) : "",
        "Color de la sangre": e.bloodColor ? (bloodMap[e.bloodColor]||e.bloodColor) : "",
        "Coágulos": e.clots ? (clotsMap[e.clots]||e.clots) : "",
        "Dolor de ovulación": e.ovuPain==="si"?"Sí": e.ovuPain==="no"?"No":"",
        "Lado de ovulación": e.ovuSide ? (sideMap[e.ovuSide]||e.ovuSide) : "",
        "Síntomas lúteos": (e.luteal||[]).map(k=>lutMap[k]||k).join(", "),
        "Prenatal": e.prenatal ? "Sí" : "No",
        "Hora prenatal": e.prenatalTime||"",
        "Prenatal con/sin comida": e.prenatalFood==="con"?"Con comida": e.prenatalFood==="sin"?"Sin comida":"",
        "Notas": e.notes||"",
      };
    });
    const ws=window.XLSX.utils.json_to_sheet(rows);
    ws["!cols"]=[{wch:12},{wch:14},{wch:15},{wch:26},{wch:18},{wch:16},{wch:22},{wch:12},{wch:17},{wch:11},{wch:17},{wch:16},{wch:30},{wch:9},{wch:13},{wch:20},{wch:42}];
    const wb=window.XLSX.utils.book_new();
    window.XLSX.utils.book_append_sheet(wb,ws,"Diario del ciclo");
    const stamp=new Date().toISOString().slice(0,10);
    window.XLSX.writeFile(wb, `Diario_Ciclo_CNJ_${stamp}.xlsx`);
  }

  const temp = entry.temp ?? null;
  const tempPct = (((temp ?? 97.5)-96)/4)*100;

  return (
    <div className="diary">
      <div className="wrap">
        <header className="head">
          <img className="brand" src="assets/logo-full.png" alt="Dra. Carolina Nazario Josoy, ND"/>
          <div className="eyebrow">Medicina Naturopática · Salud Femenina</div>
          <h1 className="h1">Diario de tu <em>ciclo</em></h1>
          <p className="sub">Cada día, registra cómo te sientes y lo que tu cuerpo te dice. Esto me ayuda a entender tu ciclo y a personalizar tu cuidado. Todo se guarda en tu dispositivo — solo tú lo ves, hasta que decidas compartirlo conmigo.</p>
        </header>

        <div className="notice">
          <Icon name="info" s={18}/>
          <p>Para no perder tu información, abre el diario <b>siempre desde el mismo dispositivo y navegador</b>, y no borres el historial, los datos ni las cookies del navegador. Todo se guarda solo en tu equipo.</p>
        </div>

        {/* Wheel + progress */}
        <section className="wheelcard">
          <CycleWheel cycleLength={cycleLength} periodLength={periodLength} day={day} entries={entries} onPick={goDay}/>
          <div className="wheelside">
            <div className="phasedesc">
              <span className="pd-pill" style={{background:phase.soft,color:phase.ink}}><span className="pd-dot" style={{background:phase.color}}/>{phase.es}</span>
              <p>{phase.desc}</p>
            </div>
            <div className="legend">
              {Object.values(PHASES).map(p=>(
                <span key={p.key} className="legitem"><span className="legdot" style={{background:p.color}}/>{p.es}</span>
              ))}
            </div>
            <div className="progress">
              <div className="pbar"><span style={{width:`${(loggedCount/cycleLength)*100}%`}}/></div>
              <span className="pcount">{loggedCount} de {cycleLength} días registrados</span>
            </div>
            <button type="button" className="setuptoggle" onClick={()=>setSetupOpen(o=>!o)}>
              <Icon name="spark" s={15}/> <span>Ajustar mi ciclo ({cycleLength} días · {periodLength} de sangrado)</span>
            </button>
            {setupOpen && (
              <div className="setup">
                <div className="setup-row">
                  <div className="l">Duración del ciclo <small>De un sangrado al siguiente</small></div>
                  <div className="stepper">
                    <button type="button" onClick={()=>saveConfig(Math.max(21,cycleLength-1),periodLength)} aria-label="menos">−</button>
                    <b>{cycleLength}</b>
                    <button type="button" onClick={()=>saveConfig(Math.min(40,cycleLength+1),periodLength)} aria-label="más">+</button>
                  </div>
                </div>
                <div className="setup-row">
                  <div className="l">Días de sangrado <small>Lo que suele durar tu periodo</small></div>
                  <div className="stepper">
                    <button type="button" onClick={()=>saveConfig(cycleLength,Math.max(2,periodLength-1))} aria-label="menos">−</button>
                    <b>{periodLength}</b>
                    <button type="button" onClick={()=>saveConfig(cycleLength,Math.min(10,periodLength+1))} aria-label="más">+</button>
                  </div>
                </div>
              </div>
            )}
          </div>
        </section>

        {/* Day card */}
        <section className="daycard" ref={cardRef}>
          <div className="dayhdr" style={{ background:`linear-gradient(135deg, ${phase.color}, ${phase.ink})` }}>
            <button type="button" className="navbtn" onClick={()=>goDay(Math.max(1,day-1))} disabled={day<=1} aria-label="Día anterior">‹</button>
            <div className="dayhdr-mid">
              <div className="dayno">{day}<small>/ {cycleLength}</small></div>
              <div className="dayhdr-phase"><Icon name={phase.icon} s={16}/> {phase.es}</div>
            </div>
            <button type="button" className="navbtn" onClick={()=>goDay(Math.min(cycleLength,day+1))} disabled={day>=cycleLength} aria-label="Día siguiente">›</button>
          </div>

          <div className="body">
            <Field icon="thermo" label="Temperatura basal" hint="Tómala al despertar, antes de levantarte, a la misma hora cada día.">
              <div className="temp-row">
                <div className="temp-val">{temp!=null ? <span>{temp.toFixed(1)}<small>°F</small></span> : <small className="temp-empty">sin registrar</small>}</div>
                <input className="range" type="range" min="96" max="100" step="0.1" value={temp ?? 97.5}
                  style={{ background:`linear-gradient(90deg, var(--salvia) ${tempPct}%, #E2DDCB ${tempPct}%)` }}
                  onChange={(e)=>up({ temp:+e.target.value })}/>
              </div>
              {temp!=null && <button type="button" className="clearlink" onClick={()=>up({ temp:null })}>✕ Borrar la temperatura de hoy</button>}
            </Field>

            <Field icon="pill" label="Pastilla prenatal">
              <div className="pill-card">
                <button type="button" className="pill-top" onClick={()=>up({ prenatal:!entry.prenatal })}>
                  <span className="t">¿Tomaste tu prenatal hoy?</span>
                  <span className={"toggle"+(entry.prenatal?" on":"")}><i/></span>
                </button>
                {entry.prenatal && (
                  <div className="pill-detail">
                    <div>
                      <div className="mini-l">¿A qué hora?</div>
                      <input className="timeinput" type="time" value={entry.prenatalTime||""} onChange={(e)=>up({ prenatalTime:e.target.value })}/>
                    </div>
                    <div>
                      <div className="mini-l">¿Con o sin comida?</div>
                      <Seg value={entry.prenatalFood} onChange={(v)=>up({ prenatalFood:v })} options={[{v:"con",t:"Con comida"},{v:"sin",t:"Sin comida"}]}/>
                    </div>
                  </div>
                )}
              </div>
            </Field>

            <Field icon="moon" label="Estado de ánimo" hint="Cómo te sentiste hoy. Puedes marcar más de uno.">
              <div className="chips">
                {MOODS.map(m=>(
                  <Chip key={m.k} emoji={m.e} on={(entry.mood||[]).includes(m.k)} tone="peri" onClick={()=>toggleArr("mood",m.k)}>{m.es}</Chip>
                ))}
              </div>
            </Field>

            <Field icon="drop" label="Descarga vaginal" hint="El flujo cambia durante el ciclo — es una señal importante de tu fertilidad.">
              <div className="chips">
                {DISCHARGE.map(d=>(
                  <Chip key={d.k} on={entry.discharge===d.k} onClick={()=>up({ discharge: entry.discharge===d.k?null:d.k })}>{d.es}</Chip>
                ))}
              </div>
            </Field>

            <Field icon="heart" label="Relaciones sexuales" hint="Opcional. Ayuda a entender tu fertilidad y tu ciclo.">
              <div className="pill-card">
                <button type="button" className="pill-top" onClick={()=>up({ sex:!entry.sex })}>
                  <span className="t">¿Tuviste relaciones sexuales hoy?</span>
                  <span className={"toggle"+(entry.sex?" on":"")}><i/></span>
                </button>
                {entry.sex && (
                  <div className="pill-detail">
                    <div>
                      <div className="mini-l">¿Usaron protección?</div>
                      <Seg value={entry.sexProtection} onChange={(v)=>up({ sexProtection:v })} options={[{v:"protegida",t:"Con protección"},{v:"sin",t:"Sin protección"}]}/>
                    </div>
                  </div>
                )}
              </div>
            </Field>

            {phase.key==="menstrual" && (
              <React.Fragment>
                <Field icon="drop" label="Sangrado" req hint="Qué tan abundante es tu sangrado hoy.">
                  <div className="chips">
                    {FLOW.map(f=>(
                      <Chip key={f.k} tone="clay" on={entry.flow===f.k} onClick={()=>up({ flow: entry.flow===f.k?null:f.k })}>
                        <span className="flowdots" style={{color:"var(--clay)"}}>{Array.from({length:f.dots}).map((_,i)=><i key={i}/>)}</span>{f.es}
                      </Chip>
                    ))}
                  </div>
                </Field>
                <Field label="Color de la sangre" hint="El color da pistas sobre tu salud hormonal.">
                  <div className="chips">
                    {BLOOD_COLORS.map(b=>(
                      <Chip key={b.k} tone="clay" swatch={b.c} on={entry.bloodColor===b.k} onClick={()=>up({ bloodColor: entry.bloodColor===b.k?null:b.k })}>{b.es}</Chip>
                    ))}
                  </div>
                </Field>
                <Field label="¿Hay coágulos?">
                  <Seg value={entry.clots} onChange={(v)=>up({ clots:v })} options={[{v:"no",t:"No"},{v:"pequenos",t:"Pequeños"},{v:"grandes",t:"Grandes"}]}/>
                </Field>
              </React.Fragment>
            )}

            {phase.key==="ovulacion" && (
              <Field icon="sun" label="Dolor de ovulación" req hint="Muchas mujeres sienten una molestia leve al ovular. Marca si la sientes y dónde.">
                <div style={{marginBottom:12}}>
                  <Seg value={entry.ovuPain} onChange={(v)=>up({ ovuPain:v })} options={[{v:"no",t:"Sin dolor"},{v:"si",t:"Sí, siento dolor"}]}/>
                </div>
                {entry.ovuPain==="si" && (
                  <div className="chips">
                    {OVU_SIDE.map(s=>(
                      <Chip key={s.k} tone="ochre" on={entry.ovuSide===s.k} onClick={()=>up({ ovuSide: entry.ovuSide===s.k?null:s.k })}>{s.es}</Chip>
                    ))}
                  </div>
                )}
              </Field>
            )}

            {phase.key==="lutea" && (
              <Field icon="moon" label="Síntomas de fase lútea" hint="Síntomas comunes antes de la menstruación. Marca los que tengas hoy.">
                <div className="chips">
                  {LUTEAL_SX.map(s=>(
                    <Chip key={s.k} tone="peri" on={(entry.luteal||[]).includes(s.k)} onClick={()=>toggleArr("luteal",s.k)}>{s.es}</Chip>
                  ))}
                </div>
              </Field>
            )}

            <Field icon="note" label="Otros síntomas o notas" hint="Cualquier cosa que quieras que sepa: dolores, digestión, sueño, energía, libido, etc.">
              <textarea className="txtinput" placeholder="Escribe aquí lo que notes hoy…" value={entry.notes||""} onChange={(e)=>up({ notes:e.target.value })}/>
            </Field>

            <div className={"saved"+(savedFlash?" show":"")}><Icon name="check" s={15}/> Guardado en tu dispositivo</div>
          </div>
        </section>

        {/* Toolbar */}
        <div className="toolbar">
          <button type="button" className="tbtn export" onClick={exportXlsx}><Icon name="download" s={18}/> Exportar a Excel (.xlsx)</button>
          <button type="button" className="tbtn print" onClick={()=>window.print()}><Icon name="print" s={18}/> Imprimir para mi cita</button>
          <button type="button" className="tbtn" onClick={()=>{
            if (confirm("¿Empezar un ciclo nuevo? Esto borra los registros actuales. (Imprime antes si quieres conservarlos.)")){
              store.clearDays(); setEntries({}); goDay(1);
            }
          }}><Icon name="reset" s={17}/> Empezar ciclo nuevo</button>
        </div>

        <footer className="footer">
          ¿Prefieres papel? <a href="Calendario del Ciclo.html" style={{color:"var(--bronze-deep)",fontWeight:700}}>Descarga el calendario imprimible (PDF)</a> para llenarlo a mano.<br/><br/>
          Hecho con cuidado para las pacientes de la Dra. Carolina Nazario Josoy, ND.<br/>
          Esta herramienta registra tu ciclo; no reemplaza una consulta médica.
        </footer>
      </div>
    </div>
  );
}

ReactDOM.createRoot(document.getElementById("root")).render(<App/>);
