// Pau Fit — Detail screens (DetalleReto, DetalleReceta, Paywall)

const { useState: useS2, useEffect: useE2 } = React;

// ─────────────────────────────────────────────────────────────
// composeStoryImage — compone la foto del usuario sobre un canvas
// 9:16 (Instagram story) con overlay branded Pau Fit.
// Devuelve un Blob PNG listo para compartir o descargar.
// ─────────────────────────────────────────────────────────────
async function composeStoryImage(file, opts) {
  const { day, totalDays, retoTitle, retoColor, durationMin, userName } = opts;
  // Cargar la foto del usuario
  const img = new Image();
  const url = URL.createObjectURL(file);
  await new Promise((resolve, reject) => {
    img.onload = resolve;
    img.onerror = reject;
    img.src = url;
  });
  // Canvas 1080×1920 (Instagram story HD)
  const W = 1080, H = 1920;
  const canvas = document.createElement('canvas');
  canvas.width = W; canvas.height = H;
  const ctx = canvas.getContext('2d');
  // Background sólido por si la foto no cubre todo
  ctx.fillStyle = '#0E0A0C';
  ctx.fillRect(0, 0, W, H);
  // Foto cubre todo el canvas (object-fit: cover)
  const scale = Math.max(W / img.width, H / img.height);
  const drawW = img.width * scale;
  const drawH = img.height * scale;
  const drawX = (W - drawW) / 2;
  const drawY = (H - drawH) / 2;
  ctx.drawImage(img, drawX, drawY, drawW, drawH);
  // Gradiente oscuro arriba y abajo para que se lean los textos
  const grad = ctx.createLinearGradient(0, 0, 0, H);
  grad.addColorStop(0, 'rgba(0,0,0,0.65)');
  grad.addColorStop(0.22, 'rgba(0,0,0,0.05)');
  grad.addColorStop(0.55, 'rgba(0,0,0,0)');
  grad.addColorStop(0.78, 'rgba(0,0,0,0.4)');
  grad.addColorStop(1, 'rgba(0,0,0,0.92)');
  ctx.fillStyle = grad;
  ctx.fillRect(0, 0, W, H);

  // ── HEADER: badge Pau Fit (top-left) ──
  ctx.fillStyle = 'rgba(255,255,255,0.95)';
  const badgeY = 80;
  // Pill blanco redondeado
  roundRect(ctx, 60, badgeY, 230, 70, 35);
  ctx.fill();
  // Texto "Pau Fit"
  ctx.fillStyle = '#0E0A0C';
  ctx.font = '700 30px Poppins, system-ui, sans-serif';
  ctx.textBaseline = 'middle';
  ctx.fillText('💗 Pau Fit', 90, badgeY + 35);

  // Día X / Y badge (top-right)
  const dayBadgeText = `DÍA ${day} · ${totalDays}`;
  ctx.font = '700 26px Poppins, system-ui, sans-serif';
  const dayW = ctx.measureText(dayBadgeText).width;
  const dayBadgeW = dayW + 50;
  ctx.fillStyle = retoColor || '#D9477E';
  roundRect(ctx, W - 60 - dayBadgeW, badgeY, dayBadgeW, 70, 35);
  ctx.fill();
  ctx.fillStyle = '#fff';
  ctx.fillText(dayBadgeText, W - 60 - dayBadgeW + 25, badgeY + 35);

  // ── BOTTOM ── Reto title + duración + nombre
  // Título del reto
  ctx.fillStyle = '#fff';
  ctx.font = '600 36px Poppins, system-ui, sans-serif';
  ctx.fillText(retoTitle, 60, H - 360);

  // Mensaje principal (con nombre si tiene)
  ctx.font = '700 88px Poppins, system-ui, sans-serif';
  const headline = userName ? `${userName} lo hizo` : 'Día hecho';
  ctx.fillText(headline, 60, H - 270);

  // Subtítulo motivacional
  ctx.font = '500 32px Poppins, system-ui, sans-serif';
  ctx.fillStyle = 'rgba(255,255,255,0.85)';
  ctx.fillText('💗 #YoSiemprePuedo', 60, H - 195);

  // Stats pills bottom
  const pillY = H - 130;
  // Duración
  if (durationMin) {
    ctx.fillStyle = 'rgba(255,255,255,0.2)';
    roundRect(ctx, 60, pillY, 260, 75, 38);
    ctx.fill();
    ctx.fillStyle = '#fff';
    ctx.font = '700 28px Poppins, system-ui, sans-serif';
    ctx.fillText(`⏱ ${durationMin} min`, 90, pillY + 38);
  }
  // app.paufit.co
  ctx.fillStyle = 'rgba(255,255,255,0.2)';
  const urlText = 'app.paufit.co';
  ctx.font = '700 28px Poppins, system-ui, sans-serif';
  const urlW = ctx.measureText(urlText).width + 60;
  roundRect(ctx, W - 60 - urlW, pillY, urlW, 75, 38);
  ctx.fill();
  ctx.fillStyle = '#fff';
  ctx.fillText(urlText, W - 60 - urlW + 30, pillY + 38);

  URL.revokeObjectURL(url);
  // Convertir a blob PNG
  return new Promise((resolve, reject) => {
    canvas.toBlob((b) => {
      if (b) resolve(b); else reject(new Error('No se pudo generar la imagen'));
    }, 'image/png', 0.92);
  });
}

function roundRect(ctx, x, y, w, h, r) {
  ctx.beginPath();
  ctx.moveTo(x + r, y);
  ctx.arcTo(x + w, y, x + w, y + h, r);
  ctx.arcTo(x + w, y + h, x, y + h, r);
  ctx.arcTo(x, y + h, x, y, r);
  ctx.arcTo(x, y, x + w, y, r);
  ctx.closePath();
}

// ═════════════════════════════════════════════════════════════
// DETALLE RETO — la pantalla estrella
// ═════════════════════════════════════════════════════════════
function DetalleRetoScreen({ retoId, theme, isPremium, nav, onComplete }) {
  const T = theme;
  const reto = window.pauRetoById(retoId);
  const isLocked = reto.tag === 'PRO' && !isPremium;

  // FUENTE DE VERDAD: cache.activeReto de Supabase (no del mock).
  // Si está unida a este reto, leer current_day y completed_days REALES.
  const cacheRoot = (typeof window !== 'undefined' && window.__pauCache) || {};
  const activeUserReto = cacheRoot.activeReto;
  const isThisActive = activeUserReto && activeUserReto.reto_id === reto.id;
  const realCurrentDay = isThisActive ? (activeUserReto.current_day || 1) : 1;
  const realCompletedDays = isThisActive ? (activeUserReto.completed_days || []) : [];

  const [selectedDay, setSelectedDay] = useS2(realCurrentDay);
  const [doneVideos, setDoneVideos] = useS2(new Set());
  const [confetti, setConfetti] = useS2(false);
  const [localCompleted, setLocalCompleted] = useS2(new Set(realCompletedDays));

  // ── DURACIÓN REAL del entreno (estilo Silbe) ─────────────────
  // Empieza a contar cuando marca el primer video. Pausa cuando sale (cleanup).
  // El total se calcula en MIN al completar el día.
  const [workoutStartedAt, setWorkoutStartedAt] = useS2(null);
  const [workoutDurationMs, setWorkoutDurationMs] = useS2(0);
  useE2(() => {
    // Cuando inicia el primer video (doneVideos no vacío), arranca timer
    if (doneVideos.size > 0 && !workoutStartedAt) {
      setWorkoutStartedAt(Date.now());
    }
  }, [doneVideos.size, workoutStartedAt]);
  useE2(() => {
    if (!workoutStartedAt) return;
    // Cleanup: cuando se desmonta o cambia día, acumular el tiempo
    return () => {
      if (workoutStartedAt) {
        setWorkoutDurationMs(d => d + (Date.now() - workoutStartedAt));
      }
    };
  }, [workoutStartedAt, selectedDay]);

  // CTA sticky inferior — se registra solo si NO está unida al reto.
  // joined = true si o el state local lo marca, O hay reto activo en Supabase.
  const joined = isThisActive || (nav.joinedRetos && nav.joinedRetos.has(reto.id));
  useE2(() => {
    if (joined || isLocked) {
      nav.hideCTA && nav.hideCTA();
      return;
    }
    if (nav.showCTA) {
      nav.showCTA({
        label: `Unirme al reto · ${reto.days} días`,
        onClick: () => openJoinModal(),
        color: T.accent,
      });
    }
    return () => { nav.hideCTA && nav.hideCTA(); };
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [joined, isLocked, reto.id, reto.days]);

  // Sin vídeos falsos: el día es UN entreno honesto (duración del reto).
  // Cuando Pau suba vídeos reales (Bunny→rutinas), aquí se conectarán.
  const completed = Array.from(localCompleted);
  const progress = completed.length / reto.days;
  const totalMinutes = reto.minPerDay || 20;

  // ¿Ya hizo un día hoy? (lectura desde localStorage de paufit-last-done-{retoId})
  // Si sí, mostrar banner "adelantarte al día siguiente"
  const todayStrLocal = new Date().toLocaleDateString('en-CA');
  let lastDoneLocalDate = null;
  try { lastDoneLocalDate = localStorage.getItem(`paufit-last-done-${reto.id}`); } catch {}
  const doneTodayHere = lastDoneLocalDate === todayStrLocal;

  // Estado del modal "Día completado" — para mostrar "nos vemos mañana" + "hacer ya el siguiente"
  const [showDayDone, setShowDayDone] = useS2(false);
  const [justCompletedDay, setJustCompletedDay] = useS2(null);

  async function completeDay() {
    // UI optimista: marca local primero
    setLocalCompleted(prev => {
      const next = new Set(prev);
      next.add(selectedDay);
      return next;
    });
    setDoneVideos(new Set());

    // Guardar el día que acabamos de completar (para el modal)
    const doneDay = selectedDay;
    const isLast = selectedDay >= reto.days;
    setJustCompletedDay(doneDay);
    // Guardar fecha local del último día completado para
    // que el TodayHero del Home sepa "ya hiciste tu día, vuelve mañana"
    try {
      const todayStr = new Date().toLocaleDateString('en-CA');
      localStorage.setItem(`paufit-last-done-${reto.id}`, todayStr);
    } catch {}

    // PERSISTIR en Supabase: day_completions + user_retos.completed_days
    // + sumar puntos automáticamente
    try {
      const cache = window.__pauCache || {};
      let userReto = cache.activeReto;
      // AUTO-REPARACIÓN: si está "unida" solo en local (sin fila en Supabase,
      // p.ej. sesión que expiró al unirse), crear la inscripción ahora.
      if ((!userReto || userReto.reto_id !== reto.id) && window.PauUserRetos) {
        const s = await window.PauUserRetos.start(reto.id, { force: false });
        if (s && s.error === 'no-auth') {
          nav.toast('Tu sesión expiró — cierra sesión y vuelve a entrar', { icon: '🔒' });
          return;
        }
        if (s && s.row) {
          userReto = s.row;
          window.__pauCache.activeReto = s.row;
        } else if (s && s.conflict && s.active) {
          userReto = s.active;
        }
      }
      if (userReto && userReto.id && window.PauUserRetos) {
        const res = await window.PauUserRetos.completeDay(userReto.id, selectedDay, reto.days);
        if (res && res.error) {
          nav.toast('No se pudo guardar el día: ' + res.error, { icon: '⚠️' });
          return;
        }
        if (res && res.row) {
          // Actualizar cache
          window.__pauCache.activeReto = res.row;
          window.dispatchEvent(new CustomEvent("pau:cache-updated"));
          // Refrescar stats + achievements
          if (window.PauUserRetos.getStats) {
            window.PauUserRetos.getStats().then(s => {
              if (s) {
                window.__pauCache.stats = s;
                if (window.PauUserRetos.computeAchievements) {
                  window.__pauCache.achievements = window.PauUserRetos.computeAchievements(s);
                }
              }
            });
          }
          // Refrescar profile (puntos actualizados)
          const sb = window.__PAU_SUPABASE;
          if (sb) {
            const { data: { user } } = await sb.auth.getUser();
            if (user) {
              const { data: p } = await sb.from('profiles')
                .select('id, full_name, username, avatar_url, bio, is_premium, premium_until, trial_ends_at, points, level, goal, target_days_per_week, height_cm, weight_kg, birth_date, gender, phone, is_public')
                .eq('id', user.id).maybeSingle();
              if (p) window.__pauCache.profile = { ...p, email: user.email || '' };
            }
          }
        }
      }
    } catch (e) {
      console.warn('[completeDay] error guardando:', e?.message || e);
    }

    // Mostrar modal "Día completado · nos vemos mañana" con opción "Hacer el siguiente ya"
    // NO avanza automáticamente — la usuaria decide.
    setTimeout(() => setShowDayDone(true), 250);
  }

  function continueNextDay() {
    setShowDayDone(false);
    if (justCompletedDay && justCompletedDay < reto.days) {
      setSelectedDay(justCompletedDay + 1);
    }
  }

  function closeDayDone() {
    setShowDayDone(false);
    // Volver al Home para que vea su progreso actualizado
    nav.tab && nav.tab('home');
  }

  function openRateThenComplete() {
    // Confetti al completar — celebración real, no simulada
    setConfetti(true);
    setTimeout(() => setConfetti(false), 1800);
    nav.openModal(<RateWorkoutModal
      open target={`Día ${selectedDay} · ${reto.title}`}
      T={T} accent={T.accent} retoColor={reto.color}
      onClose={() => { nav.closeModal(); completeDay(); }}
      onSave={(r) => {
        nav.closeModal();
        nav.toast('Puntuación guardada 💗', { icon: '✓' });
        completeDay();
      }}
    />);
  }

  if (isLocked) return <PaywallScreen theme={T} nav={nav} fromReto={reto} onComplete={onComplete}/>;

  // joined ya declarado arriba (línea 23)
  // ¿Tiene la usuaria OTRO reto activo distinto a este? (lectura desde cache de Supabase)
  const cache = (typeof window !== 'undefined' && window.__pauCache) || {};
  const activeOther = cache.activeReto && cache.activeReto.reto_id !== reto.id ? cache.activeReto : null;
  const activeOtherTitle = activeOther ? (window.pauRetoById(activeOther.reto_id)?.title || 'tu reto actual') : null;

  function openJoinModal() {
    // CASO A: la usuaria YA está en otro reto. Mostrar aviso antes de unirse.
    if (activeOther) {
      nav.openModal(<AlreadyInRetoModal
        T={T}
        currentRetoTitle={activeOtherTitle}
        newRetoTitle={reto.title}
        onClose={() => nav.closeModal()}
        onConfirm={async () => {
          // Forzar: abandonar el actual y empezar el nuevo en Supabase
          if (window.PauUserRetos) {
            const res = await window.PauUserRetos.start(reto.id, { force: true });
            if (res.error) { nav.toast('Error: ' + res.error, { icon: '⚠️' }); return; }
            // refrescar cache
            window.__pauCache.activeReto = res.row;
          window.dispatchEvent(new CustomEvent("pau:cache-updated"));
          }
          nav.joinReto(reto.id);
          nav.closeModal();
          nav.toast(`Empezaste ${reto.title} 💗`, { icon: '✓' });
        }}
      />);
      return;
    }
    // CASO B: no tiene reto activo — flujo normal con modal de fecha
    nav.openModal(<JoinRetoModal
      reto={reto} T={T}
      onClose={() => nav.closeModal()}
      onJoin={async () => {
        try {
          if (!window.PauUserRetos) {
            nav.toast('Sistema no cargado. Recarga la app.', { icon: '⚠️' });
            return;
          }
          if (!window.__PAU_SUPABASE) {
            nav.toast('Sin conexión a Supabase', { icon: '⚠️' });
            return;
          }
          // Verifica que hay sesión
          const { data: { user } } = await window.__PAU_SUPABASE.auth.getUser();
          if (!user) {
            nav.closeModal();
            nav.toast('Inicia sesión para unirte', { icon: '🔒' });
            return;
          }

          const res = await window.PauUserRetos.start(reto.id);
          if (res.conflict) {
            nav.closeModal();
            nav.toast('Ya tienes otro reto activo', { icon: '⚠️' });
            return;
          }
          if (res.error) {
            nav.toast('Error: ' + res.error, { icon: '⚠️' });
            console.error('[unirme] error de Supabase:', res.error);
            return;
          }
          if (!res.row) {
            nav.toast('No se pudo guardar', { icon: '⚠️' });
            return;
          }
          window.__pauCache = window.__pauCache || {};
          window.__pauCache.activeReto = res.row;
          window.dispatchEvent(new CustomEvent("pau:cache-updated"));
          nav.joinReto(reto.id);
          nav.closeModal();
          nav.toast(`¡Te uniste a ${reto.title}! 💗`, { icon: '✓' });
        } catch (e) {
          console.error('[unirme] excepción:', e);
          nav.toast('Error inesperado: ' + (e?.message || e), { icon: '⚠️' });
        }
      }}
    />);
  }

  // ════════════════ NOT JOINED — landing CTA ════════════════
  if (!joined) {
    return (
      <div style={{ paddingBottom: 110, position: 'relative' }}>
        {/* Hero photo full-bleed 3:4 (portada Silbe) */}
        <div style={{
          position: 'relative', aspectRatio: '3 / 4',
          background: 'rgba(0,0,0,0.04)',
          borderBottomLeftRadius: 28, borderBottomRightRadius: 28,
          overflow: 'hidden',
        }}>
          {reto.image
            ? <img loading="lazy" src={reto.image} alt={reto.title} style={{ position: 'absolute', inset: 0, width: '100%', height: '100%', objectFit: 'cover' }}/>
            : <div style={{ position: 'absolute', inset: 0, background: `linear-gradient(160deg, ${reto.bg}, ${reto.color}aa)` }}/>
          }
          {/* Top chrome — back / share / fav */}
          <div style={{
            position: 'absolute', top: 12, left: 18, right: 18,
            display: 'flex', alignItems: 'center', justifyContent: 'space-between',
          }}>
            <BackBtn onClick={() => nav.back()} light/>
            <div style={{ display: 'flex', gap: 8 }}>
              <RoundBtn light onClick={() => {
                const userName = (window.__pauCache?.profile?.full_name || window.__pauCache?.profile?.username || '').trim();
                const text = userName
                  ? `${userName} está haciendo "${reto.title}" en Pau Fit 💗 ${reto.days} días para sentirte mejor. ¡Únete!`
                  : `Mira este reto: "${reto.title}" — ${reto.days} días en Pau Fit 💗 ¿Te apuntas?`;
                window.PauShare && window.PauShare({ title: `${reto.title} · Pau Fit`, text, url: 'https://app.paufit.co' }).then(function(r){ if (r.shared) nav.toast(r.method === 'native' ? 'Compartido' : 'Enlace copiado 💗', { icon: '↗' }) });
              }}>{Icon.share('#0E0A0C')}</RoundBtn>
              <RoundBtn light onClick={() => {const k='paufit-favs';const cur=JSON.parse(localStorage.getItem(k)||'[]');const id=(typeof r!=='undefined'?r.id:(typeof reto!=='undefined'?reto.id:''));if (cur.includes(id)) {localStorage.setItem(k,JSON.stringify(cur.filter(x=>x!==id)));nav.toast('Quitado de favoritos',{icon:'❤️'});} else {localStorage.setItem(k,JSON.stringify([...cur,id]));nav.toast('Guardado en favoritos 💗',{icon:'❤️'});}}}>{Icon.heart('#0E0A0C')}</RoundBtn>
            </div>
          </div>
          {/* Bottom badge */}
          <div style={{
            position: 'absolute', bottom: 16, left: 18,
            padding: '5px 10px', borderRadius: 6,
            background: 'rgba(255,255,255,0.95)',
            color: T.deep, fontSize: 10, fontWeight: 700, letterSpacing: 1.2,
          }}>{reto.tag} · {reto.days} días</div>
        </div>

        {/* Title + desc */}
        <div style={{ padding: '22px 20px 0' }}>
          <div style={{ fontSize: 10, color: T.muted, fontWeight: 600, letterSpacing: 1,  }}>
            {reto.category}
          </div>
          <div className="pf-display" style={{
            fontSize: 32, fontWeight: 500, color: T.text, marginTop: 8,
            letterSpacing: -0.7, lineHeight: 1.05,
          }}>{reto.title}</div>
          <p style={{ fontSize: 14, color: T.text, marginTop: 12, lineHeight: 1.55, fontWeight: 400 }}>
            {reto.desc}
          </p>
        </div>

        {/* Stats grid */}
        <div style={{
          margin: '20px 18px 0',
          display: 'grid', gridTemplateColumns: '1fr 1fr 1fr', gap: 8,
        }}>
          <StatTile label="Duración" value={`${reto.days} días`} T={T}/>
          <StatTile label="Por día" value={`${reto.minPerDay} min`} T={T}/>
          <StatTile label="Nivel" value={reto.intensity.split(' ')[0]} T={T}/>
        </div>

        {/* What's included */}
        <div style={{ padding: '24px 20px 0' }}>
          <div style={{ fontSize: 10, color: T.muted, fontWeight: 600, letterSpacing: 1,  }}>
            Qué incluye
          </div>
          <div style={{ marginTop: 12, display: 'flex', flexDirection: 'column', gap: 10 }}>
            {[
              { e: '🎥', t: `${reto.days} días de rutinas`, s: 'Videos cortos guiados por Pau' },
              { e: '🍓', t: 'Plan de alimentación', s: 'Comidas sincronizadas con tu reto' },
              { e: '📐', t: 'Tracking de medidas', s: 'Fotos y medidas antes/después' },
              { e: '💗', t: 'Comunidad del reto', s: 'Habla con otras que lo están haciendo' },
            ].map((o, i) => (
              <div key={i} style={{
                padding: '12px 14px', background: T.card, borderRadius: 20, border: T.border,
                display: 'flex', alignItems: 'center', gap: 12,
              }}>
                <div style={{
                  width: 40, height: 40, borderRadius: 14,
                  background: T.subtle,
                  display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: 20,
                }}>{o.e}</div>
                <div style={{ flex: 1 }}>
                  <div style={{ fontSize: 13, fontWeight: 600, color: T.text }}>{o.t}</div>
                  <div style={{ fontSize: 11, color: T.muted, marginTop: 1, fontWeight: 500 }}>{o.s}</div>
                </div>
              </div>
            ))}
          </div>
        </div>

        {/* Reviews */}
        <ReviewsSection type="reto" id={reto.id} T={T} accent={T.accent}/>

        {/* CTA sticky inferior ahora vive en App.jsx — registrado via nav.showCTA
            en el useEffect arriba. Solo dejamos un spacer para que el contenido
            no quede tapado por el CTA flotante. */}
        <div style={{ height: 100 }}/>
      </div>
    );
  }

  // ════════════════ JOINED — daily content ════════════════
  return (
    <div style={{ paddingBottom: 110, position: 'relative' }}>
      <Confetti show={confetti}/>

      {/* Hero header — portada 3:4 */}
      <div style={{
        position: 'relative', aspectRatio: '3 / 4',
        background: 'rgba(0,0,0,0.04)',
        borderBottomLeftRadius: 28, borderBottomRightRadius: 28,
        overflow: 'hidden',
      }}>
        {reto.image
          ? <img loading="lazy" src={reto.image} alt={reto.title} style={{ position: 'absolute', inset: 0, width: '100%', height: '100%', objectFit: 'cover' }}/>
          : <div style={{ position: 'absolute', inset: 0, background: `linear-gradient(160deg, ${reto.bg}, ${reto.color}aa)` }}/>
        }
        <div style={{
          position: 'absolute', inset: 0,
          background: 'linear-gradient(180deg, rgba(0,0,0,0.4) 0%, transparent 35%, transparent 55%, rgba(0,0,0,0.85) 100%)',
        }}/>
        <div style={{
          position: 'absolute', top: 12, left: 18, right: 18,
          display: 'flex', alignItems: 'center', justifyContent: 'space-between',
        }}>
          <BackBtn onClick={() => nav.back()} light/>
          <div style={{ display: 'flex', gap: 8 }}>
            <RoundBtn light onClick={() => {
              const userName = (window.__pauCache?.profile?.full_name || window.__pauCache?.profile?.username || '').trim();
              const text = userName
                ? `${userName} va por el día ${realCurrentDay}/${reto.days} de "${reto.title}" en Pau Fit 💗 ¡Hazlo tú también!`
                : `Estoy en el día ${realCurrentDay}/${reto.days} de "${reto.title}" en Pau Fit 💗 ¿Te apuntas?`;
              window.PauShare && window.PauShare({ title: `${reto.title} · día ${realCurrentDay}`, text, url: 'https://app.paufit.co' }).then(function(r){ if (r.shared) nav.toast(r.method === 'native' ? 'Compartido' : 'Enlace copiado 💗', { icon: '↗' }) });
            }}>{Icon.share('#0E0A0C')}</RoundBtn>
          </div>
        </div>
        <div style={{
          position: 'absolute', bottom: 16, left: 18, right: 18, color: '#fff',
        }}>
          <div style={{ fontSize: 10, fontWeight: 500, letterSpacing: 1,  color: 'rgba(255,255,255,0.85)' }}>
            ✓ Día {realCurrentDay} de {reto.days}
          </div>
          <div className="pf-display" style={{
            fontSize: 26, fontWeight: 500, marginTop: 4, letterSpacing: -0.5, lineHeight: 1.1,
            textShadow: '0 2px 8px rgba(0,0,0,0.3)',
          }}>{reto.title}</div>
        </div>
      </div>

      {/* Progress */}
      <div style={{
        margin: '16px 18px 0', padding: '14px 16px',
        background: T.card, borderRadius: 20, border: T.border,
      }}>
        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline' }}>
          <span style={{ fontSize: 10, fontWeight: 600, color: T.muted, letterSpacing: 0.8,  }}>Tu progreso</span>
          <span style={{ fontSize: 13, fontWeight: 700, color: T.text }}>{completed.length}/{reto.days} días</span>
        </div>
        <div style={{ marginTop: 8, height: 4, background: T.subtle, borderRadius: 999, overflow: 'hidden' }}>
          <div style={{ width: `${progress*100}%`, height: '100%', background: T.accent, borderRadius: 999, transition: 'width 600ms ease' }}/>
        </div>
      </div>

      {/* Stats row */}
      <div style={{ display: 'flex', justifyContent: 'space-around', padding: '20px 20px 0' }}>
        <SmallStat v={reto.days} l="días" T={T}/>
        <SmallStat v={`~${reto.minPerDay}`} l="min/día" T={T}/>
        <SmallStat v={reto.intensity.split(' ')[0]} l="intensidad" T={T}/>
      </div>

      {/* Day selector */}
      <div className="pf-display" style={{
        margin: '24px 0 0', padding: '0 22px',
        fontSize: 24, fontWeight: 500, color: T.text, letterSpacing: -0.4,
      }}>Día {selectedDay}</div>
      <div style={{
        display: 'flex', gap: 8, padding: '12px 20px 4px',
        overflowX: 'auto', scrollSnapType: 'x mandatory',
      }} className="hide-scroll">
        {Array.from({ length: reto.days }, (_, i) => i + 1).map(d => {
          const isCompleted = completed.includes(d);
          const isSelected = d === selectedDay;
          const isToday = d === realCurrentDay;
          // PUEDEN ENTRAR a todos los días (estilo Silbe). Solo el día actual
          // se puede completar. Los futuros se ven como preview.
          const isFuture = d > realCurrentDay;
          return (
            <button key={d} onClick={() => setSelectedDay(d)} style={{
              flexShrink: 0, width: 52, height: 64,
              cursor: 'pointer', borderRadius: 20,
              background: isSelected ? reto.color : (isCompleted ? T.subtle : T.card),
              color: isSelected ? '#fff' : (isCompleted ? '#5C7A56' : T.text),
              display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', gap: 2,
              position: 'relative',
              border: isToday && !isSelected ? `1.5px solid ${reto.color}` : T.border,
              opacity: isFuture && !isSelected ? 0.55 : 1,
              transition: 'all 200ms ease',
            }}>
              <span style={{ fontSize: 10, fontWeight: 500, opacity: 0.7, letterSpacing: 0.3,  }}>Día</span>
              <span style={{ fontSize: 18, fontWeight: 600, letterSpacing: -0.3 }}>{d}</span>
              {isCompleted && !isSelected && (
                <div style={{
                  position: 'absolute', top: 6, right: 6,
                  width: 14, height: 14, borderRadius: 999, background: '#A8C5A0',
                  display: 'flex', alignItems: 'center', justifyContent: 'center',
                }}>{Icon.check('#fff', 10)}</div>
              )}
            </button>
          );
        })}
      </div>

      <div style={{ padding: '6px 22px 0', fontFamily: 'Poppins', fontSize: 11, color: T.muted, lineHeight: 1.4 }}>
        Los días se desbloquean al completar el anterior 🔒
      </div>

      {/* Banner "Adelantarte al día siguiente" — claro y con UN solo CTA */}
      {doneTodayHere && selectedDay === realCurrentDay && !localCompleted.has(realCurrentDay) && (
        <div style={{
          margin: '16px 20px 0', padding: '18px 18px 16px',
          background: `linear-gradient(135deg, ${reto.color}18, ${reto.color}08)`,
          border: `1.5px solid ${reto.color}50`,
          borderRadius: 20,
        }}>
          <div style={{ display: 'flex', alignItems: 'center', gap: 12 }}>
            <div style={{
              width: 48, height: 48, borderRadius: 20,
              background: `${reto.color}30`,
              display: 'flex', alignItems: 'center', justifyContent: 'center',
              fontSize: 26, flexShrink: 0,
            }}>🌙</div>
            <div style={{ flex: 1, minWidth: 0 }}>
              <div style={{ fontSize: 15, fontWeight: 700, color: T.text, letterSpacing: -0.2 }}>
                Este día es para mañana
              </div>
              <div style={{ fontSize: 12, color: T.muted, marginTop: 3, lineHeight: 1.4 }}>
                Ya entrenaste hoy 💗 Descansa — mañana lo completas.
              </div>
            </div>
          </div>
        </div>
      )}

      {/* Entreno del día — tarjeta honesta (sin vídeos inventados) */}
      <div style={{ padding: '20px 20px 0' }}>
        <div style={{
          background: T.card, borderRadius: 20, padding: '18px 18px',
          border: T.border, display: 'flex', alignItems: 'center', gap: 14,
        }}>
          <div style={{
            width: 56, height: 56, borderRadius: 18, flexShrink: 0,
            background: `linear-gradient(135deg, ${reto.bg}, ${reto.color}80)`,
            display: 'flex', alignItems: 'center', justifyContent: 'center',
            fontSize: 28,
          }}>{reto.emoji || '💪'}</div>
          <div style={{ flex: 1, minWidth: 0 }}>
            <div style={{ fontFamily: 'Poppins', fontSize: 10, color: T.muted, fontWeight: 700, letterSpacing: 0.6,  }}>
              Día {selectedDay} · {reto.category || 'Entreno'}
            </div>
            <div style={{ fontFamily: 'Poppins', fontSize: 15, fontWeight: 700, color: T.text, marginTop: 2, letterSpacing: -0.2 }}>
              Tu entreno de hoy
            </div>
            <div style={{ fontFamily: 'Poppins', fontSize: 11.5, color: T.muted, marginTop: 2 }}>
              ~{totalMinutes} min · {reto.intensity || 'A tu ritmo'}
            </div>
          </div>
        </div>
        {/* Rutinas REALES sugeridas si existen en el catálogo */}
        {(window.__pauCache?.rutinas || []).length > 0 && (
          <div style={{ marginTop: 12 }}>
            <div style={{ fontFamily: 'Poppins', fontSize: 10, fontWeight: 700, letterSpacing: 0.6, color: T.muted,  marginBottom: 8 }}>
              Elige tu rutina de hoy
            </div>
            <div style={{ display: 'flex', gap: 10, overflowX: 'auto', paddingBottom: 4 }} className="hide-scroll">
              {(window.__pauCache.rutinas || []).slice(0, 6).map(r => (
                <button key={r.id} onClick={() => nav.go('rutina', r.id)} style={{
                  flexShrink: 0, padding: '12px 14px', borderRadius: 14, cursor: 'pointer',
                  border: T.border, background: T.card, textAlign: 'left', fontFamily: 'inherit',
                }}>
                  <div style={{ fontSize: 18 }}>{r.emoji || '💪'}</div>
                  <div style={{ fontSize: 12, fontWeight: 700, color: T.text, marginTop: 4, maxWidth: 120, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{r.title}</div>
                  <div style={{ fontSize: 10, color: T.muted, marginTop: 2 }}>{r.minutes} min</div>
                </button>
              ))}
            </div>
          </div>
        )}
      </div>

      {/* MODO ENTRENO — fase 2: cronómetro real a pantalla completa.
          Solo el día actual y si aún no está completado. */}
      {selectedDay === realCurrentDay && !localCompleted.has(selectedDay) && (
        <div style={{ padding: '14px 20px 0' }}>
          <button onClick={() => {
            if (!window.EntrenoPlayer) return;
            nav.openModal(React.createElement(window.EntrenoPlayer, {
              T, nav,
              session: {
                title: `Día ${selectedDay} · ${reto.title}`,
                subtitle: reto.category || 'Entreno',
                targetMinutes: totalMinutes,
              },
              onClose: () => nav.closeModal(),
              onFinish: () => { nav.closeModal(); openRateThenComplete(); },
            }));
          }} style={{
            width: '100%', padding: '16px',
            border: 'none', borderRadius: 999, cursor: 'pointer',
            background: T.accent, color: '#fff',
            fontFamily: 'Poppins', fontSize: 14, fontWeight: 700, letterSpacing: -0.1,
            display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 8,
            boxShadow: `0 6px 18px ${T.accent}40`,
          }}>
            {Icon.playFilled ? Icon.playFilled({ c: '#fff', size: 12 }) : '▶'} Modo entreno · ~{totalMinutes} min
          </button>
        </div>
      )}

      {/* Complete day button — solo el día actual se puede completar */}
      <div style={{ padding: '20px 20px 0' }}>
        {(() => {
          const isFuture = selectedDay > realCurrentDay;
          const isPast = selectedDay < realCurrentDay;
          const isCurrentDay = selectedDay === realCurrentDay;
          const alreadyDone = localCompleted.has(selectedDay);
          const canComplete = isCurrentDay && !alreadyDone;
          return (
            <button disabled={!canComplete} onClick={() => canComplete && openRateThenComplete()} style={{
              width: '100%', padding: '16px',
              border: 'none', borderRadius: 20, cursor: canComplete ? 'pointer' : 'default',
              background: canComplete ? reto.color : T.subtle,
              color: canComplete ? '#fff' : T.muted,
              fontFamily: 'Poppins', fontSize: 14, fontWeight: 600, letterSpacing: -0.1,
              transition: 'all 200ms ease',
              boxShadow: canComplete ? `0 6px 18px ${reto.color}55` : 'none',
            }}>
              {alreadyDone
                ? `✓ Día ${selectedDay} ya completado`
                : isFuture
                  ? `Día ${selectedDay} disponible cuando llegues`
                  : isPast
                    ? `Día ${selectedDay} sin completar`
                    : `✓ Completar día ${selectedDay} · ${totalMinutes} min`}
            </button>
          );
        })()}
      </div>

      {/* Reviews */}
      <ReviewsSection type="reto" id={reto.id} T={T} accent={reto.color}/>

      {/* Acciones del reto: REHACER ÚLTIMO / REINICIAR / SALIR (estilo Silbe, al fondo) */}
      <div style={{ padding: '32px 20px 0' }}>
        <div className="pf-eyebrow" style={{ color: T.muted, marginBottom: 10 }}>Reto</div>

        {/* Rehacer último día — solo si hay algún día completado */}
        {realCompletedDays.length > 0 && (() => {
          const ultimoDia = Math.max(...realCompletedDays);
          return (
            <button onClick={async () => {
              if (!window.confirm(`¿Rehacer el día ${ultimoDia}?\nSe borrará del historial y vuelves a hacerlo.`)) return;
              try {
                const sb = window.__PAU_SUPABASE;
                const userReto = window.__pauCache?.activeReto;
                if (!sb || !userReto) { nav.toast('Sin reto activo', { icon: '⚠️' }); return; }
                const { data: { user } } = await sb.auth.getUser();
                if (!user) { nav.toast('Inicia sesión', { icon: '🔒' }); return; }
                const newCompletedDays = (userReto.completed_days || []).filter(d => d !== ultimoDia);
                await sb.from('user_retos')
                  .update({ completed_days: newCompletedDays, current_day: ultimoDia })
                  .eq('id', userReto.id);
                // FIX calendario: la columna correcta es reto_id (user_reto_id
                // no existe — el delete fallaba en silencio y el día quedaba
                // "completado" para siempre en el calendario)
                const { error: delErr } = await sb.from('day_completions')
                  .delete()
                  .eq('user_id', user.id)
                  .eq('reto_id', reto.id)
                  .eq('day_number', ultimoDia);
                if (delErr) { nav.toast('No se pudo rehacer el día', { icon: '⚠️' }); return; }
                try { localStorage.removeItem(`paufit-last-done-${reto.id}`); } catch {}
                const { data: row } = await sb.from('user_retos').select('*').eq('id', userReto.id).maybeSingle();
                if (row) {
                  window.__pauCache.activeReto = row;
                  window.dispatchEvent(new CustomEvent('pau:cache-updated'));
                }
                setLocalCompleted(new Set(newCompletedDays));
                setSelectedDay(ultimoDia);
                setDoneVideos(new Set());
                nav.toast(`Día ${ultimoDia} listo para rehacerse 🔄`, { icon: '✓' });
              } catch (e) {
                nav.toast('Error: ' + (e?.message || e), { icon: '⚠️' });
              }
            }} style={{
              width: '100%', padding: '16px 18px', marginBottom: 10,
              border: T.border, borderRadius: 20, cursor: 'pointer',
              background: T.card, color: T.text,
              fontSize: 14, fontWeight: 600, letterSpacing: -0.2,
              display: 'flex', alignItems: 'center', gap: 12, textAlign: 'left',
              fontFamily: 'inherit',
            }}>
              <span style={{ fontSize: 22 }}>↩️</span>
              <div style={{ flex: 1 }}>
                <div style={{ fontSize: 13, fontWeight: 700 }}>Rehacer día {ultimoDia}</div>
                <div style={{ fontSize: 11, color: T.muted, marginTop: 2 }}>Lo borra del historial y vuelves a empezarlo</div>
              </div>
            </button>
          );
        })()}

        <button onClick={async () => {
          if (!window.confirm('¿Reiniciar el reto? Volverás al día 1 y se borrará tu progreso.')) return;
          try {
            const cache = window.__pauCache || {};
            const userReto = cache.activeReto;
            if (userReto && window.PauUserRetos) {
              // Abandonar y volver a empezar
              await window.PauUserRetos.abandon(userReto.id);
              const res = await window.PauUserRetos.start(reto.id, { force: true });
              if (res?.row) {
                window.__pauCache.activeReto = res.row;
                window.dispatchEvent(new CustomEvent('pau:cache-updated'));
                setSelectedDay(1);
                setLocalCompleted(new Set());
                setDoneVideos(new Set());
                nav.toast('Reto reiniciado · ¡vamos! 💪', { icon: '🔄' });
              }
            }
          } catch (e) {
            nav.toast('Error: ' + (e?.message || e), { icon: '⚠️' });
          }
        }} style={{
          width: '100%', padding: '16px 18px',
          border: T.border, borderRadius: 20, cursor: 'pointer',
          background: T.card, color: T.text,
          fontSize: 14, fontWeight: 600, letterSpacing: -0.2,
          display: 'flex', alignItems: 'center', gap: 12, textAlign: 'left',
          fontFamily: 'inherit',
        }}>
          <span style={{ fontSize: 22 }}>🔄</span>
          <div style={{ flex: 1 }}>
            <div style={{ fontSize: 13, fontWeight: 700 }}>Reiniciar reto</div>
            <div style={{ fontSize: 11, color: T.muted, marginTop: 2 }}>Empieza desde el día 1</div>
          </div>
        </button>

        <button onClick={async () => {
          if (!window.confirm('¿Seguro que quieres salir del reto? Tu progreso se guarda en el historial.')) return;
          try {
            await nav.leaveReto(reto.id);
            nav.toast('Saliste del reto', { icon: '👋' });
            setTimeout(() => nav.tab('home'), 500);
          } catch (e) {
            nav.toast('Error: ' + (e?.message || e), { icon: '⚠️' });
          }
        }} style={{
          marginTop: 10, width: '100%', padding: '16px 18px',
          border: '1.5px solid #E6363633', borderRadius: 20, cursor: 'pointer',
          background: 'transparent', color: '#D63636',
          fontSize: 14, fontWeight: 600, letterSpacing: -0.2,
          display: 'flex', alignItems: 'center', gap: 12, textAlign: 'left',
          fontFamily: 'inherit',
        }}>
          <span style={{ fontSize: 22 }}>👋</span>
          <div style={{ flex: 1 }}>
            <div style={{ fontSize: 13, fontWeight: 700 }}>Salir del reto</div>
            <div style={{ fontSize: 11, opacity: 0.7, marginTop: 2 }}>Tu progreso queda en el historial</div>
          </div>
        </button>
      </div>

      {/* MODAL "Día X completado" — sale al completar el día */}
      {showDayDone && (
        <DayCompletedModal
          T={T}
          retoColor={reto.color}
          retoTitle={reto.title}
          dayNumber={Number(justCompletedDay) || 1}
          nextDayNumber={(Number(justCompletedDay) || 1) + 1}
          totalDays={reto.days}
          isLastDay={(Number(justCompletedDay) || 1) >= reto.days}
          durationMin={Math.max(1, Math.round(workoutDurationMs / 60000)) || totalMinutes}
          onContinueNow={continueNextDay}
          onSeeYouTomorrow={closeDayDone}
          onSharePhoto={async () => {
            // 1) Mostrar guía Pau Fit ANTES de abrir cámara
            //    (Pau pidió: que vean las instrucciones para tomar bien la foto)
            const ok = window.confirm(
              '📸 Cómo tomarte tu foto Pau Fit\n\n' +
              '• Ropa ajustada o bikini (que se vea el cuerpo)\n' +
              '• Frente, lateral y espalda — siempre las 3\n' +
              '• Misma luz y misma hora cada vez\n' +
              '• Fondo neutro (pared blanca o lisa)\n' +
              '• Cuerpo entero — usa el temporizador si vas sola\n' +
              '• Mismo sitio, misma distancia, misma ropa\n\n' +
              '¿Lista? Toca OK para abrir la cámara.'
            );
            if (!ok) return;
            // 2) Abrir cámara / galería
            const input = document.createElement('input');
            input.type = 'file';
            input.accept = 'image/*';
            input.capture = 'environment';
            input.onchange = async (e) => {
              const file = e.target.files && e.target.files[0];
              if (!file) return;
              nav.toast('Preparando tu story…', { icon: '✨' });
              try {
                // 2) Componer canvas con foto + branded overlay
                const blob = await composeStoryImage(file, {
                  day: Number(justCompletedDay) || 1,
                  totalDays: reto.days,
                  retoTitle: reto.title,
                  retoColor: reto.color,
                  durationMin: Math.max(1, Math.round(workoutDurationMs / 60000)) || totalMinutes,
                  userName: (window.__pauCache?.profile?.full_name || window.__pauCache?.profile?.username || '').trim(),
                });
                const shareFile = new File([blob], `pau-fit-dia-${justCompletedDay}.png`, { type: 'image/png' });
                const userName = (window.__pauCache?.profile?.full_name || window.__pauCache?.profile?.username || '').trim();
                const shareText = userName
                  ? `${userName} acaba de completar el día ${justCompletedDay} de "${reto.title}" en Pau Fit 💗 ¡Únete tú también!\n\nhttps://app.paufit.co`
                  : `¡Acabo de completar el día ${justCompletedDay} de "${reto.title}" en Pau Fit 💗 Únete tú también!\n\nhttps://app.paufit.co`;

                // 3) Intentar share NATIVO con file
                if (navigator.canShare && navigator.canShare({ files: [shareFile] })) {
                  try {
                    await navigator.share({
                      files: [shareFile],
                      title: `Día ${justCompletedDay} · Pau Fit`,
                      text: shareText,
                    });
                    nav.toast('¡Compartido! 💗', { icon: '✓' });
                    return;
                  } catch (err) {
                    if (err?.name === 'AbortError') return;
                    console.warn('[share] native falló, fallback download', err?.message);
                  }
                }

                // 4) Fallback: DESCARGAR el PNG para que lo suba ella manualmente
                const url = URL.createObjectURL(blob);
                const a = document.createElement('a');
                a.href = url;
                a.download = `pau-fit-dia-${justCompletedDay}.png`;
                document.body.appendChild(a);
                a.click();
                document.body.removeChild(a);
                setTimeout(() => URL.revokeObjectURL(url), 2000);

                // 5) Y copiamos el texto al portapapeles por si quiere pegarlo
                try { await navigator.clipboard.writeText(shareText); } catch {}
                nav.toast('Foto descargada · texto copiado 💗', { icon: '💾' });
              } catch (err) {
                console.error('[share-photo]', err);
                nav.toast('Error: ' + (err?.message || 'no se pudo crear la foto'), { icon: '⚠️' });
              }
            };
            input.click();
          }}
        />
      )}
    </div>
  );
}

// ─────────────────────────────────────────────────────────────
// DayCompletedModal — modal estilo Sweat/Silbe al completar día
// Muestra felicitación + dos opciones:
//   1. "Nos vemos mañana 💗" → vuelve al Home
//   2. "Hacer el día siguiente ya" → carga día Y
// ─────────────────────────────────────────────────────────────
function DayCompletedModal({ T, retoColor, retoTitle, dayNumber, nextDayNumber, totalDays, isLastDay, durationMin, onContinueNow, onSeeYouTomorrow, onSharePhoto }) {
  // Asegurar que dayNumber y nextDayNumber son números válidos
  const day = Number(dayNumber) || 1;
  const next = Number(nextDayNumber) || (day + 1);
  return (
    <div style={{
      position: 'fixed', inset: 0, zIndex: 9999,
      background: 'rgba(0,0,0,0.6)',
      display: 'flex', alignItems: 'center', justifyContent: 'center',
      padding: '20px',
      animation: 'fade-in 240ms ease',
    }}>
      <div style={{
        width: '100%', maxWidth: 380, maxHeight: '88dvh', overflowY: 'auto',
        background: T.bg,
        borderRadius: 28,
        padding: '24px 22px',
        position: 'relative',
        animation: 'slide-up 380ms cubic-bezier(.34,1.56,.64,1)',
        boxShadow: '0 24px 70px rgba(0,0,0,0.35)',
        WebkitOverflowScrolling: 'touch',
      }}>
        {/* Halo gradient detrás del check */}
        <div style={{
          position: 'absolute', top: -40, left: '50%', transform: 'translateX(-50%)',
          width: 200, height: 200, borderRadius: '50%',
          background: `radial-gradient(circle, ${retoColor}40, transparent 70%)`,
          pointerEvents: 'none',
        }}/>

        {/* Check con glow — más compacto */}
        <div style={{
          position: 'relative', width: 64, height: 64, margin: '0 auto 14px',
          borderRadius: '50%',
          background: `linear-gradient(135deg, ${retoColor}, ${retoColor}cc)`,
          display: 'flex', alignItems: 'center', justifyContent: 'center',
          boxShadow: `0 10px 26px ${retoColor}66`,
        }}>
          <svg width="32" height="32" viewBox="0 0 40 40">
            <path d="M10 20 L17 27 L30 13" stroke="#fff" strokeWidth="4" fill="none" strokeLinecap="round" strokeLinejoin="round"/>
          </svg>
        </div>

        {/* Título */}
        <div className="pf-display" style={{
          fontSize: 22, fontWeight: 700, color: T.text,
          letterSpacing: -0.5, lineHeight: 1.1, textAlign: 'center',
          position: 'relative',
        }}>
          {isLastDay
            ? `¡Reto completado! 💗`
            : `¡Día ${day} completado!`}
        </div>
        <div style={{
          fontSize: 13, color: T.muted, lineHeight: 1.4, textAlign: 'center',
          marginTop: 6, position: 'relative',
        }}>
          {isLastDay
            ? `Eres una crack 💪🏻`
            : `Nos vemos mañana para el día ${next}`}
        </div>

        {/* Stats: tiempo + puntos — compacto */}
        <div style={{
          marginTop: 14, padding: '10px 14px',
          background: T.subtle, borderRadius: 14,
          display: 'flex', alignItems: 'center', justifyContent: 'space-around', gap: 10,
          position: 'relative',
        }}>
          {typeof durationMin === 'number' && durationMin > 0 && (
            <div style={{ textAlign: 'center' }}>
              <div style={{ fontSize: 16, fontWeight: 800, color: T.text, letterSpacing: -0.3 }}>{durationMin}</div>
              <div style={{ fontSize: 9, fontWeight: 700, color: T.muted, letterSpacing: 0.4,  marginTop: 1 }}>MIN</div>
            </div>
          )}
          <div style={{ textAlign: 'center' }}>
            <div style={{ fontSize: 16, fontWeight: 800, color: retoColor, letterSpacing: -0.3 }}>+{isLastDay ? 250 : 50}</div>
            <div style={{ fontSize: 9, fontWeight: 700, color: T.muted, letterSpacing: 0.4,  marginTop: 1 }}>⭐ PUNTOS</div>
          </div>
        </div>

        {/* Botones */}
        <div style={{ marginTop: 14, display: 'flex', flexDirection: 'column', gap: 8, position: 'relative' }}>
          <button onClick={onSeeYouTomorrow} style={{
            width: '100%', padding: '14px',
            border: 'none', borderRadius: 14, cursor: 'pointer',
            background: retoColor, color: '#fff',
            fontSize: 14, fontWeight: 700, letterSpacing: 0.2,
            boxShadow: `0 6px 18px ${retoColor}40`,
            fontFamily: 'inherit',
          }}>
            {isLastDay ? 'Volver al inicio' : 'Listo, hasta mañana 💗'}
          </button>

          {/* 📸 Cómo tomarte la foto (guía Pau Fit antes de abrir cámara) */}
          {onSharePhoto && (
            <button onClick={onSharePhoto} style={{
              width: '100%', padding: '12px',
              border: T.border, borderRadius: 14, cursor: 'pointer',
              background: T.card, color: T.text,
              fontSize: 13, fontWeight: 600,
              fontFamily: 'inherit',
              display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 8,
            }}>
              <span style={{ fontSize: 16 }}>📸</span>
              Cómo tomarte la foto
            </button>
          )}

          {!isLastDay && (
            <button onClick={onContinueNow} style={{
              width: '100%', padding: '10px',
              border: 'none', borderRadius: 14, cursor: 'pointer',
              background: 'transparent', color: T.muted,
              fontSize: 12, fontWeight: 600,
              fontFamily: 'inherit',
            }}>
              Hacer el día {next} ya →
            </button>
          )}
        </div>
      </div>
    </div>
  );
}

function BackBtn({ onClick, light }) {
  return (
    <button onClick={onClick} style={{
      width: 36, height: 36, borderRadius: 999, border: 'none',
      background: light ? 'rgba(255,255,255,0.95)' : 'rgba(255,255,255,0.6)',
      backdropFilter: 'blur(10px)',
      cursor: 'pointer', display: 'flex', alignItems: 'center', justifyContent: 'center',
    }}>{Icon.back('#0E0A0C')}</button>
  );
}

function RoundBtn({ children, onClick, light }) {
  return (
    <button onClick={onClick || (() => window.__pauNav && window.__pauNav.toast('Enlace copiado 💗', { icon: '↗' }))} style={{
      width: 36, height: 36, borderRadius: 999, border: 'none',
      background: light ? 'rgba(255,255,255,0.95)' : 'rgba(255,255,255,0.6)',
      backdropFilter: 'blur(10px)',
      cursor: 'pointer', display: 'flex', alignItems: 'center', justifyContent: 'center',
    }}>{children}</button>
  );
}

function SmallStat({ v, l, T }) {
  return (
    <div style={{ textAlign: 'center', flex: 1 }}>
      <div className="pf-display" style={{ fontSize: 26, fontWeight: 500, color: T.text, letterSpacing: -0.5, lineHeight: 1 }}>{v}</div>
      <div style={{ fontSize: 10, color: T.muted, marginTop: 6, fontWeight: 600, letterSpacing: 0.5,  }}>{l}</div>
    </div>
  );
}

function StatTile({ label, value, T }) {
  return (
    <div style={{
      padding: '14px 12px', background: T.card, border: T.border, borderRadius: 20,
      textAlign: 'center',
    }}>
      <div className="pf-display" style={{ fontSize: 22, fontWeight: 500, color: T.text, letterSpacing: -0.4, lineHeight: 1 }}>{value}</div>
      <div style={{ fontSize: 10, color: T.muted, marginTop: 6, fontWeight: 600, letterSpacing: 0.6,  }}>{label}</div>
    </div>
  );
}

// ─────────────────────────────────────────────────────────────
// AlreadyInRetoModal — aviso cuando intenta empezar un reto
// teniendo ya OTRO reto activo. Confirma abandonar+cambiar.
// ─────────────────────────────────────────────────────────────
function AlreadyInRetoModal({ T, currentRetoTitle, newRetoTitle, onClose, onConfirm }) {
  return (
    <div style={{
      position: 'absolute', inset: 0, zIndex: 320, display: 'flex', alignItems: 'flex-end',
      background: 'rgba(0,0,0,0.45)', animation: 'fade-in 200ms ease',
    }} onClick={onClose}>
      <div onClick={(e) => e.stopPropagation()} style={{
        width: '100%', background: T.bg,
        borderTopLeftRadius: 28, borderTopRightRadius: 28,
        padding: '14px 22px 32px',
        animation: 'slide-up 320ms cubic-bezier(.2,.8,.2,1)',
      }}>
        <div style={{ width: 40, height: 4, borderRadius: 999, background: 'rgba(0,0,0,0.15)', margin: '4px auto 22px' }}/>

        <div style={{ textAlign: 'center', fontSize: 44, marginBottom: 12 }}>⚠️</div>
        <div className="pf-display" style={{
          fontSize: 22, fontWeight: 500, color: T.text, letterSpacing: -0.4, lineHeight: 1.2,
          textAlign: 'center',
        }}>
          Ya estás en otro reto
        </div>
        <div style={{ fontSize: 13, color: T.muted, marginTop: 10, lineHeight: 1.5, textAlign: 'center' }}>
          Estás haciendo <strong style={{ color: T.text }}>{currentRetoTitle}</strong>.
          Si empiezas <strong style={{ color: T.text }}>{newRetoTitle}</strong>,
          se cerrará el reto actual y perderás el progreso de los días que aún no completaste.
        </div>

        <button onClick={onConfirm} style={{
          marginTop: 24, width: '100%', padding: '16px',
          border: 'none', borderRadius: 20, cursor: 'pointer',
          background: T.accent, color: '#fff',
          fontSize: 14, fontWeight: 700, letterSpacing: 0.3,
          boxShadow: `0 8px 20px ${T.accent}55`,
        }}>Sí, cambiar a {newRetoTitle}</button>

        <button onClick={onClose} style={{
          marginTop: 8, width: '100%', padding: '14px',
          border: T.border, borderRadius: 20, background: T.card, cursor: 'pointer',
          fontSize: 13, fontWeight: 600, color: T.text,
        }}>Seguir con {currentRetoTitle}</button>
      </div>
    </div>
  );
}

// ─────────────────────────────────────────────────────────────
// JoinRetoModal — slide up sheet: confirm join + add to calendar
// ─────────────────────────────────────────────────────────────
function JoinRetoModal({ reto, T, onClose, onJoin }) {
  const [startMode, setStartMode] = useS2('today'); // today | monday | custom
  const [addCalendar, setAddCalendar] = useS2(true);
  const [reminder, setReminder] = useS2('19:00');

  // Fechas REALES en español
  const today = new Date();
  const todayFmt = today.toLocaleDateString('es', { weekday: 'long', day: 'numeric', month: 'long' });
  // Próximo lunes
  const nextMon = new Date(today);
  const dow = today.getDay(); // 0=Dom, 1=Lun, ...
  const daysUntilMon = dow === 1 ? 7 : (8 - dow) % 7 || 7;
  nextMon.setDate(today.getDate() + daysUntilMon);
  const mondayFmt = nextMon.toLocaleDateString('es', { weekday: 'long', day: 'numeric', month: 'long' });

  const startLabel = startMode === 'today' ? `Hoy, ${todayFmt}` :
                     startMode === 'monday' ? mondayFmt :
                     'Personalizado';

  return (
    <div style={{
      position: 'absolute', inset: 0, zIndex: 310, display: 'flex', alignItems: 'flex-end',
      background: 'rgba(0,0,0,0.4)', animation: 'fade-in 200ms ease',
    }} onClick={onClose}>
      <div onClick={(e) => e.stopPropagation()} style={{
        width: '100%', background: T.bg,
        borderTopLeftRadius: 28, borderTopRightRadius: 28,
        padding: '14px 22px 32px',
        animation: 'slide-up 320ms cubic-bezier(.2,.8,.2,1)',
        maxHeight: '92%', overflowY: 'auto',
      }}>
        <div style={{ width: 40, height: 4, borderRadius: 999, background: 'rgba(0,0,0,0.15)', margin: '4px auto 18px' }}/>

        {/* Header with image */}
        <div style={{
          aspectRatio: '16 / 8', borderRadius: 20, overflow: 'hidden',
          background: 'rgba(0,0,0,0.04)', position: 'relative',
        }}>
          {reto.image
            ? <img loading="lazy" src={reto.image} alt={reto.title} style={{ position: 'absolute', inset: 0, width: '100%', height: '100%', objectFit: 'cover' }}/>
            : <div style={{ position: 'absolute', inset: 0, background: `linear-gradient(135deg, ${T.accent}, ${T.deep})` }}/>
          }
        </div>

        <div className="pf-display" style={{
          fontSize: 26, fontWeight: 500, color: T.text, marginTop: 14, letterSpacing: -0.5, lineHeight: 1.1,
        }}>{reto.title}</div>
        <div style={{ fontSize: 12, color: T.muted, marginTop: 4, fontWeight: 500 }}>
          {reto.days} días · {reto.minPerDay} min/día · {reto.intensity}
        </div>

        {/* Start date */}
        <div style={{ marginTop: 20 }}>
          <div style={{ fontSize: 10, color: T.muted, fontWeight: 600, letterSpacing: 0.8,  }}>
            Empezar
          </div>
          <div style={{ marginTop: 8, display: 'flex', flexDirection: 'column', gap: 6 }}>
            {[
              { v: 'today',  e: '🌟', t: 'Hoy mismo', s: 'Empieza ya con el día 1' },
              { v: 'monday', e: '📅', t: 'Próximo lunes', s: `${mondayFmt} · empezar fresca` },
              { v: 'custom', e: '🗓️', t: 'Otra fecha', s: 'Elige cuando empezar' },
            ].map(o => {
              const sel = startMode === o.v;
              return (
                <button key={o.v} onClick={() => setStartMode(o.v)} style={{
                  padding: '12px 14px',
                  border: sel ? `1.5px solid ${T.accent}` : T.border,
                  background: sel ? `${T.accent}10` : T.card,
                  borderRadius: 20, cursor: 'pointer', textAlign: 'left',
                  display: 'flex', alignItems: 'center', gap: 12,
                }}>
                  <span style={{ fontSize: 22 }}>{o.e}</span>
                  <div style={{ flex: 1 }}>
                    <div style={{ fontSize: 13, fontWeight: 600, color: T.text }}>{o.t}</div>
                    <div style={{ fontSize: 11, color: T.muted, marginTop: 1 }}>{o.s}</div>
                  </div>
                  <div style={{
                    width: 18, height: 18, borderRadius: 999, flexShrink: 0,
                    border: sel ? 'none' : `1.5px solid ${T.muted}50`,
                    background: sel ? T.accent : 'transparent',
                    display: 'flex', alignItems: 'center', justifyContent: 'center',
                  }}>{sel && <div style={{ width: 7, height: 7, borderRadius: 999, background: '#fff' }}/>}</div>
                </button>
              );
            })}
          </div>
        </div>

        {/* Add to calendar toggle */}
        <div style={{
          marginTop: 16, padding: '14px 16px',
          background: T.card, borderRadius: 20, border: T.border,
          display: 'flex', alignItems: 'center', gap: 12,
        }}>
          <span style={{ fontSize: 22 }}>📅</span>
          <div style={{ flex: 1 }}>
            <div style={{ fontSize: 13, fontWeight: 600, color: T.text }}>Agregar al calendario</div>
            <div style={{ fontSize: 11, color: T.muted, marginTop: 1 }}>{reto.days} días en tu Apple Calendar</div>
          </div>
          <button onClick={() => setAddCalendar(!addCalendar)} style={{
            width: 42, height: 24, borderRadius: 999, border: 'none', cursor: 'pointer',
            background: addCalendar ? T.accent : 'rgba(0,0,0,0.12)', position: 'relative',
            transition: 'background 200ms ease',
          }}>
            <div style={{
              position: 'absolute', top: 3, left: addCalendar ? 21 : 3,
              width: 18, height: 18, borderRadius: 999, background: '#fff',
              transition: 'left 200ms ease', boxShadow: '0 1px 3px rgba(0,0,0,0.15)',
            }}/>
          </button>
        </div>

        {/* Reminder time */}
        <div style={{
          marginTop: 8, padding: '14px 16px',
          background: T.card, borderRadius: 20, border: T.border,
          display: 'flex', alignItems: 'center', gap: 12,
        }}>
          <span style={{ fontSize: 22 }}>🔔</span>
          <div style={{ flex: 1 }}>
            <div style={{ fontSize: 13, fontWeight: 600, color: T.text }}>Recordatorio diario</div>
            <div style={{ fontSize: 11, color: T.muted, marginTop: 1 }}>Te avisamos para no romper la racha</div>
          </div>
          <input type="time" value={reminder} onChange={(e) => setReminder(e.target.value)} style={{
            padding: '6px 10px', borderRadius: 8, border: T.border,
            background: T.subtle, fontSize: 13, fontWeight: 600, color: T.text,
            outline: 'none', letterSpacing: -0.2,
          }}/>
        </div>

        {/* CTA */}
        <button onClick={onJoin} style={{
          marginTop: 18, width: '100%', padding: '16px',
          border: 'none', borderRadius: 20, cursor: 'pointer',
          background: T.text, color: T.card,
          fontSize: 14, fontWeight: 600, letterSpacing: -0.1,
          boxShadow: `0 8px 20px rgba(0,0,0,0.15)`,
        }}>✓ Unirme · empezar {startLabel.split(',')[0].toLowerCase()}</button>

        <button onClick={onClose} style={{
          marginTop: 6, width: '100%', padding: '12px',
          border: 'none', background: 'transparent', cursor: 'pointer',
          fontSize: 12, fontWeight: 500, color: T.muted,
        }}>Cancelar</button>
      </div>
    </div>
  );
}

function SocialChip({ emoji, value }) {
  return (
    <span style={{
      display: 'inline-flex', alignItems: 'center', gap: 4,
      padding: '5px 10px', borderRadius: 999,
      background: 'rgba(255,255,255,0.55)', backdropFilter: 'blur(8px)',
      fontFamily: 'Poppins', fontSize: 11, fontWeight: 600, color: '#2D2A26',
    }}>
      <span style={{ fontSize: 12 }}>{emoji}</span>
      {value}
    </span>
  );
}

// ═════════════════════════════════════════════════════════════
// Video Player (mocked)
// ═════════════════════════════════════════════════════════════
function VideoPlayer({ video, reto, onClose, onFinish, T, isPremium = false }) {
  const [time, setTime] = useS2(0);
  const [finishedNotice, setFinishedNotice] = useS2(false);
  const [audioMode, setAudioMode] = useS2('full');
  const [musicOn, setMusicOn] = useS2(true);
  const [hr, setHr] = useS2(112);

  // Mock interval program: 6 sets of (40s work + 20s rest)
  const SETS = 6;
  const WORK = 40, REST = 20;
  const SET_LEN = WORK + REST;
  const totalLen = SETS * SET_LEN;
  const totalRealSec = video.minutes * 60;

  useE2(() => {
    const i = setInterval(() => {
      setTime(t => {
        const next = Math.min(t + 8, totalRealSec);
        if (next >= totalRealSec && t < totalRealSec) {
          onFinish && onFinish();
          setFinishedNotice(true);
        }
        return next;
      });
      setHr(h => {
        // bobble heart rate between 95-155
        const target = 95 + Math.random() * 60;
        return Math.round(h + (target - h) * 0.3);
      });
    }, 1000);
    return () => clearInterval(i);
  }, [video]);

  // Map real elapsed to interval program (loop the program over the video length)
  const intervalT = (time / totalRealSec) * totalLen;
  const currentSet = Math.min(SETS, Math.floor(intervalT / SET_LEN) + 1);
  const inSet = intervalT % SET_LEN;
  const isWork = inSet < WORK;
  const phaseRemaining = Math.ceil(isWork ? (WORK - inSet) : (SET_LEN - inSet));

  const pct = (time / totalRealSec) * 100;
  const fmt = (s) => `${Math.floor(s/60)}:${String(Math.floor(s%60)).padStart(2,'0')}`;
  const finished = time >= totalRealSec;

  const audioModes = [
    { id: 'full',   label: 'Música Pau', sub: 'Música + voz',  icon: '🎵' },
    { id: 'voice',  label: 'Solo voz',   sub: 'Tu música',     icon: '🎙️' },
    { id: 'silent', label: 'Silencio',   sub: 'Sin audio',     icon: '🔇' },
  ];

  return (
    <div style={{
      position: 'absolute', inset: 0, background: '#0A0A0F', zIndex: 200,
      display: 'flex', flexDirection: 'column', color: '#fff',
      animation: 'fade-in 240ms ease',
    }}>
      {/* Top bar */}
      <div style={{
        padding: '50px 18px 12px', display: 'flex', alignItems: 'center', gap: 12,
        position: 'relative', zIndex: 2,
      }}>
        <button onClick={onClose} style={{
          width: 36, height: 36, borderRadius: 999, border: 'none',
          background: 'rgba(255,255,255,0.15)', cursor: 'pointer',
          display: 'flex', alignItems: 'center', justifyContent: 'center',
          backdropFilter: 'blur(10px)',
        }}>{Icon.close('#fff')}</button>
        <div style={{ flex: 1 }}>
          <div style={{ fontSize: 10, color: 'rgba(255,255,255,0.5)', fontWeight: 600, letterSpacing: 0.6,  }}>{reto.title}</div>
          <div style={{ fontSize: 14, fontWeight: 600, color: '#fff', marginTop: 2 }}>{video.title}</div>
        </div>
        {/* Apple Health HR pill */}
        <div style={{
          display: 'flex', alignItems: 'center', gap: 6,
          padding: '6px 11px', borderRadius: 999,
          background: 'rgba(255,255,255,0.12)', backdropFilter: 'blur(10px)',
        }}>
          <span style={{ fontSize: 13, animation: 'live-pulse 1s ease-in-out infinite' }}>❤️</span>
          <span className="pf-mono" style={{ fontSize: 13, fontWeight: 700, fontVariantNumeric: 'tabular-nums' }}>{hr}</span>
        </div>
      </div>

      {/* Video area */}
      <div style={{
        flex: 1, display: 'flex', alignItems: 'center', justifyContent: 'center',
        background: `radial-gradient(circle at 50% 40%, ${reto.color}50, #0A0A0F 70%)`,
        position: 'relative', overflow: 'hidden',
      }}>
        <image-slot
          id={`player-${video.id}`}
          placeholder="Frame del video"
          shape="rect"
          style={{ position: 'absolute', inset: 0, opacity: 0.85 }}
        />

        {/* Big interval indicator */}
        <div style={{ position: 'relative', textAlign: 'center', zIndex: 2 }}>
          <div style={{
            fontSize: 10, fontWeight: 700, letterSpacing: 2.5,
            color: isWork ? '#FF4D6B' : '#7CD2A0', 
            marginBottom: 8,
          }}>{isWork ? '● Trabajando' : '○ Descanso'}</div>
          <div className="pf-display" style={{
            fontSize: 96, fontWeight: 400, color: '#fff', letterSpacing: -3, lineHeight: 1,
            fontVariantNumeric: 'tabular-nums',
            textShadow: '0 4px 24px rgba(0,0,0,0.5)',
          }}>{phaseRemaining}</div>
          <div style={{ fontSize: 11, color: 'rgba(255,255,255,0.6)', marginTop: 6, letterSpacing: 0.5 }}>
            Set <b>{currentSet}</b> de {SETS} · {isWork ? '40s trabajo' : '20s descanso'}
          </div>
        </div>

        {finished && finishedNotice && (
          <div style={{
            position: 'absolute', top: 24, left: '50%', transform: 'translateX(-50%)',
            padding: '10px 16px', borderRadius: 999,
            background: 'rgba(124,210,160,0.95)',
            display: 'flex', alignItems: 'center', gap: 8,
            animation: 'slide-down 360ms cubic-bezier(.2,.8,.2,1)',
          }}>
            <div style={{
              width: 22, height: 22, borderRadius: 999, background: '#fff',
              display: 'flex', alignItems: 'center', justifyContent: 'center',
            }}>{Icon.check('#3C7150', 14)}</div>
            <span style={{ fontSize: 13, fontWeight: 600, color: '#0A0A0F' }}>Marcado automático · ¡Bien hecho!</span>
          </div>
        )}

        {/* Set dots indicator (bottom) */}
        <div style={{
          position: 'absolute', bottom: 18, left: '50%', transform: 'translateX(-50%)',
          display: 'flex', gap: 6,
        }}>
          {Array.from({length: SETS}).map((_, i) => (
            <span key={i} style={{
              width: i + 1 < currentSet ? 14 : 6, height: 6, borderRadius: 999,
              background: i + 1 <= currentSet ? '#fff' : 'rgba(255,255,255,0.25)',
              transition: 'width 240ms ease, background 240ms ease',
            }}/>
          ))}
        </div>
      </div>

      {/* Spotify mini player */}
      {SPOTIFY.current && <div style={{
        margin: '0 18px 12px', padding: '10px 14px',
        background: 'rgba(29,185,84,0.18)', border: '0.5px solid rgba(29,185,84,0.4)',
        borderRadius: 20, display: 'flex', alignItems: 'center', gap: 10,
        backdropFilter: 'blur(20px)',
      }}>
        <SpotifyGlyph size={16} c="#1DB954"/>
        <div style={{ flex: 1, minWidth: 0 }}>
          <div style={{ fontSize: 9, color: 'rgba(255,255,255,0.6)', letterSpacing: 0.6,  fontWeight: 600 }}>Pau Cardio Mix</div>
          <div style={{ fontSize: 12, fontWeight: 600, color: '#fff', marginTop: 1, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>
            {SPOTIFY.current.song} · {SPOTIFY.current.artist}
          </div>
        </div>
        <button onClick={() => setMusicOn(!musicOn)} style={{
          width: 32, height: 32, borderRadius: 999, border: 'none',
          background: '#1DB954', cursor: 'pointer', flexShrink: 0,
          display: 'flex', alignItems: 'center', justifyContent: 'center',
          paddingLeft: musicOn ? 0 : 2,
        }}>
          {musicOn
            ? <svg width="12" height="12" viewBox="0 0 14 14"><rect x="3" y="2" width="3" height="10" rx="1" fill="#fff"/><rect x="8" y="2" width="3" height="10" rx="1" fill="#fff"/></svg>
            : <svg width="11" height="11" viewBox="0 0 13 13"><path d="M3 2l8 4.5-8 4.5V2z" fill="#fff"/></svg>
          }
        </button>
      </div>}

      {/* Audio modes */}
      <div style={{ padding: '0 18px 10px' }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 6, marginBottom: 8 }}>
          <span style={{ fontSize: 10, color: 'rgba(255,255,255,0.5)', fontWeight: 600, letterSpacing: 0.6,  }}>Audio guía</span>
          {!isPremium && (
            <span style={{
              padding: '2px 6px', borderRadius: 5, background: T?.gold || '#D9B074',
              fontSize: 8, fontWeight: 800, color: '#0A0A0F', letterSpacing: 0.6,
            }}>PRO</span>
          )}
        </div>
        <div style={{ display: 'flex', gap: 6 }}>
          {audioModes.map(m => {
            const locked = !isPremium && m.id !== 'full';
            const sel = audioMode === m.id;
            return (
              <button key={m.id} onClick={() => !locked && setAudioMode(m.id)}
                disabled={locked} style={{
                flex: 1, padding: '10px 8px',
                border: sel ? '1.5px solid #fff' : '1.5px solid rgba(255,255,255,0.12)',
                background: sel ? 'rgba(255,255,255,0.14)' : 'rgba(255,255,255,0.04)',
                borderRadius: 14, cursor: locked ? 'not-allowed' : 'pointer',
                opacity: locked ? 0.45 : 1,
                position: 'relative',
                display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 2,
              }}>
                <span style={{ fontSize: 16 }}>{m.icon}</span>
                <span style={{ fontSize: 10, fontWeight: 600, color: '#fff' }}>{m.label}</span>
                <span style={{ fontSize: 8, color: 'rgba(255,255,255,0.55)' }}>{m.sub}</span>
                {locked && (
                  <div style={{ position: 'absolute', top: 6, right: 6 }}>{Icon.lock('rgba(255,255,255,0.6)', 9)}</div>
                )}
              </button>
            );
          })}
        </div>
      </div>

      {/* Controls */}
      <div style={{ padding: '0 22px 50px' }}>
        <div style={{ height: 3, background: 'rgba(255,255,255,0.2)', borderRadius: 999, overflow: 'hidden' }}>
          <div style={{ width: `${pct}%`, height: '100%', background: finished ? '#7CD2A0' : '#fff', transition: 'background 240ms ease' }}/>
        </div>
        <div style={{ display: 'flex', justifyContent: 'space-between', marginTop: 8 }}>
          <span style={{ fontSize: 11, color: 'rgba(255,255,255,0.7)', fontVariantNumeric: 'tabular-nums' }}>{fmt(time)}</span>
          <span style={{ fontSize: 11, color: 'rgba(255,255,255,0.7)', fontVariantNumeric: 'tabular-nums' }}>{fmt(totalRealSec)}</span>
        </div>
        <div style={{ display: 'flex', justifyContent: 'center', gap: 28, marginTop: 14, alignItems: 'center' }}>
          <button onClick={() => setTime(t => Math.max(0, t - 15))} style={{ background: 'transparent', border: 'none', cursor: 'pointer', color: '#fff', fontSize: 13, fontWeight: 500 }}>−15s</button>
          <div style={{
            width: 64, height: 64, borderRadius: 999, background: '#fff',
            display: 'flex', alignItems: 'center', justifyContent: 'center', paddingLeft: 4,
          }}>
            {finished ? Icon.check('#000', 24) : <svg width="22" height="22" viewBox="0 0 22 22"><path d="M5 3l13 8-13 8V3z" fill="#000"/></svg>}
          </div>
          <button onClick={() => setTime(t => Math.min(totalRealSec, t + 15))} style={{ background: 'transparent', border: 'none', cursor: 'pointer', color: '#fff', fontSize: 13, fontWeight: 500 }}>+15s</button>
        </div>
        {finished && (
          <button onClick={onClose} style={{
            marginTop: 14, width: '100%', padding: '14px',
            border: 'none', borderRadius: 20, cursor: 'pointer',
            background: '#7CD2A0', color: '#0A0A0F',
            fontSize: 14, fontWeight: 600,
          }}>✓ Volver al reto</button>
        )}
      </div>
    </div>
  );
}

// ═════════════════════════════════════════════════════════════
// DETALLE RECETA
// ═════════════════════════════════════════════════════════════
function DetalleRecetaScreen({ recetaId, theme, nav }) {
  const T = theme;
  const r = ((window.__pauCache && window.__pauCache.recetas) || []).find(x => x.id === recetaId) || RECETAS.find(x => x.id === recetaId);
  const [checked, setChecked] = useS2(new Set());
  const [fav, setFav] = useS2(false);

  function toggle(i) {
    setChecked(prev => {
      const next = new Set(prev);
      if (next.has(i)) next.delete(i); else next.add(i);
      return next;
    });
  }

  return (
    <div style={{ paddingBottom: 110 }}>
      {/* Hero — usa imagen real si la tiene */}
      {r.image ? (
        <div style={{ position: 'relative' }}>
          <div style={{
            height: 320, backgroundImage: `url(${r.image})`,
            backgroundSize: 'cover', backgroundPosition: 'center',
            borderBottomLeftRadius: 32, borderBottomRightRadius: 32,
          }}/>
          <div style={{
            position: 'absolute', inset: 0,
            background: 'linear-gradient(180deg, rgba(0,0,0,0.18) 0%, transparent 30%, rgba(0,0,0,0.55) 100%)',
            borderBottomLeftRadius: 32, borderBottomRightRadius: 32,
          }}/>
          <div style={{
            position: 'absolute', top: 12, left: 22, right: 22,
            display: 'flex', justifyContent: 'space-between',
          }}>
            <BackBtn onClick={() => nav.back()}/>
            <div style={{ display: 'flex', gap: 8 }}>
              <RoundBtn onClick={() => {
                const userName = (window.__pauCache?.profile?.full_name || window.__pauCache?.profile?.username || '').trim();
                const text = userName
                  ? `${userName} recomienda esta receta: "${r.title}" 🍓 ${r.kcal} kcal · ${r.minutes} min — en Pau Fit 💗`
                  : `Mira esta receta: "${r.title}" 🍓 ${r.kcal} kcal · ${r.minutes} min — en Pau Fit 💗`;
                window.PauShare && window.PauShare({ title: `${r.title} · Pau Fit`, text, url: 'https://app.paufit.co' }).then(function(rs){ if (rs.shared) nav.toast(rs.method === 'native' ? 'Compartido' : 'Enlace copiado 💗', { icon: '↗' }) });
              }}>{Icon.share('#2D2A26')}</RoundBtn>
              <RoundBtn onClick={() => setFav(!fav)}>{Icon.heart(fav ? '#D4847A' : '#2D2A26', fav)}</RoundBtn>
            </div>
          </div>
          <div style={{
            position: 'absolute', bottom: 18, left: 22, right: 22,
          }}>
            <span style={{
              display: 'inline-block',
              fontFamily: 'Poppins', fontSize: 9, fontWeight: 700, letterSpacing: 1, 
              color: '#2D2A26', background: 'rgba(255,255,255,0.95)', padding: '4px 8px', borderRadius: 6,
            }}>{r.category}</span>
            <div style={{ fontFamily: 'Poppins', fontSize: 26, fontWeight: 600, color: '#fff', marginTop: 8, letterSpacing: -0.6, lineHeight: 1.15, textShadow: '0 1px 8px rgba(0,0,0,0.3)' }}>{r.title}</div>
            <div style={{ display: 'flex', alignItems: 'center', gap: 6, marginTop: 6 }}>
              <span style={{ fontFamily: 'Poppins', fontSize: 12, fontWeight: 700, color: '#F5E6C8' }}>💗 {recommendsPercent(r.id) ? recommendsPercent(r.id) + '% lo recomienda' : ''}</span>
              <span style={{ fontFamily: 'Poppins', fontSize: 11, color: 'rgba(255,255,255,0.7)' }}>· {testimoniesFor(r.id).length || 0} testimonios</span>
            </div>
          </div>
        </div>
      ) : (
        <div style={{
          background: T.dark ? 'linear-gradient(160deg, #3B2F26, #2A2520)' : 'linear-gradient(160deg, #F5E6C8, #FAF3EE)',
          padding: '12px 20px 26px',
          borderBottomLeftRadius: 32, borderBottomRightRadius: 32,
          position: 'relative',
        }}>
          <div style={{ display: 'flex', justifyContent: 'space-between' }}>
            <BackBtn onClick={() => nav.back()}/>
            <div style={{ display: 'flex', gap: 8 }}>
              <RoundBtn onClick={() => {
                const userName = (window.__pauCache?.profile?.full_name || window.__pauCache?.profile?.username || '').trim();
                const text = userName
                  ? `${userName} recomienda esta receta: "${r.title}" 🍓 ${r.kcal} kcal · ${r.minutes} min — en Pau Fit 💗`
                  : `Mira esta receta: "${r.title}" 🍓 ${r.kcal} kcal · ${r.minutes} min — en Pau Fit 💗`;
                window.PauShare && window.PauShare({ title: `${r.title} · Pau Fit`, text, url: 'https://app.paufit.co' }).then(function(rs){ if (rs.shared) nav.toast(rs.method === 'native' ? 'Compartido' : 'Enlace copiado 💗', { icon: '↗' }) });
              }}>{Icon.share('#2D2A26')}</RoundBtn>
              <RoundBtn onClick={() => setFav(!fav)}>{Icon.heart(fav ? '#D4847A' : '#2D2A26', fav)}</RoundBtn>
            </div>
          </div>
          <div style={{ textAlign: 'center', marginTop: 12 }}>
            <div style={{ fontSize: 80, lineHeight: 1 }}>{r.emoji}</div>
          </div>
          <div style={{ marginTop: 14 }}>
            <span style={{
              fontFamily: 'Poppins', fontSize: 10, fontWeight: 600, letterSpacing: 1, 
              color: T.dark ? '#F5E6C8' : '#9C7340',
            }}>{r.category}</span>
            <div style={{ fontFamily: 'Poppins', fontSize: 26, fontWeight: 600, color: T.dark ? '#fff' : '#2D2A26', marginTop: 6, letterSpacing: -0.6, lineHeight: 1.15 }}>{r.title}</div>
            <div style={{ display: 'flex', alignItems: 'center', gap: 6, marginTop: 6 }}>
              <span style={{ fontFamily: 'Poppins', fontSize: 12, fontWeight: 700, color: T.accent }}>💗 {recommendsPercent(r.id) ? recommendsPercent(r.id) + '% lo recomienda' : ''}</span>
              <span style={{ fontFamily: 'Poppins', fontSize: 11, color: T.muted }}>· {testimoniesFor(r.id).length || 0} testimonios</span>
            </div>
          </div>
        </div>
      )}

      {/* Description */}
      <div style={{ padding: '20px 22px 0', fontFamily: 'Poppins', fontSize: 13, color: T.muted, lineHeight: 1.5 }}>{r.desc}</div>

      {/* Macros */}
      <div style={{ display: 'flex', justifyContent: 'space-around', padding: '16px 20px 0' }}>
        <SmallStat v={`${r.kcal}`} l="kcal" T={T}/>
        <SmallStat v={`${r.minutes}'`} l="prep" T={T}/>
        <SmallStat v={`${r.macros.p}g`} l="proteína" T={T}/>
        <SmallStat v={`${r.macros.c}g`} l="carbos" T={T}/>
      </div>

      {/* Ingredients */}
      <div style={{ padding: '24px 20px 0' }}>
        <div style={{ fontFamily: 'Poppins', fontSize: 18, fontWeight: 600, color: T.text, letterSpacing: -0.3 }}>Ingredientes</div>
      </div>
      <div style={{ margin: '12px 18px 0', background: T.card, borderRadius: 20, padding: 6, border: T.border }}>
        {r.ingredients.map((ing, i) => {
          const isChecked = checked.has(i);
          return (
            <button key={i} onClick={() => toggle(i)} style={{
              width: '100%', display: 'flex', alignItems: 'center', gap: 12,
              padding: '12px 14px', border: 'none', background: 'transparent', cursor: 'pointer', textAlign: 'left',
              borderRadius: 14,
            }}>
              <div style={{
                width: 22, height: 22, borderRadius: 6, flexShrink: 0,
                border: isChecked ? 'none' : (T.dark ? '1.5px solid rgba(255,255,255,0.2)' : '1.5px solid rgba(0,0,0,0.15)'),
                background: isChecked ? '#A8C5A0' : 'transparent',
                display: 'flex', alignItems: 'center', justifyContent: 'center',
              }}>{isChecked && Icon.check('#fff', 12)}</div>
              <span style={{
                fontFamily: 'Poppins', fontSize: 14, color: T.text, fontWeight: 500,
                textDecoration: isChecked ? 'line-through' : 'none',
                opacity: isChecked ? 0.5 : 1,
              }}>{ing}</span>
            </button>
          );
        })}
      </div>

      {/* Steps */}
      <div style={{ padding: '24px 20px 0' }}>
        <div style={{ fontFamily: 'Poppins', fontSize: 18, fontWeight: 600, color: T.text, letterSpacing: -0.3 }}>Preparación</div>
      </div>
      <div style={{ margin: '12px 18px 0', display: 'flex', flexDirection: 'column', gap: 10 }}>
        {r.steps.map((s, i) => (
          <div key={i} style={{
            display: 'flex', gap: 14, padding: 14, background: T.card, borderRadius: 20, border: T.border,
          }}>
            <div style={{
              width: 26, height: 26, borderRadius: 999, background: T.accent, color: '#fff',
              display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0,
              fontFamily: 'Poppins', fontSize: 12, fontWeight: 700,
            }}>{i + 1}</div>
            <div style={{ fontFamily: 'Poppins', fontSize: 14, color: T.text, fontWeight: 500, lineHeight: 1.5 }}>{s}</div>
          </div>
        ))}
      </div>

      {/* Reviews */}
      <ReviewsSection type="receta" id={r.id} T={T} accent={T.accent}/>
    </div>
  );
}

// ═════════════════════════════════════════════════════════════
// PAYWALL
// ═════════════════════════════════════════════════════════════
function PaywallScreen({ theme, nav, fromReto, onComplete }) {
  const T = theme;
  const [plan, setPlan] = useS2('annual');

  const features = [
    { e: '🔓', t: '+12 retos premium', d: 'Glow Up, Glúteos PRO, HIIT total y más' },
    { e: '🥗', t: 'Planes de alimentación', d: 'Sincronizados con tu reto activo' },
    { e: '🎥', t: 'Clases en vivo con Pau', d: 'HIIT, yoga, cardio cada semana' },
    { e: '⏱️', t: 'Player con intervalos', d: 'Timer, descansos y música a la medida' },
    { e: '❤️', t: 'Sync con Apple Health', d: 'Calorías y ritmo cardíaco en pantalla' },
    { e: '🎵', t: 'Spotify integrado', d: 'Playlists Pau · sin anuncios' },
    { e: '📐', t: 'Progreso fotográfico', d: 'Medidas, fotos y comparativas' },
    { e: '💗', t: 'Comunidad PRO', d: 'Retos en pareja, ranking, chat grupal' },
  ];

  // Sin testimonios fake — se llenan cuando haya usuarias reales dejando reseñas
  const testimonios = [];

  return (
    <div style={{
      paddingBottom: 130, background: '#15101A', minHeight: '100%',
      color: '#fff', position: 'relative', overflow: 'hidden',
    }}>
      {/* Decorative gradient mesh */}
      <div style={{
        position: 'absolute', top: -120, right: -100, width: 380, height: 380,
        borderRadius: '50%', background: `radial-gradient(circle, ${T.accent}55, transparent 70%)`,
      }}/>
      <div style={{
        position: 'absolute', top: 220, left: -120, width: 320, height: 320,
        borderRadius: '50%', background: 'radial-gradient(circle, rgba(217,176,116,0.25), transparent 70%)',
      }}/>
      <div style={{
        position: 'absolute', bottom: 0, right: -60, width: 280, height: 280,
        borderRadius: '50%', background: `radial-gradient(circle, ${T.accent}35, transparent 70%)`,
      }}/>

      {/* Top */}
      <div style={{ padding: '12px 20px 0', position: 'relative', display: 'flex', justifyContent: 'space-between' }}>
        <button onClick={() => nav.back()} style={{
          width: 36, height: 36, borderRadius: 999, border: 'none',
          background: 'rgba(255,255,255,0.1)', cursor: 'pointer',
          display: 'flex', alignItems: 'center', justifyContent: 'center',
          backdropFilter: 'blur(10px)',
        }}>{Icon.close('#fff')}</button>
        <button onClick={async () => {
          // Verificar status premium en Supabase (refresca profile + active subscription)
          const sb = window.__PAU_SUPABASE;
          if (!sb) { nav.toast('Sin conexión', { icon: '⚠️' }); return; }
          nav.toast('Verificando tu suscripción…', { icon: '⏳' });
          try {
            const { data: { user } } = await sb.auth.getUser();
            if (!user) { nav.toast('Inicia sesión', { icon: '🔒' }); return; }
            const { data: p } = await sb.from('profiles')
              .select('is_premium, premium_until, trial_ends_at')
              .eq('id', user.id).maybeSingle();
            if (p?.is_premium) {
              nav.toast('¡Premium activo! 💗', { icon: '✓' });
              // Refrescar cache global
              if (window.__pauCache?.profile) {
                window.__pauCache.profile = { ...window.__pauCache.profile, ...p };
                window.dispatchEvent(new CustomEvent('pau:cache-updated'));
              }
              setTimeout(() => nav.back(), 800);
            } else if (p?.trial_ends_at && new Date(p.trial_ends_at) > new Date()) {
              const days = Math.ceil((new Date(p.trial_ends_at) - new Date()) / (1000 * 60 * 60 * 24));
              nav.toast(`Tu prueba expira en ${days} día${days === 1 ? '' : 's'}`, { icon: '⏳' });
            } else {
              nav.toast('No encontramos premium activo. Inicia una suscripción 💗', { icon: 'ℹ️' });
            }
          } catch (e) {
            nav.toast('Error: ' + (e?.message || e), { icon: '⚠️' });
          }
        }} style={{
          padding: '8px 14px', borderRadius: 999, border: 'none', cursor: 'pointer',
          background: 'rgba(255,255,255,0.1)', color: '#fff',
          fontSize: 11, fontWeight: 500, backdropFilter: 'blur(10px)',
        }}>Restaurar compra</button>
      </div>

      {/* Hero */}
      <div style={{ padding: '20px 28px 0', position: 'relative', textAlign: 'center' }}>
        <span style={{
          display: 'inline-block', padding: '5px 11px', borderRadius: 999,
          background: `${T.accent}30`, color: T.gold,
          fontSize: 9, fontWeight: 800, letterSpacing: 1.6, 
        }}>Pau Fit · Premium</span>
        <div className="pf-display" style={{
          fontSize: 46, fontWeight: 400, marginTop: 18,
          letterSpacing: -1.2, lineHeight: 1.0, color: '#fff',
        }}>
          Todo Pau Fit,<br/>
          <span className="pf-display-italic" style={{ color: T.gold }}>desbloqueado</span>
        </div>
        <div style={{
          fontSize: 14, color: 'rgba(255,255,255,0.65)', marginTop: 14, lineHeight: 1.5, maxWidth: 280, margin: '14px auto 0',
        }}>
          {fromReto
            ? <>Accede al reto <b style={{color:'#fff'}}>{fromReto.title}</b> y a todo lo demás. 7 días gratis.</>
            : <>La app fitness más cálida y completa. <b style={{color:'#fff'}}>7 días gratis</b>, sin compromiso.</>
          }
        </div>
      </div>

      {/* Features */}
      <div style={{ padding: '32px 18px 0', position: 'relative', display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 8 }}>
        {features.map((b, i) => (
          <div key={i} style={{
            padding: '14px 12px', background: 'rgba(255,255,255,0.04)', borderRadius: 20,
            border: '0.5px solid rgba(255,255,255,0.08)',
            backdropFilter: 'blur(10px)',
          }}>
            <div style={{ fontSize: 20 }}>{b.e}</div>
            <div style={{ fontSize: 12, fontWeight: 600, color: '#fff', marginTop: 6, letterSpacing: -0.1, lineHeight: 1.2 }}>{b.t}</div>
            <div style={{ fontSize: 10, color: 'rgba(255,255,255,0.55)', marginTop: 3, lineHeight: 1.3 }}>{b.d}</div>
          </div>
        ))}
      </div>

      {/* Testimonios horizontales */}
      <div style={{ padding: '28px 0 0', position: 'relative' }}>
        <div style={{ padding: '0 22px 12px' }}>
          <span className="pf-display" style={{ fontSize: 20, fontWeight: 500, color: '#fff' }}>Lo que dicen</span>
        </div>
        <div style={{ display: testimonios.length === 0 ? 'none' : 'flex', gap: 10, padding: '0 20px', overflowX: 'auto' }} className="hide-scroll">
          {testimonios.map((t, i) => (
            <div key={i} style={{
              flexShrink: 0, width: 240, padding: 14,
              background: 'rgba(255,255,255,0.05)', borderRadius: 20,
              border: '0.5px solid rgba(255,255,255,0.08)',
            }}>
              <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
                <div style={{
                  width: 32, height: 32, borderRadius: 999,
                  background: `linear-gradient(135deg, ${T.accent}, ${T.accent}aa)`,
                  display: 'flex', alignItems: 'center', justifyContent: 'center',
                  fontSize: 12, fontWeight: 700, color: '#fff',
                }}>{t.initials}</div>
                <div style={{ flex: 1 }}>
                  <span style={{ fontSize: 12, fontWeight: 600, color: '#fff' }}>{t.user}</span>
                  <div style={{ fontSize: 10, color: 'rgba(255,255,255,0.5)' }}>💗 lo recomienda</div>
                </div>
              </div>
              <div style={{ fontSize: 12, color: 'rgba(255,255,255,0.8)', marginTop: 10, lineHeight: 1.5 }}>"{t.text}"</div>
            </div>
          ))}
        </div>
      </div>

      {/* Plans */}
      <div style={{ padding: '32px 22px 0', position: 'relative', display: 'flex', flexDirection: 'column', gap: 10 }}>
        <span className="pf-display" style={{ fontSize: 20, fontWeight: 500, color: '#fff' }}>Elige tu plan</span>
        <PlanCard
          id="annual" selected={plan==='annual'} onClick={() => setPlan('annual')}
          title="Anual" price="39,99€" sub="3,33€/mes" badge="AHORRA 33%" highlight T={T}/>
        <PlanCard
          id="monthly" selected={plan==='monthly'} onClick={() => setPlan('monthly')}
          title="Mensual" price="4,99€" sub="/mes" T={T}/>
        {fromReto && (
          <PlanCard
            id="single" selected={plan==='single'} onClick={() => setPlan('single')}
            title={`Solo ${fromReto.title}`} price="9,99€" sub="pago único" muted T={T}/>
        )}
      </div>

      {/* CTA — Stripe checkout REAL */}
      <div style={{ padding: '24px 20px 0', position: 'relative' }}>
        <button onClick={async () => {
          try {
            nav.toast('Abriendo checkout…', { icon: '💳' });
            const stripePlan = plan === 'annual' ? 'annual' : 'monthly';
            const res = await fetch('/api/stripe/checkout', {
              method: 'POST',
              headers: { 'Content-Type': 'application/json' },
              body: JSON.stringify({ plan: stripePlan }),
            });
            const data = await res.json();
            if (!res.ok || !data.url) {
              nav.toast('Error: ' + (data.error || 'No se pudo iniciar'), { icon: '⚠️' });
              return;
            }
            // Redirigir a Stripe Checkout (en la app o en una nueva pestaña)
            if (window.PauNative && window.PauNative.isNativeApp) {
              window.PauNative.openExternal(data.url);
            } else if (window.top && window.top !== window) {
              window.top.location.href = data.url;
            } else {
              window.location.href = data.url;
            }
          } catch (e) {
            nav.toast('Error de conexión', { icon: '⚠️' });
            console.error('[stripe-checkout]', e);
          }
        }} style={{
          width: '100%', padding: '18px',
          border: 'none', borderRadius: 20, cursor: 'pointer',
          background: '#fff', color: '#15101A',
          fontSize: 15, fontWeight: 700, letterSpacing: -0.1,
          boxShadow: '0 10px 30px rgba(255,255,255,0.25)',
          fontFamily: 'inherit',
        }}>Empezar prueba de 7 días</button>
        <div style={{
          textAlign: 'center', marginTop: 12, fontSize: 10,
          color: 'rgba(255,255,255,0.45)', lineHeight: 1.5,
        }}>
          Cancela cuando quieras desde ajustes. Sin penalizaciones.<br/>
          Al continuar aceptas los términos y la política de privacidad.
        </div>
      </div>
    </div>
  );
}

function PlanCard({ selected, onClick, title, price, sub, badge, highlight, muted, T }) {
  return (
    <button onClick={onClick} style={{
      width: '100%', padding: '16px 20px', cursor: 'pointer', textAlign: 'left',
      borderRadius: 20, position: 'relative',
      background: selected ? 'rgba(255,255,255,0.1)' : 'rgba(255,255,255,0.04)',
      border: selected ? `1.5px solid ${T?.gold || '#D9B074'}` : '1.5px solid rgba(255,255,255,0.08)',
      transition: 'all 200ms ease',
      display: 'flex', alignItems: 'center', gap: 14,
      backdropFilter: 'blur(10px)',
    }}>
      <div style={{
        width: 22, height: 22, borderRadius: 999, flexShrink: 0,
        border: selected ? 'none' : '1.5px solid rgba(255,255,255,0.3)',
        background: selected ? (T?.gold || '#D9B074') : 'transparent',
        display: 'flex', alignItems: 'center', justifyContent: 'center',
      }}>{selected && <div style={{ width: 9, height: 9, borderRadius: 999, background: '#15101A' }}/>}</div>
      <div style={{ flex: 1 }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
          <span style={{ fontSize: 15, fontWeight: 600, color: muted ? 'rgba(255,255,255,0.7)' : '#fff' }}>{title}</span>
          {badge && (
            <span style={{
              fontSize: 9, fontWeight: 800, letterSpacing: 0.8,
              color: '#15101A', background: T?.gold || '#D9B074', padding: '3px 7px', borderRadius: 6,
            }}>{badge}</span>
          )}
        </div>
      </div>
      <div style={{ textAlign: 'right' }}>
        <div className="pf-display" style={{ fontSize: 22, fontWeight: 500, color: '#fff', letterSpacing: -0.6 }}>{price}</div>
        <div style={{ fontSize: 10, color: 'rgba(255,255,255,0.5)', marginTop: -2 }}>{sub}</div>
      </div>
    </button>
  );
}

Object.assign(window, { DetalleRetoScreen, DetalleRecetaScreen, PaywallScreen, VideoPlayer, PlanDetailScreen });

// ═════════════════════════════════════════════════════════════
// PLAN DETAIL — plan de alimentación
// ═════════════════════════════════════════════════════════════
function PlanDetailScreen({ planId, theme, isPremium, nav, onComplete }) {
  const T = theme;
  const p = PLANES.find(x => x.id === planId);
  const isLocked = p.tag === 'PRO' && !isPremium;

  // CTA sticky inferior estilo Sweat/BODi
  useE2(() => {
    if (!p || isLocked) { nav.hideCTA && nav.hideCTA(); return; }
    if (nav.showCTA) {
      nav.showCTA({
        label: `Empezar plan · ${p.days} días`,
        color: p.color,
        onClick: async () => {
          try {
            if (window.PauUserRetos?.startPlan) {
              const res = await window.PauUserRetos.startPlan(p.id);
              if (res?.error) { nav.toast('Error: ' + res.error, { icon: '⚠️' }); return; }
            }
            nav.toast('Plan iniciado 💗', { icon: '✓' });
            setTimeout(() => nav.back(), 700);
          } catch (e) {
            nav.toast('Error: ' + (e.message || e), { icon: '⚠️' });
          }
        },
      });
    }
    return () => { nav.hideCTA && nav.hideCTA(); };
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [p?.id, p?.days, isLocked]);

  if (isLocked) {
    return (
      <PaywallScreen theme={T} nav={nav}
        fromReto={{ title: p.title, days: p.days }}
        onComplete={onComplete}/>
    );
  }

  return (
    <div style={{ paddingBottom: 110 }}>
      {/* Hero */}
      <div style={{
        background: `linear-gradient(160deg, ${p.bg}, ${p.color}50)`,
        padding: '12px 20px 24px',
        borderBottomLeftRadius: 32, borderBottomRightRadius: 32,
        position: 'relative', overflow: 'hidden',
      }}>
        <div style={{
          position: 'absolute', top: -30, right: -40, width: 180, height: 180,
          borderRadius: '50%', background: `${p.color}30`,
        }}/>
        <div style={{ display: 'flex', justifyContent: 'space-between', position: 'relative' }}>
          <BackBtn onClick={() => nav.back()}/>
          <div style={{ display: 'flex', gap: 8 }}>
            <RoundBtn onClick={() => {
              const userName = (window.__pauCache?.profile?.full_name || window.__pauCache?.profile?.username || '').trim();
              const text = userName
                ? `${userName} está haciendo el plan "${p.title}" en Pau Fit 🍓 ${p.kcalDay} kcal/día · ${p.days} días — ¡pruébalo!`
                : `Mira este plan de comidas: "${p.title}" 🍓 ${p.kcalDay} kcal/día — en Pau Fit`;
              window.PauShare && window.PauShare({ title: `${p.title} · Pau Fit`, text, url: 'https://app.paufit.co' }).then(function(rs){ if (rs.shared) nav.toast(rs.method === 'native' ? 'Compartido' : 'Enlace copiado 💗', { icon: '↗' }) });
            }}>{Icon.share('#2D2A26')}</RoundBtn>
            <RoundBtn onClick={() => {const k='paufit-favs';const cur=JSON.parse(localStorage.getItem(k)||'[]');const id=(typeof r!=='undefined'?r.id:(typeof reto!=='undefined'?reto.id:''));if (cur.includes(id)) {localStorage.setItem(k,JSON.stringify(cur.filter(x=>x!==id)));nav.toast('Quitado de favoritos',{icon:'❤️'});} else {localStorage.setItem(k,JSON.stringify([...cur,id]));nav.toast('Guardado en favoritos 💗',{icon:'❤️'});}}}>{Icon.heart('#2D2A26')}</RoundBtn>
          </div>
        </div>
        <div style={{ marginTop: 16, position: 'relative' }}>
          <div style={{ fontSize: 56, lineHeight: 1 }}>{p.emoji}</div>
          <div style={{ marginTop: 12 }}><RetoBadge tag={p.tag} isPremium={isPremium}/></div>
          <div style={{ fontFamily: 'Poppins', fontSize: 26, fontWeight: 600, color: '#2D2A26', marginTop: 8, letterSpacing: -0.5, lineHeight: 1.15 }}>{p.title}</div>
          <div style={{ fontFamily: 'Poppins', fontSize: 13, color: 'rgba(45,42,38,0.7)', marginTop: 6, lineHeight: 1.4 }}>{p.desc}</div>
        </div>
        <div style={{ marginTop: 14, padding: '12px 16px', background: 'rgba(255,255,255,0.5)', backdropFilter: 'blur(10px)', borderRadius: 20, display: 'flex', justifyContent: 'space-between' }}>
          <PStat v={p.days} l="días"/>
          <PStat v={p.kcalDay} l="kcal/día"/>
          <PStat v={p.meals.length} l="comidas/día"/>
        </div>
      </div>

      {/* Sample day */}
      <div style={{ padding: '24px 20px 0' }}>
        <div style={{ fontFamily: 'Poppins', fontSize: 11, color: T.muted, fontWeight: 500, letterSpacing: 0.5,  }}>Día de muestra</div>
        <div style={{ fontFamily: 'Poppins', fontSize: 18, fontWeight: 600, color: T.text, letterSpacing: -0.3, marginTop: 4 }}>Cómo se ve un día</div>
      </div>

      <div style={{ padding: '14px 20px 0', display: 'flex', flexDirection: 'column', gap: 10 }}>
        {p.sampleDay.map((s, i) => {
          const r = RECETAS.find(x => x.id === s.recetaId);
          if (!r) return null;
          return (
            <div key={i} onClick={() => nav.go('receta', r.id)} style={{
              display: 'flex', gap: 12, padding: 10, background: T.card, borderRadius: 20, cursor: 'pointer', border: T.border,
              alignItems: 'center',
            }}>
              <RecipeImage receta={r} T={T} style={{ width: 60, height: 60, borderRadius: 14, flexShrink: 0 }}/>
              <div style={{ flex: 1, minWidth: 0 }}>
                <div style={{ fontFamily: 'Poppins', fontSize: 9, color: p.color, fontWeight: 700, letterSpacing: 0.6,  }}>{s.meal}</div>
                <div style={{ fontFamily: 'Poppins', fontSize: 14, fontWeight: 600, color: T.text, marginTop: 1, letterSpacing: -0.2 }}>{r.title}</div>
                <div style={{ fontFamily: 'Poppins', fontSize: 11, color: T.muted, marginTop: 2 }}>{r.kcal} kcal · {r.minutes} min</div>
              </div>
              {Icon.chevR(T.muted, 8)}
            </div>
          );
        })}
      </div>

      {/* Synced with reto */}
      <div style={{
        margin: '20px 18px 0', padding: '14px 16px',
        background: T.card, borderRadius: 20, border: T.border,
        display: 'flex', alignItems: 'center', gap: 10,
      }}>
        <span style={{ fontSize: 18 }}>🔗</span>
        <div style={{ flex: 1 }}>
          <div style={{ fontFamily: 'Poppins', fontSize: 12, fontWeight: 600, color: T.text }}>Sincronizado con reto</div>
          <div style={{ fontFamily: 'Poppins', fontSize: 11, color: T.muted, marginTop: 1 }}>Si activas este plan, tus comidas se ajustan al reto que estés haciendo.</div>
        </div>
      </div>

      {/* Reviews */}
      <ReviewsSection type="plan" id={p.id} T={T} accent={p.color}/>

      {/* CTA sticky inferior ahora vive en App.jsx (slot global) — registrado
          via nav.showCTA en el useEffect arriba. Solo dejamos un spacer.
          NOTA: lo que sigue es código legacy que NO se renderiza (oculto via display:none). */}
      <div style={{ display: 'none' }}>
        <button onClick={async () => {
          try {
            if (window.PauUserRetos?.startPlan) {
              const res = await window.PauUserRetos.startPlan(p.id);
              if (res?.error) { nav.toast('Error: ' + res.error, { icon: '⚠️' }); return; }
            }
            nav.toast('Plan iniciado 💗', { icon: '✓' });
            setTimeout(() => nav.back(), 700);
          } catch (e) {
            nav.toast('Error: ' + (e.message || e), { icon: '⚠️' });
          }
        }} style={{
          width: '100%', padding: '16px',
          border: 'none', borderRadius: 20, cursor: 'pointer',
          background: p.color, color: '#fff',
          fontFamily: 'Poppins', fontSize: 14, fontWeight: 700, letterSpacing: 0.3,
          boxShadow: `0 8px 20px ${p.color}55`,
        }}>Empezar plan · {p.days} días</button>
      </div>
      <div style={{ height: 90 }}/>
    </div>
  );
}

function PStat({ v, l }) {
  return (
    <div style={{ textAlign: 'center' }}>
      <div style={{ fontFamily: 'Poppins', fontSize: 18, fontWeight: 700, color: '#2D2A26', letterSpacing: -0.4, lineHeight: 1 }}>{v}</div>
      <div style={{ fontFamily: 'Poppins', fontSize: 9, color: 'rgba(45,42,38,0.55)', marginTop: 4, fontWeight: 500, letterSpacing: 0.5,  }}>{l}</div>
    </div>
  );
}
