// screens.jsx — Home, Journey, WeekDetail, Profile screens

const { useState: useSt, useEffect: useEf, useRef: useRf } = React;

// ─────────────── HOME / TODAY ───────────────
function HomeScreen({ ctx, onOpenSaint, onOpenWeek, onTab, extras }) {
  const t = window.TOKENS;
  const { week, dark, liturgicalTheming, calendar, premium, persona } = ctx;
  const journeyEntry = window.JOURNEY[week - 1];
  // "Today" — show isidore by default (a ferial-like day) so we can demonstrate the
  // pregnancy-relevant overlay; if the journey week has a saint, surface that one too.
  const todaySaintId = 'isidore';
  const todaySaint = window.SAINTS[todaySaintId];
  const journeySaint = journeyEntry.saintId ? window.SAINTS[journeyEntry.saintId] : null;

  const litColor = todaySaint.color;
  const lit = t.liturgical[litColor];
  const headerBg = liturgicalTheming
    ? (dark ? `linear-gradient(180deg, rgba(${hexToRgb(lit.fg)},0.18), transparent)` : `linear-gradient(180deg, ${lit.bg}, ${dark ? t.bg.dark : t.bg.light} 80%)`)
    : (dark ? `linear-gradient(180deg, #2A2333, ${t.bg.dark} 80%)` : `linear-gradient(180deg, #F4E8DC, ${t.bg.light} 80%)`);

  const ink = dark ? t.ink.dark : t.ink.light;
  const inkSoft = dark ? t.inkSoft.dark : t.inkSoft.light;
  const surface = dark ? t.surface.dark : t.surface.light;

  const greeting = { anxious: 'Take a breath, Anna.', curious: 'Good morning, Anna.', devout: 'Pax tibi, Anna.' }[persona] || 'Good morning, Anna.';

  const calendarLabel = { 'novus-ordo': 'Novus Ordo', '1962': '1962 Missal', 'polish': 'Polish National' }[calendar];

  return (
    <div style={{ position: 'absolute', inset: 0, overflowY: 'auto', paddingBottom: 100 }}>
      {/* hero header */}
      <div style={{ background: headerBg, padding: '64px 20px 24px' }}>
        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 18 }}>
          <div style={{ fontFamily: 'ui-monospace, "SF Mono", Menlo, monospace', fontSize: 11, letterSpacing: 1.2, textTransform: 'uppercase', color: inkSoft }}>
            Thursday · May 15
          </div>
          <div style={{ display: 'flex', gap: 6, alignItems: 'center' }}>
            <window.LiturgicalDot color={litColor} size={8}/>
            <span style={{ fontSize: 11, fontWeight: 600, color: inkSoft, letterSpacing: 0.2 }}>{lit.name} · Easter VI</span>
          </div>
        </div>
        <div style={{ fontSize: 26, fontWeight: 700, lineHeight: 1.18, letterSpacing: -0.4, color: ink, marginBottom: 6, textWrap: 'pretty' }}>
          {greeting}
        </div>
        <div style={{ fontSize: 15, color: inkSoft, lineHeight: 1.45 }}>
          You're <b style={{ color: ink }}>20 weeks</b> along — halfway home.
        </div>
        {ctx.showSizeComparisons !== false && journeyEntry.size && (
          <div onClick={() => onOpenWeek(week)} style={{
            marginTop: 14, display: 'flex', alignItems: 'center', gap: 12,
            padding: '10px 16px 10px 10px', borderRadius: 16,
            background: dark ? 'rgba(201,168,120,0.14)' : 'rgba(255,255,255,0.55)',
            border: `0.5px solid ${dark ? t.hairline.dark : 'rgba(201,168,120,0.4)'}`,
            cursor: 'pointer',
          }}>
            <div style={{
              width: 36, height: 36, borderRadius: 12, flexShrink: 0,
              background: dark ? 'rgba(201,168,120,0.2)' : 'rgba(201,168,120,0.22)',
              display: 'flex', alignItems: 'center', justifyContent: 'center',
            }}>
              <window.SizeGlyph glyph={journeyEntry.size.glyph} size={24}/>
            </div>
            <div style={{ flex: 1, minWidth: 0, display: 'flex', flexDirection: 'column', lineHeight: 1.1 }}>
              <span style={{ fontSize: 10, fontWeight: 700, letterSpacing: 0.8, textTransform: 'uppercase', color: inkSoft }}>About the size of</span>
              <span style={{ fontSize: 14, fontWeight: 700, color: ink, letterSpacing: -0.2, marginTop: 2 }}>a {journeyEntry.size.item}</span>
            </div>
            <span style={{ fontSize: 11, color: inkSoft, fontFamily: 'ui-monospace, monospace', flexShrink: 0 }}>{window.formatSize(journeyEntry.size)}</span>
          </div>
        )}
      </div>

      {/* Saint of the Day card */}
      <div style={{ padding: '8px 16px 0' }}>
        <SectionLabel dark={dark}>Saint of the Day</SectionLabel>
        <div onClick={() => onOpenSaint(todaySaintId)} style={{
          background: surface, borderRadius: 22, padding: 16, marginTop: 8,
          display: 'flex', gap: 14, cursor: 'pointer',
          boxShadow: dark ? '0 1px 0 rgba(255,255,255,0.04)' : '0 1px 2px rgba(60,40,40,0.04)',
        }}>
          <window.SaintPlaceholder tone={todaySaint.image} label="May 15" size="md" dark={dark}/>
          <div style={{ flex: 1, minWidth: 0, display: 'flex', flexDirection: 'column', justifyContent: 'space-between' }}>
            <div>
              <div style={{ fontSize: 11, fontWeight: 600, letterSpacing: 0.4, textTransform: 'uppercase', color: lit.fg, marginBottom: 4 }}>
                {todaySaint.rank}
              </div>
              <div style={{ fontSize: 17, fontWeight: 700, color: ink, lineHeight: 1.2, letterSpacing: -0.2 }}>
                {todaySaint.short}
              </div>
              <div style={{ fontSize: 12, color: inkSoft, marginTop: 2 }}>{todaySaint.lived}</div>
            </div>
            <div style={{ display: 'flex', gap: 6, flexWrap: 'wrap', marginTop: 8 }}>
              {todaySaint.patronOf.slice(0,2).map(p => <window.Chip key={p} small dark={dark}>{p}</window.Chip>)}
            </div>
          </div>
        </div>
      </div>

      {/* This week's pregnancy patron (the "killer feature" surfaced) */}
      <div style={{ padding: '24px 16px 0' }}>
        <SectionLabel dark={dark} action="Open journey" onAction={() => onTab('journey')}>This Week's Patron</SectionLabel>
        <div onClick={() => onOpenWeek(20)} style={{
          background: dark ? 'linear-gradient(135deg, #2A2330, #1F1A26)' : 'linear-gradient(135deg, #F4E0DC, #EDD6E0)',
          borderRadius: 22, padding: 18, marginTop: 8, position: 'relative', overflow: 'hidden', cursor: 'pointer',
        }}>
          <div style={{ position: 'absolute', top: -20, right: -20, opacity: 0.3 }}>
            <window.SaintPlaceholder tone="rose" size="lg" dark={dark} halo/>
          </div>
          <div style={{ position: 'relative', zIndex: 1, maxWidth: '70%' }}>
            <div style={{ fontFamily: 'ui-monospace, monospace', fontSize: 10, letterSpacing: 1.2, textTransform: 'uppercase', color: inkSoft, marginBottom: 6 }}>
              Week 20 · Halfway
            </div>
            <div style={{ fontSize: 22, fontWeight: 700, lineHeight: 1.15, color: ink, letterSpacing: -0.3, marginBottom: 8, textWrap: 'pretty' }}>
              St. Anne walks with you this week.
            </div>
            <div style={{ fontSize: 13, color: inkSoft, lineHeight: 1.5, marginBottom: 12 }}>
              Grandmother of God, long-childless, patron of mothers in labor.
            </div>
            <div style={{ display: 'inline-flex', gap: 6, alignItems: 'center', fontSize: 12, fontWeight: 600, color: t.roseDeep }}>
              Read the week
              <svg width="12" height="12" viewBox="0 0 12 12"><path d="M3 2l5 4-5 4" stroke="currentColor" strokeWidth="1.6" fill="none" strokeLinecap="round" strokeLinejoin="round"/></svg>
            </div>
          </div>
        </div>
      </div>

      {/* Annunciation→Christmas parallel */}
      <div style={{ padding: '20px 16px 0' }}>
        <div style={{
          background: surface, borderRadius: 22, padding: 16,
          display: 'flex', gap: 14, alignItems: 'center',
          border: `0.5px solid ${dark ? t.hairline.dark : t.hairline.light}`,
        }}>
          <div style={{
            width: 44, height: 44, borderRadius: 12, flexShrink: 0,
            background: 'linear-gradient(135deg, #E8D4A8, #C9A878)',
            display: 'flex', alignItems: 'center', justifyContent: 'center',
            color: '#fff', fontWeight: 700, fontSize: 18,
          }}>✦</div>
          <div style={{ flex: 1, minWidth: 0 }}>
            <div style={{ fontSize: 13, fontWeight: 700, color: ink, letterSpacing: -0.1 }}>Walking with Mary</div>
            <div style={{ fontSize: 12, color: inkSoft, lineHeight: 1.4, marginTop: 2 }}>
              You're at the same point Mary was around early August. 20 weeks until Christmas.
            </div>
          </div>
        </div>
      </div>

      {/* Coming up */}
      <div style={{ padding: '24px 16px 0' }}>
        <SectionLabel dark={dark}>Coming Up</SectionLabel>
        <div style={{ marginTop: 8, display: 'flex', flexDirection: 'column', gap: 8 }}>
          <UpcomingRow date="May 31" weeks={3} title="The Visitation" sub="Mary visits pregnant Elizabeth" tone="sage" rank="Feast" dark={dark}/>
          <UpcomingRow date="Jul 26" weeks={10} title="St. Anne & St. Joachim" sub="Memorial · parents of Mary" tone="cream" rank="Memorial" dark={dark}/>
          <UpcomingRow date="Oct 16" weeks={22} title="St. Gerard Majella" sub="Patron of expectant mothers" tone="rose" rank="Optional Memorial" dark={dark}/>
        </div>
      </div>

      {/* Today reading / quiet line */}
      <div style={{ padding: '24px 16px 0' }}>
        <div style={{
          background: dark ? 'rgba(255,250,240,0.04)' : 'rgba(217,166,160,0.10)',
          borderRadius: 22, padding: 18, textAlign: 'center',
        }}>
          <window.CrossGlyph size={14} color={t.roseDeep} opacity={0.7}/>
          <div style={{ fontSize: 15, lineHeight: 1.55, color: ink, marginTop: 8, fontStyle: 'italic', textWrap: 'pretty' }}>
            "Behold, I am the handmaid of the Lord; let it be done unto me according to thy word."
          </div>
          <div style={{ fontSize: 11, color: inkSoft, marginTop: 8, letterSpacing: 0.4, textTransform: 'uppercase' }}>Luke 1:38</div>
        </div>
      </div>

      {/* Embedded extras slot (rendered inside the scroller) */}
      {extras}

      {/* Calendar footer */}
      <div style={{ padding: '20px 16px 0', display: 'flex', alignItems: 'center', justifyContent: 'space-between', fontSize: 11, color: inkSoft, fontFamily: 'ui-monospace, monospace' }}>
        <span>Calendar: {calendarLabel}</span>
      </div>
    </div>
  );
}

function SectionLabel({ children, dark, action, onAction }) {
  const t = window.TOKENS;
  return (
    <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline', padding: '0 4px' }}>
      <div style={{ fontSize: 11, fontWeight: 700, letterSpacing: 1.2, textTransform: 'uppercase', color: dark ? t.inkSoft.dark : t.inkSoft.light }}>
        {children}
      </div>
      {action && <button onClick={onAction} style={{ background: 'none', border: 'none', fontSize: 12, fontWeight: 600, color: t.roseDeep, cursor: 'pointer' }}>{action}</button>}
    </div>
  );
}

function UpcomingRow({ date, weeks, title, sub, tone, rank, dark }) {
  const t = window.TOKENS;
  const surface = dark ? t.surface.dark : t.surface.light;
  const ink = dark ? t.ink.dark : t.ink.light;
  const inkSoft = dark ? t.inkSoft.dark : t.inkSoft.light;
  return (
    <div style={{
      background: surface, borderRadius: 16, padding: '10px 12px',
      display: 'flex', alignItems: 'center', gap: 12,
    }}>
      <window.SaintPlaceholder tone={tone} size="sm" dark={dark} label={date}/>
      <div style={{ flex: 1, minWidth: 0 }}>
        <div style={{ fontSize: 14, fontWeight: 600, color: ink, letterSpacing: -0.1, lineHeight: 1.25 }}>{title}</div>
        <div style={{ fontSize: 12, color: inkSoft, marginTop: 2, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{sub}</div>
      </div>
      <div style={{ textAlign: 'right', flexShrink: 0 }}>
        <div style={{ fontSize: 11, fontWeight: 700, color: ink, fontFamily: 'ui-monospace, monospace' }}>{date}</div>
        <div style={{ fontSize: 10, color: inkSoft, marginTop: 2 }}>in {weeks} wks</div>
      </div>
    </div>
  );
}

// ─────────────── JOURNEY ───────────────
function JourneyScreen({ ctx, onOpenWeek, currentWeek }) {
  const t = window.TOKENS;
  const { dark } = ctx;
  const ink = dark ? t.ink.dark : t.ink.light;
  const inkSoft = dark ? t.inkSoft.dark : t.inkSoft.light;
  const surface = dark ? t.surface.dark : t.surface.light;

  // Group by month
  const byMonth = {};
  window.JOURNEY.forEach(w => {
    if (!byMonth[w.monthName]) byMonth[w.monthName] = [];
    byMonth[w.monthName].push(w);
  });

  return (
    <div style={{ position: 'absolute', inset: 0, overflowY: 'auto', paddingBottom: 100 }}>
      <div style={{ padding: '64px 20px 18px' }}>
        <div style={{ fontFamily: 'ui-monospace, monospace', fontSize: 11, letterSpacing: 1.2, textTransform: 'uppercase', color: inkSoft, marginBottom: 6 }}>
          Mar 25 → Dec 25
        </div>
        <div style={{ fontSize: 32, fontWeight: 700, letterSpacing: -0.6, color: ink, lineHeight: 1.05, textWrap: 'pretty' }}>
          Your nine months,<br/>walked with the Church.
        </div>
        <div style={{ fontSize: 14, color: inkSoft, marginTop: 10, lineHeight: 1.5 }}>
          From the Annunciation to Christmas — the same span Mary carried Jesus.
        </div>
      </div>

      {/* Progress strip */}
      <div style={{ padding: '0 20px 16px' }}>
        <div style={{ display: 'flex', justifyContent: 'space-between', fontSize: 11, color: inkSoft, fontFamily: 'ui-monospace, monospace', marginBottom: 6 }}>
          <span>Week 1</span><span>Week {currentWeek} · today</span><span>Week 40</span>
        </div>
        <div style={{ height: 6, borderRadius: 3, background: dark ? 'rgba(255,255,255,0.08)' : 'rgba(60,55,70,0.08)', position: 'relative', overflow: 'hidden' }}>
          <div style={{ position: 'absolute', inset: 0, width: `${currentWeek/40*100}%`, background: `linear-gradient(90deg, ${t.gold}, ${t.rose})`, borderRadius: 3 }}/>
          <div style={{ position: 'absolute', top: -3, left: `calc(${currentWeek/40*100}% - 6px)`, width: 12, height: 12, borderRadius: '50%', background: t.roseDeep, boxShadow: '0 2px 6px rgba(176,122,122,0.5)' }}/>
        </div>
      </div>

      {/* Month columns */}
      <div style={{ padding: '0 16px' }}>
        {Object.entries(byMonth).map(([month, weeks]) => (
          <div key={month} style={{ marginBottom: 24 }}>
            <div style={{ display: 'flex', alignItems: 'baseline', gap: 8, padding: '0 4px 8px', borderBottom: `0.5px solid ${dark ? t.hairline.dark : t.hairline.light}`, marginBottom: 10 }}>
              <span style={{ fontSize: 13, fontWeight: 700, color: ink, letterSpacing: -0.1 }}>{month}</span>
              <span style={{ fontSize: 11, color: inkSoft, fontFamily: 'ui-monospace, monospace' }}>weeks {weeks[0].week}–{weeks[weeks.length-1].week}</span>
            </div>
            <div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
              {weeks.map(w => {
                const saint = w.saintId ? window.SAINTS[w.saintId] : null;
                const isCurrent = w.week === currentWeek;
                const isPast = w.week < currentWeek;
                const hasSaint = !!saint;
                return (
                  <div key={w.week} onClick={() => onOpenWeek(w.week)} style={{
                    background: isCurrent
                      ? (dark ? 'linear-gradient(135deg, #3A2D3A, #2A2330)' : 'linear-gradient(135deg, #F4E0DC, #EDD6E0)')
                      : surface,
                    borderRadius: 14, padding: '10px 12px',
                    display: 'flex', alignItems: 'center', gap: 12,
                    opacity: isPast && !hasSaint ? 0.55 : 1,
                    cursor: 'pointer',
                    border: isCurrent ? `1px solid ${t.rose}` : `0.5px solid ${dark ? t.hairline.dark : t.hairline.light}`,
                  }}>
                    <div style={{
                      width: 38, textAlign: 'center', flexShrink: 0,
                      fontFamily: 'ui-monospace, monospace',
                    }}>
                      <div style={{ fontSize: 10, color: inkSoft, letterSpacing: 0.2 }}>WK</div>
                      <div style={{ fontSize: 18, fontWeight: 700, color: ink, lineHeight: 1, marginTop: 2 }}>{w.week}</div>
                    </div>
                    {hasSaint ? (
                      <window.SaintPlaceholder tone={saint.image} size="sm" dark={dark} label={w.date}/>
                    ) : (
                      <div style={{
                        width: 64, height: 75, borderRadius: 14, flexShrink: 0,
                        background: dark ? 'rgba(255,255,255,0.04)' : 'rgba(60,55,70,0.04)',
                        border: `1px dashed ${dark ? t.hairline.dark : t.hairline.light}`,
                        display: 'flex', alignItems: 'center', justifyContent: 'center',
                      }}>
                        <window.CrossGlyph size={14} color={inkSoft} opacity={0.4}/>
                      </div>
                    )}
                    <div style={{ flex: 1, minWidth: 0 }}>
                      <div style={{ fontSize: 11, color: inkSoft, fontFamily: 'ui-monospace, monospace', marginBottom: 2 }}>{w.date} · {w.phase}</div>
                      <div style={{ fontSize: 13, fontWeight: hasSaint ? 600 : 400, color: ink, lineHeight: 1.35, letterSpacing: -0.1, textWrap: 'pretty' }}>{w.note}</div>
                      {ctx.showSizeComparisons !== false && w.size && (
                        <div style={{ display: 'inline-flex', alignItems: 'center', gap: 5, marginTop: 6, padding: '2px 7px 2px 4px', borderRadius: 999, background: dark ? 'rgba(201,168,120,0.12)' : 'rgba(201,168,120,0.18)', fontSize: 10.5, color: inkSoft, fontFamily: 'ui-monospace, monospace' }}>
                          <window.SizeGlyph glyph={w.size.glyph} size={16}/>
                          <span style={{ color: ink, fontWeight: 600 }}>{w.size.item}</span>
                          <span style={{ opacity: 0.7 }}>· {window.formatSize(w.size)}</span>
                        </div>
                      )}
                    </div>
                    {isCurrent && (
                      <div style={{ flexShrink: 0, padding: '3px 7px', borderRadius: 999, background: t.roseDeep, color: '#fff', fontSize: 9, fontWeight: 700, letterSpacing: 0.6 }}>NOW</div>
                    )}
                  </div>
                );
              })}
            </div>
          </div>
        ))}
      </div>
    </div>
  );
}

// ─────────────── WEEK DETAIL ───────────────
function WeekDetailScreen({ ctx, week, onBack, onOpenSaint }) {
  const t = window.TOKENS;
  const { dark } = ctx;
  const ink = dark ? t.ink.dark : t.ink.light;
  const inkSoft = dark ? t.inkSoft.dark : t.inkSoft.light;
  const surface = dark ? t.surface.dark : t.surface.light;
  const entry = window.JOURNEY[week - 1];
  const saint = entry.saintId ? window.SAINTS[entry.saintId] : null;

  return (
    <div style={{ position: 'absolute', inset: 0, overflowY: 'auto', paddingBottom: 100 }}>
      {/* hero */}
      <div style={{
        background: saint ? `linear-gradient(180deg, ${tonalBg(saint.image)}, ${dark ? t.bg.dark : t.bg.light})` : (dark ? '#1A1820' : '#F2EDE4'),
        padding: '54px 20px 28px', position: 'relative',
      }}>
        <button onClick={onBack} style={{
          background: dark ? 'rgba(255,255,255,0.12)' : 'rgba(255,255,255,0.7)',
          backdropFilter: 'blur(10px)', WebkitBackdropFilter: 'blur(10px)',
          border: 'none', borderRadius: 999, width: 36, height: 36,
          display: 'flex', alignItems: 'center', justifyContent: 'center',
          cursor: 'pointer', position: 'absolute', top: 54, left: 16,
        }}>
          <svg width="14" height="14" viewBox="0 0 14 14"><path d="M9 2L3 7l6 5" stroke={ink} strokeWidth="2" fill="none" strokeLinecap="round" strokeLinejoin="round"/></svg>
        </button>
        <div style={{ marginTop: 32, display: 'flex', alignItems: 'flex-end', gap: 16 }}>
          <div style={{ flex: 1 }}>
            <div style={{ fontFamily: 'ui-monospace, monospace', fontSize: 11, letterSpacing: 1.2, textTransform: 'uppercase', color: inkSoft, marginBottom: 6 }}>
              Week {week} · {entry.date} · Trimester {entry.trimester}
            </div>
            <div style={{ fontSize: 28, fontWeight: 700, letterSpacing: -0.5, lineHeight: 1.1, color: ink, textWrap: 'pretty' }}>
              {entry.phase}
            </div>
          </div>
          {saint && <window.SaintPlaceholder tone={saint.image} size="lg" dark={dark} halo label={saint.feast}/>}
        </div>
      </div>

      {/* Size of the child */}
      {ctx.showSizeComparisons !== false && entry.size && (
        <div style={{ padding: '20px 16px 0' }}>
          <div style={{
            background: surface, borderRadius: 22, padding: '16px 18px',
            display: 'flex', alignItems: 'center', gap: 16,
            border: `0.5px solid ${dark ? t.hairline.dark : t.hairline.light}`,
          }}>
            <div style={{
              width: 64, height: 64, flexShrink: 0, borderRadius: 16,
              background: dark ? 'rgba(201,168,120,0.12)' : 'rgba(201,168,120,0.18)',
              display: 'flex', alignItems: 'center', justifyContent: 'center',
            }}>
              <window.SizeGlyph glyph={entry.size.glyph} size={42}/>
            </div>
            <div style={{ flex: 1, minWidth: 0 }}>
              <div style={{ fontSize: 10.5, fontWeight: 700, letterSpacing: 1.2, textTransform: 'uppercase', color: inkSoft, marginBottom: 3 }}>About the size of</div>
              <div style={{ fontSize: 19, fontWeight: 700, color: ink, letterSpacing: -0.3, lineHeight: 1.15, textWrap: 'pretty' }}>a {entry.size.item}</div>
              <div style={{ fontSize: 12, color: inkSoft, marginTop: 4, fontFamily: 'ui-monospace, monospace' }}>{window.formatSize(entry.size)}</div>
            </div>
          </div>
        </div>
      )}

      {saint ? (
        <div style={{ padding: '20px 16px 0' }}>
          <div onClick={() => onOpenSaint(saint.id)} style={{ background: surface, borderRadius: 22, padding: 18, cursor: 'pointer' }}>
            <div style={{ fontSize: 11, fontWeight: 700, letterSpacing: 1, textTransform: 'uppercase', color: t.roseDeep, marginBottom: 6 }}>This week's patron</div>
            <div style={{ fontSize: 22, fontWeight: 700, color: ink, letterSpacing: -0.3, lineHeight: 1.15 }}>{saint.name}</div>
            <div style={{ fontSize: 13, color: inkSoft, marginTop: 4 }}>{saint.feast} · {saint.lived} · {saint.rank}</div>
            <div style={{ fontSize: 14, color: ink, lineHeight: 1.55, marginTop: 14, textWrap: 'pretty' }}>{saint.bioShort}</div>
            <div style={{ display: 'flex', gap: 6, flexWrap: 'wrap', marginTop: 14 }}>
              {saint.patronOf.map(p => <window.Chip key={p} tone="rose" small>{p}</window.Chip>)}
            </div>
            <div style={{ marginTop: 16, display: 'inline-flex', gap: 6, alignItems: 'center', fontSize: 13, fontWeight: 600, color: t.roseDeep }}>
              Read the full life
              <svg width="12" height="12" viewBox="0 0 12 12"><path d="M3 2l5 4-5 4" stroke="currentColor" strokeWidth="1.6" fill="none" strokeLinecap="round" strokeLinejoin="round"/></svg>
            </div>
          </div>
        </div>
      ) : (
        <div style={{ padding: '20px 16px 0' }}>
          <div style={{ background: surface, borderRadius: 22, padding: 18 }}>
            <div style={{ fontSize: 14, color: ink, lineHeight: 1.6, textWrap: 'pretty' }}>{entry.note}</div>
          </div>
        </div>
      )}

      {/* Reflection */}
      <div style={{ padding: '20px 16px 0' }}>
        <SectionLabel dark={dark}>This Week</SectionLabel>
        <div style={{ background: surface, borderRadius: 22, padding: 18, marginTop: 8 }}>
          <div style={{ fontSize: 14, color: ink, lineHeight: 1.6, textWrap: 'pretty' }}>
            {saint
              ? `Carry ${saint.short.split(' ')[0]} with you. A small candle, a quiet "${saint.short}, pray for us" before bed. The week asks little — only company.`
              : 'A quiet week. The Church gives us ferial days for ordinary growth — yours, and the child\'s.'}
          </div>
        </div>
      </div>

      {/* Mary parallel */}
      <div style={{ padding: '20px 16px 0' }}>
        <div style={{
          background: dark ? 'rgba(201,168,120,0.10)' : 'rgba(201,168,120,0.14)',
          borderRadius: 22, padding: 18, display: 'flex', gap: 14,
        }}>
          <div style={{ width: 40, height: 40, flexShrink: 0, borderRadius: 10, background: 'linear-gradient(135deg, #E8D4A8, #C9A878)', display: 'flex', alignItems: 'center', justifyContent: 'center', color: '#fff', fontSize: 18 }}>✦</div>
          <div style={{ flex: 1 }}>
            <div style={{ fontSize: 13, fontWeight: 700, color: ink }}>Mary at the same point</div>
            <div style={{ fontSize: 13, color: inkSoft, marginTop: 4, lineHeight: 1.5, textWrap: 'pretty' }}>
              In her timeline (Mar 25 → Dec 25), Mary was around {entry.date}. {week === 20 ? 'Halfway. The pregnancy was beginning to be visible.' : 'A quiet stretch in Nazareth.'}
            </div>
          </div>
        </div>
      </div>
    </div>
  );
}

// ─────────────── PROFILE / SAINT DETAIL ───────────────
function SaintProfileScreen({ ctx, saintId, onBack }) {
  const t = window.TOKENS;
  const { dark } = ctx;
  const saint = window.SAINTS[saintId];
  if (!saint) return null;
  const ink = dark ? t.ink.dark : t.ink.light;
  const inkSoft = dark ? t.inkSoft.dark : t.inkSoft.light;
  const surface = dark ? t.surface.dark : t.surface.light;

  return (
    <div style={{ position: 'absolute', inset: 0, overflowY: 'auto', paddingBottom: 100 }}>
      {/* parallax-ish hero */}
      <div style={{
        height: 360, position: 'relative', overflow: 'hidden',
        background: `linear-gradient(180deg, ${tonalBg(saint.image)}, ${dark ? t.bg.dark : t.bg.light})`,
      }}>
        <button onClick={onBack} style={{
          position: 'absolute', top: 54, left: 16, zIndex: 2,
          background: 'rgba(255,255,255,0.7)', backdropFilter: 'blur(10px)', WebkitBackdropFilter: 'blur(10px)',
          border: 'none', borderRadius: 999, width: 36, height: 36,
          display: 'flex', alignItems: 'center', justifyContent: 'center', cursor: 'pointer',
        }}>
          <svg width="14" height="14" viewBox="0 0 14 14"><path d="M9 2L3 7l6 5" stroke="#2A2530" strokeWidth="2" fill="none" strokeLinecap="round" strokeLinejoin="round"/></svg>
        </button>
        <div style={{ position: 'absolute', top: 100, left: '50%', transform: 'translateX(-50%)' }}>
          <window.SaintPlaceholder tone={saint.image} size="xl" dark={dark} halo label={saint.feast}/>
        </div>
      </div>

      <div style={{ padding: '0 20px', marginTop: -8, position: 'relative', zIndex: 1, textAlign: 'center' }}>
        <div style={{ fontSize: 11, letterSpacing: 1.4, textTransform: 'uppercase', color: t.roseDeep, fontWeight: 700, marginBottom: 6 }}>
          Feast Day · {saint.feast}
        </div>
        <div style={{ fontSize: 28, fontWeight: 700, color: ink, lineHeight: 1.1, letterSpacing: -0.5, marginBottom: 6, textWrap: 'pretty' }}>
          {saint.name}
        </div>
        <div style={{ fontSize: 13, color: inkSoft, marginBottom: 14 }}>{saint.lived} · {saint.rank}</div>
        <div style={{ display: 'flex', gap: 6, justifyContent: 'center', flexWrap: 'wrap' }}>
          {saint.patronOf.map(p => <window.Chip key={p} tone="rose" small>{p}</window.Chip>)}
        </div>
      </div>

      <div style={{ padding: '24px 20px 0' }}>
        <div style={{ fontSize: 16, lineHeight: 1.65, color: ink, textWrap: 'pretty' }}>
          {saint.bioLong}
        </div>
      </div>

      <div style={{ padding: '24px 16px 0' }}>
        <SectionLabel dark={dark}>A Short Prayer</SectionLabel>
        <div style={{ background: surface, borderRadius: 22, padding: 18, marginTop: 8, textAlign: 'center' }}>
          <window.CrossGlyph size={14} color={t.roseDeep} opacity={0.7}/>
          <div style={{ fontSize: 15, lineHeight: 1.6, color: ink, marginTop: 10, fontStyle: 'italic', textWrap: 'pretty' }}>
            {saint.short}, pray for us — for safe pregnancy, for our children, for the strength to receive what is given.
          </div>
          <button style={{
            marginTop: 16, padding: '10px 18px', borderRadius: 999,
            background: t.roseDeep, color: '#fff', border: 'none', cursor: 'pointer',
            fontSize: 13, fontWeight: 600, letterSpacing: 0.2,
          }}>Save to my prayers</button>
        </div>
      </div>

      <div style={{ padding: '20px 16px 0', display: 'flex', gap: 8 }}>
        <FactCard label="Born"  value={saint.lived.split('–')[0]} dark={dark}/>
        <FactCard label="Died"  value={saint.lived.split('–')[1] || '—'} dark={dark}/>
        <FactCard label="Color" value={t.liturgical[saint.color]?.name} dark={dark}/>
      </div>

      <div style={{ padding: '20px 16px 0', fontSize: 11, color: inkSoft, fontFamily: 'ui-monospace, monospace', textAlign: 'center' }}>
        Source: hand-curated · Wikidata · MIT
      </div>
    </div>
  );
}

function FactCard({ label, value, dark }) {
  const t = window.TOKENS;
  const ink = dark ? t.ink.dark : t.ink.light;
  const inkSoft = dark ? t.inkSoft.dark : t.inkSoft.light;
  const surface = dark ? t.surface.dark : t.surface.light;
  return (
    <div style={{ flex: 1, background: surface, borderRadius: 16, padding: '12px 10px', textAlign: 'center' }}>
      <div style={{ fontSize: 10, fontWeight: 700, letterSpacing: 0.8, textTransform: 'uppercase', color: inkSoft }}>{label}</div>
      <div style={{ fontSize: 15, fontWeight: 700, color: ink, marginTop: 4, letterSpacing: -0.2 }}>{value}</div>
    </div>
  );
}

// helpers
function hexToRgb(hex) {
  const m = hex.replace('#','').match(/.{1,2}/g);
  return m.map(x => parseInt(x,16)).join(',');
}
function tonalBg(tone) {
  return ({
    rose:  '#F4DDD8',
    blush: '#F2D8D2',
    cream: '#F0E5D2',
    sage:  '#DDE5D2',
    gold:  '#EDDDC0',
    violet:'#E2D8E8',
  })[tone] || '#F4DDD8';
}

window.HomeScreen = HomeScreen;
window.JourneyScreen = JourneyScreen;
window.WeekDetailScreen = WeekDetailScreen;
window.SaintProfileScreen = SaintProfileScreen;
