// screens-other.jsx — Give, Visit, About, Prayer Chapel, Events

// ─────────────────────────────────────────────────────────────
// FACEBOOK PAGE EMBED — uses Facebook's plain-iframe variant of the
// Page Plugin. Renders the same timeline-of-posts as the SDK version
// but doesn't depend on the SDK re-initializing on route changes,
// which is the SPA-React quirk that left this empty on /events.
// ─────────────────────────────────────────────────────────────
function FacebookPageEmbed({ theme, href, height = 340, width = 340 }) {
  const params = new URLSearchParams({
    href,
    tabs: 'timeline',
    width: String(width),
    height: String(height),
    small_header: 'true',
    adapt_container_width: 'true',
    hide_cover: 'true',
    show_facepile: 'false',
  });
  const src = `https://www.facebook.com/plugins/page.php?${params.toString()}`;

  return (
    <div style={{ background: theme.paper, border: `1px solid ${theme.rule}`, padding: 14 }}>
      <div style={{ ...smallCaps(theme, 9), color: theme.inkMute, marginBottom: 10 }}>Recent from Facebook</div>
      <div style={{ display: 'flex', justifyContent: 'center' }}>
        <iframe
          src={src}
          width={width}
          height={height}
          style={{ border: 'none', overflow: 'hidden', maxWidth: '100%' }}
          scrolling="no"
          frameBorder="0"
          allow="autoplay; clipboard-write; encrypted-media; picture-in-picture; web-share"
          title="Recent posts from Monticello UMC on Facebook"
        />
      </div>
      <div style={{ marginTop: 8, textAlign: 'center' }}>
        <a href={href} target="_blank" rel="noopener noreferrer"
           style={{ ...smallCaps(theme, 9), color: theme.inkMute, textDecoration: 'none', borderBottom: `1px dotted ${theme.rule}` }}>
          Open on Facebook ↗
        </a>
      </div>
    </div>
  );
}

// ─────────────────────────────────────────────────────────────
// GIVE — single button to Tithe.ly
// ─────────────────────────────────────────────────────────────
function GiveScreen({ theme, onBack }) {
  const TITHELY_URL = 'https://give.tithe.ly/?formId=c71d621b-a12b-49a4-ac40-ded302a70c04';

  return (
    <div style={{ background: theme.bg, color: theme.ink, paddingBottom: 60 }} className="paper-grain">
      <SeasonRibbon theme={theme} />

      <div style={{ padding: '22px 22px 28px', background: theme.paper, borderBottom: `1px solid ${theme.rule}` }}>
        <button onClick={onBack} style={{ background: 'transparent', border: 'none', cursor: 'pointer', ...smallCaps(theme, 9), color: theme.inkMute, padding: 0, marginBottom: 12 }}>‹ &nbsp; Back to index</button>

        <div style={{ ...smallCaps(theme, 9), color: theme.accent, marginBottom: 10 }}>An Act of Worship</div>
        <h1 style={{ fontFamily: theme.fonts.display, fontWeight: 500, fontSize: 48, lineHeight: 0.98, margin: 0, color: theme.ink, letterSpacing: '-0.01em' }}>
          Gifts <span style={{ fontStyle: 'italic', color: theme.accent }}>&amp;</span> Offerings
        </h1>
        <p style={{ fontFamily: theme.fonts.display, fontStyle: 'italic', fontSize: 16, color: theme.inkSoft, lineHeight: 1.45, marginTop: 18 }}>
          “Each of you should give what you have decided in your heart to give, not reluctantly or under compulsion, for God loves a cheerful giver.”
        </p>
        <div style={{ ...smallCaps(theme, 9), color: theme.gold, marginTop: 8 }}>2 Corinthians 9 : 7</div>
      </div>

      {/* Tithe.ly inline form — embedded directly so visitors don't leave the site */}
      <div style={{ padding: '24px 22px 0' }}>
        <div style={{ color: theme.gold, fontFamily: theme.fonts.display, fontStyle: 'italic', fontSize: 18, textAlign: 'center', marginBottom: 16 }}>
          †
        </div>
        <div style={{ background: theme.paper, border: `1px solid ${theme.rule}`, padding: 0, overflow: 'hidden' }}>
          <iframe
            src={TITHELY_URL}
            width="100%"
            height="900"
            style={{ border: 'none', display: 'block', background: '#ffffff' }}
            title="Give to Monticello United Methodist Church"
            allow="payment"
          />
        </div>
        <div style={{ ...smallCaps(theme, 9), color: theme.inkMute, marginTop: 14, lineHeight: 1.7, textAlign: 'center' }}>
          Secured by Tithe.ly · Tax-deductible · IRS 501(c)(3)<br/>
          <a href={TITHELY_URL} target="_blank" rel="noopener noreferrer" style={{ color: theme.inkMute, textDecoration: 'underline' }}>
            or open Tithe.ly in a new tab ↗
          </a>
        </div>
      </div>

      {/* Designated funds — informational only; chosen on the Tithe.ly form */}
      <div style={{ padding: '40px 22px 0' }}>
        <MissalRule theme={theme} label="Where it goes" />
        <div style={{ fontFamily: theme.fonts.body, fontSize: 14, color: theme.inkSoft, lineHeight: 1.55 }}>
          You can designate your gift to any of these:
        </div>
        <ul style={{
          fontFamily: theme.fonts.display, fontSize: 17, fontStyle: 'italic',
          color: theme.ink, lineHeight: 1.9, paddingLeft: 18, marginTop: 12,
        }}>
          <li>General Operating</li>
          <li>Building &amp; Grounds</li>
          <li>Missions</li>
          <li>Pastor's Discretionary Fund</li>
        </ul>
        <div style={{ fontFamily: theme.fonts.body, fontStyle: 'italic', fontSize: 14, color: theme.inkSoft, lineHeight: 1.55, marginTop: 4 }}>
          For anything else — a memorial, a special project, a particular need — write it in the <span style={{ color: theme.accent }}>memo line</span> on the form, and we'll honor it.
        </div>
      </div>

      <div style={{ padding: '28px 22px 0', textAlign: 'center' }}>
        <div style={{ fontFamily: theme.fonts.display, fontStyle: 'italic', fontSize: 14, color: theme.inkMute }}>
          Or by mail: <a href="https://maps.apple.com/?address=PO+Box+87,+Monticello,+MS+39654" style={{ color: 'inherit', textDecoration: 'none', borderBottom: `1px dotted ${theme.inkMute}` }}>PO Box 87 · Monticello, MS 39654</a>
        </div>
      </div>
    </div>
  );
}

// ─────────────────────────────────────────────────────────────
// VISIT / NEW HERE — illustrated guide
// ─────────────────────────────────────────────────────────────
function VisitScreen({ theme, onBack }) {
  const faqs = [
    { q: 'What should I wear?', a: 'Anything you’re comfortable in. You’ll see suits beside flannel shirts. Come as you are.' },
    { q: 'Where do I park?', a: 'Free parking in the lot off South Main, with two reserved guest spots near the breezeway entrance.' },
    { q: 'Are children welcome?', a: 'Joyfully. Children stay in the pew with their families and learn the rhythms of faith alongside them.' },
    { q: 'What is a “liturgical” service?', a: 'A service that follows an ancient pattern: gathering, the Word, the Table, sending. Don’t worry — every prayer and response is printed in the bulletin.' },
    { q: 'Will I be singled out?', a: 'No. Visitors are welcomed warmly but never pointed out from the pew. The congregation stands and sits together at certain points in the service — for the Gospel, the hymns, the creed — but you\'ll be doing it with everyone, not on display.' },
  ];
  const [open, setOpen] = React.useState(0);

  return (
    <div style={{ background: theme.bg, color: theme.ink, paddingBottom: 60 }} className="paper-grain">
      <SeasonRibbon theme={theme} />

      <div style={{ padding: '22px 22px 0', background: theme.paper }}>
        <button onClick={onBack} style={{ background: 'transparent', border: 'none', cursor: 'pointer', ...smallCaps(theme, 9), color: theme.inkMute, padding: 0, marginBottom: 12 }}>‹ &nbsp; Back to index</button>

        <div style={{ ...smallCaps(theme, 9), color: theme.accent, marginBottom: 8 }}>A guide for the curious</div>
        <h1 style={{ fontFamily: theme.fonts.display, fontWeight: 500, fontSize: 36, lineHeight: 0.98, margin: 0, color: theme.ink }}>
          You are <span style={{ fontStyle: 'italic', color: theme.accent }}>welcome</span> here.
        </h1>
      </div>

      <div style={{ background: theme.paper, marginTop: 18 }}>
        <SanctuaryPhoto theme={theme} height={200} />
      </div>

      {/* Sit with someone */}
      <div style={{ padding: '18px 0 0' }}>
        <SitWithSomeone theme={theme} />
      </div>

      {/* Three-step visit timeline */}
      <div style={{ padding: '22px 22px 0' }}>
        <MissalRule theme={theme} label="What to expect" />
      </div>
      <div style={{ padding: '0 22px' }}>
        {[
          { t: '10:15', title: 'Arrive at the Sanctuary', body: 'A greeter meets you with a bulletin and a warm welcome.' },
          { t: '10:30', title: 'Worship', body: 'About 60 minutes — hymns, scripture, sermon, prayers, and the Lord’s Supper on the first Sunday of each month. Children stay in the pew with their families and learn the rhythms of faith.' },
          { t: '11:30', title: 'Coffee Hour', body: 'Stay for cookies and conversation in the dining hall. No pressure.' },
        ].map((s, i, arr) => (
          <div key={i} style={{ display: 'flex', gap: 16, position: 'relative' }}>
            <div style={{ width: 60, flexShrink: 0, textAlign: 'right', paddingTop: 14, position: 'relative' }}>
              <div style={{ fontFamily: theme.fonts.display, fontSize: 22, color: theme.accent, fontWeight: 500 }}>{s.t}</div>
              {i < arr.length - 1 && (
                <div style={{ position: 'absolute', right: 6, top: 42, bottom: -10, width: 1, background: theme.rule }} />
              )}
            </div>
            <div style={{ flex: 1, padding: '14px 0', borderBottom: i < arr.length - 1 ? `1px solid ${theme.ruleSoft}` : 'none' }}>
              <div style={{ fontFamily: theme.fonts.display, fontSize: 18, color: theme.ink, fontWeight: 500 }}>{s.title}</div>
              <div style={{ fontFamily: theme.fonts.body, fontSize: 13, color: theme.inkSoft, lineHeight: 1.45, marginTop: 4 }}>{s.body}</div>
            </div>
          </div>
        ))}
      </div>

      {/* Address card */}
      <div style={{ padding: '24px 22px 0' }}>
        <MissalRule theme={theme} label="Find us" />
        <div style={{ background: theme.paper, padding: 18, border: `1px solid ${theme.rule}`, display: 'flex', alignItems: 'flex-start', gap: 14 }}>
          <div style={{ color: theme.accent, marginTop: 2 }}>{Icons.pin(22, theme.accent)}</div>
          <div style={{ flex: 1 }}>
            <a href="https://maps.apple.com/?address=130+East+Broad+Street,+Monticello,+MS+39654" style={{ color: 'inherit', textDecoration: 'none', display: 'block' }}>
              <div style={{ fontFamily: theme.fonts.display, fontSize: 18, color: theme.ink, fontWeight: 500 }}>130 East Broad Street</div>
              <div style={{ fontFamily: theme.fonts.display, fontStyle: 'italic', fontSize: 14, color: theme.inkSoft }}>Monticello, Mississippi 39654</div>
            </a>
            <a href="tel:+16015872987" style={{ ...smallCaps(theme, 9), color: theme.inkMute, marginTop: 8, display: 'inline-block', textDecoration: 'none', borderBottom: `1px dotted ${theme.rule}` }}>601 / 587 / 2987</a>
          </div>
        </div>
      </div>

      {/* FAQ accordion */}
      <div style={{ padding: '24px 22px 0' }}>
        <MissalRule theme={theme} label="Common questions" />
        {faqs.map((f, i) => (
          <div key={i} style={{ borderBottom: `1px solid ${theme.ruleSoft}` }}>
            <button onClick={() => setOpen(open === i ? -1 : i)} style={{
              display: 'flex', justifyContent: 'space-between', alignItems: 'center',
              width: '100%', padding: '14px 0', background: 'transparent', border: 'none',
              cursor: 'pointer', textAlign: 'left',
            }}>
              <span style={{ fontFamily: theme.fonts.display, fontSize: 17, color: theme.ink, fontStyle: 'italic', fontWeight: 400 }}>{f.q}</span>
              <span style={{ fontFamily: theme.fonts.display, fontSize: 24, color: theme.gold, transform: open === i ? 'rotate(45deg)' : 'none', transition: 'transform 0.2s' }}>+</span>
            </button>
            {open === i && (
              <div style={{ paddingBottom: 14, fontFamily: theme.fonts.body, fontSize: 13, color: theme.inkSoft, lineHeight: 1.5, animation: 'fadein 0.3s ease' }}>
                {f.a}
              </div>
            )}
          </div>
        ))}
      </div>

      {/* Stay close — Facebook */}
      <div style={{ padding: '24px 22px 0' }}>
        <MissalRule theme={theme} label="Stay close" />
        <a href="https://www.facebook.com/monticellounited.methodistchurch" target="_blank" rel="noopener noreferrer" style={{
          display: 'flex', alignItems: 'center', gap: 14,
          background: theme.paper, padding: 16, border: `1px solid ${theme.rule}`,
          textDecoration: 'none',
        }}>
          <div style={{
            width: 42, height: 42, borderRadius: '50%',
            background: theme.ink, color: theme.paper,
            display: 'flex', alignItems: 'center', justifyContent: 'center',
            fontFamily: 'serif', fontSize: 24, fontWeight: 700, fontStyle: 'italic',
            flexShrink: 0,
          }}>f</div>
          <div style={{ flex: 1, minWidth: 0 }}>
            <div style={{ fontFamily: theme.fonts.display, fontSize: 16, color: theme.ink, fontWeight: 500 }}>
              Follow us on Facebook
            </div>
            <div style={{ ...smallCaps(theme, 9), color: theme.inkMute, marginTop: 4 }}>
              @monticellounited.methodistchurch
            </div>
          </div>
          <div style={{ color: theme.gold, fontFamily: theme.fonts.mono, fontSize: 14 }}>↗</div>
        </a>

        <div style={{ marginTop: 18 }}>
          <FacebookPageEmbed
            theme={theme}
            href="https://www.facebook.com/monticellounited.methodistchurch"
          />
        </div>
      </div>
    </div>
  );
}

// ─────────────────────────────────────────────────────────────
// PRAYER WALL — votive candles you can light
// ─────────────────────────────────────────────────────────────
// The eight candles are a shortened form of the great litany — each candle a petition.
// Defined at module scope so the merge with localStorage works cleanly when the
// litany text is later updated without invalidating user-added candles.
const PRAYER_LITANY_CANDLES = [
  { name: 'For the Church',         prayer: 'and all the holy people of God',          lit: true,  by: 'the litany' },
  { name: 'For the world',          prayer: 'and our nation and its people',           lit: true,  by: 'the litany' },
  { name: 'For those in need',      prayer: 'the suffering, dying, and dead',          lit: true,  by: 'the litany' },
  { name: 'For our families',       prayer: 'and those we love',                       lit: true,  by: 'the litany' },
  { name: 'For triumph',            prayer: 'over our enemies seen and unseen',        lit: true,  by: 'the litany' },
  { name: "For Christ's victory",   prayer: 'over the powers of darkness',             lit: true,  by: 'the litany' },
  { name: 'For Easter joy',         prayer: 'and the happiness of his Resurrection',   lit: false, by: 'tap to light' },
  { name: 'That we may at last',    prayer: 'feast with the saints and angels',        lit: false, by: 'tap to light' },
];

const PRAYER_STORAGE_USER = 'mumc.prayer.user.v1';
const PRAYER_STORAGE_LIT  = 'mumc.prayer.lit.v1';

function PrayerScreen({ theme, onBack, setModal }) {
  // Strategy:
  //   • The 8 litany candles are local — every visitor sees them, lit-overrides
  //     are remembered per-device via localStorage as before.
  //   • Visitor-added candles ("personal intentions") now go to /api/candles, a
  //     SHARED prayer chapel stored in Azure. Everyone sees everyone's. We fall
  //     back to localStorage if the network fails, so the wall isn't broken
  //     when the visitor is offline.
  const [serverCandles, setServerCandles] = React.useState([]);
  const [serverLoaded, setServerLoaded]   = React.useState(false);
  const [submitting, setSubmitting]       = React.useState(false);
  const [postError, setPostError]         = React.useState('');

  // Load shared candles from the API on mount.
  React.useEffect(() => {
    let cancelled = false;
    fetch('/api/candles', { headers: { 'Accept': 'application/json' } })
      .then(r => r.ok ? r.json() : Promise.reject(new Error('HTTP ' + r.status)))
      .then(data => {
        if (cancelled) return;
        setServerCandles((data.candles || []).map(c => ({ ...c, lit: true })));
        setServerLoaded(true);
      })
      .catch(() => {
        if (cancelled) return;
        // Network unavailable — fall back to local-only candles
        try {
          const local = JSON.parse(localStorage.getItem(PRAYER_STORAGE_USER) || '[]');
          setServerCandles(local);
        } catch (e) {}
        setServerLoaded(true);
      });
    return () => { cancelled = true; };
  }, []);

  // Local lit-overrides for the litany candles (Easter joy / Wedding Feast).
  const [litOverrides, setLitOverrides] = React.useState(() => {
    try { return new Set(JSON.parse(localStorage.getItem(PRAYER_STORAGE_LIT) || '[]')); }
    catch (e) { return new Set(); }
  });
  React.useEffect(() => {
    try { localStorage.setItem(PRAYER_STORAGE_LIT, JSON.stringify(Array.from(litOverrides))); }
    catch (e) {}
  }, [litOverrides]);

  // Build the displayed candles list: server-added first, then the litany.
  const candles = [
    ...serverCandles,
    ...PRAYER_LITANY_CANDLES.map(c =>
      c.lit ? c : (litOverrides.has(c.name) ? { ...c, lit: true, by: 'you' } : c)
    ),
  ];

  const [composing, setComposing] = React.useState(false);
  const [name, setName] = React.useState('');
  const [prayer, setPrayer] = React.useState('');

  // Tap-to-light: only meaningful for the two unlit litany candles. Server-side
  // candles are always lit (you can't un-pray for someone).
  const light = (i) => {
    const c = candles[i];
    if (!c || c.lit) return;
    setLitOverrides(s => { const n = new Set(s); n.add(c.name); return n; });
    try { window.playSound && window.playSound('match-strike'); } catch (e) {}
  };

  const submit = async () => {
    if (!name || submitting) return;
    setSubmitting(true);
    setPostError('');
    try {
      const res = await fetch('/api/candles', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json', 'Accept': 'application/json' },
        body: JSON.stringify({ name, prayer }),
      });
      if (!res.ok) {
        const err = await res.json().catch(() => ({}));
        throw new Error(err.error || ('HTTP ' + res.status));
      }
      const data = await res.json();
      setServerCandles(prev => [{ ...data.candle, lit: true }, ...prev]);
      setName(''); setPrayer(''); setComposing(false);
      try { window.playSound && window.playSound('match-strike'); } catch (e) {}
    } catch (e) {
      setPostError(e.message || 'Could not save your prayer just now.');
    } finally {
      setSubmitting(false);
    }
  };

  return (
    <div style={{ background: theme.bg, color: theme.ink, paddingBottom: 60, minHeight: '100%' }} className="paper-grain">
      <SeasonRibbon theme={theme} />

      <div style={{ padding: '22px 22px 16px', background: theme.paper, borderBottom: `1px solid ${theme.rule}` }}>
        <button onClick={onBack} style={{ background: 'transparent', border: 'none', cursor: 'pointer', ...smallCaps(theme, 9), color: theme.inkMute, padding: 0, marginBottom: 12 }}>‹ &nbsp; Back to index</button>

        <div style={{ ...smallCaps(theme, 9), color: theme.accent, marginBottom: 8 }}>The Prayer Chapel</div>
        <h1 style={{ fontFamily: theme.fonts.display, fontWeight: 500, fontSize: 36, lineHeight: 0.98, margin: 0, color: theme.ink }}>
          Light a <span style={{ fontStyle: 'italic', color: theme.accent }}>candle</span>
        </h1>
        <p style={{ fontFamily: theme.fonts.display, fontStyle: 'italic', fontSize: 14, color: theme.inkSoft, marginTop: 8, lineHeight: 1.4 }}>
          A candle here is a candle lit in our digital chapel — the flame rising upward like incense, the prayer that continues after we have moved on with the day. The Prayer Team prays through this wall each morning.
        </p>
        <button onClick={() => setModal && setModal('pray')} style={{
          marginTop: 14, padding: '10px 16px', background: 'transparent', color: theme.ink,
          border: `1px solid ${theme.gold}`,
          fontFamily: theme.fonts.mono, fontSize: 11, letterSpacing: '0.16em', textTransform: 'uppercase', cursor: 'pointer',
        }}>† &nbsp; Pray the Lord's Prayer with us</button>
      </div>

      {/* candle wall */}
      <div style={{
        background: `linear-gradient(180deg, ${theme.bgAlt}, ${theme.bg})`,
        padding: '28px 18px 20px',
        borderBottom: `1px solid ${theme.rule}`,
        position: 'relative',
        minHeight: 180,
      }}>
        <div style={{
          display: 'grid',
          gridTemplateColumns: 'repeat(3, 1fr)',
          gap: '16px 8px',
          rowGap: 24,
        }}>
          {candles.map((c, i) => (
            <button key={i} onClick={() => !c.lit && light(i)} style={{
              background: 'transparent', border: 'none', padding: 0, cursor: c.lit ? 'default' : 'pointer',
            }}>
              <Candle theme={theme} lit={c.lit} size={0.9} name={c.name} prayer={c.prayer} />
            </button>
          ))}
        </div>
        {/* altar shelf */}
        <div style={{
          position: 'absolute', left: 0, right: 0, bottom: 0, height: 4,
          background: `linear-gradient(180deg, ${theme.gold}, ${theme.accent})`,
          opacity: 0.8,
        }} />
      </div>

      <div style={{ padding: '20px 22px 0', display: 'flex', justifyContent: 'space-between', alignItems: 'baseline' }}>
        <div style={{ ...smallCaps(theme, 9), color: theme.inkMute }}>
          {candles.filter(c => c.lit).length} candles lit · {candles.length} requests
        </div>
        <button onClick={() => setComposing(!composing)} style={{
          background: 'transparent', border: 'none', cursor: 'pointer',
          ...smallCaps(theme, 10), color: theme.accent,
        }}>+ Add a prayer</button>
      </div>

      {composing && (
        <div style={{ padding: '14px 22px 0', animation: 'fadein 0.3s' }}>
          <div style={{ background: theme.paper, padding: 16, border: `1px solid ${theme.rule}` }}>
            <div style={{ ...smallCaps(theme, 9), color: theme.inkMute, marginBottom: 6 }}>Your intention</div>
            <input value={name} onChange={e => setName(e.target.value)} placeholder="For…" style={{
              width: '100%', padding: '8px 0', background: 'transparent', border: 'none',
              borderBottom: `1px solid ${theme.rule}`,
              fontFamily: theme.fonts.display, fontSize: 18, color: theme.ink, outline: 'none', fontStyle: 'italic',
            }} />
            <textarea value={prayer} onChange={e => setPrayer(e.target.value)} placeholder="A few words (optional)" rows={2} style={{
              width: '100%', padding: '8px 0', background: 'transparent', border: 'none',
              borderBottom: `1px solid ${theme.rule}`, marginTop: 8,
              fontFamily: theme.fonts.body, fontSize: 13, color: theme.ink, outline: 'none', resize: 'none',
            }} />
            <button onClick={submit} disabled={submitting || !name} style={{
              width: '100%', padding: '12px', marginTop: 14,
              background: (submitting || !name) ? theme.inkMute : theme.accent,
              color: theme.paper, border: 'none',
              fontFamily: theme.fonts.mono, fontSize: 11, letterSpacing: '0.16em', textTransform: 'uppercase',
              cursor: (submitting || !name) ? 'not-allowed' : 'pointer',
            }}>{submitting ? '… Lighting' : '†   Light my candle   †'}</button>
            {postError && (
              <div style={{ fontFamily: theme.fonts.body, fontStyle: 'italic', fontSize: 12, color: theme.accent, marginTop: 10, textAlign: 'center' }}>
                {postError}
              </div>
            )}
          </div>
        </div>
      )}

      {/* Send a private prayer to the pastor — distinct from the public
          candle wall above. The candle wall is a community of prayer; this
          card is a one-to-one pastoral channel. Name + contact required —
          we never accept anonymous requests, because pastoral care is
          relational and the pastor needs a way to follow up. */}
      <div style={{ padding: '32px 22px 0' }}>
        <PastorPrayerCard theme={theme} />
      </div>
    </div>
  );
}

// ─────────────────────────────────────────────────────────────
// PASTOR PRAYER CARD — private channel to Pastor Jonathan
// ─────────────────────────────────────────────────────────────
// Inline expanding card. Submits to /api/pray-pastor which sends through
// Resend to the pastor's inbox. Required fields: name, contact, message.
// No anonymous option — by design.
function PastorPrayerCard({ theme }) {
  const [open, setOpen]       = React.useState(false);
  const [name, setName]       = React.useState('');
  const [contact, setContact] = React.useState('');
  const [message, setMessage] = React.useState('');
  const [hp, setHp]           = React.useState(''); // honeypot
  const [submitting, setSubmitting] = React.useState(false);
  const [done, setDone]       = React.useState(false);
  const [err, setErr]         = React.useState('');

  const ready = name.trim().length >= 2 && contact.trim().length >= 4 && message.trim().length >= 4;

  const submit = async () => {
    if (!ready || submitting) return;
    setSubmitting(true); setErr('');
    try {
      const r = await fetch('/api/pray-pastor', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ name: name.trim(), contact: contact.trim(), message: message.trim(), hp }),
      });
      if (!r.ok) {
        const data = await r.json().catch(() => ({}));
        throw new Error(data.error || 'could not send');
      }
      setDone(true);
    } catch (e) {
      setErr(String(e.message || e));
    } finally {
      setSubmitting(false);
    }
  };

  if (done) {
    return (
      <div style={{
        background: theme.paper, padding: '24px 20px',
        border: `1px solid ${theme.rule}`,
        textAlign: 'center', animation: 'fadein 0.5s ease',
      }}>
        <div style={{ fontFamily: theme.fonts.display, fontSize: 22, fontStyle: 'italic', color: theme.ink, marginBottom: 6 }}>
          Peace be with you, {name.split(' ')[0]}.
        </div>
        <div style={{ fontFamily: theme.fonts.body, fontStyle: 'italic', fontSize: 14, color: theme.inkSoft, lineHeight: 1.5 }}>
          Pastor Jonathan will be praying for you.
        </div>
        <div style={{ ...smallCaps(theme, 9), color: theme.gold, marginTop: 14 }}>
          † &nbsp; Sent &nbsp; †
        </div>
      </div>
    );
  }

  if (!open) {
    return (
      <button onClick={() => setOpen(true)} style={{
        width: '100%', textAlign: 'left',
        background: theme.paper, padding: '20px 18px',
        border: `1px solid ${theme.rule}`, cursor: 'pointer',
        fontFamily: 'inherit',
        display: 'flex', gap: 14, alignItems: 'flex-start',
      }}>
        <div style={{ color: theme.gold, fontFamily: theme.fonts.display, fontSize: 28, lineHeight: 0.9, flexShrink: 0 }}>†</div>
        <div style={{ flex: 1 }}>
          <div style={{ ...smallCaps(theme, 9), color: theme.accent, marginBottom: 4 }}>A private word</div>
          <div style={{ fontFamily: theme.fonts.display, fontSize: 19, color: theme.ink, fontStyle: 'italic', lineHeight: 1.3 }}>
            Send a prayer to Pastor Jonathan
          </div>
          <div style={{ fontFamily: theme.fonts.body, fontStyle: 'italic', fontSize: 13, color: theme.inkSoft, lineHeight: 1.5, marginTop: 6 }}>
            For something that needs more than a candle on the wall.
            Goes only to the pastor.
          </div>
        </div>
        <div style={{ color: theme.inkMute, fontFamily: theme.fonts.display, fontSize: 22, flexShrink: 0 }}>›</div>
      </button>
    );
  }

  return (
    <div style={{
      background: theme.paper, padding: 18, position: 'relative',
      border: `1px solid ${theme.rule}`, animation: 'fadein 0.3s ease',
    }}>
      <div style={{ display: 'flex', alignItems: 'baseline', justifyContent: 'space-between', marginBottom: 10 }}>
        <div style={{ ...smallCaps(theme, 9), color: theme.accent }}>To Pastor Jonathan</div>
        <button onClick={() => setOpen(false)} style={{
          background: 'transparent', border: 'none', cursor: 'pointer',
          color: theme.inkMute, fontFamily: theme.fonts.mono, fontSize: 11, padding: 0,
        }}>close</button>
      </div>

      <div style={{ fontFamily: theme.fonts.body, fontStyle: 'italic', fontSize: 13, color: theme.inkSoft, lineHeight: 1.5, marginBottom: 14 }}>
        This message goes only to the pastor — not to the public Prayer Chapel.
        Please share your name and a way to reach you, so he can pray with you and follow up.
      </div>

      <input value={name} onChange={e => setName(e.target.value)} placeholder="Your name"
        style={{
          width: '100%', padding: '10px 0', background: 'transparent', border: 'none',
          borderBottom: `1px solid ${theme.rule}`,
          fontFamily: theme.fonts.display, fontSize: 17, color: theme.ink, outline: 'none', fontStyle: 'italic',
        }} />

      <input value={contact} onChange={e => setContact(e.target.value)} placeholder="Email or phone (so the pastor can reach you)"
        style={{
          width: '100%', padding: '10px 0', background: 'transparent', border: 'none',
          borderBottom: `1px solid ${theme.rule}`, marginTop: 10,
          fontFamily: theme.fonts.body, fontSize: 14, color: theme.ink, outline: 'none',
        }} />

      <textarea value={message} onChange={e => setMessage(e.target.value)} rows={5}
        placeholder="What would you like the pastor to pray for?"
        style={{
          width: '100%', padding: '10px 0', background: 'transparent', border: 'none',
          borderBottom: `1px solid ${theme.rule}`, marginTop: 10,
          fontFamily: theme.fonts.body, fontSize: 14, color: theme.ink, outline: 'none',
          resize: 'vertical', lineHeight: 1.55,
        }} />

      {/* Honeypot — invisible to humans, irresistible to dumb bots. */}
      <input type="text" tabIndex="-1" autoComplete="off" value={hp}
        onChange={e => setHp(e.target.value)}
        style={{ position: 'absolute', left: '-9999px', width: 1, height: 1, opacity: 0 }}
        aria-hidden="true" />

      <button onClick={submit} disabled={!ready || submitting} style={{
        width: '100%', padding: '14px', marginTop: 18,
        background: (!ready || submitting) ? theme.inkMute : theme.accent,
        color: theme.paper, border: 'none',
        fontFamily: theme.fonts.mono, fontSize: 11, letterSpacing: '0.16em', textTransform: 'uppercase',
        cursor: (!ready || submitting) ? 'not-allowed' : 'pointer',
      }}>{submitting ? '… Sending' : '†   Send to the pastor   †'}</button>

      {err && (
        <div style={{ fontFamily: theme.fonts.body, fontStyle: 'italic', fontSize: 12, color: theme.accent, marginTop: 10, textAlign: 'center' }}>
          {err}
        </div>
      )}

      <div style={{ ...smallCaps(theme, 8), color: theme.inkMute, textAlign: 'center', marginTop: 12 }}>
        Held in confidence.
      </div>
    </div>
  );
}

// ─────────────────────────────────────────────────────────────
// EVENTS — calendar of feasts & fellowship
// ─────────────────────────────────────────────────────────────
// Heuristic categorization based on event title — used to color the
// left rule and label each card. Pure visual nicety; doesn't affect data.
// Order matters: more specific patterns first (e.g., "sunday school" must
// match before "school" would catch on the children pattern).
function categorizeEvent(title) {
  const t = (title || '').toLowerCase();
  if (/(christmas|easter|pentecost|advent|lent|epiphany|trinity|ash wednesday|good friday|maundy|all saints|reformation|christ the king|reign of christ)/i.test(t)) return 'feast';
  if (/(confirmation|baptism|communion|eucharist|lord'?s supper)/i.test(t)) return 'sacrament';
  if (/(worship|service|mass|liturgy)/i.test(t)) return 'worship';
  if (/(sunday school|sunday-school|bible study|book club|catechism|class|study)/i.test(t)) return 'study';
  if (/(rehearsal|practice|choir|hymn)/i.test(t)) return 'rehearsal';
  if (/(soup|food bank|outreach|mission|service project|volunteer|backpack)/i.test(t)) return 'mission';
  if (/(vbs|kids|children|youth|teen|graduation)/i.test(t)) return 'children';
  if (/(fellowship|coffee|brunch|potluck|reunion|dinner|breakfast|supper|picnic|meal)/i.test(t)) return 'fellowship';
  return 'event';
}

// Format a JS Date into the screen's tiny day-of-month / day-of-week pair,
// rendered in the church's local timezone (Central — same as iCloud feed).
function formatEventDate(iso, allDay) {
  const d = new Date(iso);
  const tz = 'America/Chicago';
  return {
    d: d.toLocaleDateString('en-US', { day: '2-digit', timeZone: tz }),
    day: d.toLocaleDateString('en-US', { weekday: 'short', timeZone: tz }),
    monthKey: d.toLocaleDateString('en-US', { month: 'long', year: 'numeric', timeZone: tz }),
    monthName: d.toLocaleDateString('en-US', { month: 'long', timeZone: tz }),
    year: d.toLocaleDateString('en-US', { year: 'numeric', timeZone: tz }),
    time: allDay ? '' : d.toLocaleTimeString('en-US', { hour: 'numeric', minute: '2-digit', timeZone: tz }).replace(' ', '').toLowerCase(),
  };
}

// Events that show up every single Sunday and would otherwise flood the
// "Feasts & Fellowship" page. The /sunday page covers the regular
// Sunday rhythm; this page is for specials. Match is case-insensitive
// and trim-tolerant.
const ROUTINE_WEEKLY_TITLES = [
  'sunday school',
  'monticello worship',
  'worship',
  'coffee fellowship',
];

function isRoutineWeekly(title) {
  if (!title) return false;
  const t = title.trim().toLowerCase();
  return ROUTINE_WEEKLY_TITLES.includes(t);
}

// Group a flat array of API events into the {name, items} month buckets
// the existing render block consumes — minimal change to the JSX below.
function groupByMonth(events) {
  const buckets = new Map();
  for (const ev of events) {
    const f = formatEventDate(ev.start, ev.allDay);
    const key = f.monthKey;
    if (!buckets.has(key)) {
      buckets.set(key, { name: f.monthName, year: f.year, items: [] });
    }
    const subParts = [];
    if (f.time) subParts.push(f.time);
    if (ev.location) subParts.push(ev.location.split(',')[0]); // first line of location only
    // Prefer the API-supplied category (which comes from a #hashtag in the
    // iCal notes — open-ended, so any tag the pastor uses becomes the cat).
    // Fall back to title-based heuristics for legacy events that aren't
    // tagged yet. Final fallback: 'event' catchall.
    const apiCat = ev.category && ev.category !== 'event' ? ev.category : null;
    const cat = apiCat || categorizeEvent(ev.title);
    buckets.get(key).items.push({
      d: f.d,
      day: f.day,
      t: ev.title,
      sub: subParts.join(' · '),
      cat,
    });
  }
  return Array.from(buckets.values());
}

function EventsScreen({ theme, onBack }) {
  const [state, setState] = React.useState({ status: 'loading', months: [], updated: null, error: null });

  React.useEffect(() => {
    let cancelled = false;
    fetch('/api/events')
      .then(r => r.ok ? r.json() : Promise.reject(new Error('HTTP ' + r.status)))
      .then(data => {
        if (cancelled) return;
        // Show the next occurrence of each routine Sunday-morning event
        // exactly once (so visitors see the regular rhythm), plus every
        // special / one-off event. Events from the API are already
        // sorted chronologically, so the first match is always next.
        // Show only the FIRST upcoming occurrence of each recurring event,
        // plus every one-off event. Events from the same recurring series
        // share a UID, so we dedupe by uid (with a title-based fallback for
        // events lacking a uid). Non-recurring events have unique uids and
        // are unaffected.
        const seenUid   = new Set();
        const seenTitle = new Set(); // fallback when uid is missing
        const filtered = (data.events || []).filter(ev => {
          const key = ev.uid || ('title:' + (ev.title || '').trim().toLowerCase());
          const set = ev.uid ? seenUid : seenTitle;
          if (set.has(key)) return false;
          set.add(key);
          return true;
        });
        const months = groupByMonth(filtered);
        setState({ status: months.length ? 'ok' : 'empty', months, updated: data.updated, error: null });
      })
      .catch(err => {
        if (cancelled) return;
        setState({ status: 'error', months: [], updated: null, error: String(err.message || err) });
      });
    return () => { cancelled = true; };
  }, []);

  const months = state.months;
  // Color for the left rule + label of each event card. The five user-
  // facing categories (worship/fellowship/celebration/study/outreach) plus
  // the legacy title-heuristic categories (feast/sacrament/etc.) are
  // mapped explicitly. Anything else — a brand-new tag the pastor coined
  // in iCloud last week — falls through to gold (the church's accent),
  // which keeps unknown tags looking dignified.
  const catColor = (c) => ({
    feast:       theme.gold,
    sacrament:   theme.accent,
    worship:     theme.gold,
    fellowship:  theme.accent,
    celebration: theme.gold,
    study:       theme.inkSoft,
    outreach:    theme.accent,
    rehearsal:   theme.inkMute,
    mission:     theme.gold,
    children:    theme.gold,
    event:       theme.inkMute,
  }[c] || theme.gold);

  return (
    <div style={{ background: theme.bg, color: theme.ink, paddingBottom: 60 }} className="paper-grain">
      <SeasonRibbon theme={theme} />

      <div style={{ padding: '22px 22px 16px', background: theme.paper, borderBottom: `1px solid ${theme.rule}` }}>
        <button onClick={onBack} style={{ background: 'transparent', border: 'none', cursor: 'pointer', ...smallCaps(theme, 9), color: theme.inkMute, padding: 0, marginBottom: 12 }}>‹ &nbsp; Back to index</button>

        <div style={{ ...smallCaps(theme, 9), color: theme.accent, marginBottom: 8 }}>Calendar and Events</div>
        <h1 style={{ fontFamily: theme.fonts.display, fontWeight: 500, fontSize: 36, lineHeight: 0.98, margin: 0, color: theme.ink }}>
          Feasts <span style={{ fontStyle: 'italic', color: theme.accent }}>& </span>Fellowship
        </h1>
      </div>

      {state.status === 'loading' && (
        <div style={{ padding: '40px 22px', textAlign: 'center', fontFamily: theme.fonts.body, fontStyle: 'italic', color: theme.inkMute }}>
          Reading the calendar…
        </div>
      )}

      {state.status === 'empty' && (
        <div style={{ padding: '40px 22px', textAlign: 'center' }}>
          <div style={{ fontFamily: theme.fonts.display, fontStyle: 'italic', fontSize: 18, color: theme.ink }}>The calendar is quiet for now.</div>
          <div style={{ fontFamily: theme.fonts.body, fontSize: 13, color: theme.inkSoft, marginTop: 8, lineHeight: 1.5 }}>
            New events appear here automatically once they're added.
          </div>
        </div>
      )}

      {state.status === 'error' && (
        <div style={{ padding: '40px 22px', textAlign: 'center' }}>
          <div style={{ fontFamily: theme.fonts.display, fontStyle: 'italic', fontSize: 18, color: theme.ink }}>The calendar couldn't load just now.</div>
          <div style={{ fontFamily: theme.fonts.body, fontSize: 12, color: theme.inkMute, marginTop: 8, fontStyle: 'italic' }}>
            Please check back in a moment.
          </div>
        </div>
      )}

      {state.status === 'ok' && months.map((m, mi) => (
        <div key={'month-' + m.name + m.year}>
          <div style={{
            padding: '20px 22px 8px', display: 'flex', alignItems: 'baseline', gap: 12,
          }}>
            <div style={{ fontFamily: theme.fonts.display, fontSize: 28, color: theme.ink, fontWeight: 500, fontStyle: 'italic' }}>{m.name}</div>
            <div style={{ flex: 1, height: 1, background: theme.gold, opacity: 0.4 }} />
            <div style={{ ...smallCaps(theme, 9), color: theme.inkMute }}>{m.year} · A.D.</div>
          </div>
          <div style={{ padding: '0 22px' }}>
            {m.items.map((e, i) => (
              <div key={i} style={{
                display: 'flex', gap: 14, padding: '12px 0',
                borderBottom: i < m.items.length - 1 ? `1px solid ${theme.ruleSoft}` : 'none',
              }}>
                <div style={{ width: 40, flexShrink: 0, textAlign: 'center' }}>
                  <div style={{ ...smallCaps(theme, 9), color: theme.inkMute }}>{e.day}</div>
                  <div style={{ fontFamily: theme.fonts.display, fontSize: 24, color: theme.ink, lineHeight: 1, fontWeight: 500 }}>{e.d}</div>
                </div>
                <div style={{ flex: 1, minWidth: 0, borderLeft: `2px solid ${catColor(e.cat)}`, paddingLeft: 14 }}>
                  <div style={{ fontFamily: theme.fonts.display, fontSize: 18, color: theme.ink, fontWeight: 500, lineHeight: 1.2 }}>{e.t}</div>
                  {e.sub && <div style={{ fontFamily: theme.fonts.body, fontSize: 12, color: theme.inkSoft, fontStyle: 'italic', marginTop: 2 }}>{e.sub}</div>}
                  <div style={{ ...smallCaps(theme, 8), color: catColor(e.cat), marginTop: 4 }}>{e.cat}</div>
                </div>
              </div>
            ))}
          </div>
        </div>
      ))}

      {/* Recent from Facebook — same panel as the Visit page, anchored at the bottom */}
      <div style={{ padding: '32px 22px 0' }}>
        <FacebookPageEmbed
          theme={theme}
          href="https://www.facebook.com/monticellounited.methodistchurch"
        />
      </div>
    </div>
  );
}

// ─────────────────────────────────────────────────────────────
// ABOUT — what we believe
// ─────────────────────────────────────────────────────────────
function AboutScreen({ theme, onBack }) {
  // Deep-link target: when ContactScreen sends the visitor here to read the
  // pastor's bio, it sets sessionStorage 'mumc.scrollToPastor' = '1'.
  // Detect the flag on mount, scroll smoothly to the #pastor section,
  // then clear the flag so a normal navigation to About doesn't auto-scroll.
  React.useEffect(() => {
    try {
      if (sessionStorage.getItem('mumc.scrollToPastor') === '1') {
        sessionStorage.removeItem('mumc.scrollToPastor');
        // Wait a tick so the DOM has finished laying out before we measure.
        setTimeout(() => {
          const el = document.getElementById('pastor');
          if (el) el.scrollIntoView({ behavior: 'smooth', block: 'start' });
        }, 80);
      }
    } catch (e) {}
  }, []);

  return (
    <div style={{ background: theme.bg, color: theme.ink, paddingBottom: 60 }} className="paper-grain">
      <SeasonRibbon theme={theme} />

      <div style={{ padding: '22px 22px 0', background: theme.paper }}>
        <button onClick={onBack} style={{ background: 'transparent', border: 'none', cursor: 'pointer', ...smallCaps(theme, 9), color: theme.inkMute, padding: 0, marginBottom: 12 }}>‹ &nbsp; Back to index</button>

        <div style={{ ...smallCaps(theme, 9), color: theme.accent, marginBottom: 8 }}>Our shared life</div>
        <h1 style={{ fontFamily: theme.fonts.display, fontWeight: 500, fontSize: 36, lineHeight: 0.98, margin: 0, color: theme.ink }}>
          What we <span style={{ fontStyle: 'italic', color: theme.accent }}>believe</span>
        </h1>
      </div>

      {/* Opening manuscript paragraph */}
      <div style={{ padding: '24px 22px 0', background: theme.paper }}>
        <div style={{ fontFamily: theme.fonts.display, fontSize: 17, lineHeight: 1.55, color: theme.ink, fontWeight: 400 }}>
          <DropCap letter="W" theme={theme} size={56} />
          e are a parish in the Wesleyan tradition: shaped by Scripture, the historic creeds, the sacraments of the Lord’s Table and Holy Baptism, and a quiet conviction that grace meets us where we are and never leaves us there.
        </div>
      </div>

      {/* The five pillars */}
      <div style={{ padding: '28px 22px 0' }}>
        <MissalRule theme={theme} label="Our pillars" />
      </div>
      <div style={{ padding: '0 22px' }}>
        {[
          { roman: 'i',   t: 'Tradition',  body: 'We stand in a long line of saints — Apostles and Fathers, Reformers and Wesleys — whose faithfulness shapes ours. To pray here is to pray with the whole Church in every age.' },
          { roman: 'ii',  t: 'Scripture',  body: 'The Bible is our authority and our daily bread. We read it together, listen for the Spirit’s voice, and let the Word form who we are becoming.' },
          { roman: 'iii', t: 'Liturgy',    body: 'The ancient pattern of gathering: Word and Table, silence and song, kneeling and standing. Liturgy is the work of the people — what we do, week by week, to be made the body of Christ.' },
          { roman: 'iv',  t: 'Community',  body: 'A family of every age, drawn from Monticello and the wider area we love, and from the world God so loves. We are not consumers of religion; we are members of one another.' },
          { roman: 'v',   t: 'Mission',    body: 'We are sent: to feed, to shelter, to listen, to bear one another’s burdens in Monticello and beyond.' },
        ].map((p, i, arr) => (
          <div key={i} style={{
            display: 'flex', gap: 18, padding: '18px 0',
            borderBottom: i < arr.length - 1 ? `1px solid ${theme.ruleSoft}` : 'none',
          }}>
            <div style={{ ...smallCaps(theme, 14), color: theme.gold, fontWeight: 500, width: 32, flexShrink: 0 }}>{p.roman}</div>
            <div style={{ flex: 1, minWidth: 0 }}>
              <div style={{ fontFamily: theme.fonts.display, fontSize: 22, color: theme.ink, fontWeight: 500, fontStyle: 'italic' }}>{p.t}</div>
              <div style={{ fontFamily: theme.fonts.body, fontSize: 13, color: theme.inkSoft, lineHeight: 1.5, marginTop: 4 }}>{p.body}</div>
            </div>
          </div>
        ))}
      </div>

      {/* The Apostles' Creed callout */}
      <div style={{ padding: '24px 22px 0' }}>
        <MissalRule theme={theme} label="The Apostles' Creed" />
        <div style={{ fontFamily: theme.fonts.display, fontStyle: 'italic', fontSize: 16, lineHeight: 1.6, color: theme.inkSoft, padding: '4px 0', fontWeight: 400 }}>
          I believe in God, the Father Almighty, creator of heaven and earth.<br/><br/>
          I believe in Jesus Christ, his only Son, our Lord, who was conceived by the Holy Spirit, born of the Virgin Mary, suffered under Pontius Pilate, was crucified, died, and was buried; he descended to the dead. On the third day he rose again; he ascended into heaven, he is seated at the right hand of the Father, and he will come again to judge the living and the dead.<br/><br/>
          I believe in the Holy Spirit, the holy catholic Church, the communion of saints, the forgiveness of sins, the resurrection of the body, and the life everlasting.<br/><br/>
          <span style={{ ...smallCaps(theme, 9), color: theme.gold, fontStyle: 'normal', letterSpacing: '0.18em' }}>Amen.</span>
        </div>
      </div>

      {/* Pastor card with full bio. The id="pastor" anchor lets the Contact
          page deep-link here via scrollIntoView. */}
      <div id="pastor" style={{ padding: '24px 22px 0' }}>
        <MissalRule theme={theme} label="Our pastor" />
        <div style={{ padding: '8px 0', display: 'flex', justifyContent: 'center' }}>
          <img src="assets/pastor-jonathan-speegle.jpg" alt="The Rev. Jonathan Speegle, PhD"
               style={{
                 width: '100%', maxWidth: 480, height: 'auto',
                 display: 'block',
                 border: `1px solid ${theme.rule}`,
                 filter: 'sepia(0.08) contrast(1.02) brightness(0.97)',
               }} />
        </div>
        <div style={{ marginTop: 14 }}>
          <div style={{ fontFamily: theme.fonts.display, fontSize: 26, color: theme.ink, fontWeight: 500, lineHeight: 1.15 }}>The Rev. Jonathan Speegle, <span style={{ fontStyle: 'italic' }}>PhD</span></div>
          <div style={{ fontFamily: theme.fonts.display, fontStyle: 'italic', fontSize: 14, color: theme.inkSoft, marginTop: 4 }}>
            Pastor
          </div>

          {/* Three-paragraph bio. Body font for readability across the long form. */}
          <div style={{ marginTop: 20, fontFamily: theme.fonts.body, fontSize: 15, color: theme.ink, lineHeight: 1.7 }}>
            <div style={{ marginBottom: 14 }}>
              Dr. Jonathan Speegle has been a Methodist pastor for nearly thirty years — serving churches across Alabama, Texas, and Mississippi, and now appointed to Monticello United Methodist Church. His passion is preaching the gospel, teaching the Word of God, and magnifying the sacraments — <span style={{ fontStyle: 'italic' }}>biblically, traditionally, liturgically</span>. Visitors can expect preaching that is rooted in Scripture, formed by the Creeds, and shaped by the Wesleyan inheritance of head and heart together — orthodox in conviction, generous in spirit, and always pointed toward the abundant Life Christ promised his Church.
            </div>
            <div style={{ marginBottom: 14 }}>
              He was raised in the Church of the Nazarene in suburban Birmingham, preached his first sermon at sixteen, and became a Methodist while studying at Beeson Divinity School. He holds a BA in religion (with honors) from Samford University, an MDiv from Beeson Divinity School, and a PhD in systematic theology from Baylor University. He has taught at the undergraduate and graduate level both at home and abroad, including a season as Visiting Assistant Professor of Religion at the University of Southern Mississippi. His book <span style={{ fontStyle: 'italic' }}>We Believe in the Communion of the Saints</span> (Parson's Porch Books, 2021) is a labor of love for the Church catholic. Two more are forthcoming: <span style={{ fontStyle: 'italic' }}>We Are Not Alone: The Forgotten Doctrine That Changes Everything About Death, Grief, and Prayer</span>, and <span style={{ fontStyle: 'italic' }}>The Descent of God: Christ's Journey to the Lowest Place and What It Means for the World</span> (Cascade Books).
            </div>
            <div>
              He has been married to Lynn for thirty-nine years. They have a daughter, Tiffany, an attorney, and a granddaughter, Izzy. When he is not at the pulpit or the Lord's Table, he is most often on pilgrimage — Italy, Scotland, the Camino, the Holy Land, Taizé — or in conversation with the saints, living and dead.
            </div>
          </div>

          <a href="mailto:JonathanSpeegle@icloud.com" style={{
            display: 'inline-block', marginTop: 22, padding: '10px 16px',
            background: 'transparent', color: theme.ink,
            border: `1px solid ${theme.ink}`, textDecoration: 'none',
            ...smallCaps(theme, 10), cursor: 'pointer',
          }}>Write to Pastor Jonathan</a>
        </div>
      </div>
      {/* ─── OUR STORY ────────────────────────────────────────────
          A short narrative history of the church (1815→present), the
          theology of the six sanctuary windows, and a small gallery of
          life-of-the-congregation photographs. Photos are filtered to
          a warm parchment tone so they live in the site's visual world.
      */}
      <div style={{ padding: '24px 22px 0' }}>
        <MissalRule theme={theme} label="Our Story" />

        {/* Hero — the present sanctuary */}
        <figure style={{ margin: '14px 0 18px' }}>
          <img src="assets/history/church-exterior.jpg" alt="Monticello United Methodist Church · 130 East Broad Street"
               style={{ width: '100%', height: 'auto', display: 'block', border: `1px solid ${theme.rule}` }} />
          <figcaption style={{ ...smallCaps(theme, 9), color: theme.inkMute, textAlign: 'center', marginTop: 8, lineHeight: 1.5 }}>
            The present sanctuary · 130 East Broad Street · consecrated 1981
          </figcaption>
        </figure>

        {/* Three-paragraph narrative — early church, resilience, present age */}
        <div style={{ fontFamily: theme.fonts.body, fontSize: 15, color: theme.ink, lineHeight: 1.75 }}>
          <div style={{ marginBottom: 14 }}>
            Monticello United Methodist Church was organized in 1815 by the Rev. John Menefee, just five years after the Rev. Hezekiah Shaw became the first Methodist preacher to ride the Lawrence County circuit. The early congregation worshipped in a simple A-frame building until the 1850s, when a brick sanctuary was raised near the spot where Regions Bank stands today — spacious, well-built, padded pews, balcony, the gathering place of the whole town. In 1882 a tornado leveled it.
          </div>

          {/* The first sanctuary (1815) — watercolor by Adrianna Ross, 2015 */}
          <figure style={{ margin: '18px 0' }}>
            <img src="assets/history/first-sanctuary.jpg" alt="The first sanctuary, a small wooden church, c. 1815"
                 loading="lazy"
                 style={{ width: '100%', height: 'auto', display: 'block', border: `1px solid ${theme.rule}` }} />
            <figcaption style={{ ...smallCaps(theme, 9), color: theme.inkMute, textAlign: 'center', marginTop: 8, lineHeight: 1.5 }}>
              The first sanctuary · c. 1815 · watercolor by Adrianna Ross
            </figcaption>
          </figure>

          <div style={{ marginBottom: 14 }}>
            Members met in private homes and the Lawrence County Courthouse for fifteen years. In 1897 the congregation purchased the present site at 130 East Broad Street, and the new building was dedicated in 1898. It served the church for eighty-two years, with additions and renovations along the way: a new sanctuary and Sunday-school rooms in 1950 under the Rev. Warren E. Pittman, the present parsonage built in 1958 and dedicated in 1962, a two-story education wing added in 1974 to accommodate growth from the St. Regis Paper Company era. On January 11, 1980, fire destroyed the entire church.
          </div>

          {/* The 1898 sanctuary — watercolor */}
          <figure style={{ margin: '18px 0' }}>
            <img src="assets/history/second-sanctuary.jpg" alt="The 1898 sanctuary, used until the fire of 1980"
                 loading="lazy"
                 style={{ width: '100%', height: 'auto', display: 'block', border: `1px solid ${theme.rule}` }} />
            <figcaption style={{ ...smallCaps(theme, 9), color: theme.inkMute, textAlign: 'center', marginTop: 8, lineHeight: 1.5 }}>
              The 1898 sanctuary · used until 1980 · watercolor by Adrianna Ross
            </figcaption>
          </figure>

          {/* Photograph of fire damage to the stained glass window, January
              1980. Inset into a framed mat so the portrait photograph
              doesn't overwhelm the column the way the watercolors (which
              are landscape-oriented) do — like a framed photograph hung in
              a memorial corridor rather than a full-bleed image. */}
          <figure style={{ margin: '24px 0', display: 'flex', justifyContent: 'center' }}>
            <div style={{
              maxWidth: '62%',
              padding: '14px 14px 0',
              background: theme.paper,
              border: `1px solid ${theme.rule}`,
              boxShadow: '0 2px 10px rgba(60,40,20,0.10)',
            }}>
              <img src="assets/history/fire-1980.jpg" alt="The arched stained-glass window scorched by the fire of January 11, 1980"
                   loading="lazy"
                   style={{ width: '100%', height: 'auto', display: 'block', border: `1px solid ${theme.rule}` }} />
              <figcaption style={{ ...smallCaps(theme, 9), color: theme.inkMute, textAlign: 'center', margin: '10px 0 12px', lineHeight: 1.5 }}>
                After the fire<br/>January 11, 1980
              </figcaption>
            </div>
          </figure>

          <div style={{ marginBottom: 14 }}>
            The congregation gathered in the Hartman Wilson Funeral Home Chapel and in members' homes through the long months of rebuilding. The Rev. Ronald J. Barham was pastor through that wilderness. The present sanctuary, the old steeple bell rescued from the ashes and rung again at its dedication, was consecrated on August 23, 1981. In the years since, generations of pastors and members have continued the ordinary work — preaching, teaching, baptizing, burying, gathering at the table.
          </div>

          {/* The present sanctuary — watercolor */}
          <figure style={{ margin: '18px 0' }}>
            <img src="assets/history/present-sanctuary-watercolor.jpg" alt="The present sanctuary, consecrated 1981"
                 loading="lazy"
                 style={{ width: '100%', height: 'auto', display: 'block', border: `1px solid ${theme.rule}` }} />
            <figcaption style={{ ...smallCaps(theme, 9), color: theme.inkMute, textAlign: 'center', marginTop: 8, lineHeight: 1.5 }}>
              The present sanctuary · consecrated 1981 · watercolor by Adrianna Ross
            </figcaption>
          </figure>

          <div>
            After more than two centuries — through tornado, fire, and the ordinary patience of generations — the church has learned the lesson John Wesley first preached: the Church is not a building but a people. <span style={{ fontStyle: 'italic' }}>The people called Methodists.</span>
          </div>
        </div>
      </div>

      {/* ─── THE SANCTUARY WINDOWS ──────────────────────────────── */}
      <div style={{ padding: '32px 22px 0' }}>
        <MissalRule theme={theme} label="The Sanctuary Windows" />

        {/* Altar — Word and sacrament together: Bible open, brass cross,
            candles, "THIS DO IN REMEMBRANCE OF ME" carved across the
            communion table. Sets the scene for the gospel-in-glass below. */}
        <figure style={{ margin: '14px 0 18px' }}>
          <img src="assets/history/altar.jpg" alt='The altar with the inscription "This do in remembrance of me"'
               loading="lazy"
               style={{ width: '100%', height: 'auto', display: 'block', border: `1px solid ${theme.rule}` }} />
        </figure>

        <div style={{ fontFamily: theme.fonts.body, fontSize: 14, color: theme.inkSoft, lineHeight: 1.65, fontStyle: 'italic', marginTop: 10, marginBottom: 18, textAlign: 'center' }}>
          Above the chancel, the Light of the World stands at the door — and around the sanctuary, six windows tell the gospel in colored glass.
        </div>

        {/* Window cards — Light of the World first (the great chancel window
            after Holman Hunt), then the six round windows in narrative order
            through salvation history. */}
        {[
          {
            src: 'assets/history/light_of_the_world.jpg',
            name: 'The Light of the World',
            theology: 'The great window above the chancel renders William Holman Hunt\'s 1853 painting *The Light of the World* — Christ standing at a wooden door overgrown with brambles and night-vines. The door has no handle on the outside; it can only be opened from within. In his right hand he holds a lantern; on his head the crown of thorns has been replaced with a kingly crown. The image is drawn from his own words in Revelation: <span style="font-style: italic">Behold, I stand at the door, and knock. If any man hear my voice, and open the door, I will come in to him, and will sup with him, and he with me.</span> The door is the door of every heart, and Christ never breaks it down. He waits to be welcomed.',
          },
          {
            src: 'assets/history/nativity.jpg',
            name: 'The Nativity',
            theology: 'The wooden manger holds the chi-rho monogram — the first two Greek letters of *Christos* (Χριστός), Christ — illuminated by a star. Where the world\'s eyes saw a feeding trough for animals, the eye of faith sees the throne of the Word made flesh, lying among us as a child.',
          },
          {
            src: 'assets/history/baptism_dove.jpg',
            name: 'The Baptism of the Lord',
            theology: 'The dove descends in shafts of golden light upon the cross with its baptismal shroud, standing in the waters of the Jordan. Three things converge in this window — the voice of the Father, the descent of the Spirit, and the obedience of the Son going down into the water with sinners. The Trinity made visible at the river, sanctifying the waters of every baptism that would follow.',
          },
          {
            src: 'assets/history/loaves_and_fishes.jpg',
            name: 'Loaves and Fishes',
            theology: 'A basket holds five barley loaves and two small fish, and from the bread rises a cross. This is the miracle that fed five thousand on a Galilean hillside — and the foreshadow of every Eucharist. Christ takes ordinary food, blesses it, breaks it, gives it to a hungry world. The cross atop the loaves tells us how he is finally given: as the Bread of Life, broken for the life of the world.',
          },
          {
            src: 'assets/history/three_crosses.jpg',
            name: 'The Three Crosses',
            theology: 'On Golgotha three crosses rise — the Christ at the center, two thieves at his sides. The titulus reads *INRI*: Iesus Nazarenus Rex Iudaeorum, Jesus of Nazareth, King of the Jews — the charge nailed above his head, and the truest title he bears. The lightning remembers the darkness from the sixth hour to the ninth, and the rending of the temple veil. Every Christian\'s first lesson and every saint\'s last prayer: <span style="font-style: italic">Father, into your hands I commend my spirit.</span>',
          },
          {
            src: 'assets/history/resurrection.jpg',
            name: 'The Resurrection',
            theology: 'The tomb is empty, the stone rolled aside, and the risen Christ\'s banner of victory — white cross on red — stands planted in the earth. Behind it, the sun rises on the Eighth Day, the day no week contains, when death itself was undone. The window is a window into Easter, and into the day for which every Sunday is practice.',
          },
          {
            src: 'assets/history/chi_rho.jpg',
            name: 'Chi-Rho and the Net',
            theology: 'The Chi-Rho — Christ\'s monogram in golden lines — rises behind a fishing net cast wide. From the day the risen Christ called Peter from the boat, the Church has been a casting net pulled through the deep, gathering the world for the Kingdom. The window holds together what Pentecost joined: the name of Christ above all names, and the apostolic mission to draw every soul into the great catch of God.',
          },
        ].map((w, i) => (
          <div key={i} style={{
            marginTop: 22, padding: 18,
            background: theme.paper, border: `1px solid ${theme.gold}55`,
          }}>
            <img src={w.src} alt={w.name}
                 style={{
                   width: '100%', maxWidth: 380, height: 'auto',
                   display: 'block', margin: '0 auto 14px',
                   border: `1px solid ${theme.rule}`,
                 }} />
            <div style={{ fontFamily: theme.fonts.display, fontSize: 22, color: theme.ink, fontWeight: 500, fontStyle: 'italic', textAlign: 'center', marginBottom: 10 }}>
              {w.name}
            </div>
            <div style={{ fontFamily: theme.fonts.body, fontSize: 14, color: theme.inkSoft, lineHeight: 1.7 }}
                 dangerouslySetInnerHTML={{ __html: w.theology.replace(/\*([^*]+)\*/g, '<em>$1</em>') }} />
          </div>
        ))}
      </div>

      {/* ─── LIFE OF THE CONGREGATION ─────────────────────────── */}
      <div style={{ padding: '32px 22px 0' }}>
        <MissalRule theme={theme} label="Life of the Congregation" />
        <div style={{ fontFamily: theme.fonts.body, fontSize: 14, color: theme.inkSoft, lineHeight: 1.65, fontStyle: 'italic', marginTop: 10, marginBottom: 18, textAlign: 'center' }}>
          The work of the Church is not only what happens at the altar but what happens around the table after.
        </div>

        {[
          { src: 'assets/history/congregation-mardi-gras.jpg', caption: 'Mardi Gras fellowship · the United Methodist Women' },
          { src: 'assets/history/congregation-fellowship.jpg', caption: 'Teacher appreciation · hospitality at the table' },
          { src: 'assets/history/congregation-children.jpg',   caption: "Children's craft · the next generation gathering" },
          { src: 'assets/history/congregation-blessing-of-pets.jpg', caption: 'Blessing of the Pets · Saint Francis tide' },
          { src: 'assets/history/congregation-trunk-or-treat.jpg',   caption: 'Trunk-or-Treat · welcoming the neighborhood' },
        ].map((p, i) => (
          <figure key={i} style={{ margin: '0 0 18px' }}>
            <img src={p.src} alt={p.caption}
                 style={{ width: '100%', height: 'auto', display: 'block', border: `1px solid ${theme.rule}` }} />
            <figcaption style={{ ...smallCaps(theme, 9), color: theme.inkMute, textAlign: 'center', marginTop: 8, lineHeight: 1.5 }}>
              {p.caption}
            </figcaption>
          </figure>
        ))}
      </div>

    </div>
  );
}

// ─────────────────────────────────────────────────────────────
// DAILY OFFICE — six fixed-hour prayer services, each with its
// versicle/response, psalm, canticle, the day's Collect, and a
// closing collect appropriate to the time of day.
// ─────────────────────────────────────────────────────────────
// Generic Bible-passage hook — used for the rotating psalm, the daily
// Old Testament reading, the daily Gospel, and the Sunday Gospel. Fetches
// from bible-api.com (free, CORS-enabled, World English Bible) the first
// time, caches in localStorage by citation. Returns
// { status, ref, verses } where verses is [{n, text}, ...].
function useBiblePassage(citation, cacheKeyPrefix = 'mumc.bible') {
  const [state, setState] = React.useState({ status: 'idle', verses: null, ref: null });
  React.useEffect(() => {
    if (!citation) {
      setState({ status: 'idle', verses: null, ref: null });
      return;
    }
    const clean = String(citation).replace(/—/g, '-').replace(/–/g, '-').replace(/\s*:\s*/g, ':').trim();
    const cacheKey = `${cacheKeyPrefix}.${clean}`;
    try {
      const cached = localStorage.getItem(cacheKey);
      if (cached) {
        const parsed = JSON.parse(cached);
        setState({ status: 'ok', verses: parsed.verses, ref: parsed.ref || clean });
        return;
      }
    } catch (e) {}
    setState({ status: 'loading', verses: null, ref: clean });
    fetch('https://bible-api.com/' + encodeURIComponent(clean) + '?translation=web')
      .then(r => r.ok ? r.json() : Promise.reject(new Error('HTTP ' + r.status)))
      .then(data => {
        if (!data || !data.verses) throw new Error('no verses');
        const verses = data.verses.map(v => ({ n: v.verse, text: (v.text || '').trim() }));
        const ref = data.reference || clean;
        setState({ status: 'ok', verses, ref });
        try { localStorage.setItem(cacheKey, JSON.stringify({ verses, ref })); } catch (e) {}
      })
      .catch(() => setState({ status: 'error', verses: null, ref: clean }));
  }, [citation, cacheKeyPrefix]);
  return state;
}

function OfficeScreen({ theme, onBack }) {
  // Default to whichever office is the "current" one based on time of day.
  const initial = (typeof currentOffice === 'function') ? currentOffice() : OFFICES[0];
  const [selected, setSelected] = React.useState(initial.id);
  const office  = OFFICES.find(o => o.id === selected) || OFFICES[0];
  const content = OFFICE_CONTENT[selected] || {};
  const canticle = (typeof CANTICLES !== 'undefined') ? CANTICLES[content.canticleId] : null;
  const closingCollect = (typeof OFFICE_COLLECTS !== 'undefined') ? OFFICE_COLLECTS[content.collectKey] : null;

  // ── Today's "liturgical day" drives the daily rotation ─────────
  // The new day rolls over at 4 AM local, not midnight. Many people pray
  // Compline late or just before bed; if they're awake at 1 or 2 AM the
  // office should still show YESTERDAY's psalm, lectionary, and saint
  // until early-morning hours when the next day's Lauds approaches.
  const today = new Date(Date.now() - 4 * 60 * 60 * 1000);

  // ── Today's saint commemoration (when there is one) ─────────────
  const saint = (typeof saintToday === 'function') ? saintToday(today) : null;

  // ── Rotating psalm: 7-day cycle, different psalm per office per day
  // — falls back to the legacy fixed psalm if the rotation helper isn't
  // loaded yet. Local PSALMS dict is checked first; if absent, we fetch
  // from bible-api.com. ────────────────────────────────────────────
  const psalmCitation = (typeof getOfficePsalmCitation === 'function')
    ? getOfficePsalmCitation(selected, today)
    : null;
  const localPsalm = (typeof PSALMS !== 'undefined') ? PSALMS[content.psalmId] : null;
  const psalmFromApi = useBiblePassage(psalmCitation, 'mumc.psalter');

  // Pick which psalm representation to render. If we have a citation that
  // matches the local PSALMS dict's hand-typed KJV text, prefer it (faster
  // load, beautiful formatting). Otherwise use the bible-api.com fetch
  // (WEB translation). The two paths are unified in the render block.
  const psalm = psalmFromApi.status === 'ok'
    ? { ref: psalmFromApi.ref, verses: psalmFromApi.verses, source: 'api' }
    : (localPsalm
       ? { ref: localPsalm.ref, title: localPsalm.title,
           verses: localPsalm.verses.map((t, i) => ({ n: i + 1, text: t })),
           source: 'local' }
       : null);
  const psalmLoading = psalmFromApi.status === 'loading' && !localPsalm;

  // ── Today's readings (one Old Testament + one Gospel per day) ──
  // On Mon-Sat the citations come from DAILY_OFFICE_LECTIONARY.
  // On Sunday that table returns null, so we substitute the day's RCL
  // Sunday readings so the office still has scripture appointed for
  // today — using the SAME single-pair UI, never two Gospels at once.
  let dayCollect = null;
  let rclSunday = null;
  try {
    if (typeof getCollect === 'function') dayCollect = getCollect();
    if (typeof getRCLToday === 'function') rclSunday = getRCLToday();
  } catch (e) {}

  const dailyTable = (typeof getDailyOfficeReadings === 'function')
    ? getDailyOfficeReadings(today)
    : null;
  const dailyReadings = dailyTable
    || (rclSunday && rclSunday.readings ? {
         ot:     rclSunday.readings.first,
         gospel: rclSunday.readings.gospel,
         theme:  rclSunday.name,
       } : null);

  const dailyOt     = useBiblePassage(dailyReadings ? dailyReadings.ot     : null, 'mumc.daily-ot');
  const dailyGospel = useBiblePassage(dailyReadings ? dailyReadings.gospel : null, 'mumc.daily-gospel');

  // Live "next office" hint
  const nxt = (typeof nextOffice === 'function') ? nextOffice() : null;
  const nextHint = nxt
    ? (nxt.status === 'tomorrow'
        ? `Next: ${nxt.name} — tomorrow at ${String(nxt.hour).padStart(2,'0')}:${String(nxt.minute).padStart(2,'0')}`
        : `Next: ${nxt.name} in ${Math.floor(nxt.when/60)}h ${nxt.when % 60}m`)
    : '';

  return (
    <div style={{ background: theme.bg, color: theme.ink, paddingBottom: 60 }} className="paper-grain">
      <SeasonRibbon theme={theme} />

      <div style={{ padding: '22px 22px 16px', background: theme.paper, borderBottom: `1px solid ${theme.rule}` }}>
        <button onClick={onBack} style={{ background: 'transparent', border: 'none', cursor: 'pointer', ...smallCaps(theme, 9), color: theme.inkMute, padding: 0, marginBottom: 12 }}>‹ &nbsp; Back to index</button>

        <div style={{ ...smallCaps(theme, 9), color: theme.accent, marginBottom: 8 }}>The Daily Office</div>
        <h1 style={{ fontFamily: theme.fonts.display, fontWeight: 500, fontSize: 36, lineHeight: 0.98, margin: 0, color: theme.ink }}>
          The Hours <span style={{ fontStyle: 'italic', color: theme.accent }}>of Prayer</span>
        </h1>
        <p style={{ fontFamily: theme.fonts.display, fontStyle: 'italic', fontSize: 14, color: theme.inkSoft, marginTop: 8, lineHeight: 1.4 }}>
          A rhythm older than the church — fixed hours when, all over the world, the body of Christ stops to pray.
        </p>
      </div>

      {/* Today's saint commemoration — shown when there's a saint on the
          calendar today. Sits between the header and the office picker so
          a visitor opening Lauds or Vespers sees it as part of the page. */}
      {saint && (
        <div style={{
          padding: '16px 22px',
          background: theme.bgAlt,
          borderBottom: `1px solid ${theme.rule}`,
          textAlign: 'center',
        }}>
          <div style={{ ...smallCaps(theme, 9), color: theme.gold, marginBottom: 4 }}>
            Today we remember
          </div>
          <div style={{
            fontFamily: theme.fonts.display, fontSize: 19, fontStyle: 'italic',
            color: theme.ink, lineHeight: 1.3,
          }}>
            {saint.link ? (
              <a href={saint.link} target="_blank" rel="noopener noreferrer" style={{
                color: theme.ink, textDecoration: 'none',
                borderBottom: `1px dotted ${theme.rule}`,
              }}>{saint.name}</a>
            ) : saint.name}
          </div>
          {saint.kind && (
            <div style={{ ...smallCaps(theme, 8), color: theme.inkMute, marginTop: 4 }}>
              {saint.kind}
            </div>
          )}
        </div>
      )}

      {/* Office picker */}
      <div style={{ padding: '18px 22px 0' }}>
        <div style={{ display: 'flex', flexWrap: 'wrap', gap: 8 }}>
          {OFFICES.map(o => {
            const isActive = o.id === selected;
            return (
              <button key={o.id} onClick={() => setSelected(o.id)} style={{
                background: isActive ? theme.ink : 'transparent',
                color: isActive ? theme.paper : theme.ink,
                border: `1px solid ${isActive ? theme.ink : theme.rule}`,
                padding: '8px 12px',
                fontFamily: theme.fonts.mono, fontSize: 9, letterSpacing: '0.18em', textTransform: 'uppercase',
                cursor: 'pointer',
              }}>
                {o.name}
              </button>
            );
          })}
        </div>
        {nextHint && (
          <div style={{ ...smallCaps(theme, 9), color: theme.inkMute, marginTop: 10 }}>
            {nextHint}
          </div>
        )}
      </div>

      {/* The chosen office's liturgy */}
      <div style={{ padding: '22px 22px 0' }}>
        <div style={{ ...smallCaps(theme, 9), color: theme.accent, marginBottom: 4 }}>
          {office.name} · {office.alt} · {String(office.hour).padStart(2,'0')}:{String(office.minute).padStart(2,'0')}
        </div>

        {/* Opening versicle / response */}
        <MissalRule theme={theme} label="Opening" />
        <div style={{ fontFamily: theme.fonts.display, fontSize: 18, fontStyle: 'italic', color: theme.ink, lineHeight: 1.45, marginBottom: 6 }}>
          ℣. {content.versicle}
        </div>
        <div style={{ fontFamily: theme.fonts.display, fontSize: 18, fontStyle: 'italic', color: theme.accent, lineHeight: 1.45, marginBottom: 14 }}>
          ℟. {content.response}
        </div>

        {/* Hour-appropriate prayer (morning / noonday / evening / close of day) */}
        {closingCollect && (
          <>
            <div style={{ marginTop: 22 }}>
              <MissalRule theme={theme} label={`A Prayer for ${content.collectKey === 'morning' ? 'the Morning'
                : content.collectKey === 'noonday' ? 'Noonday'
                : content.collectKey === 'evening' ? 'the Evening'
                : 'the Close of the Day'}`} />
            </div>
            <div style={{ fontFamily: theme.fonts.display, fontSize: 16, fontStyle: 'italic', color: theme.ink, lineHeight: 1.55 }}>
              {closingCollect}
            </div>
          </>
        )}

        {/* Psalm — rotating per day-of-week. Local KJV text when available
            (fast and beautifully formatted), bible-api.com WEB fallback
            for any psalm not in the local dict. */}
        <div style={{ marginTop: 22 }} />
        <MissalRule theme={theme} label="The Psalm" />
        {psalmLoading && (
          <div style={{ fontFamily: theme.fonts.body, fontStyle: 'italic', fontSize: 13, color: theme.inkMute }}>
            Reading the psalm…
          </div>
        )}
        {psalm ? (
          <>
            <div style={{ ...smallCaps(theme, 9), color: theme.accent, marginBottom: 4 }}>{psalm.ref}</div>
            {psalm.title && (
              <div style={{ ...smallCaps(theme, 8), color: theme.inkMute, marginBottom: 12, fontStyle: 'italic' }}>{psalm.title}</div>
            )}
            <div style={{ fontFamily: theme.fonts.display, fontSize: 16, color: theme.ink, lineHeight: 1.6 }}>
              {psalm.verses.map((v, i) => (
                <div key={i} style={{ marginBottom: 8, display: 'flex', gap: 10 }}>
                  <span style={{ ...smallCaps(theme, 9), color: theme.gold, flexShrink: 0, minWidth: 18, textAlign: 'right' }}>{v.n || (i + 1)}</span>
                  <span style={{ flex: 1 }}>{v.text}</span>
                </div>
              ))}
            </div>

            {/* Gloria Patri — said after every psalm in the daily office. */}
            <div style={{
              marginTop: 16, padding: '14px 16px',
              background: theme.bgAlt,
              borderLeft: `2px solid ${theme.gold}`,
              fontFamily: theme.fonts.display, fontStyle: 'italic',
              fontSize: 15, color: theme.inkSoft, lineHeight: 1.55,
            }}>
              <div style={{ ...smallCaps(theme, 8), color: theme.gold, marginBottom: 6, fontStyle: 'normal' }}>
                Gloria Patri
              </div>
              Glory be to the Father, and to the Son, and to the Holy Ghost; <br/>
              as it was in the beginning, is now, and ever shall be: world without end.{' '}
              <span style={{ ...smallCaps(theme, 10), color: theme.gold, fontStyle: 'normal' }}>Amen.</span>
            </div>
          </>
        ) : (!psalmLoading && (
          <div style={{ fontFamily: theme.fonts.body, fontStyle: 'italic', fontSize: 13, color: theme.inkMute }}>
            (The psalm could not be loaded — open the Bible app to read {psalmCitation || 'the appointed psalm'}.)
          </div>
        ))}

        {/* ── Today's daily-office readings (Mon-Sat) ─────────────────
            One Old Testament + one Gospel passage from the parish reading
            plan. Citations in liturgical.jsx → DAILY_OFFICE_LECTIONARY. */}
        {dailyReadings && (
          <>
            <div style={{ marginTop: 26 }}>
              <MissalRule theme={theme} label="Today's Reading" />
            </div>
            {dailyReadings.theme && (
              <div style={{ fontFamily: theme.fonts.display, fontStyle: 'italic', fontSize: 14, color: theme.inkSoft, marginBottom: 14, textAlign: 'center' }}>
                {dailyReadings.theme}
              </div>
            )}

            {/* Old Testament */}
            <div style={{ ...smallCaps(theme, 9), color: theme.accent, marginBottom: 4 }}>
              From the Old Testament · {dailyOt.ref || dailyReadings.ot}
            </div>
            {dailyOt.status === 'loading' && (
              <div style={{ fontFamily: theme.fonts.body, fontStyle: 'italic', fontSize: 13, color: theme.inkMute }}>Reading the lesson…</div>
            )}
            {dailyOt.status === 'ok' && (
              <div style={{ fontFamily: theme.fonts.display, fontSize: 15, color: theme.ink, lineHeight: 1.6, marginBottom: 18 }}>
                {dailyOt.verses.map(v => (
                  <span key={v.n}>
                    <sup style={{ ...smallCaps(theme, 8), color: theme.gold, marginRight: 4 }}>{v.n}</sup>
                    {v.text}{' '}
                  </span>
                ))}
              </div>
            )}

            {/* Gospel */}
            <div style={{ ...smallCaps(theme, 9), color: theme.accent, marginBottom: 4, marginTop: 10 }}>
              From the Holy Gospel · {dailyGospel.ref || dailyReadings.gospel}
            </div>
            {dailyGospel.status === 'loading' && (
              <div style={{ fontFamily: theme.fonts.body, fontStyle: 'italic', fontSize: 13, color: theme.inkMute }}>Reading the Gospel…</div>
            )}
            {dailyGospel.status === 'ok' && (
              <div style={{ fontFamily: theme.fonts.display, fontSize: 15, color: theme.ink, lineHeight: 1.6 }}>
                {dailyGospel.verses.map(v => (
                  <span key={v.n}>
                    <sup style={{ ...smallCaps(theme, 8), color: theme.gold, marginRight: 4 }}>{v.n}</sup>
                    {v.text}{' '}
                  </span>
                ))}
              </div>
            )}
          </>
        )}

        {/* (The previous "The Holy Gospel" section that previewed the
            upcoming Sunday's Gospel during the week was removed — it
            duplicated the daily-office Gospel above. Anyone who wants to
            preview next Sunday taps "Read ahead" on the home page.) */}

        {/* Canticle */}
        {canticle && (
          <>
            <div style={{ marginTop: 22 }}>
              <MissalRule theme={theme} label="The Canticle" />
            </div>
            <div style={{ ...smallCaps(theme, 9), color: theme.accent, marginBottom: 6 }}>{canticle.name}</div>
            <div style={{ ...smallCaps(theme, 8), color: theme.inkMute, marginBottom: 12 }}>{canticle.subtitle}</div>
            <div style={{ fontFamily: theme.fonts.display, fontSize: 16, fontStyle: 'italic', color: theme.ink, lineHeight: 1.55 }}>
              {canticle.lines.map((line, i) => (
                <div key={i} style={{ paddingLeft: i % 2 === 1 ? 16 : 0, marginBottom: 4 }}>
                  {line}
                </div>
              ))}
            </div>
          </>
        )}

        {/* The Apostles' Creed — UMC Hymnal #882 (Ecumenical Version): the
            modern English text used by most Methodist, Catholic, Lutheran,
            and Anglican congregations together. Includes the descent line
            ("he descended to the dead") and uses contemporary phrasing
            throughout. The asterisk + footnote is the standard Methodist
            gloss clarifying that 'catholic' here means universal. */}
        <div style={{ marginTop: 22 }}>
          <MissalRule theme={theme} label="The Apostles' Creed" />
        </div>
        <div style={{ fontFamily: theme.fonts.display, fontSize: 16, fontStyle: 'italic', color: theme.ink, lineHeight: 1.55 }}>
          I believe in God, the Father almighty,<br/>
          creator of heaven and earth.<br/>
          <br/>
          I believe in Jesus Christ, his only Son, our Lord,<br/>
          who was conceived by the Holy Spirit,<br/>
          born of the Virgin Mary,<br/>
          suffered under Pontius Pilate,<br/>
          was crucified, died, and was buried;<br/>
          he descended to the dead.<br/>
          On the third day he rose again;<br/>
          he ascended into heaven,<br/>
          is seated at the right hand of the Father,<br/>
          and will come again to judge the living and the dead.<br/>
          <br/>
          I believe in the Holy Spirit,<br/>
          the holy catholic church,<br/>
          the communion of saints,<br/>
          the forgiveness of sins,<br/>
          the resurrection of the body,<br/>
          and the life everlasting.{' '}
          <span style={{ ...smallCaps(theme, 10), color: theme.gold, fontStyle: 'normal' }}>Amen.</span>
        </div>

        {/* The Lord's Prayer — said by all in BCP/Methodist office order, before
            the Collect of the Day. Two blank lines after the Canticle in the
            traditional layout; we render it as flowing italic verse. */}
        <div style={{ marginTop: 22 }}>
          <MissalRule theme={theme} label="The Lord's Prayer" />
        </div>
        <div style={{ fontFamily: theme.fonts.display, fontSize: 16, fontStyle: 'italic', color: theme.ink, lineHeight: 1.55 }}>
          Our Father, who art in heaven,<br/>
          hallowed be thy Name.<br/>
          Thy kingdom come, thy will be done,<br/>
          on earth as it is in heaven.<br/>
          Give us this day our daily bread.<br/>
          And forgive us our trespasses,<br/>
          as we forgive those who trespass against us.<br/>
          And lead us not into temptation,<br/>
          but deliver us from evil.<br/>
          For thine is the kingdom, and the power, and the glory,<br/>
          for ever and ever.{' '}
          <span style={{ ...smallCaps(theme, 10), color: theme.gold, fontStyle: 'normal' }}>Amen.</span>
        </div>

        {/* The day's Collect (RCL) */}
        {dayCollect && dayCollect.text && (
          <>
            <div style={{ marginTop: 22 }}>
              <MissalRule theme={theme} label="The Prayer of the Day" />
            </div>
            {dayCollect.name && (
              <div style={{ ...smallCaps(theme, 9), color: theme.inkMute, marginBottom: 8 }}>{dayCollect.name}</div>
            )}
            <div style={{ fontFamily: theme.fonts.display, fontSize: 16, fontStyle: 'italic', color: theme.ink, lineHeight: 1.55 }}>
              {dayCollect.text} <span style={{ ...smallCaps(theme, 10), color: theme.gold, fontStyle: 'normal' }}>Amen.</span>
            </div>
          </>
        )}

        {/* Dismissal */}
        <div style={{ marginTop: 28, padding: '14px 0', textAlign: 'center', borderTop: `1px solid ${theme.rule}`, borderBottom: `1px solid ${theme.rule}` }}>
          <div style={{ ...smallCaps(theme, 9), color: theme.gold, marginBottom: 6 }}>† &nbsp; Dismissal &nbsp; †</div>
          <div style={{ fontFamily: theme.fonts.display, fontSize: 16, fontStyle: 'italic', color: theme.ink, lineHeight: 1.45 }}>
            Let us bless the Lord. — <span style={{ color: theme.accent }}>Thanks be to God.</span>
          </div>
        </div>
      </div>
    </div>
  );
}

// ─────────────────────────────────────────────────────────────
// CONTACT — two paths: church business via the secretary, pastoral
// care via the pastor. The Visitation card image (a Tenniel-style
// White Rabbit invitation) lives at assets/invitation-to-visitation.png
// and is shown if present; falls back gracefully if missing.
// ─────────────────────────────────────────────────────────────
function ContactScreen({ theme, onBack, onNav }) {
  // Navigate to the About page and scroll to the pastor bio section.
  // sessionStorage flag is read by AboutScreen on mount; cleared after
  // scroll. Uses a small timeout so the new screen has time to render
  // before we try to scrollIntoView the target element.
  const goToBio = () => {
    try { sessionStorage.setItem('mumc.scrollToPastor', '1'); } catch (e) {}
    if (onNav) onNav('about');
  };
  return (
    <div style={{ background: theme.bg, color: theme.ink, paddingBottom: 60 }} className="paper-grain">
      <SeasonRibbon theme={theme} />

      <div style={{ padding: '22px 22px 16px', background: theme.paper, borderBottom: `1px solid ${theme.rule}` }}>
        <button onClick={onBack} style={{ background: 'transparent', border: 'none', cursor: 'pointer', ...smallCaps(theme, 9), color: theme.inkMute, padding: 0, marginBottom: 12 }}>‹ &nbsp; Back to index</button>
        <div style={{ ...smallCaps(theme, 9), color: theme.accent, marginBottom: 8 }}>How to reach us</div>
        <h1 style={{ fontFamily: theme.fonts.display, fontWeight: 500, fontSize: 36, lineHeight: 0.98, margin: 0, color: theme.ink }}>
          Get in <span style={{ fontStyle: 'italic', color: theme.accent }}>touch</span>
        </h1>
        <p style={{ fontFamily: theme.fonts.display, fontStyle: 'italic', fontSize: 14, color: theme.inkSoft, marginTop: 8, lineHeight: 1.4 }}>
          Two doors into the church. Walk through whichever fits.
        </p>
      </div>

      {/* Pastoral care — Dr. Speegle */}
      <div style={{ padding: '28px 22px 0' }}>
        <MissalRule theme={theme} label="For pastoral care" />
        <div style={{ background: theme.paper, padding: '22px 20px', border: `1px solid ${theme.gold}66`, marginTop: 6 }}>
          <div style={{ ...smallCaps(theme, 10), color: theme.gold, textAlign: 'center', marginBottom: 14 }}>
            † &nbsp; Invitation to Visitation &nbsp; †
          </div>
          <img
            src="assets/pastor-avatar.png"
            alt="Dr. Speegle"
            onError={(e) => { e.currentTarget.style.display = 'none'; }}
            style={{
              display: 'block',
              width: 120, height: 120, borderRadius: '50%',
              objectFit: 'cover',
              margin: '0 auto 14px',
              border: `2px solid ${theme.gold}`,
              background: theme.bgAlt,
            }}
          />
          <div style={{ fontFamily: theme.fonts.display, fontSize: 24, color: theme.ink, fontWeight: 500, fontStyle: 'italic', textAlign: 'center', lineHeight: 1.2 }}>
            Dr. Speegle wants to know you better.
          </div>
          <div style={{ fontFamily: theme.fonts.body, fontSize: 15, color: theme.inkSoft, lineHeight: 1.7, textAlign: 'center', marginTop: 16 }}>
            <a href="tel:+16628897000" style={{ color: theme.accent, textDecoration: 'none', borderBottom: `1px dotted ${theme.accent}` }}>Call or text 662 / 889 / 7000</a><br/>
            or e-mail <a href="mailto:JonathanSpeegle@icloud.com" style={{ color: theme.accent, textDecoration: 'none', borderBottom: `1px dotted ${theme.accent}` }}>JonathanSpeegle@icloud.com</a>
          </div>
          <div style={{ fontFamily: theme.fonts.display, fontStyle: 'italic', fontSize: 14, color: theme.inkSoft, lineHeight: 1.55, textAlign: 'center', marginTop: 16 }}>
            Let's go to lunch or dinner — or just meet at the church to chat — or pray in your home.
          </div>
          <div style={{ ...smallCaps(theme, 9), color: theme.inkMute, textAlign: 'center', marginTop: 14, lineHeight: 1.6 }}>
            Usually in the office<br/>
            <span style={{ color: theme.ink }}>Monday – Wednesday · 10 am – 3 pm</span>
          </div>

          {/* Read more about Pastor Jonathan — links to the bio on the About page */}
          {onNav && (
            <div style={{ textAlign: 'center', marginTop: 18 }}>
              <button onClick={goToBio} style={{
                background: 'transparent',
                border: 'none',
                color: theme.accent,
                ...smallCaps(theme, 10),
                cursor: 'pointer',
                borderBottom: `1px dotted ${theme.accent}`,
                paddingBottom: 2,
              }}>↳ &nbsp; Read Pastor Jonathan's bio</button>
            </div>
          )}
        </div>

        {/* James 5:14 — the principle behind it */}
        <div style={{
          marginTop: 18, padding: '16px 18px',
          background: theme.bgAlt,
          borderLeft: `2px solid ${theme.gold}`,
          fontFamily: theme.fonts.display, fontStyle: 'italic',
          fontSize: 15, color: theme.inkSoft, lineHeight: 1.55,
        }}>
          <div style={{ ...smallCaps(theme, 8), color: theme.gold, marginBottom: 6, fontStyle: 'normal' }}>
            James 5 : 14
          </div>
          "Is any sick among you? Let him call for the elders of the church; and let them pray over him."
          <div style={{ ...smallCaps(theme, 9), color: theme.inkMute, marginTop: 10, fontStyle: 'normal' }}>
            Pastoral visitation begins with your call. The pastor stands ready when invited; the door opens from your side first.
          </div>
        </div>
      </div>

      {/* Church business — secretary */}
      <div style={{ padding: '28px 22px 0' }}>
        <MissalRule theme={theme} label="For church business" />
        <div style={{ fontFamily: theme.fonts.body, fontSize: 14, color: theme.inkSoft, lineHeight: 1.6, marginBottom: 12 }}>
          For office hours, building rentals, weddings or funerals, donation records,
          or anything administrative — please reach the church office:
        </div>
        <div style={{ background: theme.paper, padding: 18, border: `1px solid ${theme.rule}` }}>
          <div style={{ fontFamily: theme.fonts.display, fontSize: 20, color: theme.ink, fontWeight: 500 }}>
            Michele Parker
          </div>
          <div style={{ fontFamily: theme.fonts.display, fontStyle: 'italic', fontSize: 13, color: theme.inkSoft, marginBottom: 12 }}>
            Church Secretary
          </div>
          <div style={{ fontFamily: theme.fonts.body, fontSize: 14, color: theme.inkSoft, lineHeight: 1.7 }}>
            <span style={{ ...smallCaps(theme, 9), color: theme.inkMute, marginRight: 8 }}>Phone</span>
            <a href="tel:+16015872987" style={{ color: theme.ink, textDecoration: 'none', borderBottom: `1px dotted ${theme.rule}` }}>601 / 587 / 2987</a><br/>
            <span style={{ ...smallCaps(theme, 9), color: theme.inkMute, marginRight: 8 }}>E-mail</span>
            <a href="mailto:office@monticelloumc.church" style={{ color: theme.ink, textDecoration: 'none', borderBottom: `1px dotted ${theme.rule}` }}>office@monticelloumc.church</a><br/>
            <span style={{ ...smallCaps(theme, 9), color: theme.inkMute, marginRight: 8 }}>Hours</span>
            Monday – Wednesday · 8 am – 12 pm
          </div>
        </div>
      </div>

      {/* Address card — same as on Visit, repeated here for completeness */}
      <div style={{ padding: '28px 22px 0' }}>
        <MissalRule theme={theme} label="In person" />
        <div style={{ background: theme.paper, padding: 18, border: `1px solid ${theme.rule}`, display: 'flex', alignItems: 'flex-start', gap: 14 }}>
          <div style={{ color: theme.accent, marginTop: 2 }}>{Icons.pin(22, theme.accent)}</div>
          <div style={{ flex: 1 }}>
            <a href="https://maps.apple.com/?address=130+East+Broad+Street,+Monticello,+MS+39654" style={{ color: 'inherit', textDecoration: 'none', display: 'block' }}>
              <div style={{ fontFamily: theme.fonts.display, fontSize: 18, color: theme.ink, fontWeight: 500 }}>130 East Broad Street</div>
              <div style={{ fontFamily: theme.fonts.display, fontStyle: 'italic', fontSize: 14, color: theme.inkSoft }}>Monticello, Mississippi 39654</div>
            </a>
          </div>
        </div>
      </div>
    </div>
  );
}

Object.assign(window, { GiveScreen, VisitScreen, PrayerScreen, EventsScreen, AboutScreen, OfficeScreen, ContactScreen });
