/* nutri-goals.jsx — Goals & Habits module
   ─────────────────────────────────────────────────────────────────
   Updates vs previous version:
   • New scheduling helpers (_goalIsScheduledOn, _goalStatusForDate, _dayProgress)
   • GoalsHome: Recent 7 days quick-access section + onPickDate prop
   • GoalsDayReview (NEW): backdate editing — select any date, log/skip/miss goals
   • GoalsCalendar (NEW): visual month calendar with per-goal color markers
   • GoalsProgress: date range filter + expanded stats + SVG weekly chart
   • GoalDetailSheet: supports logDate prop for per-date logging
   • GoalCard: uses _goalIsScheduledOn for correctness
*/

// ── Scheduling / status helpers ──────────────────────────────────

function _goalIsScheduledOn(goal, dateISO) {
  if (goal.startDate && dateISO < goal.startDate) return false;
  if (goal.endDate   && dateISO > goal.endDate)   return false;
  // Interval type: every N days from startDate
  if (goal.repeatType === 'interval' && goal.repeatInterval > 0 && goal.startDate) {
    const diff = Math.round(
      (new Date(dateISO + 'T00:00:00') - new Date(goal.startDate + 'T00:00:00')) / 86400000
    );
    return diff >= 0 && diff % goal.repeatInterval === 0;
  }
  // Default: weekdays bitmask
  const wd  = new Date(dateISO + 'T00:00:00').getDay();
  const wds = Array.isArray(goal.weekdays) && goal.weekdays.length > 0 ? goal.weekdays : [0,1,2,3,4,5,6];
  return wds.includes(wd);
}

function _rawSlots(goal, dateISO) {
  const raw = goal._raw || goal;
  return ((raw.log || {})[dateISO]) || null;
}

function _goalDoneForDate(goal, logs, dateISO) {
  return (logs[dateISO] || {})[goal.id] || 0;
}

function _goalStatusForDate(goal, logs, dateISO) {
  if (!_goalIsScheduledOn(goal, dateISO)) return 'unscheduled';
  const slots = _rawSlots(goal, dateISO);
  if (slots && Array.isArray(slots) && slots.length > 0 && slots.every(s => s === 'skip')) return 'skipped';
  const done   = _goalDoneForDate(goal, logs, dateISO);
  const target = goal.timesPerDay || goal.target || 1;
  if (done >= target) return 'done';
  if (done > 0)       return 'partial';
  if ((slots && slots.length > 0) || dateISO < todayISO()) return 'missed';
  return 'pending';
}

function _dayProgress(goals, logs, dateISO) {
  const scheduled = goals.filter(g => _goalIsScheduledOn(g, dateISO));
  const counts = { done:0, missed:0, partial:0, skipped:0, pending:0 };
  scheduled.forEach(g => {
    const s = _goalStatusForDate(g, logs, dateISO);
    if (counts[s] !== undefined) counts[s]++;
  });
  const pct = scheduled.length ? Math.round(counts.done / scheduled.length * 100) : 0;
  return { total: scheduled.length, ...counts, pct, scheduled };
}

const _STATUS_META = {
  done:        { label: 'Done',    bg: 'var(--c-protein-soft)',  color: 'var(--c-protein)', char: '✓' },
  partial:     { label: 'Partial', bg: 'var(--c-carbs-soft)',    color: 'var(--c-carbs)',   char: '◑' },
  missed:      { label: 'Missed',  bg: 'rgba(194,90,78,0.12)',   color: '#C25A4E',          char: '✕' },
  skipped:     { label: 'Skipped', bg: 'var(--surface-3)',       color: 'var(--muted)',     char: '—' },
  pending:     { label: 'Pending', bg: 'var(--surface-2)',       color: 'var(--muted)',     char: '○' },
  unscheduled: { label: '',        bg: 'transparent',            color: 'var(--muted-2)',   char: '' },
};

const _GOALS_RANGE_PRESETS = [
  { id: 'last7',   label: 'Last 7d' },
  { id: 'last14',  label: 'Last 14d' },
  { id: 'last30',  label: 'Last 30d' },
  { id: 'month',   label: 'This month' },
  { id: 'quarter', label: 'This quarter' },
  { id: 'year',    label: 'This year' },
  { id: 'all',     label: 'All time' },
];

function _goalsRangeCompute(rangeId) {
  const today = todayISO(); // live local date — NUTRI_TODAY is stale if loaded yesterday
  const d = new Date(today + 'T00:00:00');
  const pad = n => String(n).padStart(2, '0');
  if (rangeId === 'last7')   return { start: daysAgo(6),  end: today };
  if (rangeId === 'last14')  return { start: daysAgo(13), end: today };
  if (rangeId === 'last30')  return { start: daysAgo(29), end: today };
  if (rangeId === 'month')   return { start: `${d.getFullYear()}-${pad(d.getMonth()+1)}-01`, end: today };
  if (rangeId === 'quarter') {
    const qm = Math.floor(d.getMonth()/3)*3;
    return { start: `${d.getFullYear()}-${pad(qm+1)}-01`, end: today };
  }
  if (rangeId === 'year')    return { start: `${d.getFullYear()}-01-01`, end: today };
  return { start: '2020-01-01', end: today };
}

/* ── GOAL CARD — inline +/- for today ─────────────────────────── */
function GoalCard({ goal, logs, onClick, onInc, onDec, dim = false }) {
  const today     = todayISO();
  const doneCount = _goalDoneForDate(goal, logs, today);
  const scheduled = _goalIsScheduledOn(goal, today);
  const streak    = ngStreak(goal, logs, today);
  const endDate   = goal.endDate || null;
  const isEnded   = endDate && endDate < today;
  const daysLeft  = (endDate && !isEnded)
    ? Math.ceil((new Date(endDate + 'T00:00:00') - new Date()) / 86400000)
    : null;

  return (
    <div style={{ ...nutriStyles.card, padding: 0, overflow: 'hidden', opacity: dim ? 0.65 : 1 }}>
      <button onClick={onClick} style={{
        width: '100%', padding: 14,
        display: 'flex', alignItems: 'center', gap: 12,
        cursor: 'pointer', textAlign: 'left', font: 'inherit',
        color: 'var(--text)', background: 'transparent', border: 0,
      }}>
        <FoodThumb emoji={goal.emoji} tint={goal.color} size={48}/>
        <div style={{ flex: 1, minWidth: 0 }}>
          <div style={{ display: 'flex', alignItems: 'center', gap: 6, flexWrap: 'wrap' }}>
            <div style={{ fontSize: 14.5, fontWeight: 600, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap', maxWidth: '70%' }}>{goal.title}</div>
            {streak > 0 && <span style={{ fontSize: 11, color: '#E89B3C', fontWeight: 600 }}>🔥{streak}</span>}
            {isEnded && <span style={{ fontSize: 10, padding: '2px 7px', borderRadius: 999, background: 'var(--c-protein-soft)', color: 'var(--c-protein)', fontWeight: 600 }}>Finished</span>}
          </div>
          {scheduled ? (
            <div style={{ fontSize: 12, color: 'var(--muted)', marginTop: 2 }}>
              {doneCount} / {goal.target} {goal.unit} today
            </div>
          ) : (
            <div style={{ fontSize: 12, color: 'var(--muted)', marginTop: 2 }}>Not scheduled today</div>
          )}
          {endDate && (
            <div style={{ fontSize: 11, color: isEnded ? 'var(--c-protein)' : 'var(--muted-2)', marginTop: 2 }}>
              {isEnded ? `✓ Ended ${prettyDateShort(endDate)}` : daysLeft !== null ? `${daysLeft}d left · ends ${prettyDateShort(endDate)}` : ''}
            </div>
          )}
          {scheduled && !isEnded && (
            <div style={{ marginTop: 8 }}>
              <MacroBar value={doneCount} goal={goal.target} color={goal.color}/>
            </div>
          )}
        </div>
      </button>
      {scheduled && !isEnded && (
        <div style={{ display: 'flex', alignItems: 'center', gap: 10, padding: '8px 14px 12px', borderTop: '1px solid var(--border)' }}>
          <button onClick={e => { e.stopPropagation(); onDec && onDec(goal); }} style={{
            width: 36, height: 36, borderRadius: '50%',
            border: '1px solid var(--border-2)', background: 'var(--surface-2)',
            color: 'var(--text)', cursor: 'pointer', font: 'inherit', fontSize: 20, fontWeight: 600,
            display: 'grid', placeItems: 'center', flexShrink: 0,
          }}>−</button>
          <div style={{ flex: 1, textAlign: 'center' }}>
            <span style={{ fontSize: 22, fontWeight: 700, letterSpacing: '-0.03em' }}>{doneCount}</span>
            <span style={{ fontSize: 12, color: 'var(--muted)', fontWeight: 500, marginLeft: 4 }}>/ {goal.target} {goal.unit}</span>
          </div>
          <button onClick={e => { e.stopPropagation(); onInc && onInc(goal); }} style={{
            width: 36, height: 36, borderRadius: '50%',
            border: '1px solid var(--accent)', background: 'var(--accent)',
            color: 'var(--on-accent)', cursor: 'pointer', font: 'inherit', fontSize: 20, fontWeight: 600,
            display: 'grid', placeItems: 'center', flexShrink: 0,
          }}>+</button>
        </div>
      )}
    </div>
  );
}

/* ── GOALS HOME ─────────────────────────────────────────────────── */
function GoalsHome({ goals, logs, onOpenGoal, onAdd, onInc, onDec, onPickDate }) {
  const today = todayISO();

  // Recent 7 days including today
  const recentDays = [];
  for (let i = 6; i >= 0; i--) {
    const iso = daysAgo(i);
    const prog = _dayProgress(goals, logs, iso);
    const d = new Date(iso + 'T00:00:00');
    const dayLabel = i === 0 ? 'Today' : i === 1 ? 'Yest' : d.toLocaleDateString(undefined, { weekday: 'short' });
    const dateLabel = d.toLocaleDateString(undefined, { month: 'short', day: 'numeric' });
    recentDays.push({ iso, ...prog, isToday: i === 0, dayLabel, dateLabel });
  }

  const scheduledToday = goals.filter(g => _goalIsScheduledOn(g, today));
  const completedToday = scheduledToday.filter(g => _goalStatusForDate(g, logs, today) === 'done').length;

  const todayProg = _dayProgress(goals, logs, today);

  const otherActive = goals.filter(g =>
    !scheduledToday.includes(g) && (!g.endDate || g.endDate >= today)
  );

  return (
    <div style={{ padding: '12px 18px 24px', display: 'flex', flexDirection: 'column', gap: 16 }}>
      {/* Header */}
      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', paddingTop: 4 }}>
        <div>
          <div style={{ fontSize: 22, fontWeight: 700, letterSpacing: '-0.02em' }}>Goals</div>
          <div style={{ fontSize: 12.5, color: 'var(--muted)', marginTop: 2, fontWeight: 500 }}>{prettyDate(today)}</div>
        </div>
        <button onClick={onAdd} style={{
          display: 'inline-flex', alignItems: 'center', gap: 6,
          padding: '7px 14px', borderRadius: 999,
          background: 'var(--accent)', color: 'var(--on-accent)',
          border: '1px solid var(--accent)', font: 'inherit', fontSize: 12.5, fontWeight: 600, cursor: 'pointer',
        }}><PlusIcon size={14}/>New goal</button>
      </div>

      {/* HERO — Today summary */}
      <div style={{ ...nutriStyles.card, padding: 20, display: 'flex', flexDirection: 'column', gap: 14 }}>
        <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
          <div>
            <div style={{ fontSize: 11, color: 'var(--muted)', fontWeight: 600, letterSpacing: '0.04em', textTransform: 'uppercase' }}>Today</div>
            <div style={{ fontSize: 36, fontWeight: 600, letterSpacing: '-0.03em', marginTop: 4, lineHeight: 1 }}>
              {completedToday}<span style={{ fontSize: 18, color: 'var(--muted)', fontWeight: 500 }}>/{scheduledToday.length}</span>
            </div>
            <div style={{ fontSize: 13, color: 'var(--muted)', marginTop: 4 }}>
              habits done{todayProg.missed > 0 ? ` · ${todayProg.missed} missed` : ''}
            </div>
          </div>
          <CalorieRing value={completedToday} goal={scheduledToday.length || 1} size={88} stroke={10}/>
        </div>
      </div>

      {/* ── Recent 7 Days ── */}
      {goals.length > 0 && (
        <div>
          <div style={{ fontSize: 13, fontWeight: 600, letterSpacing: '-0.01em', marginBottom: 8 }}>Recent days</div>
          <div style={{ display: 'flex', gap: 6, overflowX: 'auto', paddingBottom: 4, WebkitOverflowScrolling: 'touch' }}>
            {recentDays.map(d => {
              const isToday = d.isToday;
              const hasData = d.total > 0;
              const progressColor = d.pct >= 100 ? 'var(--c-protein)' : d.pct > 0 ? 'var(--c-carbs)' : '#C25A4E';
              return (
                <button key={d.iso} onClick={() => onPickDate && onPickDate(d.iso)} style={{
                  flexShrink: 0,
                  display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 4,
                  padding: '10px 12px', borderRadius: 14,
                  background: isToday ? 'var(--text)' : 'var(--surface)',
                  color: isToday ? 'var(--bg)' : 'var(--text)',
                  border: isToday ? '1px solid var(--text)' : '1px solid var(--border-2)',
                  cursor: 'pointer', font: 'inherit', minWidth: 62,
                }}>
                  <div style={{ fontSize: 10, fontWeight: 700, letterSpacing: '0.03em', textTransform: 'uppercase', opacity: isToday ? 1 : 0.7 }}>{d.dayLabel}</div>
                  <div style={{ fontSize: 11, opacity: 0.65 }}>{d.dateLabel}</div>
                  {hasData ? (
                    <>
                      <div style={{ fontSize: 13, fontWeight: 700, letterSpacing: '-0.02em', color: isToday ? 'inherit' : progressColor }}>
                        {d.done}/{d.total}
                      </div>
                      <div style={{ fontSize: 10, fontWeight: 600, color: isToday ? 'inherit' : progressColor }}>{d.pct}%</div>
                    </>
                  ) : (
                    <div style={{ fontSize: 10, opacity: 0.45 }}>—</div>
                  )}
                </button>
              );
            })}
          </div>
        </div>
      )}

      {/* Today's schedule */}
      <div style={{ fontSize: 15, fontWeight: 600, letterSpacing: '-0.01em' }}>Today's schedule</div>
      <div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
        {scheduledToday.map(g => (
          <GoalCard key={g.id} goal={g} logs={logs}
            onClick={() => onOpenGoal(g)} onInc={onInc} onDec={onDec}/>
        ))}
        {!scheduledToday.length && (
          <EmptyState icon="🛌" title="Nothing scheduled today" subtitle="Enjoy the rest day — or tap + to add a new goal."/>
        )}
      </div>

      {/* Other active goals */}
      {otherActive.length > 0 && (<>
        <div style={{ fontSize: 15, fontWeight: 600, letterSpacing: '-0.01em', marginTop: 6 }}>Other goals</div>
        <div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
          {otherActive.map(g => (
            <GoalCard key={g.id} goal={g} logs={logs}
              onClick={() => onOpenGoal(g)} onInc={onInc} onDec={onDec} dim/>
          ))}
        </div>
      </>)}

      <div style={{ height: 60 }}/>
    </div>
  );
}

/* ── GOALS DAY REVIEW — backdate edit ──────────────────────────── */
function GoalsDayReview({ goals, logs, selectedDate, onSetDate, onAdjust, onSkip, onOpenGoal }) {
  const [date, setDateLocal] = React.useState(selectedDate || todayISO());
  const today = todayISO();

  // Sync if parent changes selectedDate
  React.useEffect(() => {
    if (selectedDate && selectedDate !== date) setDateLocal(selectedDate);
  }, [selectedDate]);

  function setDate(d) { setDateLocal(d); onSetDate && onSetDate(d); }
  function prevDay() { const d = new Date(date + 'T00:00:00'); d.setDate(d.getDate()-1); setDate(isoOf(d)); }
  function nextDay() { if (date >= today) return; const d = new Date(date + 'T00:00:00'); d.setDate(d.getDate()+1); setDate(isoOf(d)); }

  const scheduledGoals = goals.filter(g => _goalIsScheduledOn(g, date));
  const prog = _dayProgress(goals, logs, date);
  const isPast = date < today;
  const isToday = date === today;

  const dateLabel = isToday ? 'Today' : isPast
    ? new Date(date + 'T00:00:00').toLocaleDateString(undefined, { weekday: 'long', month: 'short', day: 'numeric' })
    : new Date(date + 'T00:00:00').toLocaleDateString(undefined, { weekday: 'long', month: 'short', day: 'numeric' });

  return (
    <div style={{ padding: '12px 18px 24px', display: 'flex', flexDirection: 'column', gap: 14 }}>
      {/* Header */}
      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', paddingTop: 4 }}>
        <div>
          <div style={{ fontSize: 22, fontWeight: 700, letterSpacing: '-0.02em' }}>Review</div>
          <div style={{ fontSize: 12.5, color: 'var(--muted)', marginTop: 2, fontWeight: 500 }}>Edit any past or today's goals</div>
        </div>
        {!isToday && (
          <button onClick={() => setDate(today)} style={{
            padding: '6px 12px', borderRadius: 999,
            background: 'var(--surface)', color: 'var(--text)',
            border: '1px solid var(--border-2)', font: 'inherit', fontSize: 12, fontWeight: 500, cursor: 'pointer',
          }}>Today</button>
        )}
      </div>

      {/* Date nav */}
      <div style={{ ...nutriStyles.card, padding: '10px 14px', display: 'flex', alignItems: 'center', gap: 10 }}>
        <button onClick={prevDay} style={{
          width: 34, height: 34, borderRadius: '50%',
          border: '1px solid var(--border-2)', background: 'var(--surface-2)',
          color: 'var(--text)', cursor: 'pointer', font: 'inherit', fontSize: 16, fontWeight: 600,
          display: 'grid', placeItems: 'center', flexShrink: 0,
        }}>‹</button>
        <div style={{ flex: 1, textAlign: 'center' }}>
          <div style={{ fontSize: 15, fontWeight: 600, letterSpacing: '-0.01em' }}>{dateLabel}</div>
          {scheduledGoals.length > 0 && (
            <div style={{ fontSize: 12, color: 'var(--muted)', marginTop: 2 }}>
              {prog.done}/{prog.total} done · {prog.pct}%
              {prog.missed > 0 ? ` · ${prog.missed} missed` : ''}
            </div>
          )}
        </div>
        <button onClick={nextDay} disabled={date >= today} style={{
          width: 34, height: 34, borderRadius: '50%',
          border: '1px solid var(--border-2)', background: 'var(--surface-2)',
          color: date >= today ? 'var(--muted-2)' : 'var(--text)', cursor: date >= today ? 'default' : 'pointer',
          font: 'inherit', fontSize: 16, fontWeight: 600,
          display: 'grid', placeItems: 'center', flexShrink: 0,
        }}>›</button>
      </div>

      {/* Date picker */}
      <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
        <div style={{ fontSize: 11, color: 'var(--muted)', fontWeight: 600, letterSpacing: '0.04em', textTransform: 'uppercase', flexShrink: 0 }}>Jump to</div>
        <input type="date" value={date} max={today} onChange={e => e.target.value && setDate(e.target.value)} style={{
          flex: 1, padding: '7px 12px', borderRadius: 10,
          background: 'var(--surface-2)', border: '1px solid var(--border)',
          color: 'var(--text)', font: 'inherit', fontSize: 13,
        }}/>
      </div>

      {/* Goals list */}
      {scheduledGoals.length === 0 ? (
        <EmptyState icon="🎯" title="No goals scheduled" subtitle={`No habits are scheduled for ${dateLabel.toLowerCase()}.`}/>
      ) : (
        <div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
          {scheduledGoals.map(g => {
            const doneCount = _goalDoneForDate(g, logs, date);
            const status    = _goalStatusForDate(g, logs, date);
            const meta      = _STATUS_META[status] || _STATUS_META.pending;
            const target    = g.timesPerDay || g.target || 1;
            const isSkipped = status === 'skipped';

            return (
              <div key={g.id} style={{ ...nutriStyles.card, padding: 0, overflow: 'hidden', opacity: isSkipped ? 0.6 : 1 }}>
                {/* Main info row */}
                <button onClick={() => onOpenGoal && onOpenGoal(g)} style={{
                  width: '100%', padding: '12px 14px',
                  display: 'flex', alignItems: 'center', gap: 12,
                  cursor: 'pointer', textAlign: 'left', font: 'inherit',
                  color: 'var(--text)', background: 'transparent', border: 0,
                }}>
                  <FoodThumb emoji={g.emoji} tint={g.color} size={42}/>
                  <div style={{ flex: 1, minWidth: 0 }}>
                    <div style={{ fontSize: 14, fontWeight: 600, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{g.title}</div>
                    <div style={{ fontSize: 12, color: 'var(--muted)', marginTop: 2 }}>
                      {isSkipped ? 'Skipped' : `${doneCount} / ${target} ${g.unit}`}
                    </div>
                    {!isSkipped && (
                      <div style={{ marginTop: 6 }}>
                        <MacroBar value={doneCount} goal={target} color={g.color}/>
                      </div>
                    )}
                  </div>
                  {/* Status badge */}
                  <span style={{
                    padding: '3px 9px', borderRadius: 999,
                    background: meta.bg, color: meta.color,
                    fontSize: 11, fontWeight: 700, flexShrink: 0,
                  }}>{meta.char} {meta.label}</span>
                </button>

                {/* Controls row */}
                <div style={{
                  display: 'flex', alignItems: 'center', gap: 8,
                  padding: '8px 14px 12px',
                  borderTop: '1px solid var(--border)',
                }}>
                  <button onClick={() => onAdjust && onAdjust(g.id, date, -1)} style={{
                    width: 36, height: 36, borderRadius: '50%',
                    border: '1px solid var(--border-2)', background: 'var(--surface-2)',
                    color: 'var(--text)', cursor: 'pointer', font: 'inherit', fontSize: 18, fontWeight: 700,
                    display: 'grid', placeItems: 'center', flexShrink: 0,
                  }}>−</button>
                  <div style={{ textAlign: 'center', minWidth: 52 }}>
                    <span style={{ fontSize: 20, fontWeight: 700, letterSpacing: '-0.02em' }}>{doneCount}</span>
                    <span style={{ fontSize: 11, color: 'var(--muted)', marginLeft: 2 }}>/{target}</span>
                  </div>
                  <button onClick={() => onAdjust && onAdjust(g.id, date, +1)} style={{
                    width: 36, height: 36, borderRadius: '50%',
                    border: '1px solid var(--accent)', background: 'var(--accent)',
                    color: 'var(--on-accent)', cursor: 'pointer', font: 'inherit', fontSize: 18, fontWeight: 700,
                    display: 'grid', placeItems: 'center', flexShrink: 0,
                  }}>+</button>
                  <div style={{ flex: 1 }}/>
                  <button onClick={() => onSkip && onSkip(g.id, date)} style={{
                    padding: '6px 12px', borderRadius: 999,
                    background: isSkipped ? 'var(--text)' : 'var(--surface-2)',
                    color: isSkipped ? 'var(--bg)' : 'var(--muted)',
                    border: '1px solid var(--border-2)',
                    font: 'inherit', fontSize: 11, fontWeight: 600, cursor: 'pointer',
                  }}>{isSkipped ? 'Undo skip' : 'Skip'}</button>
                </div>
              </div>
            );
          })}
        </div>
      )}

      {/* Unscheduled goals (collapsed hint) */}
      {goals.length > scheduledGoals.length && (
        <div style={{ fontSize: 12, color: 'var(--muted)', textAlign: 'center', marginTop: 2 }}>
          {goals.length - scheduledGoals.length} goal{goals.length - scheduledGoals.length > 1 ? 's' : ''} not scheduled for this day
        </div>
      )}

      <div style={{ height: 60 }}/>
    </div>
  );
}

/* ── GOALS CALENDAR ─────────────────────────────────────────────── */
function GoalsCalendar({ goals, logs, selectedDate, onPickDate, onAdjust }) {
  const today = todayISO();
  const initD = new Date(today + 'T00:00:00');
  const [viewYear,  setViewYear]  = React.useState(initD.getFullYear());
  const [viewMonth, setViewMonth] = React.useState(initD.getMonth());
  const [expanded,  setExpanded]  = React.useState(null); // ISO of expanded day

  function prevMonth() {
    if (viewMonth === 0) { setViewYear(y => y-1); setViewMonth(11); }
    else setViewMonth(m => m-1);
  }
  function nextMonth() {
    if (viewMonth === 11) { setViewYear(y => y+1); setViewMonth(0); }
    else setViewMonth(m => m+1);
  }

  // Build calendar days
  const firstDay = new Date(viewYear, viewMonth, 1);
  const lastDay  = new Date(viewYear, viewMonth+1, 0);
  const startWd  = firstDay.getDay();
  const totalDays = lastDay.getDate();
  const cells = [];
  for (let i = 0; i < startWd; i++) cells.push(null);
  for (let d = 1; d <= totalDays; d++) cells.push(d);
  while (cells.length % 7 !== 0) cells.push(null);

  const monthLabel = firstDay.toLocaleDateString(undefined, { month: 'long', year: 'numeric' });
  const WD_LABELS = ['Su','Mo','Tu','We','Th','Fr','Sa'];
  const pad = n => String(n).padStart(2,'0');

  function isoForDay(d) {
    return `${viewYear}-${pad(viewMonth+1)}-${pad(d)}`;
  }

  function toggleDay(iso) {
    setExpanded(e => e === iso ? null : iso);
  }

  return (
    <div style={{ padding: '12px 18px 24px', display: 'flex', flexDirection: 'column', gap: 14 }}>
      {/* Header */}
      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', paddingTop: 4 }}>
        <div>
          <div style={{ fontSize: 22, fontWeight: 700, letterSpacing: '-0.02em' }}>Calendar</div>
          <div style={{ fontSize: 12.5, color: 'var(--muted)', marginTop: 2, fontWeight: 500 }}>Goal schedule overview</div>
        </div>
        <button onClick={() => { setViewYear(initD.getFullYear()); setViewMonth(initD.getMonth()); }} style={{
          padding: '6px 12px', borderRadius: 999,
          background: 'var(--surface)', color: 'var(--text)',
          border: '1px solid var(--border-2)', font: 'inherit', fontSize: 12, fontWeight: 500, cursor: 'pointer',
        }}>Today</button>
      </div>

      {/* Month nav */}
      <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
        <button onClick={prevMonth} style={{
          width: 34, height: 34, borderRadius: '50%',
          border: '1px solid var(--border-2)', background: 'var(--surface-2)',
          color: 'var(--text)', cursor: 'pointer', font: 'inherit', fontSize: 16,
          display: 'grid', placeItems: 'center',
        }}>‹</button>
        <div style={{ flex: 1, textAlign: 'center', fontSize: 15, fontWeight: 700, letterSpacing: '-0.01em' }}>{monthLabel}</div>
        <button onClick={nextMonth} style={{
          width: 34, height: 34, borderRadius: '50%',
          border: '1px solid var(--border-2)', background: 'var(--surface-2)',
          color: 'var(--text)', cursor: 'pointer', font: 'inherit', fontSize: 16,
          display: 'grid', placeItems: 'center',
        }}>›</button>
      </div>

      {/* Legend */}
      {goals.length > 0 && (
        <div style={{ display: 'flex', gap: 8, flexWrap: 'wrap' }}>
          {goals.slice(0, 6).map(g => (
            <div key={g.id} style={{ display: 'flex', alignItems: 'center', gap: 4, fontSize: 11, color: 'var(--muted)', fontWeight: 500 }}>
              <div style={{ width: 8, height: 8, borderRadius: '50%', background: g.color, flexShrink: 0 }}/>
              <span style={{ overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap', maxWidth: 70 }}>{g.title}</span>
            </div>
          ))}
          {goals.length > 6 && <div style={{ fontSize: 11, color: 'var(--muted-2)' }}>+{goals.length-6} more</div>}
        </div>
      )}

      {/* Calendar grid */}
      <div style={{ ...nutriStyles.card, padding: '12px 10px', display: 'flex', flexDirection: 'column', gap: 2 }}>
        {/* Weekday headers */}
        <div style={{ display: 'grid', gridTemplateColumns: 'repeat(7, 1fr)', gap: 2, marginBottom: 4 }}>
          {WD_LABELS.map(l => (
            <div key={l} style={{ textAlign: 'center', fontSize: 10, fontWeight: 700, color: 'var(--muted)', letterSpacing: '0.04em', textTransform: 'uppercase', padding: '2px 0' }}>{l}</div>
          ))}
        </div>

        {/* Day cells */}
        <div style={{ display: 'grid', gridTemplateColumns: 'repeat(7, 1fr)', gap: 2 }}>
          {cells.map((day, idx) => {
            if (!day) return <div key={`e${idx}`}/>;
            const iso = isoForDay(day);
            const isToday  = iso === today;
            const isFuture = iso > today;
            const isExpanded = expanded === iso;
            const scheduledHere = goals.filter(g => _goalIsScheduledOn(g, iso));
            const prog = _dayProgress(goals, logs, iso);
            const dotGoals = scheduledHere.slice(0, 4);

            return (
              <div key={iso} style={{ display: 'flex', flexDirection: 'column', gap: 1 }}>
                <button onClick={() => toggleDay(iso)} style={{
                  width: '100%', aspectRatio: '1/1', minHeight: 36,
                  borderRadius: 8,
                  background: isToday ? 'var(--text)' : isExpanded ? 'var(--surface-3)' : 'var(--surface-2)',
                  border: isToday ? '1px solid var(--text)' : '1px solid var(--border)',
                  cursor: 'pointer', display: 'flex', flexDirection: 'column',
                  alignItems: 'center', justifyContent: 'flex-start',
                  padding: '4px 2px 2px', gap: 2, font: 'inherit',
                }}>
                  <span style={{
                    fontSize: 11, fontWeight: isToday ? 700 : 500,
                    color: isToday ? 'var(--bg)' : isFuture ? 'var(--muted)' : 'var(--text)',
                    lineHeight: 1,
                  }}>{day}</span>
                  {/* Goal dots */}
                  {dotGoals.length > 0 && (
                    <div style={{ display: 'flex', flexWrap: 'wrap', gap: 1, justifyContent: 'center' }}>
                      {dotGoals.map(g => {
                        const s = isFuture ? 'pending' : _goalStatusForDate(g, logs, iso);
                        const isDone    = s === 'done';
                        const isMissed  = s === 'missed';
                        return (
                          <div key={g.id} style={{
                            width: 5, height: 5, borderRadius: '50%',
                            background: isDone ? g.color : isMissed ? '#C25A4E' : 'transparent',
                            border: `1.5px solid ${isDone ? g.color : isMissed ? '#C25A4E' : g.color}`,
                            opacity: isFuture ? 0.5 : 1,
                          }}/>
                        );
                      })}
                      {scheduledHere.length > 4 && (
                        <div style={{ fontSize: 7, color: 'var(--muted)', fontWeight: 700 }}>+{scheduledHere.length-4}</div>
                      )}
                    </div>
                  )}
                </button>
              </div>
            );
          })}
        </div>
      </div>

      {/* Expanded day panel */}
      {expanded && (() => {
        const dayGoals = goals.filter(g => _goalIsScheduledOn(g, expanded));
        const d = new Date(expanded + 'T00:00:00');
        const expandedLabel = expanded === today ? 'Today' : d.toLocaleDateString(undefined, { weekday: 'long', month: 'short', day: 'numeric' });
        const isFuture = expanded > today;
        return (
          <div style={{ ...nutriStyles.card, padding: 14, display: 'flex', flexDirection: 'column', gap: 4 }}>
            <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 4 }}>
              <div style={{ fontSize: 14, fontWeight: 700 }}>{expandedLabel}</div>
              {onPickDate && (
                <button onClick={() => { onPickDate(expanded); setExpanded(null); }} style={{
                  padding: '5px 12px', borderRadius: 999,
                  background: 'var(--surface-2)', color: 'var(--text)',
                  border: '1px solid var(--border-2)', font: 'inherit', fontSize: 11, fontWeight: 600, cursor: 'pointer',
                }}>Full edit →</button>
              )}
            </div>
            {dayGoals.length === 0 ? (
              <div style={{ fontSize: 12.5, color: 'var(--muted)', textAlign: 'center', padding: '8px 0' }}>No goals scheduled</div>
            ) : (
              dayGoals.map((g, gi) => {
                const s = isFuture ? 'pending' : _goalStatusForDate(g, logs, expanded);
                const meta = _STATUS_META[s] || _STATUS_META.pending;
                const done = _goalDoneForDate(g, logs, expanded);
                return (
                  <div key={g.id} style={{ display: 'flex', alignItems: 'center', gap: 10, padding: '8px 0', borderTop: gi === 0 ? 'none' : '1px solid var(--border)' }}>
                    <div style={{ width: 10, height: 10, borderRadius: '50%', background: g.color, flexShrink: 0 }}/>
                    <div style={{ flex: 1, minWidth: 0 }}>
                      <div style={{ fontSize: 13, fontWeight: 600, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{g.title}</div>
                      {!isFuture && <div style={{ marginTop: 5 }}><MacroBar value={done} goal={g.target} color={g.color}/></div>}
                    </div>
                    {isFuture ? (
                      <span style={{ fontSize: 11, color: 'var(--muted)', flexShrink: 0 }}>—</span>
                    ) : onAdjust ? (
                      <div style={{ display: 'flex', alignItems: 'center', gap: 7, flexShrink: 0 }}>
                        <button onClick={() => onAdjust(g.id, expanded, -1)} style={{
                          width: 30, height: 30, borderRadius: '50%', border: '1px solid var(--border-2)',
                          background: 'var(--surface-2)', color: 'var(--text)', cursor: 'pointer', font: 'inherit',
                          fontSize: 17, fontWeight: 600, display: 'grid', placeItems: 'center',
                        }}>−</button>
                        <span style={{ minWidth: 46, textAlign: 'center', fontSize: 14, fontWeight: 700 }}>
                          {done}<span style={{ fontSize: 10, color: 'var(--muted)', fontWeight: 500 }}> / {g.target}</span>
                        </span>
                        <button onClick={() => onAdjust(g.id, expanded, +1)} style={{
                          width: 30, height: 30, borderRadius: '50%', border: '1px solid var(--accent)',
                          background: 'var(--accent)', color: 'var(--on-accent)', cursor: 'pointer', font: 'inherit',
                          fontSize: 17, fontWeight: 600, display: 'grid', placeItems: 'center',
                        }}>+</button>
                      </div>
                    ) : (
                      <span style={{ padding: '2px 7px', borderRadius: 999, background: meta.bg, color: meta.color, fontSize: 10, fontWeight: 700, flexShrink: 0 }}>{meta.char} {meta.label}</span>
                    )}
                  </div>
                );
              })
            )}
          </div>
        );
      })()}

      <div style={{ height: 60 }}/>
    </div>
  );
}

/* ── GOAL STAT TILE ─────────────────────────────────────────────── */
function GoalStatTile({ label, value, unit, color, icon }) {
  return (
    <div style={{ padding: 12, borderRadius: 14, background: 'var(--surface)', border: '1px solid var(--border)', textAlign: 'center' }}>
      <div style={{ fontSize: 22, fontWeight: 600, color, letterSpacing: '-0.02em' }}>
        {value}<span style={{ fontSize: 11, color: 'var(--muted)', fontWeight: 500, marginLeft: 2 }}>{unit}</span>
      </div>
      <div style={{ fontSize: 10.5, color: 'var(--muted)', fontWeight: 600, textTransform: 'uppercase', letterSpacing: '0.04em', marginTop: 2 }}>{label}</div>
    </div>
  );
}

/* ── GOALS PROGRESS — with date range filter + charts ──────────── */
function GoalsProgress({ goals, logs }) {
  const today = todayISO();
  const [rangeId, setRangeId] = React.useState('last30');
  const range = _goalsRangeCompute(rangeId);

  // Build list of dates in range
  function datesInRange(start, end) {
    const out = [];
    let cur = new Date(start + 'T00:00:00');
    const endD = new Date(end + 'T00:00:00');
    while (cur <= endD) { out.push(isoOf(cur)); cur.setDate(cur.getDate()+1); }
    return out;
  }
  const rangeDates = datesInRange(range.start, range.end);

  // Per-goal stats
  const goalStats = goals.map(g => {
    let sch = 0, done = 0;
    rangeDates.forEach(iso => {
      const s = _goalStatusForDate(g, logs, iso);
      if (s === 'unscheduled') return;
      sch++;
      if (s === 'done') done++;
    });
    return { goal: g, rate: sch ? done / sch : 0, done, sch, streak: ngStreak(g, logs, today) };
  });

  // Global stats
  let totalSch = 0, totalDone = 0, totalMissed = 0;
  rangeDates.forEach(iso => {
    goals.forEach(g => {
      const s = _goalStatusForDate(g, logs, iso);
      if (s === 'unscheduled') return;
      totalSch++;
      if (s === 'done') totalDone++;
      else if (s === 'missed') totalMissed++;
    });
  });
  const overallRate = totalSch ? Math.round(totalDone / totalSch * 100) : 0;

  const sortedByStreak = goalStats.slice().sort((a, b) => b.streak - a.streak);
  const bestStreak = sortedByStreak.length ? sortedByStreak[0].streak : 0;
  const bestStreakTitle = sortedByStreak.length ? sortedByStreak[0].goal.title : '—';
  const activeGoals = goals.filter(g => !g.endDate || g.endDate >= today);

  // Weekly bar chart — last 8 weeks completion rates
  const weeks = [];
  for (let w = 7; w >= 0; w--) {
    const wStart = daysAgo(w * 7 + 6);
    const wEnd   = daysAgo(w * 7);
    const wDates = datesInRange(wStart, wEnd);
    let wSch = 0, wDone = 0;
    wDates.forEach(iso => {
      goals.forEach(g => {
        const s = _goalStatusForDate(g, logs, iso);
        if (s === 'unscheduled') return;
        wSch++;
        if (s === 'done') wDone++;
      });
    });
    const pct = wSch ? Math.round(wDone / wSch * 100) : 0;
    const labelD = new Date(wEnd + 'T00:00:00');
    weeks.push({ label: labelD.toLocaleDateString(undefined, { month: 'short', day: 'numeric' }), pct, wSch });
  }

  return (
    <div style={{ padding: '12px 18px 24px', display: 'flex', flexDirection: 'column', gap: 14 }}>
      <div style={{ paddingTop: 4 }}>
        <div style={{ fontSize: 22, fontWeight: 700, letterSpacing: '-0.02em' }}>Progress</div>
        <div style={{ fontSize: 12.5, color: 'var(--muted)', marginTop: 2, fontWeight: 500 }}>Goal & habit statistics</div>
      </div>

      {/* Range filter */}
      <div style={{ display: 'flex', gap: 6, overflowX: 'auto', paddingBottom: 2, WebkitOverflowScrolling: 'touch' }}>
        {_GOALS_RANGE_PRESETS.map(p => (
          <button key={p.id} onClick={() => setRangeId(p.id)} style={{
            flexShrink: 0, padding: '6px 12px', borderRadius: 999,
            background: rangeId === p.id ? 'var(--text)' : 'var(--surface)',
            color:      rangeId === p.id ? 'var(--bg)'  : 'var(--text)',
            border:     rangeId === p.id ? '1px solid var(--text)' : '1px solid var(--border-2)',
            font: 'inherit', fontSize: 12, fontWeight: 500, cursor: 'pointer', whiteSpace: 'nowrap',
          }}>{p.label}</button>
        ))}
      </div>

      {/* Stats grid */}
      <div style={{ display: 'grid', gridTemplateColumns: 'repeat(2, 1fr)', gap: 10 }}>
        <GoalStatTile label="Completion rate" value={overallRate} unit="%"     color="var(--c-protein)" icon="✓"/>
        <GoalStatTile label="Best streak"     value={`${bestStreak} 🔥`} unit="" color="var(--c-carbs)"   icon="🔥"/>
        <GoalStatTile label="Active goals"    value={activeGoals.length} unit="" color="var(--accent)"    icon="🎯"/>
        <GoalStatTile label="Done / Scheduled" value={`${totalDone}/${totalSch}`} unit="" color="var(--text)" icon="📅"/>
      </div>
      {bestStreak > 0 && (
        <div style={{ fontSize: 12, color: 'var(--muted)', textAlign: 'center', marginTop: -6 }}>
          Best streak: <strong style={{ color: 'var(--text)' }}>{bestStreakTitle}</strong>
        </div>
      )}

      {/* Weekly completion bar chart */}
      {weeks.some(w => w.wSch > 0) && (
        <div style={{ ...nutriStyles.card, padding: 16 }}>
          <div style={{ fontSize: 13, fontWeight: 600, marginBottom: 14 }}>Weekly completion</div>
          <div style={{ display: 'flex', alignItems: 'flex-end', gap: 4, height: 80 }}>
            {weeks.map((w, i) => (
              <div key={i} style={{ flex: 1, display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 3, height: '100%', justifyContent: 'flex-end' }}>
                {w.wSch > 0 && (
                  <div style={{ fontSize: 9, color: 'var(--muted)', fontWeight: 600 }}>{w.pct}%</div>
                )}
                <div style={{
                  width: '100%', borderRadius: '4px 4px 0 0',
                  background: w.wSch > 0
                    ? (w.pct >= 80 ? 'var(--c-protein)' : w.pct >= 50 ? 'var(--c-carbs)' : '#C25A4E')
                    : 'var(--ring-track)',
                  height: w.wSch > 0 ? `${Math.max(8, w.pct * 0.6)}%` : '4%',
                  minHeight: 4, transition: 'height .3s',
                }}/>
              </div>
            ))}
          </div>
          {/* X-axis labels — show 1st, middle, last */}
          <div style={{ display: 'flex', justifyContent: 'space-between', marginTop: 6 }}>
            <div style={{ fontSize: 10, color: 'var(--muted)' }}>{weeks[0]?.label}</div>
            <div style={{ fontSize: 10, color: 'var(--muted)' }}>This week</div>
          </div>
        </div>
      )}

      {/* Per-goal breakdown */}
      {!goalStats.length ? (
        <EmptyState icon="🎯" title="No goals yet" subtitle="Tap the + button to add your first habit or target."/>
      ) : (
        <div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
          <div style={{ fontSize: 15, fontWeight: 600 }}>Per goal</div>
          {goalStats.map(s => (
            <div key={s.goal.id} style={{ ...nutriStyles.card, padding: 14 }}>
              <div style={{ display: 'flex', alignItems: 'center', gap: 12, marginBottom: 10 }}>
                <FoodThumb emoji={s.goal.emoji} tint={s.goal.color} size={40}/>
                <div style={{ flex: 1, minWidth: 0 }}>
                  <div style={{ fontSize: 14, fontWeight: 600 }}>{s.goal.title}</div>
                  <div style={{ fontSize: 11.5, color: 'var(--muted)', marginTop: 2 }}>
                    {s.done}/{s.sch} sessions · streak {s.streak}🔥
                  </div>
                </div>
                <div style={{ fontSize: 18, fontWeight: 600, letterSpacing: '-0.02em', color: s.rate >= 0.8 ? 'var(--c-protein)' : s.rate >= 0.5 ? 'var(--c-carbs)' : '#C25A4E' }}>
                  {Math.round(s.rate * 100)}%
                </div>
              </div>
              <MacroBar value={s.rate} goal={1} color={s.goal.color}/>
            </div>
          ))}
        </div>
      )}

      <div style={{ height: 60 }}/>
    </div>
  );
}

/* ── GOAL DETAIL SHEET ──────────────────────────────────────────── */
function GoalDetailSheet({ goal, logs, onClose, onInc, onDec, onDelete, logDate, onAdjust }) {
  if (!goal) return null;
  const today    = todayISO();
  const date     = logDate || today;
  const streak   = ngStreak(goal, logs, today);
  const endDate  = goal.endDate || null;
  const isEnded  = endDate && endDate < today;
  const daysLeft = endDate && !isEnded
    ? Math.ceil((new Date(endDate + 'T00:00:00') - new Date()) / 86400000)
    : null;

  let sch = 0, done = 0;
  for (let i = 0; i < 30; i++) {
    const iso = daysAgo(i);
    const s = _goalStatusForDate(goal, logs, iso);
    if (s === 'unscheduled') continue;
    sch++;
    if (s === 'done') done++;
  }
  const rate = sch ? done / sch : 0;

  const days14 = [];
  for (let i = 13; i >= 0; i--) {
    const iso = daysAgo(i);
    const s   = _goalStatusForDate(goal, logs, iso);
    days14.push({ iso, s });
  }

  const loggedCount = _goalDoneForDate(goal, logs, date);

  return (
    <div style={{
      position: 'absolute', inset: 0, zIndex: 30,
      display: 'flex', flexDirection: 'column', background: 'var(--bg)',
      animation: 'sheetIn .25s cubic-bezier(.2,.7,.2,1)',
      paddingTop: 'var(--safe-top)',
    }}>
      <div style={{
        position: 'relative', height: 180,
        background: `linear-gradient(135deg, ${goal.color}55, ${goal.color}aa)`,
        display: 'grid', placeItems: 'center', fontSize: 64, lineHeight: 1, flexShrink: 0,
      }}>
        <button onClick={onClose} style={{
          position: 'absolute', top: 14, left: 14,
          width: 36, height: 36, borderRadius: '50%',
          border: '1px solid rgba(0,0,0,0.1)', background: 'rgba(255,255,255,0.9)',
          color: '#14140F', display: 'grid', placeItems: 'center', cursor: 'pointer',
        }}><XIcon size={18}/></button>
        <span style={{ filter: 'drop-shadow(0 6px 16px rgba(20,20,15,0.18))' }}>{goal.emoji}</span>
      </div>

      <div style={{ flex: 1, overflow: 'auto', padding: '18px 18px 80px' }}>
        <div style={{ fontSize: 22, fontWeight: 700, letterSpacing: '-0.02em' }}>{goal.title}</div>
        <div style={{ fontSize: 13, color: 'var(--muted)', marginTop: 4 }}>
          {goal.target} {goal.unit} / day · {goal.timesPerDay > 1 ? `${goal.timesPerDay}× per day` : 'Daily'}
        </div>
        {(goal.startDate || endDate) && (
          <div style={{ fontSize: 12, color: 'var(--muted)', marginTop: 4, display: 'flex', gap: 12, flexWrap: 'wrap' }}>
            {goal.startDate && <span>Started {prettyDateShort(goal.startDate)}</span>}
            {endDate && (
              <span style={{ color: isEnded ? 'var(--c-protein)' : 'var(--muted)' }}>
                {isEnded ? `✓ Finished ${prettyDateShort(endDate)}` : `Ends ${prettyDateShort(endDate)} · ${daysLeft}d left`}
              </span>
            )}
          </div>
        )}

        {/* Stats */}
        <div style={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: 10, marginTop: 18 }}>
          <GoalStatTile label="Streak"     value={streak}                 unit="days"            color="var(--c-carbs)"   icon="🔥"/>
          <GoalStatTile label="30-day"     value={Math.round(rate * 100)} unit="%"               color="var(--c-protein)" icon="✓"/>
          <GoalStatTile label="Done · 30d" value={done}                   unit={`/ ${sch}`}      color="var(--text)"      icon="📅"/>
        </div>

        {/* 14-day strip */}
        <div style={{ ...nutriStyles.card, padding: 16, marginTop: 14 }}>
          <div style={{ fontSize: 13, fontWeight: 600, marginBottom: 12 }}>Last 14 days</div>
          <div style={{ display: 'grid', gridTemplateColumns: 'repeat(14, 1fr)', gap: 4 }}>
            {days14.map(d => {
              const isDone    = d.s === 'done';
              const isMissed  = d.s === 'missed';
              const isSkipped = d.s === 'skipped';
              const isPartial = d.s === 'partial';
              return (
                <div key={d.iso} style={{
                  aspectRatio: '1/1', borderRadius: 6,
                  background: isDone ? goal.color : isPartial ? `${goal.color}66` : isMissed ? 'rgba(194,90,78,0.2)' : 'var(--surface-2)',
                  border: isSkipped ? '1px dashed var(--border-2)' : '1px solid var(--border)',
                  display: 'grid', placeItems: 'center',
                  fontSize: 10, fontWeight: 600,
                  color: isDone ? '#fff' : 'var(--muted-2)',
                }}>
                  {new Date(d.iso + 'T00:00:00').getDate()}
                </div>
              );
            })}
          </div>
        </div>

        {/* Log section */}
        {!isEnded && (
          <div style={{ ...nutriStyles.card, padding: 16, marginTop: 14 }}>
            <div style={{ fontSize: 13, fontWeight: 600, marginBottom: 12 }}>
              Log {date === today ? 'today' : prettyDateShort(date)}
            </div>
            <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
              <button onClick={onDec} style={{
                width: 44, height: 44, borderRadius: '50%',
                border: '1px solid var(--border-2)', background: 'var(--surface-2)',
                color: 'var(--text)', cursor: 'pointer', font: 'inherit', fontSize: 20, fontWeight: 600,
              }}>−</button>
              <div style={{ flex: 1, textAlign: 'center' }}>
                <div style={{ fontSize: 32, fontWeight: 600, letterSpacing: '-0.03em' }}>
                  {loggedCount}
                  <span style={{ fontSize: 14, color: 'var(--muted)', fontWeight: 500, marginLeft: 4 }}>/ {goal.target}</span>
                </div>
                <div style={{ fontSize: 12, color: 'var(--muted)' }}>{goal.unit}</div>
              </div>
              <button onClick={onInc} style={{
                width: 44, height: 44, borderRadius: '50%',
                border: '1px solid var(--accent)', background: 'var(--accent)',
                color: 'var(--on-accent)', cursor: 'pointer', font: 'inherit', fontSize: 20, fontWeight: 600,
              }}>+</button>
            </div>
          </div>
        )}

        <div style={{ display: 'flex', gap: 10, marginTop: 18 }}>
          <button onClick={onDelete} style={{
            flex: 1, padding: '12px', borderRadius: 999,
            background: 'transparent', color: '#A33',
            border: '1px solid rgba(170,51,51,.35)',
            fontSize: 13.5, fontWeight: 600, cursor: 'pointer', font: 'inherit',
          }}>Delete goal</button>
          <button onClick={onClose} style={{
            flex: 1, padding: '12px', borderRadius: 999,
            background: 'var(--text)', color: 'var(--bg)',
            border: '1px solid var(--text)',
            fontSize: 13.5, fontWeight: 600, cursor: 'pointer', font: 'inherit',
          }}>Done</button>
        </div>
      </div>
    </div>
  );
}

Object.assign(window, {
  GoalCard, GoalsHome, GoalsDayReview, GoalsCalendar,
  GoalDetailSheet, GoalStatTile, GoalsProgress,
  _goalIsScheduledOn, _goalStatusForDate, _dayProgress,
});
