// Today tab — wired to /api/today + the last-14d slice of /api/sleep-trends.
const { fmtBedtime, fmtDelta, fmtHoursMinutes } = window.HC_DATA;
function Card({ children, style = {}, theme }) {
const p = theme.palette;
return (
{/* Sleep card */}
{fmtHoursMinutes(sleepH)}
{deltaStr}
{today.sleep_score ?? '—'}
sleep score
{/* Metrics grid 2×2 */}
= today.readiness_10d_avg : null}
sparkSeries="ready" />
{/* Drinks card — yesterday's intake, contextualizes last night's sleep */}
{(() => {
const yd = today.drinks_yesterday || {};
const ydUnits = yd.units || 0;
const history14 = (today.drinks_14d || []).map((d) => d.units);
const valueColor = ydUnits >= 3 ? p.warning : ydUnits > 0 ? p.text : p.text3;
return (
{ydUnits > 0 ? (
<>{ydUnits}u>
) : (
—
)}
{yd.text && (
{yd.text}
)}
);
})()}
{/* Training card */}
Training
{daysSince != null ? daysSince : '—'}
days since last
{training.comeback_mode && (
comeback mode · re-entry when ready
)}
{training.vo2max != null ? Math.round(training.vo2max) : '—'}
vo₂max
10
: false} />
7
: false} />
7
: false} />
{/* Context strip */}
{efficiency != null ? `Eff ${Math.round(efficiency)}%` : ''}
{efficiency != null && today.resilience ? ' · ' : ''}
{today.resilience ? today.resilience.charAt(0).toUpperCase() + today.resilience.slice(1) : ''}
{(efficiency != null || today.resilience) && daysSince != null ? ' · ' : ''}
{daysSince != null ? `Last training ${daysSince}d ago` : ''}
);
}
window.TodayTab = TodayTab;
window.HCCard = Card;