// screens-other.jsx — Give, Visit, About, Prayer Wall, 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: 56, lineHeight: 0.95, margin: 0, color: theme.ink, letterSpacing: '-0.01em' }}>
          <span style={{ fontStyle: 'italic', color: theme.accent }}>Offerings</span>
        </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 Tithe.ly */}
      <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 }}>
          On the next page you'll be able to designate your offering to:
        </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>Music Ministry</li>
          <li>Soup for the Soul</li>
        </ul>
      </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 asked to stand up?', a: 'No. Visitors are never asked to stand or singled out. Welcome means welcome.' },
  ];
  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 name tag if you want one.' },
          { 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. Visitors are never asked to stand or singled out.' },
          { 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 wall 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; });
  };

  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);
    } 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 chapel. The pastoral team prays through this wall each morning at the office of Lauds.
        </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>
      )}
    </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
    buckets.get(key).items.push({
      d: f.d,
      day: f.day,
      t: ev.title,
      sub: subParts.join(' · '),
      cat: categorizeEvent(ev.title),
    });
  }
  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.
        const seenRoutine = new Set();
        const filtered = (data.events || []).filter(ev => {
          if (!isRoutineWeekly(ev.title)) return true;
          const key = ev.title.trim().toLowerCase();
          if (seenRoutine.has(key)) return false;
          seenRoutine.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;
  const catColor = (c) => ({
    feast:      theme.gold,
    sacrament:  theme.accent,
    worship:    theme.accent,
    study:      theme.inkSoft,
    rehearsal:  theme.inkMute,
    mission:    theme.gold,
    children:   theme.gold,
    fellowship: theme.inkSoft,
    event:      theme.inkMute,
  }[c] || theme.inkMute);

  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 }) {
  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 }}>The four marks</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 four marks */}
      <div style={{ padding: '28px 22px 0' }}>
        <MissalRule theme={theme} label="Our pillars" />
      </div>
      <div style={{ padding: '0 22px' }}>
        {[
          { roman: 'i',   t: 'Worship',     body: 'We gather weekly around Word and Table — the ancient pattern of God’s people in every age.' },
          { roman: 'ii',  t: 'Discipleship', body: 'We grow as followers of Jesus through Scripture, prayer, and life together in small groups.' },
          { roman: 'iii', t: 'Mission',     body: 'We are sent: to feed, to shelter, to listen, to bear one another’s burdens in Monticello and beyond.' },
          { roman: 'iv',  t: 'Community',   body: 'We are a family of every age, drawn from the lake town we love and the world God so loves.' },
        ].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 */}
      <div style={{ padding: '24px 22px 0' }}>
        <MissalRule theme={theme} label="Our pastor" />
        <div style={{ padding: '8px 0' }}>
          <img src="assets/pastor-jonathan-speegle.jpg" alt="The Rev. Jonathan Speegle, PhD"
               style={{
                 width: '100%', height: 280, objectFit: 'cover', objectPosition: 'center 25%',
                 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: 22, 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: 13, color: theme.inkSoft, marginTop: 4 }}>
            Senior Pastor
          </div>
          <a href="mailto:JonathanSpeegle@icloud.com" style={{
            display: 'inline-block', marginTop: 14, 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>
    </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.
// ─────────────────────────────────────────────────────────────
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;
  const psalm = (typeof PSALMS !== 'undefined') ? PSALMS[content.psalmId] : null;

  // The day's Collect and Gospel reading from the RCL helper.
  let dayCollect = null;
  let gospelRef  = null;
  try {
    if (typeof getCollect === 'function') dayCollect = getCollect();
    if (typeof getRCLToday === 'function') {
      const rcl = getRCLToday();
      if (rcl && rcl.readings && rcl.readings.gospel) gospelRef = rcl.readings.gospel;
    }
  } catch (e) {}

  // Fetch the Gospel passage from bible-api.com (free, CORS-enabled, public-domain
  // World English Bible). Cached in localStorage by ref so we only fetch once
  // per Sunday per device.
  const [gospel, setGospel] = React.useState({ status: 'idle', text: null, ref: null });
  React.useEffect(() => {
    if (!gospelRef) return;
    const cleanRef = gospelRef.replace(/—/g, '-').replace(/–/g, '-').replace(/\s*:\s*/g, ':').trim();
    const cacheKey = 'mumc.gospel.' + cleanRef;
    try {
      const cached = localStorage.getItem(cacheKey);
      if (cached) {
        const parsed = JSON.parse(cached);
        setGospel({ status: 'ok', text: parsed.text, ref: parsed.ref || cleanRef });
        return;
      }
    } catch (e) {}
    setGospel({ status: 'loading', text: null, ref: cleanRef });
    fetch('https://bible-api.com/' + encodeURIComponent(cleanRef) + '?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() }));
        setGospel({ status: 'ok', text: verses, ref: data.reference || cleanRef });
        try { localStorage.setItem(cacheKey, JSON.stringify({ text: verses, ref: data.reference || cleanRef })); } catch (e) {}
      })
      .catch(() => setGospel({ status: 'error', text: null, ref: cleanRef }));
  }, [gospelRef]);

  // 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>

      {/* 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 — full text in KJV */}
        <div style={{ marginTop: 22 }} />
        <MissalRule theme={theme} label="The Psalm" />
        {psalm ? (
          <>
            <div style={{ ...smallCaps(theme, 9), color: theme.accent, marginBottom: 4 }}>{psalm.ref}</div>
            <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' }}>{i + 1}</span>
                  <span style={{ flex: 1 }}>{v}</span>
                </div>
              ))}
            </div>
          </>
        ) : (
          <div style={{ fontFamily: theme.fonts.display, fontSize: 17, color: theme.ink, fontWeight: 500, marginBottom: 4 }}>
            {content.psalm || ''}
          </div>
        )}

        {/* The Gospel reading — fetched from a public-domain Bible API for the
            upcoming Sunday's RCL Gospel. */}
        {gospelRef && (
          <>
            <div style={{ marginTop: 26 }}>
              <MissalRule theme={theme} label="The Holy Gospel" />
            </div>
            <div style={{ ...smallCaps(theme, 9), color: theme.accent, marginBottom: 12 }}>{gospel.ref || gospelRef}</div>
            {gospel.status === 'loading' && (
              <div style={{ fontFamily: theme.fonts.body, fontStyle: 'italic', fontSize: 13, color: theme.inkMute }}>Reading the Gospel…</div>
            )}
            {gospel.status === 'error' && (
              <div style={{ fontFamily: theme.fonts.body, fontStyle: 'italic', fontSize: 13, color: theme.inkMute }}>
                The Gospel text isn't available offline. Tap to{' '}
                <a href={'https://www.biblegateway.com/passage/?search=' + encodeURIComponent(gospelRef.replace(/—/g, '-')) + '&version=NRSVUE'}
                   target="_blank" rel="noopener noreferrer"
                   style={{ color: theme.accent }}>read on Bible Gateway</a>.
              </div>
            )}
            {gospel.status === 'ok' && gospel.text && (
              <div style={{ fontFamily: theme.fonts.display, fontSize: 16, color: theme.ink, lineHeight: 1.65 }}>
                {gospel.text.map((v, i) => (
                  <span key={i}>
                    <sup style={{ ...smallCaps(theme, 8), color: theme.gold, marginRight: 4, verticalAlign: 'baseline' }}>{v.n}</sup>
                    {v.text}{' '}
                  </span>
                ))}
                <div style={{ ...smallCaps(theme, 9), color: theme.inkMute, marginTop: 12, fontStyle: 'italic' }}>
                  World English Bible · public domain
                </div>
              </div>
            )}
          </>
        )}

        {/* 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 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>
  );
}

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