// liturgical.jsx — auto-detect season, saints, daily office, lectionary

// ─────────────────────────────────────────────────────────────
// Easter calculation — Anonymous Gregorian (Meeus/Jones/Butcher)
// Returns Date for Easter Sunday in given year
// ─────────────────────────────────────────────────────────────
function easterDate(year) {
  const a = year % 19;
  const b = Math.floor(year / 100);
  const c = year % 100;
  const d = Math.floor(b / 4);
  const e = b % 4;
  const f = Math.floor((b + 8) / 25);
  const g = Math.floor((b - f + 1) / 3);
  const h = (19 * a + b - d - g + 15) % 30;
  const i = Math.floor(c / 4);
  const k = c % 4;
  const L = (32 + 2 * e + 2 * i - h - k) % 7;
  const m = Math.floor((a + 11 * h + 22 * L) / 451);
  const month = Math.floor((h + L - 7 * m + 114) / 31); // 3=Mar, 4=Apr
  const day = ((h + L - 7 * m + 114) % 31) + 1;
  return new Date(year, month - 1, day);
}

function addDays(d, n) {
  const r = new Date(d);
  r.setDate(r.getDate() + n);
  return r;
}

// ─────────────────────────────────────────────────────────────
// Detect current liturgical season
// ─────────────────────────────────────────────────────────────
function detectSeason(date = new Date()) {
  const y = date.getFullYear();
  const easter = easterDate(y);
  const ashWed = addDays(easter, -46);
  const palmSun = addDays(easter, -7);
  const pentecost = addDays(easter, 49);
  const trinity = addDays(easter, 56);
  const epiphany = new Date(y, 0, 6);

  // First Sunday of Advent: Sunday on or before Dec 3 (4 Sundays before Dec 25)
  const xmas = new Date(y, 11, 25);
  const adventStart = (() => {
    // 4 Sundays before Christmas
    const fourth = new Date(xmas);
    fourth.setDate(xmas.getDate() - xmas.getDay() - 21);
    return fourth;
  })();
  const baptismOfLord = (() => {
    // Sunday after Jan 6
    const d = new Date(y, 0, 7);
    while (d.getDay() !== 0) d.setDate(d.getDate() + 1);
    return d;
  })();

  if (date >= adventStart && date < xmas) return 'advent';
  if ((date >= xmas && date.getMonth() === 11) || date < epiphany) return 'christmas';
  if (date.getMonth() === 0 && date.getDate() === 6) return 'epiphany';
  if (date >= epiphany && date < ashWed) return 'epiphany';
  if (date >= ashWed && date < easter) return 'lent';
  if (date >= easter && date < pentecost) return 'easter';
  if (date >= pentecost && date < trinity) return 'pentecost';
  return 'ordinary';
}

// ─────────────────────────────────────────────────────────────
// Saint of the Day — small but real list (UMC commemorates many)
// ─────────────────────────────────────────────────────────────
// Each saint entry can optionally carry a `link` to a biographical page.
// Preferred source is Franciscan Media's Saint of the Day series (concise,
// pastoral, Catholic-but-broadly-Christian voice). For days where Franciscan
// Media has no entry — chiefly the Wesley brothers (Methodist, not on RC
// calendar) and Epiphany — we fall back to Wikipedia. URLs were verified
// 2026-05; see the SaintRibbon hyperlink in features.jsx.
const FM = 'https://www.franciscanmedia.org/saint-of-the-day';
const WK = 'https://en.wikipedia.org/wiki';
const SAINTS = {
  // ─── January ───
  '1-1':   { name: 'The Holy Name of Jesus', kind: 'feast', link: `${FM}/most-holy-name-of-jesus/` },
  '1-2':   { name: 'Sts. Basil & Gregory of Nazianzus', kind: 'memorial', link: `${FM}/saint-basil-the-great/` },
  '1-3':   { name: 'St. Genevieve of Paris', kind: 'memorial', link: `${WK}/Saint_Genevieve` },
  '1-4':   { name: 'St. Elizabeth Ann Seton', kind: 'memorial', link: `${FM}/saint-elizabeth-ann-seton/` },
  '1-5':   { name: 'St. John Neumann', kind: 'memorial', link: `${FM}/saint-john-neumann/` },
  '1-6':   { name: 'The Epiphany of the Lord', kind: 'principal', link: `${WK}/Epiphany_(holiday)` },
  '1-7':   { name: 'St. Raymond of Peñafort', kind: 'memorial', link: `${FM}/saint-raymond-of-penafort/` },
  '1-8':   { name: 'Harriet Bedell', kind: 'memorial', link: `${WK}/Harriet_Bedell` },
  '1-9':   { name: 'St. Adrian of Canterbury', kind: 'memorial', link: `${WK}/Adrian_of_Canterbury` },
  '1-10':  { name: 'William Laud', kind: 'memorial', link: `${WK}/William_Laud` },
  '1-11':  { name: 'St. Theodosius the Cenobiarch', kind: 'memorial', link: `${WK}/Theodosius_the_Cenobiarch` },
  '1-12':  { name: 'St. Aelred of Rievaulx', kind: 'memorial', link: `${WK}/Aelred_of_Rievaulx` },
  '1-13':  { name: 'St. Hilary of Poitiers', kind: 'memorial', link: `${FM}/saint-hilary/` },
  '1-14':  { name: 'St. Paulinus of Nola', kind: 'memorial', link: `${FM}/saint-paulinus-of-nola/` },
  '1-15':  { name: 'Martin Luther King Jr.', kind: 'memorial', link: `${WK}/Martin_Luther_King_Jr.` },
  '1-16':  { name: 'Pope St. Marcellus I', kind: 'memorial', link: `${WK}/Pope_Marcellus_I` },
  '1-17':  { name: 'St. Antony of Egypt', kind: 'memorial', link: `${FM}/saint-anthony-of-egypt/` },
  '1-18':  { name: 'The Confession of St. Peter', kind: 'feast', link: `${WK}/Confession_of_Peter` },
  '1-19':  { name: 'St. Wulfstan of Worcester', kind: 'memorial', link: `${WK}/Wulfstan_(died_1095)` },
  '1-20':  { name: 'St. Sebastian', kind: 'memorial', link: `${FM}/saint-sebastian/` },
  '1-21':  { name: 'St. Agnes of Rome', kind: 'memorial', link: `${FM}/saint-agnes/` },
  '1-22':  { name: 'St. Vincent of Saragossa', kind: 'memorial', link: `${FM}/saint-vincent-of-zaragossa/` },
  '1-23':  { name: 'Phillips Brooks', kind: 'memorial', link: `${WK}/Phillips_Brooks` },
  '1-24':  { name: 'St. Francis de Sales', kind: 'memorial', link: `${FM}/saint-francis-de-sales/` },
  '1-25':  { name: 'The Conversion of St. Paul', kind: 'feast', link: `${FM}/conversion-of-saint-paul/` },
  '1-26':  { name: 'Sts. Timothy & Titus', kind: 'memorial', link: `${FM}/saints-timothy-and-titus/` },
  '1-27':  { name: 'St. John Chrysostom', kind: 'memorial', link: `${FM}/saint-john-chrysostom/` },
  '1-28':  { name: 'St. Thomas Aquinas', kind: 'memorial', link: `${FM}/saint-thomas-aquinas/` },
  '1-29':  { name: 'Bl. Charles de Foucauld', kind: 'memorial', link: `${FM}/saint-charles-de-foucauld/` },
  '1-30':  { name: 'King Charles I, Martyr', kind: 'memorial', link: `${WK}/Charles_I_of_England` },
  '1-31':  { name: 'St. John Bosco', kind: 'memorial', link: `${FM}/saint-john-bosco/` },

  // ─── February ───
  '2-1':   { name: 'St. Brigid of Kildare', kind: 'memorial', link: `${WK}/Brigid_of_Kildare` },
  '2-2':   { name: 'The Presentation', kind: 'feast', link: `${FM}/presentation-of-the-lord/` },
  '2-3':   { name: 'Anskar of Hamburg', kind: 'memorial', link: `${WK}/Ansgar` },
  '2-4':   { name: 'Cornelius the Centurion', kind: 'memorial', link: `${WK}/Cornelius_the_Centurion` },
  '2-5':   { name: 'St. Agatha', kind: 'memorial', link: `${FM}/saint-agatha/` },
  '2-6':   { name: 'The Martyrs of Japan', kind: 'memorial', link: `${FM}/saint-paul-miki-and-companions/` },
  '2-7':   { name: 'St. Theodore Stratelates', kind: 'memorial', link: `${WK}/Theodore_Stratelates` },
  '2-8':   { name: 'St. Jerome Emiliani', kind: 'memorial', link: `${FM}/saint-jerome-emiliani/` },
  '2-9':   { name: 'St. Apollonia', kind: 'memorial', link: `${FM}/saint-apollonia/` },
  '2-10':  { name: 'St. Scholastica', kind: 'memorial', link: `${FM}/saint-scholastica/` },
  '2-11':  { name: 'Our Lady of Lourdes', kind: 'memorial', link: `${FM}/our-lady-of-lourdes/` },
  '2-12':  { name: 'St. Meletius of Antioch', kind: 'memorial', link: `${WK}/Meletius_of_Antioch` },
  '2-13':  { name: 'Absalom Jones', kind: 'memorial', link: `${WK}/Absalom_Jones` },
  '2-14':  { name: 'Sts. Cyril and Methodius', kind: 'memorial', link: `${FM}/saints-cyril-and-methodius/` },
  '2-15':  { name: 'Thomas Bray', kind: 'memorial', link: `${WK}/Thomas_Bray` },
  '2-16':  { name: 'Onesimus, Disciple of St. Paul', kind: 'memorial', link: `${WK}/Onesimus` },
  '2-17':  { name: 'Seven Founders of the Servite Order', kind: 'memorial', link: `${WK}/Seven_Holy_Founders` },
  '2-18':  { name: 'Martin Luther', kind: 'memorial', link: `${WK}/Martin_Luther` },
  '2-19':  { name: 'St. Conrad of Piacenza', kind: 'memorial', link: `${WK}/Conrad_of_Piacenza` },
  '2-20':  { name: 'Sts. Francisco & Jacinta Marto', kind: 'memorial', link: `${FM}/saints-jacinta-and-francisco-marto/` },
  '2-21':  { name: 'St. Peter Damian', kind: 'memorial', link: `${FM}/saint-peter-damian/` },
  '2-22':  { name: 'The Chair of St. Peter', kind: 'feast', link: `${FM}/chair-of-saint-peter/` },
  '2-23':  { name: 'St. Polycarp of Smyrna', kind: 'memorial', link: `${FM}/saint-polycarp/` },
  '2-24':  { name: 'St. Matthias the Apostle', kind: 'feast', link: `${FM}/saint-matthias/` },
  '2-25':  { name: 'St. Walburga', kind: 'memorial', link: `${WK}/Walburga` },
  '2-26':  { name: 'Bl. Isabel of France', kind: 'memorial', link: `${WK}/Isabelle_of_France_(saint)` },
  '2-27':  { name: 'George Herbert', kind: 'memorial', link: `${WK}/George_Herbert` },
  '2-28':  { name: 'St. Oswald of Worcester', kind: 'memorial', link: `${WK}/Oswald_of_Worcester` },

  // ─── March ───
  '3-1':   { name: 'St. David of Wales', kind: 'memorial', link: `${FM}/saint-david-of-wales/` },
  '3-2':   { name: 'Chad of Lichfield', kind: 'memorial', link: `${WK}/Chad_of_Mercia` },
  '3-3':   { name: 'St. Katharine Drexel', kind: 'memorial', link: `${FM}/saint-katharine-drexel/` },
  '3-4':   { name: 'St. Casimir of Poland', kind: 'memorial', link: `${FM}/saint-casimir/` },
  '3-5':   { name: 'St. Adrian of Caesarea', kind: 'memorial', link: `${WK}/Adrian_of_Caesarea` },
  '3-6':   { name: 'St. Colette of Corbie', kind: 'memorial', link: `${WK}/Colette_of_Corbie` },
  '3-7':   { name: 'Sts. Perpetua and Felicity', kind: 'memorial', link: `${FM}/saints-perpetua-and-felicity/` },
  '3-8':   { name: 'St. John of God', kind: 'memorial', link: `${FM}/saint-john-of-god/` },
  '3-9':   { name: 'St. Gregory of Nyssa', kind: 'memorial', link: `${WK}/Gregory_of_Nyssa` },
  '3-10':  { name: 'The Forty Martyrs of Sebaste', kind: 'memorial', link: `${WK}/Forty_Martyrs_of_Sebaste` },
  '3-11':  { name: 'St. Eulogius of Córdoba', kind: 'memorial', link: `${WK}/Eulogius_of_C%C3%B3rdoba` },
  '3-12':  { name: 'St. Gregory the Great', kind: 'memorial', link: `${FM}/saint-gregory-the-great/` },
  '3-13':  { name: 'Bl. Agnellus of Pisa', kind: 'memorial', link: `${WK}/Agnellus_of_Pisa` },
  '3-14':  { name: 'St. Matilda of Saxony', kind: 'memorial', link: `${WK}/Matilda_of_Ringelheim` },
  '3-15':  { name: 'St. Louise de Marillac', kind: 'memorial', link: `${FM}/saint-louise-de-marillac/` },
  '3-16':  { name: 'St. Clement Mary Hofbauer', kind: 'memorial', link: `${FM}/saint-clement-mary-hofbauer/` },
  '3-17':  { name: 'St. Patrick of Ireland', kind: 'memorial', link: `${FM}/saint-patrick/` },
  '3-18':  { name: 'St. Cyril of Jerusalem', kind: 'memorial', link: `${FM}/saint-cyril-of-jerusalem/` },
  '3-19':  { name: 'St. Joseph', kind: 'feast', link: `${FM}/saint-joseph/` },
  '3-20':  { name: 'St. Cuthbert of Lindisfarne', kind: 'memorial', link: `${WK}/Cuthbert` },
  '3-21':  { name: 'Thomas Cranmer', kind: 'memorial', link: `${WK}/Thomas_Cranmer` },
  '3-22':  { name: 'Jonathan Edwards', kind: 'memorial', link: `${WK}/Jonathan_Edwards_(theologian)` },
  '3-23':  { name: 'St. Gregory the Illuminator', kind: 'memorial', link: `${WK}/Gregory_the_Illuminator` },
  '3-24':  { name: 'St. Óscar Romero', kind: 'memorial', link: `${WK}/%C3%93scar_Romero` },
  '3-25':  { name: 'The Annunciation', kind: 'principal', link: `${FM}/annunciation-of-the-lord/` },
  '3-26':  { name: 'St. Liudger of Münster', kind: 'memorial', link: `${WK}/Ludger` },
  '3-27':  { name: 'St. Rupert of Salzburg', kind: 'memorial', link: `${WK}/Rupert_of_Salzburg` },
  '3-28':  { name: 'St. Tutilo of St. Gall', kind: 'memorial', link: `${WK}/Tuotilo` },
  '3-29':  { name: 'John Keble', kind: 'memorial', link: `${WK}/John_Keble` },
  '3-30':  { name: 'St. John Climacus', kind: 'memorial', link: `${WK}/John_Climacus` },
  '3-31':  { name: 'John Donne', kind: 'memorial', link: `${WK}/John_Donne` },

  // ─── April ───
  '4-1':   { name: 'F. D. Maurice', kind: 'memorial', link: `${WK}/F._D._Maurice` },
  '4-2':   { name: 'St. Francis of Paola', kind: 'memorial', link: `${FM}/saint-francis-of-paola/` },
  '4-3':   { name: 'St. Richard of Chichester', kind: 'memorial', link: `${WK}/Richard_of_Chichester` },
  '4-4':   { name: 'St. Isidore of Seville', kind: 'memorial', link: `${FM}/saint-isidore-of-seville/` },
  '4-5':   { name: 'St. Vincent Ferrer', kind: 'memorial', link: `${FM}/saint-vincent-ferrer/` },
  '4-6':   { name: 'William Law', kind: 'memorial', link: `${WK}/William_Law` },
  '4-7':   { name: 'St. John Baptist de la Salle', kind: 'memorial', link: `${FM}/saint-john-baptist-de-la-salle/` },
  '4-8':   { name: 'William Augustus Muhlenberg', kind: 'memorial', link: `${WK}/William_Augustus_Muhlenberg` },
  '4-9':   { name: 'Dietrich Bonhoeffer', kind: 'memorial', link: `${WK}/Dietrich_Bonhoeffer` },
  '4-10':  { name: 'Fulbert of Chartres', kind: 'memorial', link: `${WK}/Fulbert_of_Chartres` },
  '4-11':  { name: 'St. Stanislaus of Kraków', kind: 'memorial', link: `${FM}/saint-stanislaus/` },
  '4-12':  { name: 'Adoniram Judson', kind: 'memorial', link: `${WK}/Adoniram_Judson` },
  '4-13':  { name: 'Pope St. Martin I', kind: 'memorial', link: `${FM}/saint-martin-i/` },
  '4-14':  { name: 'St. Lydwine of Schiedam', kind: 'memorial', link: `${WK}/Lidwina` },
  '4-15':  { name: 'St. Anastasius of Sinai', kind: 'memorial', link: `${WK}/Anastasius_Sinaita` },
  '4-16':  { name: 'St. Bernadette Soubirous', kind: 'memorial', link: `${FM}/saint-bernadette-soubirous/` },
  '4-17':  { name: 'St. Stephen Harding', kind: 'memorial', link: `${WK}/Stephen_Harding` },
  '4-18':  { name: 'St. Apollonius the Apologist', kind: 'memorial', link: `${WK}/Apollonius_the_Apologist` },
  '4-19':  { name: 'Alphege of Canterbury', kind: 'memorial', link: `${WK}/%C3%86lfheah_of_Canterbury` },
  '4-20':  { name: 'St. Agnes of Montepulciano', kind: 'memorial', link: `${WK}/Agnes_of_Montepulciano` },
  '4-21':  { name: 'St. Anselm of Canterbury', kind: 'memorial', link: `${FM}/saint-anselm/` },
  '4-22':  { name: 'Bl. Maria Gabriella Sagheddu', kind: 'memorial', link: `${WK}/Maria_Gabriella_Sagheddu` },
  '4-23':  { name: 'St. George', kind: 'memorial', link: `${FM}/saint-george/` },
  '4-24':  { name: 'St. Fidelis of Sigmaringen', kind: 'memorial', link: `${FM}/saint-fidelis-of-sigmaringen/` },
  '4-25':  { name: 'St. Mark the Evangelist', kind: 'feast', link: `${FM}/saint-mark/` },
  '4-26':  { name: 'Our Lady of Good Counsel', kind: 'memorial', link: `${WK}/Our_Lady_of_Good_Counsel` },
  '4-27':  { name: 'St. Zita of Lucca', kind: 'memorial', link: `${WK}/Zita` },
  '4-28':  { name: 'St. Peter Chanel', kind: 'memorial', link: `${FM}/saint-peter-chanel/` },
  '4-29':  { name: 'St. Catherine of Siena', kind: 'memorial', link: `${FM}/saint-catherine-of-siena/` },
  '4-30':  { name: 'St. Pius V', kind: 'memorial', link: `${FM}/saint-pius-v/` },

  // ─── May ───
  '5-1':   { name: 'Sts. Philip and James', kind: 'feast', link: `${FM}/saints-philip-and-james/` },
  '5-2':   { name: 'Sts. Boris and Gleb', kind: 'memorial', link: `${WK}/Boris_and_Gleb` },
  '5-3':   { name: 'St. Athanasius', kind: 'memorial', link: `${FM}/saint-athanasius/` },
  '5-4':   { name: 'English Saints & Martyrs of the Reformation', kind: 'memorial', link: `${WK}/Forty_Martyrs_of_England_and_Wales` },
  '5-5':   { name: 'St. Hilary of Arles', kind: 'memorial', link: `${WK}/Hilary_of_Arles` },
  '5-6':   { name: 'St. Petronax of Monte Cassino', kind: 'memorial', link: `${WK}/Petronax_of_Monte_Cassino` },
  '5-7':   { name: 'St. Rose Venerini', kind: 'memorial', link: `${FM}/saint-rose-venerini/` },
  '5-8':   { name: 'Julian of Norwich', kind: 'memorial', link: `${WK}/Julian_of_Norwich` },
  '5-9':   { name: 'St. Pachomius the Great', kind: 'memorial', link: `${WK}/Pachomius_the_Great` },
  '5-10':  { name: 'St. Damien of Molokai', kind: 'memorial', link: `${FM}/saint-damien-de-veuster-of-molokai/` },
  '5-11':  { name: 'Matteo Ricci', kind: 'memorial', link: `${WK}/Matteo_Ricci` },
  '5-12':  { name: 'Sts. Nereus and Achilleus', kind: 'memorial', link: `${WK}/Nereus_and_Achilleus` },
  '5-13':  { name: 'Our Lady of Fatima', kind: 'memorial', link: `${FM}/our-lady-of-fatima/` },
  '5-14':  { name: 'St. Mary Mazzarello', kind: 'memorial', link: `${WK}/Mary_Mazzarello` },
  '5-15':  { name: 'St. Isidore the Farmer', kind: 'memorial', link: `${FM}/saint-isidore-the-farmer/` },
  '5-16':  { name: 'St. Brendan the Navigator', kind: 'memorial', link: `${WK}/Brendan_the_Navigator` },
  '5-17':  { name: 'St. Paschal Baylon', kind: 'memorial', link: `${FM}/saint-paschal-baylon/` },
  '5-18':  { name: 'Pope St. John I', kind: 'memorial', link: `${FM}/saint-john-i/` },
  '5-19':  { name: 'St. Dunstan of Canterbury', kind: 'memorial', link: `${WK}/Dunstan` },
  '5-20':  { name: 'Alcuin of York', kind: 'memorial', link: `${WK}/Alcuin` },
  '5-21':  { name: 'St. Helena', kind: 'memorial', link: `${WK}/Helena,_mother_of_Constantine_I` },
  '5-22':  { name: 'St. Rita of Cascia', kind: 'memorial', link: `${FM}/saint-rita-of-cascia/` },
  '5-23':  { name: 'St. John Baptist de Rossi', kind: 'memorial', link: `${WK}/John_Baptist_de_Rossi` },
  '5-24':  { name: 'John & Charles Wesley', kind: 'memorial', wesley: true, link: `${WK}/John_Wesley` },
  '5-25':  { name: 'St. Bede the Venerable', kind: 'memorial', link: `${FM}/saint-bede-the-venerable/` },
  '5-26':  { name: 'St. Augustine of Canterbury', kind: 'memorial', link: `${FM}/saint-augustine-of-canterbury/` },
  '5-27':  { name: 'Lanfranc of Bec', kind: 'memorial', link: `${WK}/Lanfranc` },
  '5-28':  { name: 'Bl. Margaret Pole', kind: 'memorial', link: `${WK}/Margaret_Pole,_Countess_of_Salisbury` },
  '5-29':  { name: 'Pope St. Paul VI', kind: 'memorial', link: `${FM}/saint-paul-vi/` },
  '5-30':  { name: 'St. Joan of Arc', kind: 'memorial', link: `${FM}/saint-joan-of-arc/` },
  '5-31':  { name: 'The Visitation', kind: 'feast', link: `${FM}/visitation-of-the-blessed-virgin-mary/` },

  // ─── June ───
  '6-1':   { name: 'St. Justin Martyr', kind: 'memorial', link: `${FM}/saint-justin/` },
  '6-2':   { name: 'Sts. Marcellinus and Peter', kind: 'memorial', link: `${FM}/saints-marcellinus-and-peter/` },
  '6-3':   { name: 'St. Charles Lwanga & Companions', kind: 'memorial', link: `${FM}/saint-charles-lwanga-and-companions/` },
  '6-4':   { name: 'St. Francis Caracciolo', kind: 'memorial', link: `${WK}/Francis_Caracciolo` },
  '6-5':   { name: 'St. Boniface of Mainz', kind: 'memorial', link: `${FM}/saint-boniface/` },
  '6-6':   { name: 'St. Norbert', kind: 'memorial', link: `${FM}/saint-norbert/` },
  '6-7':   { name: 'Roland Allen', kind: 'memorial', link: `${WK}/Roland_Allen` },
  '6-8':   { name: 'St. William of York', kind: 'memorial', link: `${WK}/William_of_York` },
  '6-9':   { name: 'St. Columba of Iona', kind: 'memorial', link: `${WK}/Columba` },
  '6-10':  { name: 'St. Ephrem the Syrian', kind: 'memorial', link: `${FM}/saint-ephrem/` },
  '6-11':  { name: 'St. Barnabas the Apostle', kind: 'feast', link: `${FM}/saint-barnabas/` },
  '6-12':  { name: 'St. Onuphrius the Great', kind: 'memorial', link: `${WK}/Onuphrius` },
  '6-13':  { name: 'St. Anthony of Padua', kind: 'memorial', link: `${FM}/saint-anthony-of-padua/` },
  '6-14':  { name: 'St. Basil the Great', kind: 'memorial', link: `${WK}/Basil_of_Caesarea` },
  '6-15':  { name: 'St. Vitus', kind: 'memorial', link: `${WK}/Saint_Vitus` },
  '6-16':  { name: 'Joseph Butler', kind: 'memorial', link: `${WK}/Joseph_Butler` },
  '6-17':  { name: 'St. Albert Chmielowski', kind: 'memorial', link: `${FM}/saint-albert-chmielowski/` },
  '6-18':  { name: 'St. Elisabeth of Schönau', kind: 'memorial', link: `${WK}/Elisabeth_of_Sch%C3%B6nau` },
  '6-19':  { name: 'St. Romuald', kind: 'memorial', link: `${FM}/saint-romuald/` },
  '6-20':  { name: 'Bl. Margaret Ebner', kind: 'memorial', link: `${WK}/Margaret_Ebner` },
  '6-21':  { name: 'St. Aloysius Gonzaga', kind: 'memorial', link: `${FM}/saint-aloysius-gonzaga/` },
  '6-22':  { name: 'St. Alban, Protomartyr of Britain', kind: 'memorial', link: `${WK}/Saint_Alban` },
  '6-23':  { name: 'St. Joseph Cafasso', kind: 'memorial', link: `${FM}/saint-joseph-cafasso/` },
  '6-24':  { name: 'The Nativity of John the Baptist', kind: 'feast', link: `${FM}/nativity-of-saint-john-the-baptist/` },
  '6-25':  { name: 'St. William of Vercelli', kind: 'memorial', link: `${WK}/William_of_Vercelli` },
  '6-26':  { name: 'St. Josemaría Escrivá', kind: 'memorial', link: `${FM}/st-josemaria-escriva/` },
  '6-27':  { name: 'St. Cyril of Alexandria', kind: 'memorial', link: `${FM}/saint-cyril-of-alexandria/` },
  '6-28':  { name: 'St. Irenaeus of Lyons', kind: 'memorial', link: `${FM}/saint-irenaeus/` },
  '6-29':  { name: 'Sts. Peter and Paul', kind: 'feast', link: `${FM}/saints-peter-and-paul/` },
  '6-30':  { name: 'First Martyrs of the Church of Rome', kind: 'memorial', link: `${FM}/first-martyrs-of-the-church-of-rome/` },

  // ─── July ───
  '7-1':   { name: 'Pauli Murray', kind: 'memorial', link: `${WK}/Pauli_Murray` },
  '7-2':   { name: 'St. Otto of Bamberg', kind: 'memorial', link: `${WK}/Otto_of_Bamberg` },
  '7-3':   { name: 'St. Bernardino Realino', kind: 'memorial', link: `${WK}/Bernardino_Realino` },
  '7-4':   { name: 'St. Elizabeth of Portugal', kind: 'memorial', link: `${FM}/saint-elizabeth-of-portugal/` },
  '7-5':   { name: 'St. Anthony Zaccaria', kind: 'memorial', link: `${FM}/saint-anthony-zaccaria/` },
  '7-6':   { name: 'Jan Hus', kind: 'memorial', link: `${WK}/Jan_Hus` },
  '7-7':   { name: 'St. Maria Goretti', kind: 'memorial', link: `${FM}/saint-maria-goretti/` },
  '7-8':   { name: 'Sts. Aquila & Priscilla', kind: 'memorial', link: `${WK}/Priscilla_and_Aquila` },
  '7-9':   { name: 'St. Augustine Zhao Rong & Companions', kind: 'memorial', link: `${FM}/saint-augustine-zhao-rong-and-companions/` },
  '7-10':  { name: 'Sts. Rufina and Secunda', kind: 'memorial', link: `${WK}/Rufina_and_Secunda` },
  '7-11':  { name: 'St. Benedict of Nursia', kind: 'memorial', link: `${FM}/saint-benedict/` },
  '7-12':  { name: 'St. Veronica', kind: 'memorial', link: `${WK}/Veronica` },
  '7-13':  { name: 'St. Henry the Emperor', kind: 'memorial', link: `${FM}/saint-henry/` },
  '7-14':  { name: 'St. Kateri Tekakwitha', kind: 'memorial', link: `${FM}/saint-kateri-tekakwitha/` },
  '7-15':  { name: 'St. Bonaventure', kind: 'memorial', link: `${FM}/saint-bonaventure/` },
  '7-16':  { name: 'Our Lady of Mt. Carmel', kind: 'memorial', link: `${FM}/our-lady-of-mount-carmel/` },
  '7-17':  { name: 'William White', kind: 'memorial', link: `${WK}/William_White_(bishop_of_Pennsylvania)` },
  '7-18':  { name: 'St. Camillus de Lellis', kind: 'memorial', link: `${FM}/saint-camillus-de-lellis/` },
  '7-19':  { name: 'St. Macrina the Younger', kind: 'memorial', link: `${WK}/Macrina_the_Younger` },
  '7-20':  { name: 'St. Apollinaris of Ravenna', kind: 'memorial', link: `${WK}/Apollinaris_of_Ravenna` },
  '7-21':  { name: 'St. Lawrence of Brindisi', kind: 'memorial', link: `${FM}/saint-lawrence-of-brindisi/` },
  '7-22':  { name: 'St. Mary Magdalene', kind: 'feast', link: `${FM}/saint-mary-magdalene/` },
  '7-23':  { name: 'St. Bridget of Sweden', kind: 'memorial', link: `${FM}/saint-bridget-of-sweden/` },
  '7-24':  { name: 'Thomas à Kempis', kind: 'memorial', link: `${WK}/Thomas_%C3%A0_Kempis` },
  '7-25':  { name: 'St. James the Apostle', kind: 'feast', link: `${FM}/saint-james/` },
  '7-26':  { name: 'Sts. Joachim & Anne', kind: 'memorial', link: `${FM}/saints-joachim-and-anne/` },
  '7-27':  { name: 'Bl. Titus Brandsma', kind: 'memorial', link: `${WK}/Titus_Brandsma` },
  '7-28':  { name: 'St. Samson of Dol', kind: 'memorial', link: `${WK}/Samson_of_Dol` },
  '7-29':  { name: 'Sts. Mary, Martha & Lazarus of Bethany', kind: 'memorial', link: `${FM}/saints-martha-mary-and-lazarus/` },
  '7-30':  { name: 'St. Peter Chrysologus', kind: 'memorial', link: `${FM}/saint-peter-chrysologus/` },
  '7-31':  { name: 'St. Ignatius of Loyola', kind: 'memorial', link: `${FM}/saint-ignatius-of-loyola/` },

  // ─── August ───
  '8-1':   { name: 'St. Alphonsus Liguori', kind: 'memorial', link: `${FM}/saint-alphonsus-liguori/` },
  '8-2':   { name: 'St. Eusebius of Vercelli', kind: 'memorial', link: `${FM}/saint-eusebius-of-vercelli/` },
  '8-3':   { name: 'Lydia of Thyatira', kind: 'memorial', link: `${WK}/Lydia_of_Thyatira` },
  '8-4':   { name: 'St. John Vianney', kind: 'memorial', link: `${FM}/saint-john-vianney/` },
  '8-5':   { name: 'Dedication of St. Mary Major', kind: 'memorial', link: `${FM}/dedication-of-saint-mary-major-basilica/` },
  '8-6':   { name: 'The Transfiguration', kind: 'feast', link: `${FM}/transfiguration-of-the-lord/` },
  '8-7':   { name: 'John Mason Neale', kind: 'memorial', link: `${WK}/John_Mason_Neale` },
  '8-8':   { name: 'St. Dominic', kind: 'memorial', link: `${FM}/saint-dominic/` },
  '8-9':   { name: 'St. Edith Stein', kind: 'memorial', link: `${FM}/saint-teresa-benedicta-of-the-cross/` },
  '8-10':  { name: 'St. Lawrence the Deacon', kind: 'memorial', link: `${FM}/saint-lawrence/` },
  '8-11':  { name: 'St. Clare of Assisi', kind: 'memorial', link: `${FM}/saint-clare-of-assisi/` },
  '8-12':  { name: 'St. Jane Frances de Chantal', kind: 'memorial', link: `${FM}/saint-jane-frances-de-chantal/` },
  '8-13':  { name: 'Jeremy Taylor', kind: 'memorial', link: `${WK}/Jeremy_Taylor` },
  '8-14':  { name: 'St. Maximilian Kolbe', kind: 'memorial', link: `${FM}/saint-maximilian-mary-kolbe/` },
  '8-15':  { name: 'St. Mary the Virgin', kind: 'feast', link: `${FM}/assumption-of-the-blessed-virgin-mary/` },
  '8-16':  { name: 'St. Stephen of Hungary', kind: 'memorial', link: `${FM}/saint-stephen-of-hungary/` },
  '8-17':  { name: 'St. Hyacinth of Poland', kind: 'memorial', link: `${WK}/Hyacinth_of_Poland` },
  '8-18':  { name: 'William Porcher DuBose', kind: 'memorial', link: `${WK}/William_Porcher_DuBose` },
  '8-19':  { name: 'St. John Eudes', kind: 'memorial', link: `${FM}/saint-john-eudes/` },
  '8-20':  { name: 'St. Bernard of Clairvaux', kind: 'memorial', link: `${FM}/saint-bernard-of-clairvaux/` },
  '8-21':  { name: 'Pope St. Pius X', kind: 'memorial', link: `${FM}/saint-pius-x/` },
  '8-22':  { name: 'The Queenship of Mary', kind: 'memorial', link: `${FM}/queenship-of-the-blessed-virgin-mary/` },
  '8-23':  { name: 'St. Rose of Lima', kind: 'memorial', link: `${FM}/saint-rose-of-lima/` },
  '8-24':  { name: 'St. Bartholomew', kind: 'feast', link: `${FM}/saint-bartholomew/` },
  '8-25':  { name: 'St. Louis of France', kind: 'memorial', link: `${FM}/saint-louis-of-france/` },
  '8-26':  { name: 'St. Caesarius of Arles', kind: 'memorial', link: `${WK}/Caesarius_of_Arles` },
  '8-27':  { name: 'St. Monica', kind: 'memorial', link: `${FM}/saint-monica/` },
  '8-28':  { name: 'St. Augustine of Hippo', kind: 'memorial', link: `${FM}/saint-augustine-of-hippo/` },
  '8-29':  { name: 'The Beheading of John the Baptist', kind: 'memorial', link: `${FM}/martyrdom-of-saint-john-the-baptist/` },
  '8-30':  { name: 'St. Jeanne Jugan', kind: 'memorial', link: `${FM}/saint-jeanne-jugan/` },
  '8-31':  { name: 'St. Aidan of Lindisfarne', kind: 'memorial', link: `${WK}/Aidan_of_Lindisfarne` },

  // ─── September ───
  '9-1':   { name: 'St. Giles of Provence', kind: 'memorial', link: `${FM}/saint-giles/` },
  '9-2':   { name: 'Martyrs of Papua New Guinea', kind: 'memorial', link: `${WK}/Martyrs_of_Papua_New_Guinea` },
  '9-3':   { name: 'Phoebe, Deacon of Cenchreae', kind: 'memorial', link: `${WK}/Phoebe_(biblical_figure)` },
  '9-4':   { name: 'St. Rose of Viterbo', kind: 'memorial', link: `${FM}/saint-rose-of-viterbo/` },
  '9-5':   { name: 'St. Teresa of Calcutta', kind: 'memorial', link: `${FM}/saint-teresa-of-calcutta/` },
  '9-6':   { name: 'Allen Gardiner', kind: 'memorial', link: `${WK}/Allen_Gardiner` },
  '9-7':   { name: 'St. Cloud', kind: 'memorial', link: `${WK}/Saint_Cloud` },
  '9-8':   { name: 'The Birth of Mary', kind: 'feast', link: `${FM}/nativity-of-the-blessed-virgin-mary/` },
  '9-9':   { name: 'Constance & Her Companions', kind: 'memorial', link: `${WK}/Martyrs_of_Memphis` },
  '9-10':  { name: 'St. Nicholas of Tolentino', kind: 'memorial', link: `${WK}/Nicholas_of_Tolentino` },
  '9-11':  { name: 'Sts. Protus and Hyacinth', kind: 'memorial', link: `${WK}/Protus_and_Hyacinth` },
  '9-12':  { name: 'The Holy Name of Mary', kind: 'memorial', link: `${FM}/most-holy-name-of-the-blessed-virgin-mary/` },
  '9-13':  { name: 'St. John Chrysostom', kind: 'memorial', link: `${FM}/saint-john-chrysostom/` },
  '9-14':  { name: 'Holy Cross Day', kind: 'feast', link: `${FM}/exaltation-of-the-holy-cross/` },
  '9-15':  { name: 'Our Lady of Sorrows', kind: 'memorial', link: `${FM}/our-lady-of-sorrows/` },
  '9-16':  { name: 'Sts. Cornelius & Cyprian', kind: 'memorial', link: `${FM}/saint-cyprian/` },
  '9-17':  { name: 'St. Hildegard of Bingen', kind: 'memorial', link: `${FM}/saint-hildegard-of-bingen/` },
  '9-18':  { name: 'Edward Bouverie Pusey', kind: 'memorial', link: `${WK}/Edward_Bouverie_Pusey` },
  '9-19':  { name: 'Theodore of Tarsus', kind: 'memorial', link: `${WK}/Theodore_of_Tarsus` },
  '9-20':  { name: 'John Coleridge Patteson', kind: 'memorial', link: `${WK}/John_Coleridge_Patteson` },
  '9-21':  { name: 'St. Matthew the Evangelist', kind: 'feast', link: `${FM}/saint-matthew/` },
  '9-22':  { name: 'St. Maurice', kind: 'memorial', link: `${WK}/Saint_Maurice` },
  '9-23':  { name: 'St. Padre Pio of Pietrelcina', kind: 'memorial', link: `${FM}/saint-pio-of-pietrelcina/` },
  '9-24':  { name: 'Our Lady of Walsingham', kind: 'memorial', link: `${WK}/Our_Lady_of_Walsingham` },
  '9-25':  { name: 'St. Sergius of Radonezh', kind: 'memorial', link: `${WK}/Sergius_of_Radonezh` },
  '9-26':  { name: 'Lancelot Andrewes', kind: 'memorial', link: `${WK}/Lancelot_Andrewes` },
  '9-27':  { name: 'St. Vincent de Paul', kind: 'memorial', link: `${FM}/saint-vincent-de-paul/` },
  '9-28':  { name: 'St. Wenceslaus', kind: 'memorial', link: `${FM}/saint-wenceslaus/` },
  '9-29':  { name: 'St. Michael and All Angels', kind: 'feast', link: `${FM}/saints-michael-gabriel-and-raphael/` },
  '9-30':  { name: 'St. Jerome', kind: 'memorial', link: `${FM}/saint-jerome/` },

  // ─── October ───
  '10-1':  { name: 'St. Thérèse of Lisieux', kind: 'memorial', link: `${FM}/saint-therese-of-lisieux/` },
  '10-2':  { name: 'The Holy Guardian Angels', kind: 'memorial', link: `${FM}/feast-of-the-guardian-angels/` },
  '10-3':  { name: 'George Bell', kind: 'memorial', link: `${WK}/George_Bell_(bishop)` },
  '10-4':  { name: 'St. Francis of Assisi', kind: 'memorial', link: `${FM}/saint-francis-of-assisi/` },
  '10-5':  { name: 'St. Faustina Kowalska', kind: 'memorial', link: `${FM}/saint-maria-faustina-kowalska/` },
  '10-6':  { name: 'William Tyndale', kind: 'memorial', link: `${WK}/William_Tyndale` },
  '10-7':  { name: 'Our Lady of the Rosary', kind: 'memorial', link: `${FM}/our-lady-of-the-rosary/` },
  '10-8':  { name: 'John Newton', kind: 'memorial', link: `${WK}/John_Newton` },
  '10-9':  { name: 'Robert Grosseteste', kind: 'memorial', link: `${WK}/Robert_Grosseteste` },
  '10-10': { name: 'Paulinus of York', kind: 'memorial', link: `${WK}/Paulinus_of_York` },
  '10-11': { name: 'Pope St. John XXIII', kind: 'memorial', link: `${FM}/saint-john-xxiii/` },
  '10-12': { name: 'Bl. Carlo Acutis', kind: 'memorial', link: `${WK}/Carlo_Acutis` },
  '10-13': { name: 'St. Edward the Confessor', kind: 'memorial', link: `${WK}/Edward_the_Confessor` },
  '10-14': { name: 'Pope St. Callistus I', kind: 'memorial', link: `${WK}/Pope_Callixtus_I` },
  '10-15': { name: 'St. Teresa of Ávila', kind: 'memorial', link: `${FM}/saint-teresa-of-avila/` },
  '10-16': { name: 'Hugh Latimer & Nicholas Ridley', kind: 'memorial', link: `${WK}/Oxford_Martyrs` },
  '10-17': { name: 'St. Ignatius of Antioch', kind: 'memorial', link: `${FM}/saint-ignatius-of-antioch/` },
  '10-18': { name: 'St. Luke the Evangelist', kind: 'feast', link: `${FM}/saint-luke/` },
  '10-19': { name: 'Henry Martyn', kind: 'memorial', link: `${WK}/Henry_Martyn` },
  '10-20': { name: 'St. Paul of the Cross', kind: 'memorial', link: `${FM}/saint-paul-of-the-cross/` },
  '10-21': { name: 'St. Hilarion of Gaza', kind: 'memorial', link: `${WK}/Hilarion` },
  '10-22': { name: 'Pope St. John Paul II', kind: 'memorial', link: `${FM}/saint-john-paul-ii/` },
  '10-23': { name: 'St. James of Jerusalem', kind: 'memorial', link: `${WK}/James,_brother_of_Jesus` },
  '10-24': { name: 'St. Anthony Mary Claret', kind: 'memorial', link: `${FM}/saint-anthony-mary-claret/` },
  '10-25': { name: 'Sts. Crispin and Crispinian', kind: 'memorial', link: `${WK}/Crispin_and_Crispinian` },
  '10-26': { name: 'Alfred the Great', kind: 'memorial', link: `${WK}/Alfred_the_Great` },
  '10-27': { name: 'Bl. Bartholomew of Vicenza', kind: 'memorial', link: `${WK}/Bartolomeo_da_Vicenza` },
  '10-28': { name: 'Sts. Simon and Jude', kind: 'feast', link: `${FM}/saints-simon-and-jude/` },
  '10-29': { name: 'James Hannington', kind: 'memorial', link: `${WK}/James_Hannington` },
  '10-30': { name: 'Bl. Dorothy of Montau', kind: 'memorial', link: `${WK}/Dorothy_of_Montau` },
  '10-31': { name: 'Reformation Day', kind: 'memorial', link: `${WK}/Reformation_Day` },

  // ─── November ───
  '11-1':  { name: 'All Saints', kind: 'principal', link: `${FM}/solemnity-of-all-saints/` },
  '11-2':  { name: 'All Souls', kind: 'memorial', link: `${FM}/all-souls/` },
  '11-3':  { name: 'Richard Hooker', kind: 'memorial', link: `${WK}/Richard_Hooker` },
  '11-4':  { name: 'St. Charles Borromeo', kind: 'memorial', link: `${FM}/saint-charles-borromeo/` },
  '11-5':  { name: 'Sts. Zechariah & Elizabeth', kind: 'memorial', link: `${WK}/Zechariah_(priest)` },
  '11-6':  { name: 'William Temple', kind: 'memorial', link: `${WK}/William_Temple_(bishop)` },
  '11-7':  { name: 'St. Willibrord of York', kind: 'memorial', link: `${WK}/Willibrord` },
  '11-8':  { name: 'Bl. John Duns Scotus', kind: 'memorial', link: `${WK}/Duns_Scotus` },
  '11-9':  { name: 'Dedication of the Lateran Basilica', kind: 'feast', link: `${FM}/dedication-of-saint-john-lateran-basilica/` },
  '11-10': { name: 'Pope St. Leo the Great', kind: 'memorial', link: `${FM}/saint-leo-the-great/` },
  '11-11': { name: 'St. Martin of Tours', kind: 'memorial', link: `${FM}/saint-martin-of-tours/` },
  '11-12': { name: 'Charles Simeon', kind: 'memorial', link: `${WK}/Charles_Simeon` },
  '11-13': { name: 'St. Frances Xavier Cabrini', kind: 'memorial', link: `${FM}/saint-frances-xavier-cabrini/` },
  '11-14': { name: 'Samuel Seabury', kind: 'memorial', link: `${WK}/Samuel_Seabury` },
  '11-15': { name: 'St. Albert the Great', kind: 'memorial', link: `${FM}/saint-albert-the-great/` },
  '11-16': { name: 'St. Margaret of Scotland', kind: 'memorial', link: `${FM}/saint-margaret-of-scotland/` },
  '11-17': { name: 'St. Hugh of Lincoln', kind: 'memorial', link: `${WK}/Hugh_of_Lincoln` },
  '11-18': { name: 'St. Hilda of Whitby', kind: 'memorial', link: `${WK}/Hilda_of_Whitby` },
  '11-19': { name: 'St. Elizabeth of Hungary', kind: 'memorial', link: `${FM}/saint-elizabeth-of-hungary/` },
  '11-20': { name: 'Edmund the Martyr', kind: 'memorial', link: `${WK}/Edmund_the_Martyr` },
  '11-21': { name: 'The Presentation of Mary', kind: 'memorial', link: `${FM}/presentation-of-the-blessed-virgin-mary/` },
  '11-22': { name: 'St. Cecilia', kind: 'memorial', link: `${FM}/saint-cecilia/` },
  '11-23': { name: 'St. Clement of Rome', kind: 'memorial', link: `${WK}/Pope_Clement_I` },
  '11-24': { name: 'St. Andrew Dung-Lac & Companions', kind: 'memorial', link: `${FM}/saint-andrew-dung-lac-and-companions/` },
  '11-25': { name: 'St. Catherine of Alexandria', kind: 'memorial', link: `${WK}/Catherine_of_Alexandria` },
  '11-26': { name: 'St. Catherine Labouré', kind: 'memorial', link: `${WK}/Catherine_Labour%C3%A9` },
  '11-27': { name: 'Sojourner Truth', kind: 'memorial', link: `${WK}/Sojourner_Truth` },
  '11-28': { name: 'Kamehameha & Emma of Hawaii', kind: 'memorial', link: `${WK}/Kamehameha_IV` },
  '11-29': { name: 'Dorothy Day', kind: 'memorial', link: `${WK}/Dorothy_Day` },
  '11-30': { name: 'St. Andrew the Apostle', kind: 'feast', link: `${FM}/saint-andrew/` },

  // ─── December ───
  '12-1':  { name: 'Nicholas Ferrar', kind: 'memorial', link: `${WK}/Nicholas_Ferrar` },
  '12-2':  { name: 'Channing Moore Williams', kind: 'memorial', link: `${WK}/Channing_Moore_Williams` },
  '12-3':  { name: 'St. Francis Xavier', kind: 'memorial', link: `${FM}/saint-francis-xavier/` },
  '12-4':  { name: 'St. John of Damascus', kind: 'memorial', link: `${WK}/John_of_Damascus` },
  '12-5':  { name: 'Clement of Alexandria', kind: 'memorial', link: `${WK}/Clement_of_Alexandria` },
  '12-6':  { name: 'St. Nicholas of Myra', kind: 'memorial', link: `${FM}/saint-nicholas/` },
  '12-7':  { name: 'St. Ambrose of Milan', kind: 'memorial', link: `${FM}/saint-ambrose/` },
  '12-8':  { name: 'The Immaculate Conception of Mary', kind: 'feast', link: `${FM}/immaculate-conception/` },
  '12-9':  { name: 'St. Juan Diego', kind: 'memorial', link: `${FM}/saint-juan-diego/` },
  '12-10': { name: 'Karl Barth', kind: 'memorial', link: `${WK}/Karl_Barth` },
  '12-11': { name: 'Pope St. Damasus I', kind: 'memorial', link: `${WK}/Pope_Damasus_I` },
  '12-12': { name: 'Our Lady of Guadalupe', kind: 'feast', link: `${FM}/our-lady-of-guadalupe/` },
  '12-13': { name: 'St. Lucy of Syracuse', kind: 'memorial', link: `${FM}/saint-lucy/` },
  '12-14': { name: 'St. John of the Cross', kind: 'memorial', link: `${FM}/saint-john-of-the-cross/` },
  '12-15': { name: 'Bl. Frances Schervier', kind: 'memorial', link: `${WK}/Frances_Schervier` },
  '12-16': { name: 'St. Adelaide of Italy', kind: 'memorial', link: `${WK}/Adelaide_of_Italy` },
  '12-17': { name: 'The O Antiphons', kind: 'memorial', link: `${WK}/O_Antiphons` },
  '12-18': { name: 'St. Flannan of Killaloe', kind: 'memorial', link: `${WK}/Saint_Flannan` },
  '12-19': { name: 'Bl. Pope Urban V', kind: 'memorial', link: `${WK}/Pope_Urban_V` },
  '12-20': { name: 'St. Dominic of Silos', kind: 'memorial', link: `${WK}/Dominic_of_Silos` },
  '12-21': { name: 'St. Thomas the Apostle', kind: 'feast', link: `${FM}/saint-thomas/` },
  '12-22': { name: 'St. Anastasia of Sirmium', kind: 'memorial', link: `${WK}/Anastasia_of_Sirmium` },
  '12-23': { name: 'St. John of Kanty', kind: 'memorial', link: `${FM}/saint-john-of-kanty/` },
  '12-24': { name: 'Sts. Adam and Eve', kind: 'memorial', link: `${WK}/Adam_and_Eve` },
  '12-25': { name: 'The Nativity of the Lord', kind: 'principal', link: `${WK}/Nativity_of_Jesus` },
  '12-26': { name: 'St. Stephen, Deacon & Martyr', kind: 'feast', link: `${FM}/saint-stephen/` },
  '12-27': { name: 'St. John the Evangelist', kind: 'feast', link: `${FM}/saint-john-the-evangelist/` },
  '12-28': { name: 'The Holy Innocents', kind: 'feast', link: `${FM}/holy-innocents/` },
  '12-29': { name: 'St. Thomas Becket', kind: 'memorial', link: `${FM}/saint-thomas-becket/` },
  '12-30': { name: 'St. Egwin of Worcester', kind: 'memorial', link: `${WK}/Egwin_of_Evesham` },
  '12-31': { name: 'Pope Benedict XVI', kind: 'memorial', link: `${WK}/Pope_Benedict_XVI` },
};

function saintToday(date = new Date()) {
  const key = (date.getMonth() + 1) + '-' + date.getDate();
  return SAINTS[key] || null;
}

// ─────────────────────────────────────────────────────────────
// Daily Office — hours of prayer
// ─────────────────────────────────────────────────────────────
const OFFICES = [
  { id: 'lauds',    name: 'Morning Prayer', alt: 'Lauds',    hour: 7,  minute: 0 },
  { id: 'terce',    name: 'Mid-Morning',    alt: 'Terce',    hour: 9,  minute: 0 },
  { id: 'sext',     name: 'Midday Prayer',  alt: 'Sext',     hour: 12, minute: 0 },
  { id: 'none',     name: 'Mid-Afternoon',  alt: 'None',     hour: 15, minute: 0 },
  { id: 'vespers',  name: 'Evening Prayer', alt: 'Vespers',  hour: 18, minute: 0 },
  { id: 'compline', name: 'Night Prayer',   alt: 'Compline', hour: 21, minute: 0 },
];

function nextOffice(now = new Date()) {
  const minsNow = now.getHours() * 60 + now.getMinutes();
  for (const o of OFFICES) {
    const m = o.hour * 60 + o.minute;
    if (m > minsNow) return { ...o, when: m - minsNow, status: 'upcoming' };
  }
  // tomorrow's Lauds
  const o = OFFICES[0];
  return { ...o, when: 24 * 60 - minsNow + o.hour * 60 + o.minute, status: 'tomorrow' };
}

function currentOffice(now = new Date()) {
  const minsNow = now.getHours() * 60 + now.getMinutes();
  let prev = OFFICES[OFFICES.length - 1];
  for (const o of OFFICES) {
    const m = o.hour * 60 + o.minute;
    if (m > minsNow) break;
    prev = o;
  }
  return prev;
}

// Daily office content. Each entry pairs the office with its psalm,
// canticle, and closing collect for use by the OfficeScreen.
const OFFICE_CONTENT = {
  lauds:    { versicle: 'O Lord, open thou our lips.',
              response: 'And our mouth shall show forth thy praise.',
              psalmId:  'psalm-95',
              canticleId: 'benedictus', collectKey: 'morning' },
  terce:    { versicle: 'Send forth thy Spirit and they shall be created.',
              response: 'And thou shalt renew the face of the earth.',
              psalmId:  'psalm-119-1',
              canticleId: 'teDeum',     collectKey: 'morning' },
  sext:     { versicle: 'O God, make speed to save us.',
              response: 'O Lord, make haste to help us.',
              psalmId:  'psalm-121',
              canticleId: 'teDeum',     collectKey: 'noonday' },
  none:     { versicle: 'O God, make speed to save us.',
              response: 'O Lord, make haste to help us.',
              psalmId:  'psalm-119-121',
              canticleId: 'teDeum',     collectKey: 'noonday' },
  vespers:  { versicle: 'O God, make speed to save us.',
              response: 'O Lord, make haste to help us.',
              psalmId:  'psalm-141',
              canticleId: 'magnificat', collectKey: 'evening' },
  compline: { versicle: 'The Lord almighty grant us a quiet night and a perfect end.',
              response: 'Amen.',
              psalmId:  'psalm-4',
              canticleId: 'nunc',       collectKey: 'compline' },
};

// ─────────────────────────────────────────────────────────────
// PSALTER ROTATION — a 7-day cycle
// ─────────────────────────────────────────────────────────────
// Each weekday-office pair gets its own psalm. Festal psalms on Sunday,
// the great Word-meditation Psalm 119 cycled through Terce across the
// week, penitential psalms on Friday, sabbath/preparation on Saturday.
// Citations are normalized to bible-api.com format.
const PSALTER_ROTATION = {
  // Sunday — the day of resurrection: festal, royal, jubilation
  0: { lauds:    'Psalm 100',        terce:    'Psalm 119:1-8',
       sext:     'Psalm 121',        none:     'Psalm 124',
       vespers:  'Psalm 110',        compline: 'Psalm 4' },
  // Monday — the work of creation
  1: { lauds:    'Psalm 5',          terce:    'Psalm 119:9-16',
       sext:     'Psalm 19',         none:     'Psalm 26',
       vespers:  'Psalm 11',         compline: 'Psalm 86' },
  // Tuesday — wisdom & ascent
  2: { lauds:    'Psalm 24',         terce:    'Psalm 119:17-24',
       sext:     'Psalm 67',         none:     'Psalm 79',
       vespers:  'Psalm 20',         compline: 'Psalm 16' },
  // Wednesday — the great Torah meditation
  3: { lauds:    'Psalm 36',         terce:    'Psalm 119:33-40',
       sext:     'Psalm 119:41-48',  none:     'Psalm 119:49-56',
       vespers:  'Psalm 27',         compline: 'Psalm 31:1-6' },
  // Thursday — thanksgiving and remembrance
  4: { lauds:    'Psalm 80',         terce:    'Psalm 119:73-80',
       sext:     'Psalm 84',         none:     'Psalm 119:97-104',
       vespers:  'Psalm 47',         compline: 'Psalm 91' },
  // Friday — the day of the cross: penitential, passion
  5: { lauds:    'Psalm 51',         terce:    'Psalm 119:105-112',
       sext:     'Psalm 22:1-21',    none:     'Psalm 130',
       vespers:  'Psalm 88',         compline: 'Psalm 134' },
  // Saturday — sabbath, preparation
  6: { lauds:    'Psalm 92',         terce:    'Psalm 119:129-136',
       sext:     'Psalm 8',          none:     'Psalm 116',
       vespers:  'Psalm 113',        compline: 'Psalm 31:1-6' },
};

function getOfficePsalmCitation(officeId, date = new Date()) {
  const dow = date.getDay();
  return (PSALTER_ROTATION[dow] && PSALTER_ROTATION[dow][officeId]) || 'Psalm 95';
}

// ─────────────────────────────────────────────────────────────
// DAILY OFFICE LECTIONARY — pastoral 7-day reading plan
// ─────────────────────────────────────────────────────────────
// One Old Testament reading + one Gospel passage per weekday, designed
// to flank the Sunday RCL cycle without duplicating it. Sunday's slot is
// null — Sunday's RCL Gospel is shown elsewhere on the page already.
const DAILY_OFFICE_LECTIONARY = {
  0: null, // Sunday — handled by the RCL Sunday cycle
  1: { ot: 'Genesis 1:1-13',       gospel: 'Mark 1:1-15',     theme: 'Beginnings — light, water, calling' },
  2: { ot: 'Exodus 20:1-17',       gospel: 'Matthew 5:1-20',  theme: 'The Law on the mountain' },
  3: { ot: 'Proverbs 3:1-20',      gospel: 'Luke 11:1-13',    theme: 'Wisdom and prayer' },
  4: { ot: 'Isaiah 25:1-9',        gospel: 'John 6:25-40',    theme: 'The feast prepared' },
  5: { ot: 'Isaiah 53:1-12',       gospel: 'John 19:1-30',    theme: 'The suffering servant' },
  6: { ot: 'Lamentations 3:19-33', gospel: 'Matthew 12:1-14', theme: 'Lord of the sabbath' },
};

function getDailyOfficeReadings(date = new Date()) {
  const dow = date.getDay();
  return DAILY_OFFICE_LECTIONARY[dow];
}

// ─────────────────────────────────────────────────────────────
// PSALTER — full text of the psalms used in the daily offices.
// Translation: King James Version (public domain).
// ─────────────────────────────────────────────────────────────
const PSALMS = {
  'psalm-4': {
    ref: 'Psalm 4',
    title: 'Cum invocarem',
    verses: [
      'Hear me when I call, O God of my righteousness: thou hast enlarged me when I was in distress; have mercy upon me, and hear my prayer.',
      'O ye sons of men, how long will ye turn my glory into shame? how long will ye love vanity, and seek after lies?',
      'But know that the Lord hath set apart him that is godly for himself: the Lord will hear when I call unto him.',
      'Stand in awe, and sin not: commune with your own heart upon your bed, and be still.',
      'Offer the sacrifices of righteousness, and put your trust in the Lord.',
      'There be many that say, Who will shew us any good? Lord, lift thou up the light of thy countenance upon us.',
      'Thou hast put gladness in my heart, more than in the time that their corn and their wine increased.',
      'I will both lay me down in peace, and sleep: for thou, Lord, only makest me dwell in safety.',
    ],
  },
  'psalm-95': {
    ref: 'Psalm 95',
    title: 'Venite, exultemus Domino',
    verses: [
      'O come, let us sing unto the Lord: let us make a joyful noise to the rock of our salvation.',
      'Let us come before his presence with thanksgiving, and make a joyful noise unto him with psalms.',
      'For the Lord is a great God, and a great King above all gods.',
      'In his hand are the deep places of the earth: the strength of the hills is his also.',
      'The sea is his, and he made it: and his hands formed the dry land.',
      'O come, let us worship and bow down: let us kneel before the Lord our maker.',
      'For he is our God; and we are the people of his pasture, and the sheep of his hand.',
    ],
  },
  'psalm-121': {
    ref: 'Psalm 121',
    title: 'Levavi oculos',
    verses: [
      'I will lift up mine eyes unto the hills, from whence cometh my help.',
      'My help cometh from the Lord, which made heaven and earth.',
      'He will not suffer thy foot to be moved: he that keepeth thee will not slumber.',
      'Behold, he that keepeth Israel shall neither slumber nor sleep.',
      'The Lord is thy keeper: the Lord is thy shade upon thy right hand.',
      'The sun shall not smite thee by day, nor the moon by night.',
      'The Lord shall preserve thee from all evil: he shall preserve thy soul.',
      'The Lord shall preserve thy going out and thy coming in from this time forth, and even for evermore.',
    ],
  },
  'psalm-141': {
    ref: 'Psalm 141 : 1—4',
    title: 'Domine, clamavi',
    verses: [
      'Lord, I cry unto thee: make haste unto me; give ear unto my voice, when I cry unto thee.',
      'Let my prayer be set forth before thee as incense; and the lifting up of my hands as the evening sacrifice.',
      'Set a watch, O Lord, before my mouth; keep the door of my lips.',
      'Incline not my heart to any evil thing, to practise wicked works with men that work iniquity.',
    ],
  },
  'psalm-119-1': {
    ref: 'Psalm 119 : 1—8',
    title: 'Beati immaculati',
    verses: [
      'Blessed are the undefiled in the way, who walk in the law of the Lord.',
      'Blessed are they that keep his testimonies, and that seek him with the whole heart.',
      'They also do no iniquity: they walk in his ways.',
      'Thou hast commanded us to keep thy precepts diligently.',
      'O that my ways were directed to keep thy statutes!',
      'Then shall I not be ashamed, when I have respect unto all thy commandments.',
      'I will praise thee with uprightness of heart, when I shall have learned thy righteous judgments.',
      'I will keep thy statutes: O forsake me not utterly.',
    ],
  },
  'psalm-119-121': {
    ref: 'Psalm 119 : 121—128',
    title: 'Feci judicium',
    verses: [
      'I have done judgment and justice: leave me not to mine oppressors.',
      'Be surety for thy servant for good: let not the proud oppress me.',
      'Mine eyes fail for thy salvation, and for the word of thy righteousness.',
      'Deal with thy servant according unto thy mercy, and teach me thy statutes.',
      'I am thy servant; give me understanding, that I may know thy testimonies.',
      'It is time for thee, Lord, to work: for they have made void thy law.',
      'Therefore I love thy commandments above gold; yea, above fine gold.',
      'Therefore I esteem all thy precepts concerning all things to be right; and I hate every false way.',
    ],
  },
};

// ─────────────────────────────────────────────────────────────
// Canticles — the great daily-office hymns
// ─────────────────────────────────────────────────────────────
const CANTICLES = {
  benedictus: {
    name: 'Benedictus',
    subtitle: 'The Song of Zechariah · Luke 1 : 68—79',
    lines: [
      'Blessed be the Lord, the God of Israel,',
      'for he hath visited and redeemed his people,',
      'and hath raised up a mighty salvation for us,',
      'in the house of his servant David.',
      'To shew mercy to our forefathers,',
      'and to remember his holy covenant.',
      'Glory be to the Father, and to the Son, and to the Holy Ghost;',
      'as it was in the beginning, is now, and ever shall be: world without end. Amen.',
    ],
  },
  magnificat: {
    name: 'Magnificat',
    subtitle: 'The Song of Mary · Luke 1 : 46—55',
    lines: [
      'My soul doth magnify the Lord,',
      'and my spirit hath rejoiced in God my Saviour.',
      'For he hath regarded the lowliness of his handmaiden;',
      'for, behold, from henceforth all generations shall call me blessed.',
      'For he that is mighty hath magnified me;',
      'and holy is his Name.',
      'And his mercy is on them that fear him,',
      'throughout all generations.',
      'Glory be to the Father, and to the Son, and to the Holy Ghost;',
      'as it was in the beginning, is now, and ever shall be: world without end. Amen.',
    ],
  },
  nunc: {
    name: 'Nunc dimittis',
    subtitle: 'The Song of Simeon · Luke 2 : 29—32',
    lines: [
      'Lord, now lettest thou thy servant depart in peace,',
      'according to thy word.',
      'For mine eyes have seen thy salvation,',
      'which thou hast prepared before the face of all people;',
      'to be a light to lighten the Gentiles,',
      'and to be the glory of thy people Israel.',
      'Glory be to the Father, and to the Son, and to the Holy Ghost;',
      'as it was in the beginning, is now, and ever shall be: world without end. Amen.',
    ],
  },
  teDeum: {
    name: 'Te Deum laudamus',
    subtitle: 'A song of the Church',
    lines: [
      'We praise thee, O God; we acknowledge thee to be the Lord.',
      'All the earth doth worship thee, the Father everlasting.',
      'To thee all angels cry aloud, the heavens, and all the powers therein.',
      'Holy, holy, holy, Lord God of Sabaoth;',
      'heaven and earth are full of the majesty of thy glory.',
    ],
  },
};

// Office-level closing collects (different from the day's RCL collect).
const OFFICE_COLLECTS = {
  morning:  'O Lord, our heavenly Father, almighty and everlasting God, who hast safely brought us to the beginning of this day: Defend us in the same with thy mighty power; and grant that this day we fall into no sin, neither run into any kind of danger; but that all our doings, being ordered by thy governance, may be righteous in thy sight; through Jesus Christ our Lord. Amen.',
  noonday:  'Blessed Saviour, at this hour thou didst hang upon the cross, stretching out thy loving arms: Grant that all the peoples of the earth may look unto thee and be saved; for thy tender mercies\' sake. Amen.',
  evening:  'Lighten our darkness, we beseech thee, O Lord; and by thy great mercy defend us from all perils and dangers of this night; for the love of thy only Son, our Saviour Jesus Christ. Amen.',
  compline: 'Visit, we beseech thee, O Lord, this dwelling, and drive far from it all the snares of the enemy; let thy holy angels dwell herein to preserve us in peace; and may thy blessing be upon us evermore; through Jesus Christ our Lord. Amen.',
};

// ─────────────────────────────────────────────────────────────
// Lectionary — sample Year B Proper readings (full text excerpts)
// ─────────────────────────────────────────────────────────────
const LECTIONARY_FULL = {
  first: {
    citation: '2 Kings 5 : 1—14',
    title: 'The healing of Naaman',
    body: [
      'Now Naaman, commander of the army of the king of Aram, was a great man and in high favor with his master, because by him the Lord had given victory to Aram. The man, though a mighty warrior, suffered from leprosy.',
      'Meanwhile the Arameans on one of their raids had taken a young girl captive from the land of Israel, and she served Naaman’s wife. She said to her mistress, “If only my lord were with the prophet who is in Samaria! He would cure him of his leprosy.”',
      'So Naaman went with his horses and chariots, and halted at the entrance of Elisha’s house. Elisha sent a messenger to him, saying, “Go, wash in the Jordan seven times, and your flesh shall be restored and you shall be clean.”',
      'So he went down and immersed himself seven times in the Jordan, according to the word of the man of God; his flesh was restored like the flesh of a young boy, and he was clean.',
    ],
  },
  psalm: {
    citation: 'Psalm 30',
    title: 'Exaltabo te, Domine',
    body: [
      'I will exalt you, O Lord, for you have lifted me up · and have not let my enemies triumph over me.',
      'O Lord my God, I cried out to you, · and you restored me to health.',
      'You brought me up, O Lord, from the dead; · you restored my life as I was going down to the grave.',
      'Sing to the Lord, you servants of his; · give thanks for the remembrance of his holiness.',
      'Weeping may spend the night, · but joy comes in the morning.',
    ],
  },
  epistle: {
    citation: 'Galatians 6 : 7—16',
    title: 'Bear one another’s burdens',
    body: [
      'Do not be deceived; God is not mocked, for you reap whatever you sow. Those who sow to their own flesh will from the flesh reap corruption; but those who sow to the Spirit will from the Spirit reap eternal life.',
      'So let us not grow weary in doing what is right, for we will reap at harvest time, if we do not give up. So then, whenever we have an opportunity, let us work for the good of all, and especially for those of the family of faith.',
      'May I never boast of anything except the cross of our Lord Jesus Christ, by which the world has been crucified to me, and I to the world. Peace be upon all who follow this rule.',
    ],
  },
  gospel: {
    citation: 'St. Luke 10 : 1—11',
    title: 'The sending of the seventy',
    body: [
      'After this the Lord appointed seventy others and sent them on ahead of him in pairs to every town and place where he himself intended to go.',
      'He said to them, “The harvest is plentiful, but the laborers are few; therefore ask the Lord of the harvest to send out laborers into his harvest. Go on your way. See, I am sending you out like lambs into the midst of wolves.”',
      '“Carry no purse, no bag, no sandals; and greet no one on the road. Whatever house you enter, first say, ‘Peace to this house!’”',
      '“Whenever you enter a town and its people welcome you, eat what is set before you; cure the sick who are there, and say to them, ‘The kingdom of God has come near to you.’”',
    ],
  },
};

Object.assign(window, {
  easterDate, detectSeason, saintToday, OFFICES, nextOffice, currentOffice, OFFICE_CONTENT, LECTIONARY_FULL,
  PSALTER_ROTATION, getOfficePsalmCitation,
  DAILY_OFFICE_LECTIONARY, getDailyOfficeReadings,
  rclYear, sundaysAfterPentecost, getRCLToday, RCL_SUNDAYS, getNextSundayDate,
  COLLECTS, getCollect,
});

// ─────────────────────────────────────────────────────────────
// Revised Common Lectionary — Sunday-by-Sunday feed
// ─────────────────────────────────────────────────────────────

// Returns 'A', 'B', or 'C' for the lectionary year.
// New cycle starts on the First Sunday of Advent.
// Year A = years where (year+2) % 3 === 0  (e.g. 2025-26 is C; 2026-27 is A)
function rclYear(date = new Date()) {
  let y = date.getFullYear();
  // First Sunday of Advent for THIS calendar year
  const adv = firstSundayAdvent(y);
  // If we're past Advent 1, we're in the cycle that BEGINS this year (next civil year's Year)
  const civilYear = date >= adv ? y + 1 : y;
  const r = civilYear % 3;
  return r === 1 ? 'A' : r === 2 ? 'B' : 'C';
}

function firstSundayAdvent(year) {
  // Sunday on or before Dec 3 (i.e. closest Sunday that is ≥ Nov 27 and ≤ Dec 3)
  const xmas = new Date(year, 11, 25); // Dec 25
  const f = new Date(xmas);
  f.setDate(xmas.getDate() - xmas.getDay() - 21);
  return f;
}

// Returns the boundaries of every liturgical season in the current liturgical
// year, each expressed as a fraction (0-1) of the year that starts at Advent 1.
// Used by the YearWheel diagram so arcs reflect actual season dates instead of
// fixed calendar guesses.
function getLiturgicalSeasons(date = new Date()) {
  const yY = date.getFullYear();
  const advThis = firstSundayAdvent(yY);
  const startCal = (date >= advThis) ? advThis : firstSundayAdvent(yY - 1);
  const startYear = startCal.getFullYear();
  const nextStart = firstSundayAdvent(startYear + 1);
  const totalDays = (nextStart - startCal) / 86400000;
  const frac = (d) => Math.max(0, Math.min(1, (d - startCal) / 86400000 / totalDays));

  const christmas = new Date(startYear, 11, 25);     // Dec 25
  const epiphany  = new Date(startYear + 1, 0, 6);   // Jan 6
  const easter    = easterDate(startYear + 1);
  const ashWed    = addDays(easter, -46);
  const pentecost = addDays(easter, 49);
  const trinity   = addDays(pentecost, 7);
  const reignSun  = addDays(nextStart, -7);

  return {
    advent:    { from: 0,                to: frac(christmas) },
    christmas: { from: frac(christmas),  to: frac(epiphany) },
    epiphany:  { from: frac(epiphany),   to: frac(ashWed) },
    lent:      { from: frac(ashWed),     to: frac(easter) },
    // Easter Day through Pentecost Eve
    easter:    { from: frac(easter),     to: frac(pentecost) },
    // Pentecost Day itself — a 7-day wedge so it's visible on the wheel.
    // Liturgically red, the only red day in the year apart from feasts of martyrs.
    pentecostDay: { from: frac(pentecost), to: frac(addDays(pentecost, 7)) },
    // Long Season after Pentecost — from the week after Pentecost to Reign of Christ Eve.
    pentecost: { from: frac(addDays(pentecost, 7)), to: frac(reignSun) },
    reign:     { from: frac(reignSun),   to: 1 },
    today:     frac(date),
    startYear: startYear,
    endYear:   startYear + 1,
  };
}

// Given a Sunday date, return the next Sunday Date
function getNextSundayDate(from = new Date()) {
  const d = new Date(from);
  const day = d.getDay();
  const add = day === 0 ? 7 : 7 - day;
  d.setDate(d.getDate() + add);
  return d;
}

// Approximate "Proper N" (Sundays after Pentecost / Ordinary Time)
// Used for the long stretch from Trinity Sunday to Christ the King.
function sundaysAfterPentecost(date) {
  const easter = easterDate(date.getFullYear());
  const pentecost = addDays(easter, 49);
  const trinity = addDays(pentecost, 7);
  if (date < trinity) return 0;
  const diff = Math.floor((date - trinity) / (7 * 86400000));
  return diff + 1;
}

// ── A condensed RCL — the Sundays we expect to surface in-app ─
// Each key is a liturgical-Sunday id. Values give Year A/B/C tracks.
// Citations are real RCL appointments. (We supply Track 2 / Continuous in the
// few places RCL forks; this is appropriate for a parish app.)
const RCL_SUNDAYS = {
  // ── Advent ─────────────────────────────────────────
  advent1:   { name: 'First Sunday of Advent',        season: 'Advent',
    A: { first: 'Isaiah 2 : 1—5',     psalm: 'Psalm 122',     epistle: 'Romans 13 : 11—14',         gospel: 'Matthew 24 : 36—44',
         keyVerse: { text: 'Keep awake therefore, for you do not know on what day your Lord is coming.', cite: 'Matthew 24 : 42' } },
    B: { first: 'Isaiah 64 : 1—9',    psalm: 'Psalm 80 : 1—7, 17—19', epistle: '1 Corinthians 1 : 3—9', gospel: 'Mark 13 : 24—37',
         keyVerse: { text: 'Beware, keep alert; for you do not know when the time will come.', cite: 'Mark 13 : 33' } },
    C: { first: 'Jeremiah 33 : 14—16', psalm: 'Psalm 25 : 1—10', epistle: '1 Thessalonians 3 : 9—13', gospel: 'Luke 21 : 25—36',
         keyVerse: { text: 'Stand up and raise your heads, because your redemption is drawing near.', cite: 'Luke 21 : 28' } },
  },
  advent2:   { name: 'Second Sunday of Advent',       season: 'Advent',
    A: { first: 'Isaiah 11 : 1—10',   psalm: 'Psalm 72 : 1—7, 18—19', epistle: 'Romans 15 : 4—13',  gospel: 'Matthew 3 : 1—12',
         keyVerse: { text: 'Prepare the way of the Lord, make his paths straight.', cite: 'Matthew 3 : 3' } },
    B: { first: 'Isaiah 40 : 1—11',   psalm: 'Psalm 85 : 1—2, 8—13',  epistle: '2 Peter 3 : 8—15a', gospel: 'Mark 1 : 1—8',
         keyVerse: { text: 'Comfort, O comfort my people, says your God.', cite: 'Isaiah 40 : 1' } },
    C: { first: 'Malachi 3 : 1—4',    psalm: 'Luke 1 : 68—79',         epistle: 'Philippians 1 : 3—11', gospel: 'Luke 3 : 1—6',
         keyVerse: { text: 'Every valley shall be filled, and every mountain and hill shall be made low.', cite: 'Luke 3 : 5' } },
  },
  advent3:   { name: 'Third Sunday of Advent · Gaudete', season: 'Advent',
    A: { first: 'Isaiah 35 : 1—10',   psalm: 'Psalm 146 : 5—10',      epistle: 'James 5 : 7—10',     gospel: 'Matthew 11 : 2—11',
         keyVerse: { text: 'The blind receive their sight, the lame walk, the lepers are cleansed, the deaf hear.', cite: 'Matthew 11 : 5' } },
    B: { first: 'Isaiah 61 : 1—4, 8—11', psalm: 'Psalm 126',           epistle: '1 Thessalonians 5 : 16—24', gospel: 'John 1 : 6—8, 19—28',
         keyVerse: { text: 'Rejoice always, pray without ceasing, give thanks in all circumstances.', cite: '1 Thessalonians 5 : 16—18' } },
    C: { first: 'Zephaniah 3 : 14—20', psalm: 'Isaiah 12 : 2—6',       epistle: 'Philippians 4 : 4—7', gospel: 'Luke 3 : 7—18',
         keyVerse: { text: 'Rejoice in the Lord always; again I will say, Rejoice.', cite: 'Philippians 4 : 4' } },
  },
  advent4:   { name: 'Fourth Sunday of Advent',       season: 'Advent',
    A: { first: 'Isaiah 7 : 10—16',   psalm: 'Psalm 80 : 1—7, 17—19', epistle: 'Romans 1 : 1—7',     gospel: 'Matthew 1 : 18—25',
         keyVerse: { text: 'They shall name him Emmanuel, which means, "God is with us."', cite: 'Matthew 1 : 23' } },
    B: { first: '2 Samuel 7 : 1—11, 16', psalm: 'Luke 1 : 47—55',     epistle: 'Romans 16 : 25—27',  gospel: 'Luke 1 : 26—38',
         keyVerse: { text: 'For nothing will be impossible with God.', cite: 'Luke 1 : 37' } },
    C: { first: 'Micah 5 : 2—5a',     psalm: 'Luke 1 : 47—55',         epistle: 'Hebrews 10 : 5—10',  gospel: 'Luke 1 : 39—45',
         keyVerse: { text: 'Blessed are you among women, and blessed is the fruit of your womb.', cite: 'Luke 1 : 42' } },
  },
  // ── Christmas / Epiphany ───────────────────────────
  christmas: { name: 'The Nativity of Our Lord',      season: 'Christmas',
    A: { first: 'Isaiah 9 : 2—7', psalm: 'Psalm 96',  epistle: 'Titus 2 : 11—14', gospel: 'Luke 2 : 1—20',
         keyVerse: { text: 'For unto us a child is born, unto us a son is given.', cite: 'Isaiah 9 : 6' } },
    B: { first: 'Isaiah 9 : 2—7', psalm: 'Psalm 96',  epistle: 'Titus 2 : 11—14', gospel: 'Luke 2 : 1—20',
         keyVerse: { text: 'To you is born this day in the city of David a Savior, who is the Messiah, the Lord.', cite: 'Luke 2 : 11' } },
    C: { first: 'Isaiah 9 : 2—7', psalm: 'Psalm 96',  epistle: 'Titus 2 : 11—14', gospel: 'Luke 2 : 1—20',
         keyVerse: { text: 'Glory to God in the highest heaven, and on earth peace among those whom he favors.', cite: 'Luke 2 : 14' } },
  },
  epiphany:  { name: 'The Epiphany of Our Lord',      season: 'Epiphany',
    A: { first: 'Isaiah 60 : 1—6', psalm: 'Psalm 72 : 1—7, 10—14', epistle: 'Ephesians 3 : 1—12', gospel: 'Matthew 2 : 1—12',
         keyVerse: { text: 'We observed his star at its rising, and have come to pay him homage.', cite: 'Matthew 2 : 2' } },
    B: { first: 'Isaiah 60 : 1—6', psalm: 'Psalm 72 : 1—7, 10—14', epistle: 'Ephesians 3 : 1—12', gospel: 'Matthew 2 : 1—12',
         keyVerse: { text: 'Arise, shine, for your light has come, and the glory of the Lord has risen upon you.', cite: 'Isaiah 60 : 1' } },
    C: { first: 'Isaiah 60 : 1—6', psalm: 'Psalm 72 : 1—7, 10—14', epistle: 'Ephesians 3 : 1—12', gospel: 'Matthew 2 : 1—12',
         keyVerse: { text: 'Nations shall come to your light, and kings to the brightness of your dawn.', cite: 'Isaiah 60 : 3' } },
  },
  baptism:   { name: 'The Baptism of Our Lord',       season: 'Epiphany',
    A: { first: 'Isaiah 42 : 1—9',   psalm: 'Psalm 29', epistle: 'Acts 10 : 34—43', gospel: 'Matthew 3 : 13—17',
         keyVerse: { text: 'This is my Son, the Beloved, with whom I am well pleased.', cite: 'Matthew 3 : 17' } },
    B: { first: 'Genesis 1 : 1—5',   psalm: 'Psalm 29', epistle: 'Acts 19 : 1—7',   gospel: 'Mark 1 : 4—11',
         keyVerse: { text: 'You are my Son, the Beloved; with you I am well pleased.', cite: 'Mark 1 : 11' } },
    C: { first: 'Isaiah 43 : 1—7',   psalm: 'Psalm 29', epistle: 'Acts 8 : 14—17',  gospel: 'Luke 3 : 15—17, 21—22',
         keyVerse: { text: 'Do not fear, for I have redeemed you; I have called you by name, you are mine.', cite: 'Isaiah 43 : 1' } },
  },
  transfig:  { name: 'The Transfiguration of Our Lord', season: 'Epiphany',
    A: { first: 'Exodus 24 : 12—18', psalm: 'Psalm 2',  epistle: '2 Peter 1 : 16—21', gospel: 'Matthew 17 : 1—9',
         keyVerse: { text: 'This is my Son, the Beloved; with him I am well pleased; listen to him!', cite: 'Matthew 17 : 5' } },
    B: { first: '2 Kings 2 : 1—12',  psalm: 'Psalm 50 : 1—6', epistle: '2 Corinthians 4 : 3—6', gospel: 'Mark 9 : 2—9',
         keyVerse: { text: 'This is my Son, the Beloved; listen to him!', cite: 'Mark 9 : 7' } },
    C: { first: 'Exodus 34 : 29—35', psalm: 'Psalm 99', epistle: '2 Corinthians 3 : 12 — 4 : 2', gospel: 'Luke 9 : 28—43a',
         keyVerse: { text: 'This is my Son, my Chosen; listen to him!', cite: 'Luke 9 : 35' } },
  },
  // ── Lent ───────────────────────────────────────────
  ashwed:    { name: 'Ash Wednesday',                 season: 'Lent',
    A: { first: 'Joel 2 : 1—2, 12—17', psalm: 'Psalm 51 : 1—17', epistle: '2 Corinthians 5 : 20b — 6 : 10', gospel: 'Matthew 6 : 1—6, 16—21',
         keyVerse: { text: 'Yet even now, says the Lord, return to me with all your heart.', cite: 'Joel 2 : 12' } },
    B: { first: 'Joel 2 : 1—2, 12—17', psalm: 'Psalm 51 : 1—17', epistle: '2 Corinthians 5 : 20b — 6 : 10', gospel: 'Matthew 6 : 1—6, 16—21',
         keyVerse: { text: 'Create in me a clean heart, O God, and put a new and right spirit within me.', cite: 'Psalm 51 : 10' } },
    C: { first: 'Joel 2 : 1—2, 12—17', psalm: 'Psalm 51 : 1—17', epistle: '2 Corinthians 5 : 20b — 6 : 10', gospel: 'Matthew 6 : 1—6, 16—21',
         keyVerse: { text: 'Where your treasure is, there your heart will be also.', cite: 'Matthew 6 : 21' } },
  },
  lent1:     { name: 'First Sunday in Lent',          season: 'Lent',
    A: { first: 'Genesis 2 : 15—17, 3 : 1—7', psalm: 'Psalm 32', epistle: 'Romans 5 : 12—19', gospel: 'Matthew 4 : 1—11',
         keyVerse: { text: 'One does not live by bread alone, but by every word that comes from the mouth of God.', cite: 'Matthew 4 : 4' } },
    B: { first: 'Genesis 9 : 8—17', psalm: 'Psalm 25 : 1—10', epistle: '1 Peter 3 : 18—22', gospel: 'Mark 1 : 9—15',
         keyVerse: { text: 'The kingdom of God has come near; repent, and believe in the good news.', cite: 'Mark 1 : 15' } },
    C: { first: 'Deuteronomy 26 : 1—11', psalm: 'Psalm 91 : 1—2, 9—16', epistle: 'Romans 10 : 8b—13', gospel: 'Luke 4 : 1—13',
         keyVerse: { text: 'Worship the Lord your God, and serve only him.', cite: 'Luke 4 : 8' } },
  },
  lent2:     { name: 'Second Sunday in Lent',         season: 'Lent',
    A: { first: 'Genesis 12 : 1—4a', psalm: 'Psalm 121',     epistle: 'Romans 4 : 1—5, 13—17', gospel: 'John 3 : 1—17',
         keyVerse: { text: 'For God so loved the world that he gave his only Son.', cite: 'John 3 : 16' } },
    B: { first: 'Genesis 17 : 1—7, 15—16', psalm: 'Psalm 22 : 23—31', epistle: 'Romans 4 : 13—25', gospel: 'Mark 8 : 31—38',
         keyVerse: { text: 'If any want to become my followers, let them deny themselves and take up their cross and follow me.', cite: 'Mark 8 : 34' } },
    C: { first: 'Genesis 15 : 1—12, 17—18', psalm: 'Psalm 27', epistle: 'Philippians 3 : 17 — 4 : 1', gospel: 'Luke 13 : 31—35',
         keyVerse: { text: 'The Lord is my light and my salvation; whom shall I fear?', cite: 'Psalm 27 : 1' } },
  },
  lent3:     { name: 'Third Sunday in Lent',          season: 'Lent',
    A: { first: 'Exodus 17 : 1—7',  psalm: 'Psalm 95',  epistle: 'Romans 5 : 1—11',     gospel: 'John 4 : 5—42',
         keyVerse: { text: 'The water that I will give will become in them a spring of water gushing up to eternal life.', cite: 'John 4 : 14' } },
    B: { first: 'Exodus 20 : 1—17', psalm: 'Psalm 19',  epistle: '1 Corinthians 1 : 18—25', gospel: 'John 2 : 13—22',
         keyVerse: { text: 'For the message about the cross is foolishness to those who are perishing, but to us who are being saved it is the power of God.', cite: '1 Corinthians 1 : 18' } },
    C: { first: 'Isaiah 55 : 1—9',  psalm: 'Psalm 63 : 1—8', epistle: '1 Corinthians 10 : 1—13', gospel: 'Luke 13 : 1—9',
         keyVerse: { text: 'Seek the Lord while he may be found, call upon him while he is near.', cite: 'Isaiah 55 : 6' } },
  },
  lent4:     { name: 'Fourth Sunday in Lent · Laetare', season: 'Lent',
    A: { first: '1 Samuel 16 : 1—13', psalm: 'Psalm 23', epistle: 'Ephesians 5 : 8—14', gospel: 'John 9 : 1—41',
         keyVerse: { text: 'I am the light of the world.', cite: 'John 9 : 5' } },
    B: { first: 'Numbers 21 : 4—9',   psalm: 'Psalm 107 : 1—3, 17—22', epistle: 'Ephesians 2 : 1—10', gospel: 'John 3 : 14—21',
         keyVerse: { text: 'For God so loved the world that he gave his only Son, so that everyone who believes in him may not perish but may have eternal life.', cite: 'John 3 : 16' } },
    C: { first: 'Joshua 5 : 9—12',    psalm: 'Psalm 32', epistle: '2 Corinthians 5 : 16—21', gospel: 'Luke 15 : 1—3, 11b—32',
         keyVerse: { text: 'While he was still far off, his father saw him and was filled with compassion; he ran and put his arms around him.', cite: 'Luke 15 : 20' } },
  },
  lent5:     { name: 'Fifth Sunday in Lent',          season: 'Lent',
    A: { first: 'Ezekiel 37 : 1—14',  psalm: 'Psalm 130', epistle: 'Romans 8 : 6—11', gospel: 'John 11 : 1—45',
         keyVerse: { text: 'I am the resurrection and the life. Those who believe in me, even though they die, will live.', cite: 'John 11 : 25' } },
    B: { first: 'Jeremiah 31 : 31—34', psalm: 'Psalm 51 : 1—12', epistle: 'Hebrews 5 : 5—10', gospel: 'John 12 : 20—33',
         keyVerse: { text: 'Unless a grain of wheat falls into the earth and dies, it remains just a single grain; but if it dies, it bears much fruit.', cite: 'John 12 : 24' } },
    C: { first: 'Isaiah 43 : 16—21',  psalm: 'Psalm 126', epistle: 'Philippians 3 : 4b—14', gospel: 'John 12 : 1—8',
         keyVerse: { text: 'I am about to do a new thing; now it springs forth, do you not perceive it?', cite: 'Isaiah 43 : 19' } },
  },
  palm:      { name: 'Palm Sunday',                   season: 'Lent',
    A: { first: 'Isaiah 50 : 4—9a', psalm: 'Psalm 31 : 9—16', epistle: 'Philippians 2 : 5—11', gospel: 'Matthew 26 : 14 — 27 : 66',
         keyVerse: { text: 'Hosanna to the Son of David! Blessed is the one who comes in the name of the Lord!', cite: 'Matthew 21 : 9' } },
    B: { first: 'Isaiah 50 : 4—9a', psalm: 'Psalm 31 : 9—16', epistle: 'Philippians 2 : 5—11', gospel: 'Mark 14 : 1 — 15 : 47',
         keyVerse: { text: 'And being found in human form, he humbled himself and became obedient to the point of death—even death on a cross.', cite: 'Philippians 2 : 8' } },
    C: { first: 'Isaiah 50 : 4—9a', psalm: 'Psalm 31 : 9—16', epistle: 'Philippians 2 : 5—11', gospel: 'Luke 22 : 14 — 23 : 56',
         keyVerse: { text: 'Therefore God also highly exalted him and gave him the name that is above every name.', cite: 'Philippians 2 : 9' } },
  },
  goodfri:   { name: 'Good Friday',                   season: 'Holy Week',
    A: { first: 'Isaiah 52 : 13 — 53 : 12', psalm: 'Psalm 22', epistle: 'Hebrews 10 : 16—25', gospel: 'John 18 : 1 — 19 : 42',
         keyVerse: { text: 'It is finished.', cite: 'John 19 : 30' } },
    B: { first: 'Isaiah 52 : 13 — 53 : 12', psalm: 'Psalm 22', epistle: 'Hebrews 10 : 16—25', gospel: 'John 18 : 1 — 19 : 42',
         keyVerse: { text: 'But he was wounded for our transgressions, crushed for our iniquities; by his bruises we are healed.', cite: 'Isaiah 53 : 5' } },
    C: { first: 'Isaiah 52 : 13 — 53 : 12', psalm: 'Psalm 22', epistle: 'Hebrews 10 : 16—25', gospel: 'John 18 : 1 — 19 : 42',
         keyVerse: { text: 'Father, into your hands I commend my spirit.', cite: 'Luke 23 : 46' } },
  },
  easter:    { name: 'Easter Sunday',                 season: 'Easter',
    A: { first: 'Acts 10 : 34—43',   psalm: 'Psalm 118 : 1—2, 14—24', epistle: 'Colossians 3 : 1—4', gospel: 'John 20 : 1—18',
         keyVerse: { text: 'I have seen the Lord!', cite: 'John 20 : 18' } },
    B: { first: 'Acts 10 : 34—43',   psalm: 'Psalm 118 : 1—2, 14—24', epistle: '1 Corinthians 15 : 1—11', gospel: 'Mark 16 : 1—8',
         keyVerse: { text: 'He has been raised; he is not here.', cite: 'Mark 16 : 6' } },
    C: { first: 'Acts 10 : 34—43',   psalm: 'Psalm 118 : 1—2, 14—24', epistle: '1 Corinthians 15 : 19—26', gospel: 'John 20 : 1—18',
         keyVerse: { text: 'This is the day that the Lord has made; let us rejoice and be glad in it.', cite: 'Psalm 118 : 24' } },
  },
  easter2:   { name: 'Second Sunday of Easter',       season: 'Easter',
    A: { first: 'Acts 2 : 14a, 22—32', psalm: 'Psalm 16', epistle: '1 Peter 1 : 3—9', gospel: 'John 20 : 19—31',
         keyVerse: { text: 'Blessed are those who have not seen and yet have come to believe.', cite: 'John 20 : 29' } },
    B: { first: 'Acts 4 : 32—35',     psalm: 'Psalm 133', epistle: '1 John 1 : 1 — 2 : 2', gospel: 'John 20 : 19—31',
         keyVerse: { text: 'Peace be with you. As the Father has sent me, so I send you.', cite: 'John 20 : 21' } },
    C: { first: 'Acts 5 : 27—32',     psalm: 'Psalm 118 : 14—29', epistle: 'Revelation 1 : 4—8', gospel: 'John 20 : 19—31',
         keyVerse: { text: 'I am the Alpha and the Omega, who is and who was and who is to come, the Almighty.', cite: 'Revelation 1 : 8' } },
  },
  easter3:   { name: 'Third Sunday of Easter',        season: 'Easter',
    A: { first: 'Acts 2 : 14a, 36—41', psalm: 'Psalm 116 : 1—4, 12—19', epistle: '1 Peter 1 : 17—23', gospel: 'Luke 24 : 13—35',
         keyVerse: { text: 'Were not our hearts burning within us while he was talking to us on the road, while he was opening the scriptures to us?', cite: 'Luke 24 : 32' } },
    B: { first: 'Acts 3 : 12—19',      psalm: 'Psalm 4',                epistle: '1 John 3 : 1—7',     gospel: 'Luke 24 : 36b—48',
         keyVerse: { text: 'See what love the Father has given us, that we should be called children of God; and that is what we are.', cite: '1 John 3 : 1' } },
    C: { first: 'Acts 9 : 1—6 (7—20)', psalm: 'Psalm 30',               epistle: 'Revelation 5 : 11—14', gospel: 'John 21 : 1—19',
         keyVerse: { text: 'Feed my sheep.', cite: 'John 21 : 17' } },
  },
  easter4:   { name: 'Fourth Sunday of Easter · Good Shepherd', season: 'Easter',
    A: { first: 'Acts 2 : 42—47',  psalm: 'Psalm 23', epistle: '1 Peter 2 : 19—25',  gospel: 'John 10 : 1—10',
         keyVerse: { text: 'I came that they may have life, and have it abundantly.', cite: 'John 10 : 10' } },
    B: { first: 'Acts 4 : 5—12',   psalm: 'Psalm 23', epistle: '1 John 3 : 16—24',   gospel: 'John 10 : 11—18',
         keyVerse: { text: 'I am the good shepherd. The good shepherd lays down his life for the sheep.', cite: 'John 10 : 11' } },
    C: { first: 'Acts 9 : 36—43',  psalm: 'Psalm 23', epistle: 'Revelation 7 : 9—17', gospel: 'John 10 : 22—30',
         keyVerse: { text: 'My sheep hear my voice. I know them, and they follow me.', cite: 'John 10 : 27' } },
  },
  easter5:   { name: 'Fifth Sunday of Easter',        season: 'Easter',
    A: { first: 'Acts 7 : 55—60',  psalm: 'Psalm 31 : 1—5, 15—16', epistle: '1 Peter 2 : 2—10', gospel: 'John 14 : 1—14',
         keyVerse: { text: 'I am the way, the truth, and the life.', cite: 'John 14 : 6' } },
    B: { first: 'Acts 8 : 26—40',  psalm: 'Psalm 22 : 25—31',       epistle: '1 John 4 : 7—21',  gospel: 'John 15 : 1—8',
         keyVerse: { text: 'I am the vine, you are the branches.', cite: 'John 15 : 5' } },
    C: { first: 'Acts 11 : 1—18',  psalm: 'Psalm 148',              epistle: 'Revelation 21 : 1—6', gospel: 'John 13 : 31—35',
         keyVerse: { text: 'By this everyone will know that you are my disciples, if you have love for one another.', cite: 'John 13 : 35' } },
  },
  easter6:   { name: 'Sixth Sunday of Easter',        season: 'Easter',
    A: { first: 'Acts 17 : 22—31', psalm: 'Psalm 66 : 8—20', epistle: '1 Peter 3 : 13—22', gospel: 'John 14 : 15—21',
         keyVerse: { text: 'I will not leave you orphaned; I am coming to you.', cite: 'John 14 : 18' } },
    B: { first: 'Acts 10 : 44—48', psalm: 'Psalm 98',         epistle: '1 John 5 : 1—6',    gospel: 'John 15 : 9—17',
         keyVerse: { text: 'You did not choose me, but I chose you.', cite: 'John 15 : 16' } },
    C: { first: 'Acts 16 : 9—15',  psalm: 'Psalm 67',         epistle: 'Revelation 21 : 10, 22 — 22 : 5', gospel: 'John 14 : 23—29',
         keyVerse: { text: 'Peace I leave with you; my peace I give to you.', cite: 'John 14 : 27' } },
  },
  easter7:   { name: 'Seventh Sunday of Easter',      season: 'Easter',
    A: { first: 'Acts 1 : 6—14',           psalm: 'Psalm 68 : 1—10, 32—35', epistle: '1 Peter 4 : 12—14, 5 : 6—11', gospel: 'John 17 : 1—11',
         keyVerse: { text: 'May they all be one, as you, Father, are in me and I am in you.', cite: 'John 17 : 21' } },
    B: { first: 'Acts 1 : 15—17, 21—26',   psalm: 'Psalm 1',                 epistle: '1 John 5 : 9—13',              gospel: 'John 17 : 6—19',
         keyVerse: { text: 'Sanctify them in the truth; your word is truth.', cite: 'John 17 : 17' } },
    C: { first: 'Acts 16 : 16—34',         psalm: 'Psalm 97',                epistle: 'Revelation 22 : 12—14, 16—17, 20—21', gospel: 'John 17 : 20—26',
         keyVerse: { text: 'I am the Alpha and the Omega, the first and the last, the beginning and the end.', cite: 'Revelation 22 : 13' } },
  },
  pentecost: { name: 'The Day of Pentecost',          season: 'Pentecost',
    A: { first: 'Acts 2 : 1—21',     psalm: 'Psalm 104 : 24—34, 35b', epistle: '1 Corinthians 12 : 3b—13', gospel: 'John 20 : 19—23',
         keyVerse: { text: 'All of them were filled with the Holy Spirit and began to speak in other languages, as the Spirit gave them ability.', cite: 'Acts 2 : 4' } },
    B: { first: 'Acts 2 : 1—21',     psalm: 'Psalm 104 : 24—34, 35b', epistle: 'Romans 8 : 22—27',         gospel: 'John 15 : 26—27, 16 : 4b—15',
         keyVerse: { text: 'When the Spirit of truth comes, he will guide you into all the truth.', cite: 'John 16 : 13' } },
    C: { first: 'Acts 2 : 1—21',     psalm: 'Psalm 104 : 24—34, 35b', epistle: 'Romans 8 : 14—17',         gospel: 'John 14 : 8—17, 25—27',
         keyVerse: { text: 'For all who are led by the Spirit of God are children of God.', cite: 'Romans 8 : 14' } },
  },
  trinity:   { name: 'Trinity Sunday',                season: 'Ordinary',
    A: { first: 'Genesis 1 : 1 — 2 : 4a', psalm: 'Psalm 8', epistle: '2 Corinthians 13 : 11—13', gospel: 'Matthew 28 : 16—20',
         keyVerse: { text: 'Go therefore and make disciples of all nations, baptizing them in the name of the Father and of the Son and of the Holy Spirit.', cite: 'Matthew 28 : 19' } },
    B: { first: 'Isaiah 6 : 1—8',         psalm: 'Psalm 29', epistle: 'Romans 8 : 12—17',        gospel: 'John 3 : 1—17',
         keyVerse: { text: 'Holy, holy, holy is the Lord of hosts; the whole earth is full of his glory.', cite: 'Isaiah 6 : 3' } },
    C: { first: 'Proverbs 8 : 1—4, 22—31', psalm: 'Psalm 8', epistle: 'Romans 5 : 1—5',          gospel: 'John 16 : 12—15',
         keyVerse: { text: 'Hope does not disappoint us, because God\'s love has been poured into our hearts through the Holy Spirit.', cite: 'Romans 5 : 5' } },
  },
  reign:     { name: 'Reign of Christ · Christ the King', season: 'Ordinary',
    A: { first: 'Ezekiel 34 : 11—16, 20—24', psalm: 'Psalm 100', epistle: 'Ephesians 1 : 15—23', gospel: 'Matthew 25 : 31—46',
         keyVerse: { text: 'Just as you did it to one of the least of these who are members of my family, you did it to me.', cite: 'Matthew 25 : 40' } },
    B: { first: '2 Samuel 23 : 1—7',          psalm: 'Psalm 132 : 1—12', epistle: 'Revelation 1 : 4b—8', gospel: 'John 18 : 33—37',
         keyVerse: { text: 'My kingdom is not from this world.', cite: 'John 18 : 36' } },
    C: { first: 'Jeremiah 23 : 1—6',          psalm: 'Luke 1 : 68—79',   epistle: 'Colossians 1 : 11—20', gospel: 'Luke 23 : 33—43',
         keyVerse: { text: 'Truly I tell you, today you will be with me in Paradise.', cite: 'Luke 23 : 43' } },
  },
  // Generic Ordinary Time fallback
  ordinary:  { name: 'Sunday after Pentecost',         season: 'Ordinary',
    A: { first: '1 Kings 19 : 9—18',  psalm: 'Psalm 85 : 8—13',  epistle: 'Romans 10 : 5—15',  gospel: 'Matthew 14 : 22—33',
         keyVerse: { text: 'Take heart, it is I; do not be afraid.', cite: 'Matthew 14 : 27' } },
    B: { first: '2 Kings 5 : 1—14',   psalm: 'Psalm 30',         epistle: 'Galatians 6 : 7—16', gospel: 'Luke 10 : 1—11',
         keyVerse: { text: 'Bear one another\'s burdens, and in this way you will fulfill the law of Christ.', cite: 'Galatians 6 : 2' } },
    C: { first: 'Isaiah 1 : 1, 10—20', psalm: 'Psalm 50 : 1—8, 22—23', epistle: 'Hebrews 11 : 1—3, 8—16', gospel: 'Luke 12 : 32—40',
         keyVerse: { text: 'Now faith is the assurance of things hoped for, the conviction of things not seen.', cite: 'Hebrews 11 : 1' } },
  },
};

// Today's lectionary id (for arbitrary date) — what Sunday's readings apply?
function rclSundayId(date = new Date()) {
  const y = date.getFullYear();
  const easter = easterDate(y);
  const ashWed = addDays(easter, -46);
  const palmSun = addDays(easter, -7);
  const goodFri = addDays(easter, -2);
  const pentecost = addDays(easter, 49);
  const trinity = addDays(pentecost, 7);
  const adv = firstSundayAdvent(y);
  const sameDay = (a, b) => a.toDateString() === b.toDateString();
  const between = (start, end) => date >= start && date < end;

  // Specific feast days first
  if (sameDay(date, ashWed))    return 'ashwed';
  if (sameDay(date, palmSun))   return 'palm';
  if (sameDay(date, goodFri))   return 'goodfri';
  if (sameDay(date, easter))    return 'easter';
  if (sameDay(date, pentecost)) return 'pentecost';
  if (sameDay(date, trinity))   return 'trinity';
  if (date.getMonth() === 11 && date.getDate() === 25) return 'christmas';
  if (date.getMonth() === 0  && date.getDate() === 6)  return 'epiphany';

  // Lent — Sundays after Ash Wed
  if (between(addDays(ashWed, 1), palmSun)) {
    const w = Math.floor((date - addDays(ashWed, 4)) / (7 * 86400000));
    return ['lent1','lent2','lent3','lent4','lent5'][Math.min(4, Math.max(0, w))];
  }
  // Eastertide — distinguish Easter 2 through Easter 7
  if (between(addDays(easter, 1), pentecost)) {
    const w = Math.floor((date - easter) / (7 * 86400000));
    return ['easter','easter2','easter3','easter4','easter5','easter6','easter7'][Math.min(6, Math.max(0, w))];
  }
  // Advent
  const adventEnd = new Date(y, 11, 25);
  if (between(adv, adventEnd)) {
    const w = Math.floor((date - adv) / (7 * 86400000));
    return ['advent1','advent2','advent3','advent4'][Math.min(3, Math.max(0, w))];
  }
  // Last Sunday before Advent — Reign of Christ
  if (between(addDays(adv, -7), adv)) return 'reign';
  // Default
  return 'ordinary';
}

// ─────────────────────────────────────────────────────────────
// COLLECTS — one for each liturgical Sunday + ordinary Propers
// Drawn from the BCP / UMC Book of Worship tradition.
// ─────────────────────────────────────────────────────────────
const COLLECTS = {
  advent1:    'Almighty God, give us grace to cast away the works of darkness and to put on the armour of light, now in the time of this mortal life in which thy Son Jesus Christ came to visit us in great humility; that in the last day, when he shall come again in his glorious majesty to judge both the quick and the dead, we may rise to the life immortal; through him who liveth and reigneth with thee and the Holy Spirit, one God, now and ever.',
  advent2:    'Merciful God, who sent thy messengers the prophets to preach repentance and prepare the way for our salvation: Give us grace to heed their warnings and forsake our sins, that we may greet with joy the coming of Jesus Christ our Redeemer; who liveth and reigneth with thee and the Holy Spirit, one God, now and for ever.',
  advent3:    'Stir up thy power, O Lord, and with great might come among us; and, because we are sorely hindered by our sins, let thy bountiful grace and mercy speedily help and deliver us; through Jesus Christ our Lord, to whom, with thee and the Holy Spirit, be honour and glory, world without end.',
  advent4:    'Purify our conscience, Almighty God, by thy daily visitation, that thy Son Jesus Christ, at his coming, may find in us a mansion prepared for himself; who liveth and reigneth with thee and the Holy Spirit, one God, now and for ever.',
  christmas:  'O God, who hast caused this holy night to shine with the brightness of the true Light: Grant that we, who have known the mystery of that Light on earth, may also enjoy him perfectly in heaven; through Jesus Christ our Lord, who liveth and reigneth with thee in the unity of the Holy Spirit, one God, now and for ever.',
  epiphany:   'O God, who by the leading of a star didst manifest thy only-begotten Son to the peoples of the earth: Lead us, who know thee now by faith, to thy presence, where we may behold thy glory face to face; through Jesus Christ our Lord, who liveth and reigneth with thee and the Holy Spirit, one God, now and for ever.',
  baptism:    'Father in heaven, who at the baptism of Jesus in the river Jordan didst proclaim him thy beloved Son and anoint him with the Holy Spirit: Grant that all who are baptized into his name may keep the covenant they have made, and boldly confess him as Lord and Saviour; who liveth and reigneth with thee and the Holy Spirit, one God, in glory everlasting.',
  transfig:   'O God, who before the passion of thy only-begotten Son didst reveal his glory upon the holy mount: Grant unto us that, beholding by faith the light of his countenance, we may be strengthened to bear our cross and be changed into his likeness from glory to glory; through the same Jesus Christ our Lord.',
  ashwed:     'Almighty and everlasting God, who hatest nothing that thou hast made and dost forgive the sins of all those who are penitent: Create and make in us new and contrite hearts, that we, worthily lamenting our sins and acknowledging our wretchedness, may obtain of thee, the God of all mercy, perfect remission and forgiveness; through Jesus Christ our Lord.',
  lent1:      'Almighty God, whose blessed Son was led by the Spirit to be tempted of Satan: Come quickly to help us who are assaulted by many temptations; and, as thou knowest the weakness of every one of us, let each one find thee mighty to save; through Jesus Christ thy Son our Lord.',
  lent2:      'O God, whose glory it is always to have mercy: Be gracious to all who have gone astray from thy ways, and bring them again with penitent hearts and steadfast faith to embrace and hold fast the unchangeable truth of thy Word, Jesus Christ thy Son.',
  lent3:      'Almighty God, you know that we have no power in ourselves to help ourselves: Keep us both outwardly in our bodies and inwardly in our souls, that we may be defended from all adversities which may happen to the body, and from all evil thoughts which may assault and hurt the soul; through Jesus Christ our Lord.',
  lent4:      'Gracious Father, whose blessed Son Jesus Christ came down from heaven to be the true bread which giveth life to the world: Evermore give us this bread, that he may live in us, and we in him; who liveth and reigneth with thee and the Holy Spirit, one God, now and for ever.',
  lent5:      'Almighty God, you alone can bring into order the unruly wills and affections of sinners: Grant your people grace to love what you command and desire what you promise; that, among the swift and varied changes of the world, our hearts may surely there be fixed where true joys are to be found; through Jesus Christ our Lord.',
  palm:       'Almighty and everliving God, in tender love towards the human race thou didst send thy Son our Saviour Jesus Christ to take upon him our flesh, and to suffer death upon the cross: Grant that we may walk in the way of his suffering, and also share in his resurrection; who liveth and reigneth with thee and the Holy Spirit, one God, for ever and ever.',
  goodfri:    'Almighty God, we beseech thee graciously to behold this thy family, for which our Lord Jesus Christ was contented to be betrayed, and given up into the hands of sinners, and to suffer death upon the cross; who now liveth and reigneth with thee and the Holy Spirit, one God, for ever and ever.',
  easter:     'Almighty God, who through thine only-begotten Son Jesus Christ hast overcome death and opened unto us the gate of everlasting life: Grant that we, who celebrate with joy the day of the Lord\'s resurrection, may be raised from the death of sin by thy life-giving Spirit; through Jesus Christ our Lord, who liveth and reigneth with thee and the Holy Spirit, one God, now and for ever.',
  easter2:    'Almighty and everlasting God, who in the Paschal mystery hast established the new covenant of reconciliation: Grant that all who have been reborn into the fellowship of Christ\'s Body may show forth in their lives what they profess by their faith; through Jesus Christ our Lord.',
  easter3:    'O God, whose blessed Son did manifest himself to his disciples in the breaking of bread: Open the eyes of our faith, that we may behold him in all his redeeming work; who liveth and reigneth with thee and the Holy Spirit, one God, now and for ever.',
  easter4:    'O God, whose Son Jesus is the good shepherd of thy people: Grant that, when we hear his voice, we may know him who calleth us each by name, and follow where he doth lead; who liveth and reigneth with thee and the Holy Spirit, one God, for ever and ever.',
  easter5:    'Almighty God, whom truly to know is everlasting life: Grant us so perfectly to know thy Son Jesus Christ to be the way, the truth, and the life, that we may steadfastly follow his steps in the way that leadeth to eternal life; through the same Jesus Christ our Lord.',
  easter6:    'O God, who hast prepared for those who love thee such good things as pass our understanding: Pour into our hearts such love toward thee, that we, loving thee in all things and above all things, may obtain thy promises, which exceed all that we can desire; through Jesus Christ our Lord.',
  ascension:  'Almighty God, whose blessed Son our Saviour Jesus Christ ascended far above all heavens that he might fill all things: Mercifully give us faith to perceive that, according to his promise, he abideth with his Church on earth, even to the end of the ages; who liveth and reigneth with thee and the Holy Spirit, one God, in glory everlasting.',
  easter7:    'O God, the King of glory, who hast exalted thine only Son Jesus Christ with great triumph unto thy kingdom in heaven: We beseech thee, leave us not comfortless, but send to us thine Holy Spirit to strengthen us, and exalt us unto the same place whither our Saviour Christ is gone before; who liveth and reigneth with thee and the Holy Spirit, one God, world without end.',
  pentecost:  'Almighty God, on this day thou didst open the way of eternal life to every race and nation by the promised gift of thy Holy Spirit: Shed abroad this gift throughout the world by the preaching of the Gospel, that it may reach to the ends of the earth; through Jesus Christ our Lord, who liveth and reigneth with thee, in the unity of the same Spirit, one God, for ever and ever.',
  trinity:    'Almighty and everlasting God, who hast given unto us thy servants grace, by the confession of a true faith, to acknowledge the glory of the eternal Trinity, and in the power of the divine Majesty to worship the Unity: We beseech thee that thou wouldest keep us steadfast in this faith and worship, and bring us at last to see thee in thy one and eternal glory, O Father; who with the Son and the Holy Spirit livest and reignest, one God, for ever and ever.',
  reign:      'Almighty and everlasting God, whose will it is to restore all things in thy well-beloved Son, the King of kings and Lord of lords: Mercifully grant that the peoples of the earth, divided and enslaved by sin, may be freed and brought together under his most gracious rule; who liveth and reigneth with thee and the Holy Spirit, one God, now and for ever.',

  // Ordinary Time Propers — rotated by week-of-year as a fallback
  proper4:    'O God, from whom all good doth come: Grant that by thy holy inspiration we may think those things that are right, and by thy merciful guiding may perform the same; through Jesus Christ our Lord.',
  proper5:    'O Lord, from whom no secrets are hid: Cleanse the thoughts of our hearts by the inspiration of thy Holy Spirit, that we may perfectly love thee, and worthily magnify thy holy name; through Christ our Lord.',
  proper6:    'Keep, O Lord, thy household the Church in thy steadfast faith and love, that, through thy grace, we may proclaim thy truth with boldness and minister thy justice with compassion; for the sake of our Saviour Jesus Christ, who liveth and reigneth with thee and the Holy Spirit, one God, now and for ever.',
  proper7:    'O Lord, make us to have a perpetual fear and love of thy holy name, for thou never failest to help and govern those whom thou hast set upon the sure foundation of thy loving-kindness; through Jesus Christ our Lord.',
  proper8:    'Almighty God, thou hast built thy Church upon the foundation of the apostles and prophets, Jesus Christ himself being the head corner-stone: Grant us so to be joined together in unity of spirit by their teaching, that we may be made an holy temple acceptable unto thee; through Jesus Christ our Lord.',
  proper9:    'O God, who hast taught us to keep all thy commandments by loving thee and our neighbour: Grant us the grace of thy Holy Spirit, that we may be devoted to thee with our whole heart, and united to one another with pure affection; through Jesus Christ our Lord.',
  proper10:   'O Lord, mercifully receive the prayers of thy people who call upon thee, and grant that they may both perceive and know what things they ought to do, and also may have grace and power faithfully to fulfil them; through Jesus Christ our Lord.',
  proper11:   'Almighty God, the fountain of all wisdom, who knowest our necessities before we ask and our ignorance in asking: Have compassion on our weakness, and mercifully give us those things which for our unworthiness we dare not, and for our blindness we cannot ask; through the worthiness of thy Son Jesus Christ our Lord.',
  proper12:   'O God, the protector of all that trust in thee, without whom nothing is strong, nothing is holy: Increase and multiply upon us thy mercy; that, thou being our ruler and guide, we may so pass through things temporal that we finally lose not the things eternal; through Jesus Christ our Lord.',
  proper13:   'Let thy continual mercy, O Lord, cleanse and defend thy Church; and, because it cannot continue in safety without thy succour, preserve it evermore by thy help and goodness; through Jesus Christ our Lord.',
  proper14:   'Grant to us, O Lord, we beseech thee, the spirit to think and do always those things that are right, that we, who cannot exist without thee, may by thee be enabled to live according to thy will; through Jesus Christ our Lord.',
  proper15:   'Almighty God, who hast given thy only Son to be unto us both a sacrifice for sin and also an example of godly life: Give us grace that we may always most thankfully receive that his inestimable benefit, and also daily endeavour ourselves to follow the blessed steps of his most holy life; through the same Jesus Christ thy Son our Lord.',
  proper16:   'Grant, O merciful God, that thy Church, being gathered together in unity by thy Holy Spirit, may shew forth thy power among all peoples, to the glory of thy name; through Jesus Christ our Lord.',
  proper17:   'Lord of all power and might, the author and giver of all good things: Graft in our hearts the love of thy name, increase in us true religion, nourish us with all goodness, and bring forth in us the fruit of good works; through Jesus Christ our Lord.',
  proper18:   'Grant us, O Lord, we pray thee, to trust in thee with all our heart; seeing that, as thou dost alway resist the proud who confide in their own strength, so thou never dost forsake those who make their boast of thy mercy; through Jesus Christ our Lord.',
  proper19:   'O God, because without thee we are not able to please thee, mercifully grant that thy Holy Spirit may in all things direct and rule our hearts; through Jesus Christ our Lord.',
  proper20:   'Grant us, Lord, not to be anxious about earthly things, but to love things heavenly; and even now, while we are placed among things that are passing away, to hold fast to those that shall endure; through Jesus Christ our Lord.',
  proper21:   'O God, thou declarest thy almighty power chiefly in showing mercy and pity: Grant us the fullness of thy grace, that we, running to obtain thy promises, may be made partakers of thy heavenly treasure; through Jesus Christ our Lord.',
  proper22:   'Almighty and everlasting God, who art always more ready to hear than we to pray, and to give more than either we desire or deserve: Pour down upon us the abundance of thy mercy, forgiving us those things whereof our conscience is afraid, and giving us those good things for which we are not worthy to ask; through Jesus Christ our Lord.',
  proper23:   'Lord, we pray that thy grace may always precede and follow us, that we may continually be given to good works; through Jesus Christ our Lord.',
  proper24:   'Almighty and everlasting God, in Christ thou hast revealed thy glory among the nations: Preserve the works of thy mercy, that thy Church throughout the world may persevere with steadfast faith in the confession of thy name; through Jesus Christ our Lord.',
  proper25:   'Almighty and everlasting God, increase in us the gifts of faith, hope, and charity; and, that we may obtain that which thou dost promise, make us to love that which thou dost command; through Jesus Christ our Lord.',
  proper26:   'Almighty and merciful God, of whose only gift it cometh that thy faithful people do unto thee true and laudable service: Grant, we beseech thee, that we may so faithfully serve thee in this life, that we fail not finally to attain thy heavenly promises; through the merits of Jesus Christ our Lord.',
  proper27:   'O God, whose blessed Son came into the world that he might destroy the works of the devil and make us children of God and heirs of eternal life: Grant that, having this hope, we may purify ourselves even as he is pure; that, when he shall appear again with power and great glory, we may be made like unto him in his eternal and glorious kingdom; through the same Jesus Christ our Lord.',
  proper28:   'Blessed Lord, who hast caused all holy Scriptures to be written for our learning: Grant us so to hear them, read, mark, learn, and inwardly digest them, that, by patience and the comfort of thy holy Word, we may embrace and ever hold fast the blessed hope of everlasting life; through Jesus Christ our Lord.',
  proper29:   'Almighty and everlasting God, whose will it is to restore all things in thy well-beloved Son, the King of kings and Lord of lords: Mercifully grant that the peoples of the earth, divided and enslaved by sin, may be freed and brought together under his most gracious rule; who liveth and reigneth with thee and the Holy Spirit, one God, now and for ever.',
};

// Get the collect for a given date — same Sunday id as the readings,
// falling back to a Proper-N rotation through Ordinary Time.
function getCollect(date = new Date()) {
  const id = rclSundayId(date);
  if (COLLECTS[id]) return { id, text: COLLECTS[id], name: (RCL_SUNDAYS[id] && RCL_SUNDAYS[id].name) || '' };
  // Ordinary Time → use week-of-year mod 26 as a Proper rotation
  const start = new Date(date.getFullYear(), 0, 1);
  const week = Math.floor((date - start) / (7 * 24 * 3600 * 1000));
  const propers = ['proper4','proper5','proper6','proper7','proper8','proper9','proper10','proper11','proper12','proper13','proper14','proper15','proper16','proper17','proper18','proper19','proper20','proper21','proper22','proper23','proper24','proper25','proper26','proper27','proper28','proper29'];
  const pid = propers[week % propers.length];
  return { id: pid, text: COLLECTS[pid], name: 'Ordinary Time' };
}

// Public API: returns full readings for today (or any date) in the current RCL year.
function getRCLToday(date = new Date()) {
  const id = rclSundayId(date);
  const yr = rclYear(date);
  const entry = RCL_SUNDAYS[id] || RCL_SUNDAYS.ordinary;
  const readings = entry[yr] || entry.A;
  // Find next Sunday for the date these readings will be used
  const targetDate = (id === 'goodfri' || id === 'ashwed' || id === 'christmas' || id === 'epiphany')
    ? date
    : (date.getDay() === 0 ? date : getNextSundayDate(date));
  return {
    id,
    name: entry.name,
    season: entry.season,
    year: yr,
    date: targetDate,
    readings,
  };
}

// Returns the "key verse" of the upcoming Sunday — the line we surface in the
// hero and on the share-card, tied to that Sunday's lectionary. Falls back to
// a small generic-verse pool when the Sunday entry doesn't have one curated.
function getKeyVerse(date = new Date()) {
  const id = rclSundayId(date);
  const yr = rclYear(date);
  const entry = RCL_SUNDAYS[id];
  if (entry && entry[yr] && entry[yr].keyVerse) {
    return { ...entry[yr].keyVerse, sundayName: entry.name, year: yr };
  }
  // Generic seasonal fallbacks
  const SEASONAL_VERSES = {
    Advent:    { text: 'Comfort, comfort my people, says your God.', cite: 'Isaiah 40 : 1' },
    Christmas: { text: 'For unto us a child is born, unto us a son is given.', cite: 'Isaiah 9 : 6' },
    Epiphany:  { text: 'In the beginning was the Word, and the Word was with God, and the Word was God.', cite: 'John 1 : 1' },
    Lent:      { text: 'Create in me a clean heart, O God, and renew a right spirit within me.', cite: 'Psalm 51 : 10' },
    Easter:    { text: 'I am the resurrection and the life.', cite: 'John 11 : 25' },
    Pentecost: { text: 'The fruit of the Spirit is love, joy, peace, patience, kindness.', cite: 'Galatians 5 : 22' },
    Ordinary:  { text: 'Be still, and know that I am God.', cite: 'Psalm 46 : 10' },
    'Holy Week': { text: 'Father, into your hands I commend my spirit.', cite: 'Luke 23 : 46' },
  };
  const season = (entry && entry.season) || 'Ordinary';
  const fallback = SEASONAL_VERSES[season] || SEASONAL_VERSES.Ordinary;
  return { ...fallback, sundayName: (entry && entry.name) || 'This Sunday', year: yr };
}

// ─────────────────────────────────────────────────────────────
// Hymn of the Week
// ─────────────────────────────────────────────────────────────
// Curated public-domain hymns, tagged by liturgical season. The week's hymn
// is selected by season then rotated by ISO-week index, so each Sunday brings
// a different one and the rotation repeats once you've cycled through all
// hymns for the current season. Charles Wesley is over-represented on
// purpose — this is a Methodist church.
//
// Audio: the `audio` field points to hymnary.org's hymn page, which has an
// embedded player. To replace with a self-hosted MP3, drop the file at
// /assets/hymns/{id}.mp3 and change the field to `'/assets/hymns/{id}.mp3'`.
// The component auto-detects file vs link.
const HYMNS = [
  // ── Advent ──
  {
    id: 'o-come-emmanuel',
    title: 'O Come, O Come, Emmanuel',
    author: 'Latin, 12th c. · tr. John Mason Neale, 1851',
    hymnal: 'UMH 211',
    seasons: ['advent'],
    stanzas: [
      'O come, O come, Emmanuel,\nand ransom captive Israel,\nthat mourns in lonely exile here\nuntil the Son of God appear.',
      'O come, thou Wisdom from on high,\nand order all things, far and nigh;\nto us the path of knowledge show,\nand cause us in her ways to go.',
      'O come, Desire of nations, bind\nall peoples in one heart and mind;\nbid envy, strife, and quarrels cease;\nfill the whole world with heaven\'s peace.',
    ],
    refrain: 'Rejoice! Rejoice! Emmanuel\nshall come to thee, O Israel.',
    audio: 'https://hymnary.org/hymn/UMH/211',
  },
  {
    id: 'come-thou-long-expected',
    title: 'Come, Thou Long-Expected Jesus',
    author: 'Charles Wesley, 1744',
    hymnal: 'UMH 196',
    seasons: ['advent'],
    stanzas: [
      'Come, thou long-expected Jesus,\nborn to set thy people free;\nfrom our fears and sins release us,\nlet us find our rest in thee.',
      'Israel\'s strength and consolation,\nhope of all the earth thou art;\ndear desire of every nation,\njoy of every longing heart.',
      'Born thy people to deliver,\nborn a child and yet a king,\nborn to reign in us forever,\nnow thy gracious kingdom bring.',
      'By thine own eternal Spirit\nrule in all our hearts alone;\nby thine all-sufficient merit\nraise us to thy glorious throne.',
    ],
    audio: 'https://hymnary.org/hymn/UMH/196',
  },
  // ── Christmas ──
  {
    id: 'hark-the-herald',
    title: 'Hark! The Herald Angels Sing',
    author: 'Charles Wesley, 1739',
    hymnal: 'UMH 240',
    seasons: ['christmas'],
    stanzas: [
      'Hark! the herald angels sing,\n"Glory to the newborn King;\npeace on earth, and mercy mild,\nGod and sinners reconciled!"\nJoyful, all ye nations rise,\njoin the triumph of the skies;\nwith th\'angelic host proclaim,\n"Christ is born in Bethlehem!"',
      'Christ, by highest heaven adored;\nChrist, the everlasting Lord!\nLate in time behold him come,\noffspring of a virgin\'s womb.\nVeiled in flesh the Godhead see;\nhail th\'incarnate Deity,\npleased with us in flesh to dwell,\nJesus, our Emmanuel.',
      'Hail the heaven-born Prince of Peace!\nHail the Sun of Righteousness!\nLight and life to all he brings,\nris\'n with healing in his wings.\nMild he lays his glory by,\nborn that we no more may die,\nborn to raise us from the earth,\nborn to give us second birth.',
    ],
    refrain: 'Hark! the herald angels sing,\n"Glory to the newborn King!"',
    audio: 'https://hymnary.org/hymn/UMH/240',
  },
  {
    id: 'joy-to-the-world',
    title: 'Joy to the World',
    author: 'Isaac Watts, 1719',
    hymnal: 'UMH 246',
    seasons: ['christmas'],
    stanzas: [
      'Joy to the world! the Lord is come;\nlet earth receive her King.\nLet every heart prepare him room,\nand heaven and nature sing,\nand heaven and nature sing,\nand heaven, and heaven and nature sing.',
      'Joy to the earth! the Savior reigns;\nlet all their songs employ,\nwhile fields and floods, rocks, hills, and plains\nrepeat the sounding joy.',
      'No more let sins and sorrows grow,\nnor thorns infest the ground;\nhe comes to make his blessings flow\nfar as the curse is found.',
      'He rules the world with truth and grace,\nand makes the nations prove\nthe glories of his righteousness\nand wonders of his love.',
    ],
    audio: 'https://hymnary.org/hymn/UMH/246',
  },
  // ── Epiphany ──
  {
    id: 'we-three-kings',
    title: 'We Three Kings',
    author: 'John Henry Hopkins Jr., 1857',
    hymnal: 'UMH 254',
    seasons: ['epiphany'],
    stanzas: [
      'We three kings of Orient are;\nbearing gifts we traverse afar,\nfield and fountain, moor and mountain,\nfollowing yonder star.',
      'Born a King on Bethlehem\'s plain,\ngold I bring to crown him again,\nKing forever, ceasing never\nover us all to reign.',
      'Frankincense to offer have I;\nincense owns a Deity nigh:\nprayer and praising, gladly raising,\nworshiping God Most High.',
      'Glorious now behold him arise,\nKing and God and Sacrifice;\nheaven sings alleluia:\nalleluia the earth replies.',
    ],
    refrain: 'O star of wonder, star of light,\nstar with royal beauty bright,\nwestward leading, still proceeding,\nguide us to thy perfect light.',
    audio: 'https://hymnary.org/hymn/UMH/254',
  },
  {
    id: 'as-with-gladness',
    title: 'As With Gladness Men of Old',
    author: 'William Chatterton Dix, 1860',
    hymnal: 'UMH 220',
    seasons: ['epiphany'],
    stanzas: [
      'As with gladness men of old\ndid the guiding star behold;\nas with joy they hailed its light,\nleading onward, beaming bright;\nso, most gracious God, may we\nevermore be led to thee.',
      'As with joyful steps they sped,\nSavior, to thy lowly bed,\nthere to bend the knee before\nthee, whom heaven and earth adore;\nso may we with willing feet\never seek thy mercy seat.',
      'As they offered gifts most rare\nat thy cradle, rude and bare,\nso may we with holy joy,\npure and free from sin\'s alloy,\nall our costliest treasures bring,\nChrist, to thee, our heavenly King.',
    ],
    audio: 'https://hymnary.org/hymn/UMH/220',
  },
  // ── Lent ──
  {
    id: 'when-i-survey',
    title: 'When I Survey the Wondrous Cross',
    author: 'Isaac Watts, 1707',
    hymnal: 'UMH 298',
    seasons: ['lent'],
    stanzas: [
      'When I survey the wondrous cross\non which the Prince of glory died,\nmy richest gain I count but loss,\nand pour contempt on all my pride.',
      'Forbid it, Lord, that I should boast,\nsave in the death of Christ my God!\nAll the vain things that charm me most,\nI sacrifice them to his blood.',
      'See from his head, his hands, his feet,\nsorrow and love flow mingled down!\nDid e\'er such love and sorrow meet,\nor thorns compose so rich a crown?',
      'Were the whole realm of nature mine,\nthat were a present far too small;\nlove so amazing, so divine,\ndemands my soul, my life, my all.',
    ],
    audio: 'https://hymnary.org/hymn/UMH/298',
  },
  {
    id: 'what-wondrous-love',
    title: 'What Wondrous Love Is This',
    author: 'American folk hymn, c. 1811',
    hymnal: 'UMH 292',
    seasons: ['lent'],
    stanzas: [
      'What wondrous love is this, O my soul, O my soul!\nWhat wondrous love is this, O my soul!\nWhat wondrous love is this that caused the Lord of bliss\nto bear the dreadful curse for my soul, for my soul,\nto bear the dreadful curse for my soul!',
      'When I was sinking down, sinking down, sinking down,\nwhen I was sinking down, sinking down,\nwhen I was sinking down beneath God\'s righteous frown,\nChrist laid aside his crown for my soul, for my soul,\nChrist laid aside his crown for my soul.',
      'To God and to the Lamb, I will sing, I will sing;\nto God and to the Lamb, I will sing.\nTo God and to the Lamb who is the great I AM,\nwhile millions join the theme, I will sing, I will sing,\nwhile millions join the theme, I will sing.',
    ],
    audio: 'https://hymnary.org/hymn/UMH/292',
  },
  // ── Holy Week ──
  {
    id: 'were-you-there',
    title: 'Were You There',
    author: 'African American spiritual',
    hymnal: 'UMH 288',
    seasons: ['holy_week'],
    stanzas: [
      'Were you there when they crucified my Lord?\nWere you there when they crucified my Lord?\nO! Sometimes it causes me to tremble, tremble, tremble.\nWere you there when they crucified my Lord?',
      'Were you there when they nailed him to the tree?\nWere you there when they nailed him to the tree?\nO! Sometimes it causes me to tremble, tremble, tremble.\nWere you there when they nailed him to the tree?',
      'Were you there when they laid him in the tomb?\nWere you there when they laid him in the tomb?\nO! Sometimes it causes me to tremble, tremble, tremble.\nWere you there when they laid him in the tomb?',
    ],
    audio: 'https://hymnary.org/hymn/UMH/288',
  },
  // ── Easter ──
  {
    id: 'christ-the-lord-is-risen',
    title: 'Christ the Lord Is Risen Today',
    author: 'Charles Wesley, 1739',
    hymnal: 'UMH 302',
    seasons: ['easter'],
    stanzas: [
      'Christ the Lord is risen today, Alleluia!\nEarth and heaven in chorus say, Alleluia!\nRaise your joys and triumphs high, Alleluia!\nSing, ye heavens, and earth reply, Alleluia!',
      'Love\'s redeeming work is done, Alleluia!\nFought the fight, the battle won, Alleluia!\nDeath in vain forbids him rise, Alleluia!\nChrist has opened paradise, Alleluia!',
      'Lives again our glorious King, Alleluia!\nWhere, O death, is now thy sting? Alleluia!\nDying once, he all doth save, Alleluia!\nWhere thy victory, O grave? Alleluia!',
      'Soar we now where Christ has led, Alleluia!\nFollowing our exalted Head, Alleluia!\nMade like him, like him we rise, Alleluia!\nOurs the cross, the grave, the skies, Alleluia!',
    ],
    audio: 'https://hymnary.org/hymn/UMH/302',
  },
  {
    id: 'thine-be-the-glory',
    title: 'Thine Be the Glory',
    author: 'Edmond Budry, 1884 · tr. Richard Hoyle, 1923',
    hymnal: 'UMH 308',
    seasons: ['easter'],
    stanzas: [
      'Thine be the glory, risen, conquering Son;\nendless is the victory thou o\'er death hast won.\nAngels in bright raiment rolled the stone away,\nkept the folded grave-clothes where thy body lay.',
      'Lo! Jesus meets us, risen from the tomb;\nlovingly he greets us, scatters fear and gloom;\nlet the church with gladness hymns of triumph sing,\nfor the Lord now liveth; death hath lost its sting.',
      'No more we doubt thee, glorious Prince of life;\nlife is naught without thee: aid us in our strife;\nmake us more than conquerors, through thy deathless love;\nbring us safe through Jordan to thy home above.',
    ],
    refrain: 'Thine be the glory, risen, conquering Son;\nendless is the victory thou o\'er death hast won.',
    audio: 'https://hymnary.org/hymn/UMH/308',
  },
  // ── Pentecost ──
  {
    id: 'spirit-of-god-descend',
    title: 'Spirit of God, Descend Upon My Heart',
    author: 'George Croly, 1854',
    hymnal: 'UMH 500',
    seasons: ['pentecost'],
    stanzas: [
      'Spirit of God, descend upon my heart;\nwean it from earth, through all its pulses move;\nstoop to my weakness, mighty as thou art,\nand make me love thee as I ought to love.',
      'I ask no dream, no prophet ecstasies,\nno sudden rending of the veil of clay,\nno angel visitant, no opening skies;\nbut take the dimness of my soul away.',
      'Teach me to feel that thou art always nigh;\nteach me the struggles of the soul to bear,\nto check the rising doubt, the rebel sigh;\nteach me the patience of unanswered prayer.',
      'Teach me to love thee as thine angels love,\none holy passion filling all my frame;\nthe baptism of the heaven-descended Dove,\nmy heart an altar, and thy love the flame.',
    ],
    audio: 'https://hymnary.org/hymn/UMH/500',
  },
  {
    id: 'come-holy-ghost-our-hearts',
    title: 'Come, Holy Ghost, Our Hearts Inspire',
    author: 'Charles Wesley, 1740',
    hymnal: 'UMH 603',
    seasons: ['pentecost'],
    stanzas: [
      'Come, Holy Ghost, our hearts inspire,\nlet us thine influence prove;\nsource of the old prophetic fire,\nfountain of life and love.',
      'Come, Holy Ghost, for moved by thee\nthe prophets wrote and spoke;\nunlock the truth, thyself the key,\nunseal the sacred book.',
      'Expand thy wings, celestial Dove,\nbrood o\'er our nature\'s night;\non our disordered spirits move,\nand let there now be light.',
      'God, through himself, we then shall know\nif thou within us shine,\nand sound, with all thy saints below,\nthe depths of love divine.',
    ],
    audio: 'https://hymnary.org/hymn/UMH/603',
  },
  // ── Ordinary Time ──
  {
    id: 'holy-holy-holy',
    title: 'Holy, Holy, Holy! Lord God Almighty',
    author: 'Reginald Heber, 1826',
    hymnal: 'UMH 64',
    seasons: ['ordinary'],
    stanzas: [
      'Holy, holy, holy! Lord God Almighty!\nEarly in the morning our song shall rise to thee.\nHoly, holy, holy! Merciful and mighty,\nGod in three persons, blessed Trinity!',
      'Holy, holy, holy! All the saints adore thee,\ncasting down their golden crowns around the glassy sea;\ncherubim and seraphim falling down before thee,\nwho wert and art and evermore shalt be.',
      'Holy, holy, holy! Though the darkness hide thee,\nthough the eye of sinfulness thy glory may not see,\nonly thou art holy; there is none beside thee\nperfect in power, in love, and purity.',
      'Holy, holy, holy! Lord God Almighty!\nAll thy works shall praise thy name, in earth and sky and sea.\nHoly, holy, holy! Merciful and mighty,\nGod in three persons, blessed Trinity!',
    ],
    audio: 'https://hymnary.org/hymn/UMH/64',
  },
  {
    id: 'amazing-grace',
    title: 'Amazing Grace',
    author: 'John Newton, 1779',
    hymnal: 'UMH 378',
    seasons: ['ordinary', 'lent'],
    stanzas: [
      'Amazing grace! How sweet the sound\nthat saved a wretch like me!\nI once was lost, but now am found;\nwas blind, but now I see.',
      '\'Twas grace that taught my heart to fear,\nand grace my fears relieved;\nhow precious did that grace appear\nthe hour I first believed.',
      'Through many dangers, toils, and snares,\nI have already come;\n\'tis grace hath brought me safe thus far,\nand grace will lead me home.',
      'When we\'ve been there ten thousand years,\nbright shining as the sun,\nwe\'ve no less days to sing God\'s praise\nthan when we\'d first begun.',
    ],
    audio: 'https://hymnary.org/hymn/UMH/378',
  },
  {
    id: 'be-thou-my-vision',
    title: 'Be Thou My Vision',
    author: 'Irish, 8th c. · tr. Mary Byrne, 1905; Eleanor Hull, 1912',
    hymnal: 'UMH 451',
    seasons: ['ordinary'],
    stanzas: [
      'Be thou my vision, O Lord of my heart;\nnaught be all else to me, save that thou art.\nThou my best thought, by day or by night,\nwaking or sleeping, thy presence my light.',
      'Be thou my wisdom, and thou my true word;\nI ever with thee and thou with me, Lord;\nthou my great Father, I thy true son;\nthou in me dwelling, and I with thee one.',
      'Riches I heed not, nor man\'s empty praise,\nthou mine inheritance, now and always:\nthou and thou only, first in my heart,\nHigh King of heaven, my treasure thou art.',
      'High King of heaven, my victory won,\nmay I reach heaven\'s joys, O bright heaven\'s Sun!\nHeart of my own heart, whatever befall,\nstill be my vision, O Ruler of all.',
    ],
    audio: 'https://hymnary.org/hymn/UMH/451',
  },
  {
    id: 'a-mighty-fortress',
    title: 'A Mighty Fortress Is Our God',
    author: 'Martin Luther, 1529 · tr. Frederick H. Hedge, 1853',
    hymnal: 'UMH 110',
    seasons: ['ordinary'],
    stanzas: [
      'A mighty fortress is our God,\na bulwark never failing;\nour helper he, amid the flood\nof mortal ills prevailing.\nFor still our ancient foe\ndoth seek to work us woe;\nhis craft and power are great,\nand, armed with cruel hate,\non earth is not his equal.',
      'Did we in our own strength confide,\nour striving would be losing,\nwere not the right man on our side,\nthe man of God\'s own choosing.\nDost ask who that may be?\nChrist Jesus, it is he;\nLord Sabaoth, his name,\nfrom age to age the same,\nand he must win the battle.',
      'And though this world, with devils filled,\nshould threaten to undo us,\nwe will not fear, for God hath willed\nhis truth to triumph through us.\nThe Prince of Darkness grim,\nwe tremble not for him;\nhis rage we can endure,\nfor lo, his doom is sure;\none little word shall fell him.',
    ],
    audio: 'https://hymnary.org/hymn/UMH/110',
  },
  {
    id: 'love-divine',
    title: 'Love Divine, All Loves Excelling',
    author: 'Charles Wesley, 1747',
    hymnal: 'UMH 384',
    seasons: ['ordinary'],
    stanzas: [
      'Love divine, all loves excelling,\njoy of heaven, to earth come down,\nfix in us thy humble dwelling,\nall thy faithful mercies crown.\nJesus, thou art all compassion,\npure, unbounded love thou art;\nvisit us with thy salvation,\nenter every trembling heart.',
      'Breathe, O breathe thy loving Spirit\ninto every troubled breast;\nlet us all in thee inherit,\nlet us find the promised rest.\nTake away the love of sinning;\nAlpha and Omega be;\nend of faith, as its beginning,\nset our hearts at liberty.',
      'Finish then thy new creation;\npure and spotless let us be;\nlet us see thy great salvation\nperfectly restored in thee:\nchanged from glory into glory,\ntill in heaven we take our place,\ntill we cast our crowns before thee,\nlost in wonder, love, and praise.',
    ],
    audio: 'https://hymnary.org/hymn/UMH/384',
  },
  {
    id: 'and-can-it-be',
    title: 'And Can It Be That I Should Gain',
    author: 'Charles Wesley, 1738',
    hymnal: 'UMH 363',
    seasons: ['ordinary', 'easter'],
    stanzas: [
      'And can it be that I should gain\nan interest in the Savior\'s blood?\nDied he for me, who caused his pain?\nFor me, who him to death pursued?\nAmazing love! How can it be\nthat thou, my God, shouldst die for me?',
      'He left his Father\'s throne above,\nso free, so infinite his grace!\nEmptied himself of all but love,\nand bled for Adam\'s helpless race.\n\'Tis mercy all, immense and free;\nfor, O my God, it found out me!',
      'Long my imprisoned spirit lay\nfast bound in sin and nature\'s night;\nthine eye diffused a quickening ray;\nI woke, the dungeon flamed with light;\nmy chains fell off, my heart was free,\nI rose, went forth, and followed thee.',
      'No condemnation now I dread;\nJesus, and all in him, is mine!\nAlive in him, my living Head,\nand clothed in righteousness divine,\nbold I approach the eternal throne,\nand claim the crown, through Christ my own.',
    ],
    audio: 'https://hymnary.org/hymn/UMH/363',
  },
  {
    id: 'o-for-a-thousand-tongues',
    title: 'O for a Thousand Tongues to Sing',
    author: 'Charles Wesley, 1739',
    hymnal: 'UMH 57',
    seasons: ['ordinary'],
    stanzas: [
      'O for a thousand tongues to sing\nmy great Redeemer\'s praise,\nthe glories of my God and King,\nthe triumphs of his grace!',
      'My gracious Master and my God,\nassist me to proclaim,\nto spread through all the earth abroad\nthe honors of thy name.',
      'Jesus! the name that charms our fears,\nthat bids our sorrows cease;\n\'tis music in the sinner\'s ears,\n\'tis life, and health, and peace.',
      'He breaks the power of canceled sin,\nhe sets the prisoner free;\nhis blood can make the foulest clean;\nhis blood availed for me.',
    ],
    audio: 'https://hymnary.org/hymn/UMH/57',
  },
  {
    id: 'blessed-assurance',
    title: 'Blessed Assurance',
    author: 'Fanny Crosby, 1873',
    hymnal: 'UMH 369',
    seasons: ['ordinary'],
    stanzas: [
      'Blessed assurance, Jesus is mine!\nO what a foretaste of glory divine!\nHeir of salvation, purchase of God,\nborn of his Spirit, washed in his blood.',
      'Perfect submission, perfect delight,\nvisions of rapture now burst on my sight;\nangels descending bring from above\nechoes of mercy, whispers of love.',
      'Perfect submission, all is at rest;\nI in my Savior am happy and blest,\nwatching and waiting, looking above,\nfilled with his goodness, lost in his love.',
    ],
    refrain: 'This is my story, this is my song,\npraising my Savior all the day long;\nthis is my story, this is my song,\npraising my Savior all the day long.',
    audio: 'https://hymnary.org/hymn/UMH/369',
  },
  {
    id: 'it-is-well',
    title: 'It Is Well With My Soul',
    author: 'Horatio G. Spafford, 1873',
    hymnal: 'UMH 377',
    seasons: ['ordinary'],
    stanzas: [
      'When peace, like a river, attendeth my way,\nwhen sorrows like sea billows roll;\nwhatever my lot, thou hast taught me to say,\n"It is well, it is well with my soul."',
      'Though Satan should buffet, though trials should come,\nlet this blest assurance control,\nthat Christ has regarded my helpless estate,\nand hath shed his own blood for my soul.',
      'My sin, oh, the bliss of this glorious thought,\nmy sin, not in part, but the whole,\nis nailed to the cross, and I bear it no more;\npraise the Lord, praise the Lord, O my soul!',
      'And Lord, haste the day when the faith shall be sight,\nthe clouds be rolled back as a scroll,\nthe trump shall resound and the Lord shall descend;\neven so, it is well with my soul.',
    ],
    refrain: 'It is well with my soul,\nit is well, it is well with my soul.',
    audio: 'https://hymnary.org/hymn/UMH/377',
  },
  {
    id: 'for-all-the-saints',
    title: 'For All the Saints',
    author: 'William Walsham How, 1864',
    hymnal: 'UMH 711',
    seasons: ['ordinary'],
    stanzas: [
      'For all the saints, who from their labors rest,\nwho thee by faith before the world confessed,\nthy name, O Jesus, be forever blessed.\nAlleluia! Alleluia!',
      'Thou wast their rock, their fortress, and their might;\nthou, Lord, their captain in the well-fought fight;\nthou, in the darkness drear, their one true light.\nAlleluia! Alleluia!',
      'O may thy soldiers, faithful, true, and bold,\nfight as the saints who nobly fought of old,\nand win, with them, the victor\'s crown of gold.\nAlleluia! Alleluia!',
      'From earth\'s wide bounds, from ocean\'s farthest coast,\nthrough gates of pearl streams in the countless host,\nsinging to Father, Son, and Holy Ghost.\nAlleluia! Alleluia!',
    ],
    audio: 'https://hymnary.org/hymn/UMH/711',
  },
  {
    id: 'praise-to-the-lord',
    title: 'Praise to the Lord, the Almighty',
    author: 'Joachim Neander, 1680 · tr. Catherine Winkworth, 1863',
    hymnal: 'UMH 139',
    seasons: ['ordinary'],
    stanzas: [
      'Praise to the Lord, the Almighty, the King of creation!\nO my soul, praise him, for he is thy health and salvation!\nAll ye who hear, now to his temple draw near;\njoin me in glad adoration!',
      'Praise to the Lord, who o\'er all things so wondrously reigneth,\nshelters thee under his wings, yea, so gently sustaineth!\nHast thou not seen how thy desires e\'er have been\ngranted in what he ordaineth?',
      'Praise to the Lord, who doth prosper thy work and defend thee;\nsurely his goodness and mercy here daily attend thee.\nPonder anew what the Almighty can do,\nif with his love he befriend thee.',
      'Praise to the Lord! O let all that is in me adore him!\nAll that hath life and breath, come now with praises before him.\nLet the Amen sound from his people again;\ngladly forever adore him.',
    ],
    audio: 'https://hymnary.org/hymn/UMH/139',
  },
  {
    id: 'o-god-our-help',
    title: 'O God, Our Help in Ages Past',
    author: 'Isaac Watts, 1719',
    hymnal: 'UMH 117',
    seasons: ['ordinary'],
    stanzas: [
      'O God, our help in ages past,\nour hope for years to come,\nour shelter from the stormy blast,\nand our eternal home.',
      'Under the shadow of thy throne\nthy saints have dwelt secure;\nsufficient is thine arm alone,\nand our defense is sure.',
      'Before the hills in order stood,\nor earth received her frame,\nfrom everlasting thou art God,\nto endless years the same.',
      'O God, our help in ages past,\nour hope for years to come,\nbe thou our guard while life shall last,\nand our eternal home.',
    ],
    audio: 'https://hymnary.org/hymn/UMH/117',
  },
];

// ISO week of year — used to rotate hymns within a season.
function isoWeek(date) {
  const d = new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate()));
  const dayNum = d.getUTCDay() || 7;
  d.setUTCDate(d.getUTCDate() + 4 - dayNum);
  const yearStart = new Date(Date.UTC(d.getUTCFullYear(), 0, 1));
  return Math.ceil(((d - yearStart) / 86400000 + 1) / 7);
}

// Returns the hymn for the current week. Picks from hymns tagged for the
// current liturgical season; rotates by ISO week. Falls back to "ordinary"
// hymns if the season has no curated picks (rare).
function getHymnOfWeek(date = new Date()) {
  const seasons = (typeof getLiturgicalSeasons === 'function') ? getLiturgicalSeasons(date) : null;
  // Map our liturgical labels to hymn season tags
  const seasonMap = {
    'Advent': 'advent', 'Christmas': 'christmas', 'Epiphany': 'epiphany',
    'Lent': 'lent', 'Holy Week': 'holy_week', 'Easter': 'easter',
    'Pentecost': 'pentecost', 'Ordinary': 'ordinary',
  };
  const tag = seasons && seasonMap[seasons.season] ? seasonMap[seasons.season] : 'ordinary';
  let candidates = HYMNS.filter(h => h.seasons.includes(tag));
  if (!candidates.length) candidates = HYMNS.filter(h => h.seasons.includes('ordinary'));
  if (!candidates.length) candidates = HYMNS;
  const idx = isoWeek(date) % candidates.length;
  return candidates[idx];
}

// Re-export the items declared after the earlier Object.assign call so they
// are actually accessible on `window` from other script tags.
Object.assign(window, { RCL_SUNDAYS, COLLECTS, getCollect, getRCLToday, rclSundayId, getLiturgicalSeasons, getKeyVerse, CANTICLES, OFFICE_COLLECTS, PSALMS, HYMNS, getHymnOfWeek });
