Model a Matins Gospel pericope and its paired homily as one atomic part
Deploy / deploy (push) Successful in 1m25s

Replaces the lesson+isGospel flag with a dedicated 'gospel' ResolvedPart
carrying an optional nested homily. Previously a Gospel pericope and its
patristic homily were two separate pool entries, which the front-light
1/1/rest nocturn slicer could split into different nocturns purely by
index. buildReadingPool now folds an isGospel:true reading and its
immediately-following same-nocturn homily into a single pool entry, so
the pairing is structural rather than a convention the slicer has to
honor. hour-view.ts renders the pair as one visually grouped section.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01D1LqodVbQdQVoTGPz9sSw4
This commit is contained in:
2026-08-28 19:46:48 -04:00
parent 6a17a74b9b
commit 25934865b1
6 changed files with 173 additions and 49 deletions
+30 -2
View File
@@ -91,13 +91,41 @@ function renderPart(part: ResolvedPart, languages: readonly string[]): string {
`;
case 'lesson':
return `
<section class="ordo-part ordo-part-lesson${part.isGospel ? ' ordo-part-lesson-gospel' : ''}">
${part.isGospel ? '<h3 class="ordo-part-label">Gospel</h3>' : renderLessonLabel(part.label, languages)}
<section class="ordo-part ordo-part-lesson">
${renderLessonLabel(part.label, languages)}
${renderCitation(part.text)}
${renderColumns(part.text, languages)}
${part.responsory ? `<div class="ordo-part-responsory">${renderColumns(part.responsory, languages)}</div>` : ''}
</section>
`;
// A Gospel pericope, with its paired patristic homily (when authored)
// nested right after it in the same section rather than as a separate
// pool entry — see hours/matins.ts's buildReadingPool, which combines
// the two into one atomic part specifically so they can never end up in
// different nocturns. `part.source` (rare — see the 'gospel' type's own
// doc comment) is homily attribution already folded into the pericope's
// own text at the data layer; `part.homily`, when present, is a
// genuinely separate reading, rendered with its own label underneath.
case 'gospel':
return `
<section class="ordo-part ordo-part-lesson ordo-part-gospel">
<h3 class="ordo-part-label">Gospel</h3>
${renderCitation(part.text)}
${renderColumns(part.text, languages)}
${part.source ? `<p class="ordo-part-citation">${escapeHtml(part.source)}</p>` : ''}
${part.responsory ? `<div class="ordo-part-responsory">${renderColumns(part.responsory, languages)}</div>` : ''}
${
part.homily
? `
<div class="ordo-part-homily">
${renderLessonLabel(part.homily.source, languages)}
${renderColumns(part.homily.text, languages)}
</div>
`
: ''
}
</section>
`;
case 'psalm': {
// Always cite the full range, not just the psalm number — a 4-verse
// slice of Psalm 118 is a different citation from the whole psalm.
+11
View File
@@ -307,6 +307,17 @@ button:focus-visible {
margin: 0 0 var(--space-1);
}
.ordo-part-gospel {
border-left: 2px solid var(--color-brass);
padding-left: var(--space-2);
}
.ordo-part-homily {
margin-top: var(--space-2);
padding-top: var(--space-2);
border-top: 1px solid var(--color-brass);
}
.psalm-verses {
list-style: none;
margin: 0;