From 30d9614fc35d8b5ffd161a1818b5a3a76ea4825d Mon Sep 17 00:00:00 2001 From: Aditya Date: Tue, 19 May 2026 11:42:17 -0400 Subject: [PATCH 01/12] WIP: heart-sutra all-buddhas + great-mantra TSW sections + font-slider settings UI MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit INCOMPLETE — DO NOT MERGE AS-IS. Two pieces of work landed together in this branch; both have known follow-up: 1. data/liturgy/heart-sutra.ts (+509 lines): - heart-buddhas (3 TSW segments): 三世諸佛 / 依般若波羅蜜多故 / 得阿耨多羅三藐三菩提 with Sanskrit + Devanāgarī + Chinese (Xuanzang T251) + Sino-Japanese + multi-witness English (MAPLE / Conze / Red Pine / Plum Village). Per-kanji scriptMorphemes on the load-bearing terms. - heart-great-mantra (8 TSW segments): 故知 / 是大神咒 / 是大明咒 / 是無上咒 / 是無等等咒 / 能除一切苦 / 真實不虛 / 故說般若波羅蜜多咒 / 即說咒曰. Same multi-witness pattern. - Replaces the two prose-commentary blocks (maple-all-buddhas, maple-great-spell) that PR #68 explicitly left as "deferred". - **Known failures (8 trivial alignTo length mismatches)** — caught by tests/components/liturgy/alignment-audit.test.ts: buddhas-all-three-times · Conze: alignTo=11, en-words=12 (need +1) buddhas-rely-prajna · Conze: 17 vs 18 (need +1) buddhas-attain-bodhi · Conze: 8 vs 6 (need −2) mantra-therefore-know · Plum Village: 15 vs 16 (need +1) mantra-unequaled · Red Pine: 5 vs 6 (need +1) mantra-unequaled · Plum Village: 8 vs 9 (need +1) mantra-prajna-spoken · Conze: 13 vs 12 (need −1) mantra-prajna-spoken · Plum Village: 15 vs 17 (need +2) Run `npx vitest run tests/components/liturgy/alignment-audit.test.ts` for full report. - **TODO**: after fixing alignTo, also re-run scripts/build-bodhi-heart-sutra.py to mirror these new segments into bodhi-heart-sutra.ts. 2. components/liturgy/LiturgySettings.tsx (+42 lines): - Added `fontScale: number` (default 1.0) to LiturgySettings type. - Slider UI in settings popover (range 0.7–1.6) + S/M/L/XL quick buttons (0.85 / 1.0 / 1.2 / 1.45). - **Not yet wired**: the LiturgyChantPage wrapper does NOT yet apply the CSS variable. Setting changes persist via localStorage but don't visually affect chant body. Need to: (a) wrap LiturgyChantPage children with style={{ '--liturgy-scale': String(fontScale) }} (b) update PaliLine / EnglishLine / SoundFormula Tailwind classes to use `text-[calc(var(--liturgy-scale,1)*Xrem)]` arbitrary values for the chant body — preserving current responsive breakpoints (c) also bump default sizes to match the mn10 demo's chant feel (text-3xl md:text-5xl lg:text-6xl on the chant body, per the user's image comparison). - User also flagged: per-script font-size proportions are desirable (kanji could be 20% smaller, Sino-Japanese reading 40% larger than current — captured as task #84). See docs/HANDOVER.md for full thread inventory. --- components/liturgy/LiturgySettings.tsx | 51 ++- data/liturgy/heart-sutra.ts | 518 ++++++++++++++++++++++++- 2 files changed, 560 insertions(+), 9 deletions(-) diff --git a/components/liturgy/LiturgySettings.tsx b/components/liturgy/LiturgySettings.tsx index 4bbeda9..84efefa 100644 --- a/components/liturgy/LiturgySettings.tsx +++ b/components/liturgy/LiturgySettings.tsx @@ -10,7 +10,7 @@ import React, { createContext, useContext, useEffect, useState } from 'react'; */ export type LiturgySettings = { - /** Show subtle hue accents on refrain words (Buddhaṁ=sky, Dhammaṁ=amber, etc.). */ + /** Show subtle hue accents on refrain words (Buddha=amber, Dharma=sky, Sangha=rose). */ showAccents: boolean; /** * Show a small Roman / phonetic transliteration line beneath non-Latin @@ -18,11 +18,20 @@ export type LiturgySettings = { * can't read the source script pronounce it. */ showTransliteration: boolean; + /** + * Multiplier on the chant body's base font size. 1.0 = default + * (mn10-matching large chant rendering). Range 0.7–1.6 via the + * settings slider. Applied as a `--liturgy-scale` CSS variable on + * the LiturgyChantPage wrapper; chant-body Tailwind classes read it + * via `text-[calc(var(--liturgy-scale,1)*Xrem)]`. + */ + fontScale: number; }; const DEFAULT_SETTINGS: LiturgySettings = { showAccents: true, showTransliteration: true, + fontScale: 1.0, }; const STORAGE_KEY = 'liturgy:settings'; @@ -142,6 +151,46 @@ export const SettingsButton: React.FC = () => {
Phonetic line beneath the chant: romanization beneath non-Latin scripts, pronunciation respelling beneath Latin scripts.
+ {/* Font-size slider — multiplies the chant body. Default 1.0 + matches the mn10 demo's large chant rendering. */} +
+
+ Chant text size + {Math.round(settings.fontScale * 100)}% +
+ setSettings({ ...settings, fontScale: parseFloat(e.target.value) })} + className="w-full mt-2 accent-emerald-500" + aria-label="Chant body font size" + /> +
+ + + + +
+
)} diff --git a/data/liturgy/heart-sutra.ts b/data/liturgy/heart-sutra.ts index 3341a4f..525dfda 100644 --- a/data/liturgy/heart-sutra.ts +++ b/data/liturgy/heart-sutra.ts @@ -2807,21 +2807,523 @@ export const heartSutra: LiturgyDoc = { }, // ───────────────────────────────────────────────────────────────────── - // 2e. MAPLE prose — All Buddhas of the past, present and future + // 2e. All Buddhas of the three times rely on prajñāpāramitā // ───────────────────────────────────────────────────────────────────── { - id: 'maple-all-buddhas', - shape: 'prose-commentary', - body: 'All Buddhas of the past, present and future rely on transcendent wisdom, and attain unexcelled, perfect, complete enlightenment.\n\n*MAPLE chant text. Chinese: 三世諸佛 依般若波羅蜜多故 得阿耨多羅三藐三菩提 — the *anuttarā samyaksaṃbodhi* formula. Sanskrit: "Tryadhvavyavasthitāḥ sarvabuddhāḥ prajñāpāramitām āśrityānuttarāṃ samyaksaṃbodhim abhisaṃbuddhāḥ."*', + id: 'heart-buddhas', + shape: 'triple-script-witness', + segments: [ + // ── 三世諸佛 — all buddhas of the three times ── + { + id: 'buddhas-all-three-times', + pali: 'Tryadhvavyavasthitāḥ sarvabuddhāḥ', + paliDeva: 'त्र्यध्वव्यवस्थिताः सर्वबुद्धाः', + scripts: [ + { lang: 'sa-Latn', label: 'Sanskrit (IAST)', text: 'Tryadhvavyavasthitāḥ sarvabuddhāḥ' }, + { lang: 'sa-Deva', label: 'Sanskrit (Devanāgarī)', text: 'त्र्यध्वव्यवस्थिताः सर्वबुद्धाः', transliteration: 'Tryadhva-vyavasthitāḥ sarva-buddhāḥ' }, + { + lang: 'zh-Hant', + label: 'Chinese (Xuanzang)', + text: '三世諸佛', + source: 'T251', + tokens: ['三世', '諸佛'], + transliteration: 'sān-shì zhū-fó (Mandarin pinyin)', + }, + { + lang: 'ja-Jpan', + label: 'Japanese (Sino-Japanese)', + text: '三世諸佛', + source: 'Hannya Shingyō', + tokens: ['三世', '諸佛'], + transliteration: 'San-ze sho-butsu (Sino-Japanese)', + }, + ], + witnesses: [ + { + by: 'MAPLE chant sheet (after Sheng-yen)', + text: 'All Buddhas of the past, present and future', + alignTo: [-1, 1, -1, 0, -1, 0, -1, 0], + license: 'MAPLE community chant sheet, adapted from Master Sheng-yen\'s translation', + }, + { + by: 'Conze (1958)', + text: 'All those who appear as Buddhas in the three periods of time', + alignTo: [-1, -1, -1, -1, -1, 1, -1, -1, -1, -1, 0], + url: 'https://en.wikipedia.org/wiki/Heart_Sutra', + }, + { + by: 'Red Pine (2004)', + text: 'All buddhas past, present, and future', + alignTo: [-1, 1, -1, -1, -1, 0], + url: 'https://www.counterpointpress.com/dd-product/the-heart-sutra/', + license: 'Quoted with attribution', + }, + { + by: 'Thich Nhat Hanh (2014)', + text: 'All Buddhas in the past, present and future,', + alignTo: [-1, 1, -1, 0, -1, 0, -1, 0], + url: 'https://plumvillage.org/sutra/the-other-shore', + license: 'Plum Village translation, quoted with attribution', + }, + ], + words: [ + { + form: 'Tryadhvavyavasthitāḥ', + scriptAlt: 'त्र्यध्वव्यवस्थिताः', + scriptAlts: { 'zh-Hant': '三世', 'ja-Jpan': '三世' }, + scriptMorphemes: { + 'zh-Hant': [ + { text: '三', type: 'semantic', pronunciation: 'sān', gloss: 'three — calques Sanskrit *tri*' }, + { text: '世', type: 'semantic', pronunciation: 'shì', gloss: 'world, age, generation — here "time-period". Together 三世 = the three times: past, present, future' }, + ], + 'ja-Jpan': [ + { text: '三', type: 'semantic', pronunciation: 'san', gloss: 'three' }, + { text: '世', type: 'semantic', pronunciation: 'ze', gloss: 'age, time-period. 三世 (san-ze) = the three times' }, + ], + }, + pronunciation: 'tree-AHD-vah-vyah-vahs-thee-TAHH', + etymology: '*tri-* "three" + *adhva* "way, time-period" + *vyavasthita* "established, situated"', + gloss: 'established in the three times — past, present, and future', + morphemes: [ + { text: 'tri', type: 'prefix', gloss: 'three', pronunciation: 'tree' }, + { text: 'adhva', type: 'stem', gloss: 'time, way, road', pronunciation: 'AHD-vah' }, + { text: 'vyavasthitāḥ', type: 'suffix', root: '√sthā', gloss: 'established, dwelling (plural)', pronunciation: 'vyah-vahs-thee-TAHH' }, + ], + }, + { + form: 'sarvabuddhāḥ', + scriptAlt: 'सर्वबुद्धाः', + scriptAlts: { 'zh-Hant': '諸佛', 'ja-Jpan': '諸佛' }, + scriptMorphemes: { + 'zh-Hant': [ + { text: '諸', type: 'semantic', pronunciation: 'zhū', gloss: 'all, every — calques *sarva*' }, + { text: '佛', type: 'semantic', pronunciation: 'fó', gloss: 'Buddha. Phonetic loan from Sanskrit *buddha*; the same 佛 across all Chinese Buddhist literature' }, + ], + 'ja-Jpan': [ + { text: '諸', type: 'semantic', pronunciation: 'sho', gloss: 'all — calques *sarva*' }, + { text: '佛', type: 'semantic', pronunciation: 'butsu', gloss: 'Buddha' }, + ], + }, + pronunciation: 'sahr-vah-BOOD-dhah', + etymology: '*sarva* "all" + *buddha* "awakened" (plural)', + gloss: 'all the buddhas', + accent: 'amber', + morphemes: [ + { text: 'sarva', type: 'prefix', gloss: 'all, every', pronunciation: 'SAHR-vah' }, + { text: 'buddhāḥ', type: 'stem', root: '√budh', gloss: 'awakened ones (plural)', pronunciation: 'BOOD-dhah' }, + ], + }, + ], + }, + + // ── 依般若波羅蜜多故 — relying on the perfection of wisdom ── + { + id: 'buddhas-rely-prajna', + pali: 'prajñāpāramitām āśritya', + paliDeva: 'प्रज्ञापारमिताम् आश्रित्य', + scripts: [ + { lang: 'sa-Latn', label: 'Sanskrit (IAST)', text: 'prajñāpāramitām āśritya' }, + { lang: 'sa-Deva', label: 'Sanskrit (Devanāgarī)', text: 'प्रज्ञापारमिताम् आश्रित्य', transliteration: 'prajñāpāramitām āśritya' }, + { + lang: 'zh-Hant', + label: 'Chinese (Xuanzang)', + text: '依般若波羅蜜多故', + source: 'T251', + tokens: ['依', '般若', '波羅蜜多', '故'], + transliteration: 'yī bō-rě bō-luó-mì-duō gù (Mandarin pinyin)', + }, + { + lang: 'ja-Jpan', + label: 'Japanese (Sino-Japanese)', + text: '依般若波羅蜜多故', + source: 'Hannya Shingyō', + tokens: ['依', '般若', '波羅蜜多', '故'], + transliteration: 'e hannya haramita ko (Sino-Japanese)', + }, + ], + witnesses: [ + { + by: 'MAPLE chant sheet (after Sheng-yen)', + text: 'rely on transcendent wisdom,', + alignTo: [1, -1, 0, 0], + license: 'MAPLE community chant sheet, adapted from Master Sheng-yen\'s translation', + }, + { + by: 'Conze (1958)', + text: 'fully awake to the utmost, right and perfect Enlightenment because they have relied on the Perfection of Wisdom.', + alignTo: [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1, 0, -1, 0], + url: 'https://en.wikipedia.org/wiki/Heart_Sutra', + }, + { + by: 'Red Pine (2004)', + text: 'depend on Prajñāpāramitā', + alignTo: [1, -1, 0], + url: 'https://www.counterpointpress.com/dd-product/the-heart-sutra/', + license: 'Quoted with attribution', + }, + { + by: 'Thich Nhat Hanh (2014)', + text: 'thanks to this Insight that brings us to the Other Shore,', + alignTo: [-1, -1, -1, 0, -1, -1, -1, -1, -1, -1, -1], + url: 'https://plumvillage.org/sutra/the-other-shore', + license: 'Plum Village translation, quoted with attribution', + }, + ], + words: [ + { + form: 'prajñāpāramitām', + scriptAlt: 'प्रज्ञापारमिताम्', + scriptAlts: { 'zh-Hant': '般若波羅蜜多', 'ja-Jpan': '般若波羅蜜多' }, + scriptMorphemes: { + 'zh-Hant': [ + { text: '般若', type: 'phonetic', pronunciation: 'bō-rě', gloss: 'phonetic transliteration of Sanskrit *prajñā* (wisdom)' }, + { text: '波羅蜜多', type: 'phonetic', pronunciation: 'bō-luó-mì-duō', gloss: 'phonetic transliteration of *pāramitā* (perfection)' }, + ], + 'ja-Jpan': [ + { text: '般若', type: 'phonetic', pronunciation: 'hannya', gloss: 'phonetic: *prajñā*' }, + { text: '波羅蜜多', type: 'phonetic', pronunciation: 'haramita', gloss: 'phonetic: *pāramitā*' }, + ], + }, + pronunciation: 'prahj-NYAH-pah-rah-mee-TAHM', + etymology: '*prajñā* "wisdom" + *pāramitā* "perfection" (accusative)', + gloss: 'the perfection of wisdom (accusative — object of "relying on")', + accent: 'sky', + morphemes: [ + { text: 'prajñā', type: 'stem', gloss: 'wisdom', pronunciation: 'prahj-NYAH' }, + { text: 'pāramitām', type: 'suffix', gloss: 'perfection (acc.)', pronunciation: 'pah-rah-mee-TAHM' }, + ], + }, + { + form: 'āśritya', + scriptAlt: 'आश्रित्य', + scriptAlts: { 'zh-Hant': '依', 'ja-Jpan': '依' }, + pronunciation: 'AH-shree-tyah', + etymology: '*ā-* "toward" + *√śri* "to rest on, depend on"', + gloss: 'having taken refuge in, relying on (gerund)', + }, + ], + }, + + // ── 得阿耨多羅三藐三菩提 — attain unsurpassed perfect enlightenment ── + { + id: 'buddhas-attain-bodhi', + pali: 'anuttarāṃ samyaksaṃbodhim abhisaṃbuddhāḥ', + paliDeva: 'अनुत्तरां सम्यक्संबोधिम् अभिसंबुद्धाः', + scripts: [ + { lang: 'sa-Latn', label: 'Sanskrit (IAST)', text: 'anuttarāṃ samyaksaṃbodhim abhisaṃbuddhāḥ' }, + { lang: 'sa-Deva', label: 'Sanskrit (Devanāgarī)', text: 'अनुत्तरां सम्यक्संबोधिम् अभिसंबुद्धाः', transliteration: 'anuttarāṃ samyaksaṃbodhim abhisaṃbuddhāḥ' }, + { + lang: 'zh-Hant', + label: 'Chinese (Xuanzang)', + text: '得阿耨多羅三藐三菩提', + source: 'T251', + tokens: ['得', '阿耨多羅', '三藐三', '菩提'], + transliteration: 'dé ā-nòu-duō-luó sān-miǎo-sān pú-tí (Mandarin pinyin)', + }, + { + lang: 'ja-Jpan', + label: 'Japanese (Sino-Japanese)', + text: '得阿耨多羅三藐三菩提', + source: 'Hannya Shingyō', + tokens: ['得', '阿耨多羅', '三藐三', '菩提'], + transliteration: 'toku a-noku-ta-ra san-myaku-san bo-dai (Sino-Japanese)', + }, + ], + witnesses: [ + { + by: 'MAPLE chant sheet (after Sheng-yen)', + text: 'and attain unexcelled, perfect, complete enlightenment.', + alignTo: [-1, 2, 0, 1, 1, 1], + license: 'MAPLE community chant sheet, adapted from Master Sheng-yen\'s translation', + }, + { + by: 'Conze (1958)', + text: '— see all-in-one (verse 14) above', + alignTo: [-1, -1, -1, -1, -1, -1, -1, -1], + url: 'https://en.wikipedia.org/wiki/Heart_Sutra', + license: 'Conze fuses 14 + 15 — no separate alignment', + }, + { + by: 'Red Pine (2004)', + text: 'and realize unexcelled, perfect Enlightenment.', + alignTo: [-1, -1, 0, 1, 1], + url: 'https://www.counterpointpress.com/dd-product/the-heart-sutra/', + license: 'Quoted with attribution', + }, + { + by: 'Thich Nhat Hanh (2014)', + text: 'are all capable of attaining Authentic and Perfect Enlightenment.', + alignTo: [-1, -1, -1, -1, 2, 1, -1, 1, 1], + url: 'https://plumvillage.org/sutra/the-other-shore', + license: 'Plum Village translation, quoted with attribution', + }, + ], + words: [ + { + form: 'anuttarāṃ', + scriptAlt: 'अनुत्तराम्', + scriptAlts: { 'zh-Hant': '阿耨多羅', 'ja-Jpan': '阿耨多羅' }, + scriptMorphemes: { + 'zh-Hant': [ + { text: '阿', type: 'phonetic', pronunciation: 'ā', gloss: 'phonetic: *a-* (the negation)' }, + { text: '耨', type: 'phonetic', pronunciation: 'nòu', gloss: 'phonetic: *-nu-*' }, + { text: '多', type: 'phonetic', pronunciation: 'duō', gloss: 'phonetic: *-tta-*' }, + { text: '羅', type: 'phonetic', pronunciation: 'luó', gloss: 'phonetic: *-rām* (accusative)' }, + ], + }, + pronunciation: 'ah-NOOT-tah-rahm', + etymology: '*a-* "not" + *uttara* "higher, superior" — "than which nothing is higher"', + gloss: 'unsurpassed, supreme', + }, + { + form: 'samyaksaṃbodhim', + scriptAlt: 'सम्यक्संबोधिम्', + scriptAlts: { 'zh-Hant': '三藐三菩提', 'ja-Jpan': '三藐三菩提' }, + scriptMorphemes: { + 'zh-Hant': [ + { text: '三藐', type: 'phonetic', pronunciation: 'sān-miǎo', gloss: 'phonetic: *samyak-* (perfect, complete)' }, + { text: '三', type: 'phonetic', pronunciation: 'sān', gloss: 'phonetic: *saṃ-* (together, fully)' }, + { text: '菩提', type: 'phonetic', pronunciation: 'pú-tí', gloss: 'phonetic: *bodhi* (awakening) — same 菩提 across all Chinese Buddhist texts' }, + ], + }, + pronunciation: 'sahm-YAHK-sahm-BOH-dheem', + etymology: '*samyak* "perfect, right" + *saṃ-* "together, complete" + *bodhi* "awakening"', + gloss: 'perfect complete awakening — the *anuttarā samyaksaṃbodhi* of the bodhisattva path', + accent: 'amber', + morphemes: [ + { text: 'samyak', type: 'prefix', gloss: 'right, perfect', pronunciation: 'SAHM-yahk' }, + { text: 'saṃ', type: 'prefix', gloss: 'fully, completely', pronunciation: 'sahm' }, + { text: 'bodhim', type: 'stem', root: '√budh', gloss: 'awakening (acc.)', pronunciation: 'BOH-dheem' }, + ], + }, + { + form: 'abhisaṃbuddhāḥ', + scriptAlt: 'अभिसंबुद्धाः', + scriptAlts: { 'zh-Hant': '得', 'ja-Jpan': '得' }, + pronunciation: 'ah-bhee-sahm-BOOD-dhah', + etymology: '*abhi-* "toward" + *saṃ-* "fully" + *buddha* "awakened" (plural)', + gloss: 'fully awakened to (plural — all the buddhas have attained)', + morphemes: [ + { text: 'abhi', type: 'prefix', gloss: 'toward, fully', pronunciation: 'ah-bhee' }, + { text: 'saṃ', type: 'prefix', gloss: 'completely', pronunciation: 'sahm' }, + { text: 'buddhāḥ', type: 'stem', root: '√budh', gloss: 'awakened (plural)', pronunciation: 'BOOD-dhah' }, + ], + }, + ], + }, + ], }, // ───────────────────────────────────────────────────────────────────── - // 2f. MAPLE prose — Therefore know: the great spell · into the mantra + // 2f. Therefore know: prajñāpāramitā is the great mantra // ───────────────────────────────────────────────────────────────────── { - id: 'maple-great-spell', - shape: 'prose-commentary', - body: 'Therefore know: transcendent wisdom is the great spell, the great knowledge, the supreme knowledge, the unequalled knowledge. It can remove all suffering. It is true, not false.\n\nTherefore recite the mantra of transcendent wisdom as follows:\n\n*MAPLE chant text. Chinese: 故知般若波羅蜜多 是大神咒 是大明咒 是無上咒 是無等等咒 能除一切苦 真實不虛 故說般若波羅蜜多咒 即說咒曰 — the praise of prajñāpāramitā as itself a mantra, leading into the gate gate dharani below.*', + id: 'heart-great-mantra', + shape: 'triple-script-witness', + segments: [ + // ── 故知般若波羅蜜多 — Therefore know: prajñāpāramitā ── + { + id: 'mantra-therefore-know', + pali: 'tasmāj jñātavyaṃ prajñāpāramitā', + paliDeva: 'तस्माज्ज्ञातव्यं प्रज्ञापारमिता', + scripts: [ + { lang: 'sa-Latn', label: 'Sanskrit (IAST)', text: 'tasmāj jñātavyaṃ prajñāpāramitā' }, + { lang: 'sa-Deva', label: 'Sanskrit (Devanāgarī)', text: 'तस्माज्ज्ञातव्यं प्रज्ञापारमिता', transliteration: 'tasmāj jñātavyaṃ prajñāpāramitā' }, + { lang: 'zh-Hant', label: 'Chinese (Xuanzang)', text: '故知般若波羅蜜多', source: 'T251', tokens: ['故', '知', '般若波羅蜜多'], transliteration: 'gù zhī bō-rě bō-luó-mì-duō (Mandarin pinyin)' }, + { lang: 'ja-Jpan', label: 'Japanese (Sino-Japanese)', text: '故知般若波羅蜜多', source: 'Hannya Shingyō', tokens: ['故', '知', '般若波羅蜜多'], transliteration: 'ko chi hannya haramita (Sino-Japanese)' }, + ], + witnesses: [ + { by: 'MAPLE chant sheet (after Sheng-yen)', text: 'Therefore know: transcendent wisdom', alignTo: [0, 1, -1, 2], license: 'MAPLE community chant sheet, adapted from Master Sheng-yen\'s translation' }, + { by: 'Conze (1958)', text: 'Therefore one should know the Prajñāpāramitā', alignTo: [0, -1, -1, 1, -1, 2], url: 'https://en.wikipedia.org/wiki/Heart_Sutra' }, + { by: 'Red Pine (2004)', text: 'You should therefore know that Prajñāpāramitā', alignTo: [-1, -1, 0, 1, -1, 2], url: 'https://www.counterpointpress.com/dd-product/the-heart-sutra/', license: 'Quoted with attribution' }, + { by: 'Thich Nhat Hanh (2014)', text: 'Therefore Shariputra, it should be known that the Insight that brings us to the Other Shore', alignTo: [0, -1, -1, -1, -1, 1, -1, -1, 2, -1, -1, -1, -1, -1, -1], url: 'https://plumvillage.org/sutra/the-other-shore', license: 'Plum Village translation, quoted with attribution' }, + ], + words: [ + { form: 'tasmāj', scriptAlt: 'तस्माज्', scriptAlts: { 'zh-Hant': '故', 'ja-Jpan': '故' }, pronunciation: 'tahs-MAHJ', gloss: 'therefore (ablative of *tat* "that")' }, + { form: 'jñātavyaṃ', scriptAlt: 'ज्ञातव्यं', scriptAlts: { 'zh-Hant': '知', 'ja-Jpan': '知' }, pronunciation: 'GYAH-tahv-yahm', gloss: 'should be known (gerundive)' }, + { form: 'prajñāpāramitā', scriptAlt: 'प्रज्ञापारमिता', scriptAlts: { 'zh-Hant': '般若波羅蜜多', 'ja-Jpan': '般若波羅蜜多' }, pronunciation: 'prahj-NYAH-pah-rah-mee-TAH', gloss: 'the Perfection of Wisdom (nominative)', accent: 'sky' }, + ], + }, + + // ── 是大神咒 — is the great mantra ── + { + id: 'mantra-great', + pali: 'mahāmantraḥ', + paliDeva: 'महामन्त्रः', + scripts: [ + { lang: 'sa-Latn', label: 'Sanskrit (IAST)', text: 'mahāmantraḥ' }, + { lang: 'sa-Deva', label: 'Sanskrit (Devanāgarī)', text: 'महामन्त्रः', transliteration: 'mahāmantraḥ' }, + { lang: 'zh-Hant', label: 'Chinese (Xuanzang)', text: '是大神咒', source: 'T251', tokens: ['是', '大神', '咒'], transliteration: 'shì dà-shén zhòu (Mandarin pinyin)' }, + { lang: 'ja-Jpan', label: 'Japanese (Sino-Japanese)', text: '是大神咒', source: 'Hannya Shingyō', tokens: ['是', '大神', '咒'], transliteration: 'ze dai-jin shu (Sino-Japanese)' }, + ], + witnesses: [ + { by: 'MAPLE chant sheet (after Sheng-yen)', text: 'is the great spell,', alignTo: [-1, -1, 0, 0], license: 'MAPLE community chant sheet, adapted from Master Sheng-yen\'s translation' }, + { by: 'Conze (1958)', text: 'is a great spell,', alignTo: [-1, -1, 0, 0], url: 'https://en.wikipedia.org/wiki/Heart_Sutra' }, + { by: 'Red Pine (2004)', text: 'is the great mantra,', alignTo: [-1, -1, 0, 0], url: 'https://www.counterpointpress.com/dd-product/the-heart-sutra/', license: 'Quoted with attribution' }, + { by: 'Thich Nhat Hanh (2014)', text: 'is a Great Mantra,', alignTo: [-1, -1, 0, 0], url: 'https://plumvillage.org/sutra/the-other-shore', license: 'Plum Village translation, quoted with attribution' }, + ], + words: [ + { form: 'mahāmantraḥ', scriptAlt: 'महामन्त्रः', scriptAlts: { 'zh-Hant': '大神咒', 'ja-Jpan': '大神咒' }, pronunciation: 'mah-HAH-mahn-trahh', etymology: '*mahā* "great" + *mantra* "spell, sacred utterance"', gloss: 'the great mantra' }, + ], + }, + + // ── 是大明咒 — is the great knowledge mantra ── + { + id: 'mantra-great-knowledge', + pali: 'mahāvidyāmantraḥ', + paliDeva: 'महाविद्यामन्त्रः', + scripts: [ + { lang: 'sa-Latn', label: 'Sanskrit (IAST)', text: 'mahāvidyāmantraḥ' }, + { lang: 'sa-Deva', label: 'Sanskrit (Devanāgarī)', text: 'महाविद्यामन्त्रः', transliteration: 'mahāvidyāmantraḥ' }, + { lang: 'zh-Hant', label: 'Chinese (Xuanzang)', text: '是大明咒', source: 'T251', tokens: ['是', '大明', '咒'], transliteration: 'shì dà-míng zhòu (Mandarin pinyin)' }, + { lang: 'ja-Jpan', label: 'Japanese (Sino-Japanese)', text: '是大明咒', source: 'Hannya Shingyō', tokens: ['是', '大明', '咒'], transliteration: 'ze dai-myō shu (Sino-Japanese)' }, + ], + witnesses: [ + { by: 'MAPLE chant sheet (after Sheng-yen)', text: 'the great knowledge,', alignTo: [-1, -1, 0], license: 'MAPLE community chant sheet, adapted from Master Sheng-yen\'s translation' }, + { by: 'Conze (1958)', text: 'a spell of great knowledge,', alignTo: [-1, -1, -1, -1, 0], url: 'https://en.wikipedia.org/wiki/Heart_Sutra' }, + { by: 'Red Pine (2004)', text: 'the mantra of great learning,', alignTo: [-1, -1, -1, -1, 0], url: 'https://www.counterpointpress.com/dd-product/the-heart-sutra/', license: 'Quoted with attribution' }, + { by: 'Thich Nhat Hanh (2014)', text: 'the most illuminating mantra,', alignTo: [-1, -1, -1, 0], url: 'https://plumvillage.org/sutra/the-other-shore', license: 'Plum Village translation, quoted with attribution' }, + ], + words: [ + { form: 'mahāvidyāmantraḥ', scriptAlt: 'महाविद्यामन्त्रः', scriptAlts: { 'zh-Hant': '大明咒', 'ja-Jpan': '大明咒' }, pronunciation: 'mah-HAH-veed-YAH-mahn-trahh', etymology: '*mahā* "great" + *vidyā* "knowledge, illumination" + *mantra*. *Vidyā* shares its root √vid with the 明 (míng "bright, clear")', gloss: 'the great knowledge-mantra — knowledge here is illumination, not propositional content' }, + ], + }, + + // ── 是無上咒 — is the unsurpassed mantra ── + { + id: 'mantra-unsurpassed', + pali: 'anuttaramantraḥ', + paliDeva: 'अनुत्तरमन्त्रः', + scripts: [ + { lang: 'sa-Latn', label: 'Sanskrit (IAST)', text: 'anuttaramantraḥ' }, + { lang: 'sa-Deva', label: 'Sanskrit (Devanāgarī)', text: 'अनुत्तरमन्त्रः', transliteration: 'anuttaramantraḥ' }, + { lang: 'zh-Hant', label: 'Chinese (Xuanzang)', text: '是無上咒', source: 'T251', tokens: ['是', '無上', '咒'], transliteration: 'shì wú-shàng zhòu (Mandarin pinyin)' }, + { lang: 'ja-Jpan', label: 'Japanese (Sino-Japanese)', text: '是無上咒', source: 'Hannya Shingyō', tokens: ['是', '無上', '咒'], transliteration: 'ze mu-jō shu (Sino-Japanese)' }, + ], + witnesses: [ + { by: 'MAPLE chant sheet (after Sheng-yen)', text: 'the supreme knowledge,', alignTo: [-1, -1, 0], license: 'MAPLE community chant sheet, adapted from Master Sheng-yen\'s translation' }, + { by: 'Conze (1958)', text: 'the utmost spell,', alignTo: [-1, -1, 0], url: 'https://en.wikipedia.org/wiki/Heart_Sutra' }, + { by: 'Red Pine (2004)', text: 'the unsurpassable mantra,', alignTo: [-1, -1, 0], url: 'https://www.counterpointpress.com/dd-product/the-heart-sutra/', license: 'Quoted with attribution' }, + { by: 'Thich Nhat Hanh (2014)', text: 'the highest mantra,', alignTo: [-1, -1, 0], url: 'https://plumvillage.org/sutra/the-other-shore', license: 'Plum Village translation, quoted with attribution' }, + ], + words: [ + { form: 'anuttaramantraḥ', scriptAlt: 'अनुत्तरमन्त्रः', scriptAlts: { 'zh-Hant': '無上咒', 'ja-Jpan': '無上咒' }, pronunciation: 'ah-NOOT-tah-rah-mahn-trahh', etymology: 'same *anuttara* "unsurpassed" as in *anuttarā samyaksaṃbodhi*', gloss: 'the unsurpassed mantra — nothing surpasses it' }, + ], + }, + + // ── 是無等等咒 — is the unequaled mantra ── + { + id: 'mantra-unequaled', + pali: 'asamasamamantraḥ', + paliDeva: 'असमसममन्त्रः', + scripts: [ + { lang: 'sa-Latn', label: 'Sanskrit (IAST)', text: 'asamasamamantraḥ' }, + { lang: 'sa-Deva', label: 'Sanskrit (Devanāgarī)', text: 'असमसममन्त्रः', transliteration: 'asamasamamantraḥ' }, + { lang: 'zh-Hant', label: 'Chinese (Xuanzang)', text: '是無等等咒', source: 'T251', tokens: ['是', '無等等', '咒'], transliteration: 'shì wú-děng-děng zhòu (Mandarin pinyin)' }, + { lang: 'ja-Jpan', label: 'Japanese (Sino-Japanese)', text: '是無等等咒', source: 'Hannya Shingyō', tokens: ['是', '無等等', '咒'], transliteration: 'ze mu-tō-dō shu (Sino-Japanese)' }, + ], + witnesses: [ + { by: 'MAPLE chant sheet (after Sheng-yen)', text: 'the unequalled knowledge.', alignTo: [-1, -1, 0], license: 'MAPLE community chant sheet, adapted from Master Sheng-yen\'s translation' }, + { by: 'Conze (1958)', text: 'unequalled,', alignTo: [0], url: 'https://en.wikipedia.org/wiki/Heart_Sutra' }, + { by: 'Red Pine (2004)', text: 'the mantra equal to the unequaled,', alignTo: [-1, -1, -1, -1, 0], url: 'https://www.counterpointpress.com/dd-product/the-heart-sutra/', license: 'Quoted with attribution' }, + { by: 'Thich Nhat Hanh (2014)', text: 'the mantra which is the equal of the unequalled,', alignTo: [-1, -1, -1, -1, -1, -1, -1, 0], url: 'https://plumvillage.org/sutra/the-other-shore', license: 'Plum Village translation, quoted with attribution' }, + ], + words: [ + { form: 'asamasamamantraḥ', scriptAlt: 'असमसममन्त्रः', scriptAlts: { 'zh-Hant': '無等等咒', 'ja-Jpan': '無等等咒' }, pronunciation: 'ah-SAH-mah-SAH-mah-mahn-trahh', etymology: '*a-* "not" + *sama* "equal" + *sama* "equal" — "having no equal", "equal to the unequaled"', gloss: 'the unequaled-equal mantra — paradoxical formula: equal to what has no equal' }, + ], + }, + + // ── 能除一切苦 — able to remove all suffering ── + { + id: 'mantra-removes-suffering', + pali: 'sarvaduḥkhapraśamanaḥ', + paliDeva: 'सर्वदुःखप्रशमनः', + scripts: [ + { lang: 'sa-Latn', label: 'Sanskrit (IAST)', text: 'sarvaduḥkhapraśamanaḥ' }, + { lang: 'sa-Deva', label: 'Sanskrit (Devanāgarī)', text: 'सर्वदुःखप्रशमनः', transliteration: 'sarvaduḥkhapraśamanaḥ' }, + { lang: 'zh-Hant', label: 'Chinese (Xuanzang)', text: '能除一切苦', source: 'T251', tokens: ['能', '除', '一切', '苦'], transliteration: 'néng chú yī-qiè kǔ (Mandarin pinyin)' }, + { lang: 'ja-Jpan', label: 'Japanese (Sino-Japanese)', text: '能除一切苦', source: 'Hannya Shingyō', tokens: ['能', '除', '一切', '苦'], transliteration: 'nō jo issai ku (Sino-Japanese)' }, + ], + witnesses: [ + { by: 'MAPLE chant sheet (after Sheng-yen)', text: 'It can remove all suffering.', alignTo: [-1, -1, 0, 0, 0], license: 'MAPLE community chant sheet, adapted from Master Sheng-yen\'s translation' }, + { by: 'Conze (1958)', text: 'allayer of all suffering,', alignTo: [0, 0, 0, 0], url: 'https://en.wikipedia.org/wiki/Heart_Sutra' }, + { by: 'Red Pine (2004)', text: 'the mantra that ends all suffering.', alignTo: [-1, -1, -1, 0, 0, 0], url: 'https://www.counterpointpress.com/dd-product/the-heart-sutra/', license: 'Quoted with attribution' }, + { by: 'Thich Nhat Hanh (2014)', text: 'a Mantra which is able to allay all suffering.', alignTo: [-1, -1, -1, -1, -1, 0, 0, 0, 0], url: 'https://plumvillage.org/sutra/the-other-shore', license: 'Plum Village translation, quoted with attribution' }, + ], + words: [ + { form: 'sarvaduḥkhapraśamanaḥ', scriptAlt: 'सर्वदुःखप्रशमनः', scriptAlts: { 'zh-Hant': '除一切苦', 'ja-Jpan': '除一切苦' }, pronunciation: 'sahr-vah-DOOH-khah-prah-SHAH-mah-nahh', etymology: '*sarva* "all" + *duḥkha* "suffering" + *praśamana* "calming, stilling"', gloss: 'allayer of all suffering — what calms every kind of suffering' }, + ], + }, + + // ── 真實不虛 — true, not false ── + { + id: 'mantra-true-not-false', + pali: 'satyam amithyatvāt', + paliDeva: 'सत्यम् अमिथ्यत्वात्', + scripts: [ + { lang: 'sa-Latn', label: 'Sanskrit (IAST)', text: 'satyam amithyatvāt' }, + { lang: 'sa-Deva', label: 'Sanskrit (Devanāgarī)', text: 'सत्यम् अमिथ्यत्वात्', transliteration: 'satyam amithyatvāt' }, + { lang: 'zh-Hant', label: 'Chinese (Xuanzang)', text: '真實不虛', source: 'T251', tokens: ['真實', '不虛'], transliteration: 'zhēn-shí bù-xū (Mandarin pinyin)' }, + { lang: 'ja-Jpan', label: 'Japanese (Sino-Japanese)', text: '真實不虛', source: 'Hannya Shingyō', tokens: ['真實', '不虛'], transliteration: 'shin-jitsu fu-ko (Sino-Japanese)' }, + ], + witnesses: [ + { by: 'MAPLE chant sheet (after Sheng-yen)', text: 'It is true, not false.', alignTo: [-1, -1, 0, -1, 1], license: 'MAPLE community chant sheet, adapted from Master Sheng-yen\'s translation' }, + { by: 'Conze (1958)', text: 'in truth — for what could go wrong?', alignTo: [-1, 0, -1, -1, 1, -1, -1, -1], url: 'https://en.wikipedia.org/wiki/Heart_Sutra' }, + { by: 'Red Pine (2004)', text: 'It is real and not illusory.', alignTo: [-1, -1, 0, -1, -1, 1], url: 'https://www.counterpointpress.com/dd-product/the-heart-sutra/', license: 'Quoted with attribution' }, + { by: 'Thich Nhat Hanh (2014)', text: 'This is the truth that can not be doubted,', alignTo: [-1, -1, -1, 0, -1, 1, -1, -1, -1], url: 'https://plumvillage.org/sutra/the-other-shore', license: 'Plum Village translation, quoted with attribution' }, + ], + words: [ + { form: 'satyam', scriptAlt: 'सत्यम्', scriptAlts: { 'zh-Hant': '真實', 'ja-Jpan': '真實' }, pronunciation: 'SAHT-yahm', etymology: '*sat* "being, true" + *-ya* abstract suffix — "truth itself"', gloss: 'true, real (neuter accusative)' }, + { form: 'amithyatvāt', scriptAlt: 'अमिथ्यत्वात्', scriptAlts: { 'zh-Hant': '不虛', 'ja-Jpan': '不虛' }, pronunciation: 'ah-MEETH-yaht-vaht', etymology: '*a-* "not" + *mithyā* "false" + *-tva* abstract + *-āt* ablative — "due to not being false"', gloss: 'because it is not false (ablative — gives the reason)' }, + ], + }, + + // ── 故說般若波羅蜜多咒 — therefore the prajñāpāramitā mantra is spoken ── + { + id: 'mantra-prajna-spoken', + pali: 'prajñāpāramitāyām ukto mantraḥ', + paliDeva: 'प्रज्ञापारमितायाम् उक्तो मन्त्रः', + scripts: [ + { lang: 'sa-Latn', label: 'Sanskrit (IAST)', text: 'prajñāpāramitāyām ukto mantraḥ' }, + { lang: 'sa-Deva', label: 'Sanskrit (Devanāgarī)', text: 'प्रज्ञापारमितायाम् उक्तो मन्त्रः', transliteration: 'prajñāpāramitāyām ukto mantraḥ' }, + { lang: 'zh-Hant', label: 'Chinese (Xuanzang)', text: '故說般若波羅蜜多咒', source: 'T251', tokens: ['故', '說', '般若波羅蜜多', '咒'], transliteration: 'gù shuō bō-rě bō-luó-mì-duō zhòu (Mandarin pinyin)' }, + { lang: 'ja-Jpan', label: 'Japanese (Sino-Japanese)', text: '故說般若波羅蜜多咒', source: 'Hannya Shingyō', tokens: ['故', '說', '般若波羅蜜多', '咒'], transliteration: 'ko setsu hannya haramita shu (Sino-Japanese)' }, + ], + witnesses: [ + { by: 'MAPLE chant sheet (after Sheng-yen)', text: 'Therefore recite the mantra of transcendent wisdom', alignTo: [-1, 1, -1, 2, -1, -1, 0], license: 'MAPLE community chant sheet, adapted from Master Sheng-yen\'s translation' }, + { by: 'Conze (1958)', text: 'By the Prajñāpāramitā has this spell been delivered. It runs like this:', alignTo: [-1, -1, 0, -1, -1, -1, 2, -1, 1, -1, -1, -1, -1], url: 'https://en.wikipedia.org/wiki/Heart_Sutra' }, + { by: 'Red Pine (2004)', text: 'So we proclaim the mantra of Prajñāpāramitā,', alignTo: [-1, -1, 1, -1, 2, -1, 0], url: 'https://www.counterpointpress.com/dd-product/the-heart-sutra/', license: 'Quoted with attribution' }, + { by: 'Thich Nhat Hanh (2014)', text: 'so let us proclaim a mantra to praise the Insight that brings us to the Other Shore.', alignTo: [-1, -1, -1, 1, -1, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1], url: 'https://plumvillage.org/sutra/the-other-shore', license: 'Plum Village translation, quoted with attribution' }, + ], + words: [ + { form: 'prajñāpāramitāyām', scriptAlt: 'प्रज्ञापारमितायाम्', scriptAlts: { 'zh-Hant': '般若波羅蜜多', 'ja-Jpan': '般若波羅蜜多' }, pronunciation: 'prahj-NYAH-pah-rah-mee-TAH-yahm', etymology: 'locative of *prajñāpāramitā* — "in / from the Perfection of Wisdom"', gloss: 'in the Perfection of Wisdom (locative)', accent: 'sky' }, + { form: 'ukto', scriptAlt: 'उक्तो', scriptAlts: { 'zh-Hant': '說', 'ja-Jpan': '說' }, pronunciation: 'OOK-toh', etymology: 'past participle of √vac "to speak"', gloss: 'spoken, declared' }, + { form: 'mantraḥ', scriptAlt: 'मन्त्रः', scriptAlts: { 'zh-Hant': '咒', 'ja-Jpan': '咒' }, pronunciation: 'MAHN-trahh', etymology: '*man-* "to think" + *-tra* instrument suffix — "instrument of thought"', gloss: 'the mantra (nominative)' }, + ], + }, + + // ── 即說咒曰 — thus the mantra is spoken ── + { + id: 'mantra-thus-spoken', + pali: 'tadyathā', + paliDeva: 'तद्यथा', + scripts: [ + { lang: 'sa-Latn', label: 'Sanskrit (IAST)', text: 'tadyathā' }, + { lang: 'sa-Deva', label: 'Sanskrit (Devanāgarī)', text: 'तद्यथा', transliteration: 'tadyathā' }, + { lang: 'zh-Hant', label: 'Chinese (Xuanzang)', text: '即說咒曰', source: 'T251', tokens: ['即', '說', '咒', '曰'], transliteration: 'jí shuō zhòu yuē (Mandarin pinyin)' }, + { lang: 'ja-Jpan', label: 'Japanese (Sino-Japanese)', text: '即說咒曰', source: 'Hannya Shingyō', tokens: ['即', '說', '咒', '曰'], transliteration: 'soku setsu shu watsu (Sino-Japanese)' }, + ], + witnesses: [ + { by: 'MAPLE chant sheet (after Sheng-yen)', text: 'as follows:', alignTo: [0, -1], license: 'MAPLE community chant sheet, adapted from Master Sheng-yen\'s translation' }, + { by: 'Conze (1958)', text: 'thus:', alignTo: [0], url: 'https://en.wikipedia.org/wiki/Heart_Sutra' }, + { by: 'Red Pine (2004)', text: 'the mantra that goes:', alignTo: [-1, -1, -1, 0], url: 'https://www.counterpointpress.com/dd-product/the-heart-sutra/', license: 'Quoted with attribution' }, + { by: 'Thich Nhat Hanh (2014)', text: 'It is:', alignTo: [-1, 0], url: 'https://plumvillage.org/sutra/the-other-shore', license: 'Plum Village translation, quoted with attribution' }, + ], + words: [ + { form: 'tadyathā', scriptAlt: 'तद्यथा', scriptAlts: { 'zh-Hant': '即說咒曰', 'ja-Jpan': '即說咒曰' }, pronunciation: 'tahd-yah-THAH', etymology: '*tat* "that" + *yathā* "as" — "as that", "namely", "thus"', gloss: 'thus, namely — the formula introducing the mantra' }, + ], + }, + ], }, // ───────────────────────────────────────────────────────────────────── From 455970e284a3ee129f1e9f90a32cfcb23aeacc27 Mon Sep 17 00:00:00 2001 From: Aditya Date: Tue, 19 May 2026 12:08:06 -0400 Subject: [PATCH 02/12] fix(liturgy): align Conze + Plum Village witness alignTo for new heart-buddhas + heart-great-mantra TSW sections MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Eight alignTo length mismatches surfaced by the alignment-audit test after the WIP commit that authored these segments. Re-counted English tokens (whitespace-split) and remapped to Pāli surface positions: heart-buddhas: - buddhas-all-three-times Conze: 11→12 (added "three"→0 anchor) - buddhas-rely-prajna Conze: 17→18 (re-aligned trailing -1 padding) - buddhas-attain-bodhi Conze: 8→6 (text is just "— see all-in-one (verse 14) above") heart-great-mantra: - mantra-therefore-know TNH: 15→16 (final "Shore" was missing) - mantra-unequaled Red Pine: 5→6 ("the" before final "unequaled") - mantra-unequaled TNH: 8→9 (extra article in "the unequalled") - mantra-prajna-spoken Conze: 13→12 (recounted; "this" not duplicated) - mantra-prajna-spoken TNH: 15→17 (added "Insight"→0 anchor + trailing -1) --- data/liturgy/heart-sutra.ts | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/data/liturgy/heart-sutra.ts b/data/liturgy/heart-sutra.ts index 525dfda..0ba9719 100644 --- a/data/liturgy/heart-sutra.ts +++ b/data/liturgy/heart-sutra.ts @@ -2848,7 +2848,7 @@ export const heartSutra: LiturgyDoc = { { by: 'Conze (1958)', text: 'All those who appear as Buddhas in the three periods of time', - alignTo: [-1, -1, -1, -1, -1, 1, -1, -1, -1, -1, 0], + alignTo: [-1, -1, -1, -1, -1, 1, -1, -1, 0, -1, -1, -1], url: 'https://en.wikipedia.org/wiki/Heart_Sutra', }, { @@ -2951,7 +2951,7 @@ export const heartSutra: LiturgyDoc = { { by: 'Conze (1958)', text: 'fully awake to the utmost, right and perfect Enlightenment because they have relied on the Perfection of Wisdom.', - alignTo: [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1, 0, -1, 0], + alignTo: [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1, 0, -1, 0], url: 'https://en.wikipedia.org/wiki/Heart_Sutra', }, { @@ -3039,7 +3039,7 @@ export const heartSutra: LiturgyDoc = { { by: 'Conze (1958)', text: '— see all-in-one (verse 14) above', - alignTo: [-1, -1, -1, -1, -1, -1, -1, -1], + alignTo: [-1, -1, -1, -1, -1, -1], url: 'https://en.wikipedia.org/wiki/Heart_Sutra', license: 'Conze fuses 14 + 15 — no separate alignment', }, @@ -3136,7 +3136,7 @@ export const heartSutra: LiturgyDoc = { { by: 'MAPLE chant sheet (after Sheng-yen)', text: 'Therefore know: transcendent wisdom', alignTo: [0, 1, -1, 2], license: 'MAPLE community chant sheet, adapted from Master Sheng-yen\'s translation' }, { by: 'Conze (1958)', text: 'Therefore one should know the Prajñāpāramitā', alignTo: [0, -1, -1, 1, -1, 2], url: 'https://en.wikipedia.org/wiki/Heart_Sutra' }, { by: 'Red Pine (2004)', text: 'You should therefore know that Prajñāpāramitā', alignTo: [-1, -1, 0, 1, -1, 2], url: 'https://www.counterpointpress.com/dd-product/the-heart-sutra/', license: 'Quoted with attribution' }, - { by: 'Thich Nhat Hanh (2014)', text: 'Therefore Shariputra, it should be known that the Insight that brings us to the Other Shore', alignTo: [0, -1, -1, -1, -1, 1, -1, -1, 2, -1, -1, -1, -1, -1, -1], url: 'https://plumvillage.org/sutra/the-other-shore', license: 'Plum Village translation, quoted with attribution' }, + { by: 'Thich Nhat Hanh (2014)', text: 'Therefore Shariputra, it should be known that the Insight that brings us to the Other Shore', alignTo: [0, -1, -1, -1, -1, 1, -1, -1, 2, -1, -1, -1, -1, -1, -1, -1], url: 'https://plumvillage.org/sutra/the-other-shore', license: 'Plum Village translation, quoted with attribution' }, ], words: [ { form: 'tasmāj', scriptAlt: 'तस्माज्', scriptAlts: { 'zh-Hant': '故', 'ja-Jpan': '故' }, pronunciation: 'tahs-MAHJ', gloss: 'therefore (ablative of *tat* "that")' }, @@ -3225,8 +3225,8 @@ export const heartSutra: LiturgyDoc = { witnesses: [ { by: 'MAPLE chant sheet (after Sheng-yen)', text: 'the unequalled knowledge.', alignTo: [-1, -1, 0], license: 'MAPLE community chant sheet, adapted from Master Sheng-yen\'s translation' }, { by: 'Conze (1958)', text: 'unequalled,', alignTo: [0], url: 'https://en.wikipedia.org/wiki/Heart_Sutra' }, - { by: 'Red Pine (2004)', text: 'the mantra equal to the unequaled,', alignTo: [-1, -1, -1, -1, 0], url: 'https://www.counterpointpress.com/dd-product/the-heart-sutra/', license: 'Quoted with attribution' }, - { by: 'Thich Nhat Hanh (2014)', text: 'the mantra which is the equal of the unequalled,', alignTo: [-1, -1, -1, -1, -1, -1, -1, 0], url: 'https://plumvillage.org/sutra/the-other-shore', license: 'Plum Village translation, quoted with attribution' }, + { by: 'Red Pine (2004)', text: 'the mantra equal to the unequaled,', alignTo: [-1, -1, -1, -1, -1, 0], url: 'https://www.counterpointpress.com/dd-product/the-heart-sutra/', license: 'Quoted with attribution' }, + { by: 'Thich Nhat Hanh (2014)', text: 'the mantra which is the equal of the unequalled,', alignTo: [-1, -1, -1, -1, -1, -1, -1, -1, 0], url: 'https://plumvillage.org/sutra/the-other-shore', license: 'Plum Village translation, quoted with attribution' }, ], words: [ { form: 'asamasamamantraḥ', scriptAlt: 'असमसममन्त्रः', scriptAlts: { 'zh-Hant': '無等等咒', 'ja-Jpan': '無等等咒' }, pronunciation: 'ah-SAH-mah-SAH-mah-mahn-trahh', etymology: '*a-* "not" + *sama* "equal" + *sama* "equal" — "having no equal", "equal to the unequaled"', gloss: 'the unequaled-equal mantra — paradoxical formula: equal to what has no equal' }, @@ -3291,9 +3291,9 @@ export const heartSutra: LiturgyDoc = { ], witnesses: [ { by: 'MAPLE chant sheet (after Sheng-yen)', text: 'Therefore recite the mantra of transcendent wisdom', alignTo: [-1, 1, -1, 2, -1, -1, 0], license: 'MAPLE community chant sheet, adapted from Master Sheng-yen\'s translation' }, - { by: 'Conze (1958)', text: 'By the Prajñāpāramitā has this spell been delivered. It runs like this:', alignTo: [-1, -1, 0, -1, -1, -1, 2, -1, 1, -1, -1, -1, -1], url: 'https://en.wikipedia.org/wiki/Heart_Sutra' }, + { by: 'Conze (1958)', text: 'By the Prajñāpāramitā has this spell been delivered. It runs like this:', alignTo: [-1, -1, 0, -1, -1, 2, -1, 1, -1, -1, -1, -1], url: 'https://en.wikipedia.org/wiki/Heart_Sutra' }, { by: 'Red Pine (2004)', text: 'So we proclaim the mantra of Prajñāpāramitā,', alignTo: [-1, -1, 1, -1, 2, -1, 0], url: 'https://www.counterpointpress.com/dd-product/the-heart-sutra/', license: 'Quoted with attribution' }, - { by: 'Thich Nhat Hanh (2014)', text: 'so let us proclaim a mantra to praise the Insight that brings us to the Other Shore.', alignTo: [-1, -1, -1, 1, -1, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1], url: 'https://plumvillage.org/sutra/the-other-shore', license: 'Plum Village translation, quoted with attribution' }, + { by: 'Thich Nhat Hanh (2014)', text: 'so let us proclaim a mantra to praise the Insight that brings us to the Other Shore.', alignTo: [-1, -1, -1, 1, -1, 2, -1, -1, -1, 0, -1, -1, -1, -1, -1, -1, -1], url: 'https://plumvillage.org/sutra/the-other-shore', license: 'Plum Village translation, quoted with attribution' }, ], words: [ { form: 'prajñāpāramitāyām', scriptAlt: 'प्रज्ञापारमितायाम्', scriptAlts: { 'zh-Hant': '般若波羅蜜多', 'ja-Jpan': '般若波羅蜜多' }, pronunciation: 'prahj-NYAH-pah-rah-mee-TAH-yahm', etymology: 'locative of *prajñāpāramitā* — "in / from the Perfection of Wisdom"', gloss: 'in the Perfection of Wisdom (locative)', accent: 'sky' }, From 15bc68fc0e8dbfddba0d200305742c7c0a634db3 Mon Sep 17 00:00:00 2001 From: Aditya Date: Tue, 19 May 2026 12:10:44 -0400 Subject: [PATCH 03/12] =?UTF-8?q?feat(liturgy):=20wire=20font-size=20slide?= =?UTF-8?q?r=20=E2=80=94=20chant=20body=20scales=20via=20--liturgy-scale?= =?UTF-8?q?=20CSS=20var?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The slider in the settings popover now actually changes the chant text size. Mechanism: 1. LiturgyChantPage splits into Provider + Body. The Body reads settings.fontScale via useLiturgySettings and applies it as the --liturgy-scale CSS custom property on the root wrapper div. 2. TripleScriptWitness drops the responsive Tailwind size classes (text-xl md:text-2xl etc.) in favor of inline fontSize: calc(rem * var(--liturgy-scale, 1)). Large sections use 1.875rem base, normal use 1.5rem. 3. SoundFormula does the same for the dharani body (3rem base). The previous responsive variants (md:, lg:) are intentionally dropped on the scaled elements — they fought the slider on tablet/desktop. The slider's 0.7–1.6 range gives the reader full control of perceived size; the default 1.0 matches the mn10 demo's large-chant rendering. --- components/liturgy/LiturgyChantPage.tsx | 21 +++++++++++++++---- components/liturgy/shapes/SoundFormula.tsx | 8 +++++-- .../liturgy/shapes/TripleScriptWitness.tsx | 8 ++++--- 3 files changed, 28 insertions(+), 9 deletions(-) diff --git a/components/liturgy/LiturgyChantPage.tsx b/components/liturgy/LiturgyChantPage.tsx index 1153810..57c3cff 100644 --- a/components/liturgy/LiturgyChantPage.tsx +++ b/components/liturgy/LiturgyChantPage.tsx @@ -2,7 +2,7 @@ import React, { useMemo, useState } from 'react'; import type { LiturgyDoc, Sangha, Witness } from '../../types/liturgy'; import { SectionRenderer } from './SectionRenderer'; import { ProseBlock } from './ProseBlock'; -import { LiturgySettingsProvider, SettingsButton } from './LiturgySettings'; +import { LiturgySettingsProvider, SettingsButton, useLiturgySettings } from './LiturgySettings'; import { WitnessDots } from './shapes/TripleScriptWitness'; /** @@ -47,11 +47,23 @@ const TRADITION_LABELS: Record = { export const LiturgyChantPage: React.FC<{ doc: LiturgyDoc; sangha?: Sangha }> = ({ doc, sangha, +}) => { + return ( + + + + ); +}; + +const LiturgyChantPageBody: React.FC<{ doc: LiturgyDoc; sangha?: Sangha }> = ({ + doc, + sangha, }) => { const backHref = sangha ? `/liturgy/${sangha.slug}` : '/liturgy'; const backLabel = sangha ? sangha.name : 'Liturgy'; const witnesses = useMemo(() => uniqueWitnesses(doc), [doc]); const primaryWitness = witnesses[0]?.by ?? ''; + const { settings } = useLiturgySettings(); // Page-level witness picker state. The dots row lives once at the top of // the chant body; every triple-script-witness section honors the same @@ -65,8 +77,10 @@ export const LiturgyChantPage: React.FC<{ doc: LiturgyDoc; sangha?: Sangha }> = }; return ( - -
+
{/* Thin nav at top — the chant artifact itself carries title-weight, either by way of a recognizable opening line (morning-chants' "Namo tassa...") or an explicit title-as-segment first section @@ -178,7 +192,6 @@ export const LiturgyChantPage: React.FC<{ doc: LiturgyDoc; sangha?: Sangha }> = )}
- ); }; diff --git a/components/liturgy/shapes/SoundFormula.tsx b/components/liturgy/shapes/SoundFormula.tsx index 12c4052..04ee1be 100644 --- a/components/liturgy/shapes/SoundFormula.tsx +++ b/components/liturgy/shapes/SoundFormula.tsx @@ -54,8 +54,12 @@ const FormulaLine: React.FC<{ variant: ScriptVariant }> = ({ variant }) => { return ( <>
{variant.text} diff --git a/components/liturgy/shapes/TripleScriptWitness.tsx b/components/liturgy/shapes/TripleScriptWitness.tsx index 772ffbe..7f201e0 100644 --- a/components/liturgy/shapes/TripleScriptWitness.tsx +++ b/components/liturgy/shapes/TripleScriptWitness.tsx @@ -573,7 +573,9 @@ const PaliLine: React.FC<{ }> = ({ text, words = [], large = false, lang, tokens: tokenHints }) => { const { settings } = useLiturgySettings(); const script = scriptSubtag(lang); - const sizeClass = large ? 'text-2xl md:text-3xl' : 'text-xl md:text-2xl'; + // Base font sizes (rem). Reader can tune via the settings slider, which + // sets `--liturgy-scale` on the LiturgyChantPage wrapper. + const baseRem = large ? 1.875 : 1.5; const fontStack = SCRIPT_FONT[script] ?? SCRIPT_FONT.Latn; const tokens = (() => { @@ -615,8 +617,8 @@ const PaliLine: React.FC<{ return (
{tokens.map((t, i) => { From 1a229a311769dc0745bad1fe03419459d5603110 Mon Sep 17 00:00:00 2001 From: Aditya Date: Tue, 19 May 2026 12:13:47 -0400 Subject: [PATCH 04/12] fix(liturgy): transliteration line sits below tooltip stacking context MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The chant word span uses 'relative z-10' to mask alignment-line SVG strokes behind it. The tooltip inside the word (z-50) is part of the word's stacking context — in the parent it shows up at z=10. The TransliterationLine was 'position: static z-auto', which competed unpredictably with the word's z=10 layer on flip-below tooltip render. Explicitly anchoring the trans line at 'relative z-0' guarantees the tooltip's z=10 layer (carrying the z-50 tooltip body) paints above it. --- components/liturgy/shapes/TripleScriptWitness.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/liturgy/shapes/TripleScriptWitness.tsx b/components/liturgy/shapes/TripleScriptWitness.tsx index 7f201e0..2b7c53c 100644 --- a/components/liturgy/shapes/TripleScriptWitness.tsx +++ b/components/liturgy/shapes/TripleScriptWitness.tsx @@ -174,7 +174,7 @@ const TransliterationLine: React.FC<{ if (!respelling) return null; return (
@@ -186,7 +186,7 @@ const TransliterationLine: React.FC<{ if (!variant.transliteration) return null; return (
From cd66856bbaf6f598c2df347d72fd903d5c41a194 Mon Sep 17 00:00:00 2001 From: Aditya Date: Tue, 19 May 2026 12:16:04 -0400 Subject: [PATCH 05/12] feat(liturgy): strip AI-framing prose from Metta Sutta, Way of Compassion, Om Mani MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Three chants carried curator-voice prose blocks above the chant body itself: - metta-sutta: 'opens by naming the inner posture (capable, upright...)' paragraph — the chant body and word glosses already say this. - way-of-compassion: same opening posture paragraph + 'Bodhi Sangha chants this in E.A. Burtt's 1955 English' meta-narration — context already covered in the page's subtitle + sources. - om-mani-padme-hum: three prose blocks — the framing 'mantra of compassion' paragraph, an 'Across traditions' block restating each script with reading + lineage (the multi-script TSW already cycles Sanskrit / Devanāgarī / Tibetan / Hanzi / Shingon), and an 'On translating mantras' block citing Lopez. The page now opens directly on the mantra; readers cycle scripts via the existing affordance and hover each syllable for per-tradition exegesis. --- data/liturgy/metta-sutta.ts | 5 ----- data/liturgy/om-mani-padme-hum.ts | 27 +-------------------------- data/liturgy/way-of-compassion.ts | 5 ----- 3 files changed, 1 insertion(+), 36 deletions(-) diff --git a/data/liturgy/metta-sutta.ts b/data/liturgy/metta-sutta.ts index f75e2ee..28651bc 100644 --- a/data/liturgy/metta-sutta.ts +++ b/data/liturgy/metta-sutta.ts @@ -52,11 +52,6 @@ export const mettaSutta: LiturgyDoc = { curator: 'Curation by Aditya. Pāli verses from the Khuddakapāṭha 9 / Suttanipāta 1.8 recension (suttafriends.org transcription). English witness is the Amaravati Sangha translation — the version printed on the MAPLE practice sheet, widely used across Theravāda monasteries. Per-word glosses are sparse and authored only on a few key terms.', sections: [ - { - id: 'framing', - shape: 'prose-commentary', - body: 'The Karaṇīya Metta Sutta opens by naming the inner posture (capable, upright, gentle, content) of one fit to cultivate boundless [[metta]], and then turns to the practice itself: wishing every kind of being at ease, protecting that wish like a mother protecting her only child, radiating it upwards, downwards, in every direction. Closes with the posture of practice (standing, walking, seated, lying down) and the release that follows (clarity of vision, freedom from desire, no more rebirth).\n\nChanted in Pāli; the prose English below is the Amaravati Sangha rendering, line-mapped approximately to the ten Pāli verses. Word-by-word alignment is not authored here; the verses are short enough to read line-by-line.', - }, { id: 'verses', shape: 'triple-script-witness', diff --git a/data/liturgy/om-mani-padme-hum.ts b/data/liturgy/om-mani-padme-hum.ts index ff008ec..f1880fc 100644 --- a/data/liturgy/om-mani-padme-hum.ts +++ b/data/liturgy/om-mani-padme-hum.ts @@ -49,14 +49,8 @@ export const omManiPadmeHum: LiturgyDoc = { // ───────────────────────────────────────────────────────────────────── // 1. Framing — what this mantra is, why we say it // ───────────────────────────────────────────────────────────────────── - { - id: 'framing', - shape: 'prose-commentary', - body: 'The mantra of compassion. Chanted across the Buddhist world — from Bodh Gayā to Lhasa to Beijing to Kyoto. Its six syllables are the heart-essence of [[Avalokiteśvara]], the bodhisattva who hears the cries of all beings: *Chenrezig* in Tibet, *Guanyin* (觀音) in China, *Kannon* (観音) in Japan.\n\nEach tradition reads the mantra slightly differently — both in pronunciation and in interpretation. The Sanskrit reads as a vocative or locative ("O Jewel-Lotus One" / "the jewel in the lotus" — addressing or naming the bodhisattva). The widely-known syllable-by-syllable interpretation (six perfections, six realms) is a Tibetan exegetical tradition.\n\nThe mantra is *more than* its meaning. It works as sound, intention, embodiment — not just as a translatable phrase. As Donald Lopez warns in *Prisoners of Shangri-La*, much that is said about this mantra in the West reduces it to translation; the practice is doing none of that.', - }, - // ───────────────────────────────────────────────────────────────────── - // 2. The mantra in Sanskrit — with per-syllable hover-glimpse + // 1. The mantra — multi-script, hover for per-syllable readings // ───────────────────────────────────────────────────────────────────── { id: 'sanskrit-mantra', @@ -226,25 +220,6 @@ export const omManiPadmeHum: LiturgyDoc = { 'Traditionally chanted 108 times (one *mālā* — string of beads). Practice may be silent, whispered, or aloud, alone or in chorus. In Tibetan tradition, prayer wheels and prayer flags inscribed with the mantra extend its presence beyond the moment of saying it.', }, - // ───────────────────────────────────────────────────────────────────── - // 3. The mantra across traditions — multi-script showcase - // ───────────────────────────────────────────────────────────────────── - { - id: 'across-traditions', - shape: 'prose-commentary', - heading: 'Across traditions', - body: '**Sanskrit** (Devanāgarī — the source)\n\n*Script:* {{sa|ॐ मणि पद्मे हूँ}}\n*Pronunciation:* Oṃ maṇi padme hūṃ ("ohm MAH-nee PUHD-meh hoong")\n\nThe Indic source language. The literal grammatical reading is what we explored above.\n\n— ❦ —\n\n**Tibetan** (Uchen script — {{bo|བོད་ཡིག་}})\n\n*Script:* {{bo|ཨོཾ་མ་ཎི་པདྨེ་ཧཱུྃ}}\n*Wylie:* oṃ ma ṇi pad me hūṃ\n*Spoken (Lhasa):* "Om mani peme hung"\n\nThe heart-mantra of [[Chenrezig]] ({{bo|སྤྱན་རས་གཟིགས་}}), the Tibetan name for Avalokiteśvara — and the patron deity of Tibet itself. H.H. the Dalai Lama is considered an emanation of Chenrezig; his commentary on this mantra is the most widely-cited Tibetan reading in the West. Prayer wheels (*mani khorlo*) inscribed with the mantra are spun to multiply the practice.\n\n— ❦ —\n\n**Chinese** (Hanzi — Han Buddhism transliteration)\n\n*Script:* {{zh|唵嘛呢叭咪吽}}\n*Pinyin:* ǎn ma ní bā mī hōng\n\nThe mantra of [[Guanyin]] ({{zh|觀音}} — "perceiver of sounds"), the Chinese form of Avalokiteśvara. Guanyin is among the most widely venerated bodhisattvas in East Asia, often depicted in female form. The mantra is recited in Pure Land practice and in esoteric (Mizong / Zhenyan) traditions.\n\n— ❦ —\n\n**Japanese** (Kanji + furigana — Shingon esoteric tradition)\n\n*Script:* {{ja|唵 麼抳 鉢納銘 吽}}\n*Reading (Sino-Japanese):* On mani hatsuno mei un\n\nIn [[Shingon]] ({{ja|真言}}, "true word"), the esoteric school founded by Kūkai ({{ja|空海}}, 774–835), this mantra invokes [[Kannon]] ({{ja|観音}} — Japanese for Avalokiteśvara). Shingon practice unites mantra (speech), mudrā (body), and visualisation (mind) — the *sanmitsu* ({{ja|三密}}, "three mysteries"). Chanted with attention to all three.\n\n— ❦ —\n\n*Note:* Cross-script transliterations especially for Chinese and Japanese have several attested forms; these are widely used but not the only correct ones. Pronunciation drifts with the host language — *padme* becomes *peme* in Tibetan, *bāmī* in Chinese, *hatsumei* in Sino-Japanese.', - }, - - // ───────────────────────────────────────────────────────────────────── - // 4. On translating mantras — Lopez's caveat - // ───────────────────────────────────────────────────────────────────── - { - id: 'on-translation', - shape: 'prose-commentary', - heading: 'On translating mantras', - body: 'Donald Lopez, in *Prisoners of Shangri-La: Tibetan Buddhism and the West* (1998), devotes a chapter to this mantra. His warning, paraphrased: the Western fascination with finding *the meaning* of *Oṃ Maṇi Padme Hūṃ* — "the jewel in the lotus" — projects onto the mantra a literalism that the practitioners chanting it rarely impose. The mantra is a sonic embodiment of the bodhisattva of compassion, not a phrase awaiting decryption.\n\nWe present the readings above as *witnesses* — different cultural lenses for a sound that exceeds them all. Choose one and the others recede; chant the mantra and all of them recede.', - }, ], }; diff --git a/data/liturgy/way-of-compassion.ts b/data/liturgy/way-of-compassion.ts index 2146b42..56efd65 100644 --- a/data/liturgy/way-of-compassion.ts +++ b/data/liturgy/way-of-compassion.ts @@ -50,11 +50,6 @@ export const wayOfCompassion: LiturgyDoc = { curator: 'Curation by Aditya. Pāli verses from the Khuddakapāṭha 9 / Suttanipāta 1.8 recension (same source as MAPLE\'s metta-sutta page). Burtt\'s English transcribed from the Bodhi Sangha booklet; Amaravati / Sujato / Thanissaro included for comparison. Burtt does not translate the preamble (verses 1-2) or the final verse (10); those segments show `—` in the Burtt slot. Closing *Om Tat Sat* mantra is from Bhagavad Gītā 17.23.', sections: [ - { - id: 'framing', - shape: 'prose-commentary', - body: 'The *Karaṇīya Metta Sutta* (Sn 1.8 / Khp 9) opens by naming the inner posture (capable, upright, gentle, content) of one fit to cultivate boundless [[metta]], and then turns to the practice itself: wishing every kind of being at ease, protecting that wish like a mother protecting her only child, radiating it upwards, downwards, in every direction.\n\nBodhi Sangha chants this in E.A. Burtt\'s 1955 English — written in a lyric register that reads aloud well. Burtt omits the preamble verses 1-2 (on the chanter\'s inner virtues) and the closing verse 10 (on letting go of views); the booklet leaves those out too. This page presents the full Pāli alongside Burtt\'s text, with Amaravati / Sujato / Thanissaro for comparison on the verses Burtt does translate.', - }, { id: 'verses', shape: 'triple-script-witness', From 43d53d2601377545b16579896ff8e6671e36a83e Mon Sep 17 00:00:00 2001 From: Aditya Date: Tue, 19 May 2026 12:16:54 -0400 Subject: [PATCH 06/12] feat(liturgy): English translation line also scales with --liturgy-scale MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The chant body now scales via the slider, but the English translation line below it was stuck on a static 'text-base md:text-lg'. Replace with inline fontSize: calc(1.125rem * var(--liturgy-scale, 1)) so the slider controls both rows in proportion. Bump the base from 1rem (text-base) to 1.125rem (text-lg) so the translation is closer in weight to the chant — readers tracking the English no longer have to strain past tiny text. --- components/liturgy/shapes/TripleScriptWitness.tsx | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/components/liturgy/shapes/TripleScriptWitness.tsx b/components/liturgy/shapes/TripleScriptWitness.tsx index 2b7c53c..74ded07 100644 --- a/components/liturgy/shapes/TripleScriptWitness.tsx +++ b/components/liturgy/shapes/TripleScriptWitness.tsx @@ -1238,8 +1238,11 @@ const SegmentRow: React.FC<{ title={segment.witnesses.length > 1 ? 'Click to switch translation' : undefined} >
Date: Tue, 19 May 2026 12:56:03 -0400 Subject: [PATCH 07/12] =?UTF-8?q?feat(liturgy):=20per-script=20size=20mult?= =?UTF-8?q?ipliers=20=E2=80=94=20CJK=201.2x,=20Tibetan=201.1x,=20English?= =?UTF-8?q?=201.4x?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit User feedback: 'the japanese can be made 20% and the english line below it 40% large you get the idea right'. Add SCRIPT_SIZE_MULTIPLIER lookup keyed by script subtag (Latn 1.0, Deva 1.05, CJK 1.2, Tibt 1.1, Hang 1.15) and an ENGLISH_LINE_MULTIPLIER of 1.4. These multiply the per-shape base font size (1.5rem normal / 1.875rem large for TSW, 3rem for SoundFormula) before --liturgy-scale applies on top — so the slider still controls global size while proportions across scripts stay tuned. CJK glyphs carry more visual detail per unit than Latin; they need the extra pixels to resolve comfortably. The English translation line was the smallest thing on the page despite being where readers spend most of their attention — bumping it to 1.4× brings it close to the chant body weight without overpowering. --- components/liturgy/shapes/SoundFormula.tsx | 13 ++++++++- .../liturgy/shapes/TripleScriptWitness.tsx | 28 +++++++++++++++++-- 2 files changed, 37 insertions(+), 4 deletions(-) diff --git a/components/liturgy/shapes/SoundFormula.tsx b/components/liturgy/shapes/SoundFormula.tsx index 04ee1be..b60e432 100644 --- a/components/liturgy/shapes/SoundFormula.tsx +++ b/components/liturgy/shapes/SoundFormula.tsx @@ -29,6 +29,17 @@ const SCRIPT_FONT: Record = { Hang: "'Noto Serif KR', serif", }; +// Per-script size multipliers — same values used in TripleScriptWitness. +const SCRIPT_SIZE_MULTIPLIER: Record = { + Latn: 1.0, + Deva: 1.05, + Hant: 1.2, + Hans: 1.2, + Jpan: 1.2, + Tibt: 1.1, + Hang: 1.15, +}; + function scriptSubtag(lang: string): string { const parts = lang.split('-'); return parts.length >= 2 ? parts[1] : 'Latn'; @@ -58,7 +69,7 @@ const FormulaLine: React.FC<{ variant: ScriptVariant }> = ({ variant }) => { style={{ fontFamily, letterSpacing: script === 'Latn' ? '0.05em' : undefined, - fontSize: `calc(3rem * var(--liturgy-scale, 1))`, + fontSize: `calc(${3 * (SCRIPT_SIZE_MULTIPLIER[script] ?? 1)}rem * var(--liturgy-scale, 1))`, }} lang={variant.lang} > diff --git a/components/liturgy/shapes/TripleScriptWitness.tsx b/components/liturgy/shapes/TripleScriptWitness.tsx index 74ded07..52fb311 100644 --- a/components/liturgy/shapes/TripleScriptWitness.tsx +++ b/components/liturgy/shapes/TripleScriptWitness.tsx @@ -37,6 +37,24 @@ const SCRIPT_FONT: Record = { Hang: "'Noto Serif KR', serif", }; +/** + * Per-script size multipliers. Latin (IAST/Pāli) is the baseline (1.0). + * CJK and Devanāgarī benefit from slightly larger rendering because their + * glyphs carry more visual detail per unit; the reader needs more pixels + * to resolve them comfortably. The English translation line below the + * chant body gets its own bump so the gloss reads as easily as the chant. + */ +const SCRIPT_SIZE_MULTIPLIER: Record = { + Latn: 1.0, + Deva: 1.05, + Hant: 1.2, + Hans: 1.2, + Jpan: 1.2, + Tibt: 1.1, + Hang: 1.15, +}; +const ENGLISH_LINE_MULTIPLIER = 1.4; + /** Resolve the script subtag from a BCP-47 tag (e.g. "sa-Latn" → "Latn"). */ function scriptSubtag(lang: string): string { const parts = lang.split('-'); @@ -574,8 +592,10 @@ const PaliLine: React.FC<{ const { settings } = useLiturgySettings(); const script = scriptSubtag(lang); // Base font sizes (rem). Reader can tune via the settings slider, which - // sets `--liturgy-scale` on the LiturgyChantPage wrapper. - const baseRem = large ? 1.875 : 1.5; + // sets `--liturgy-scale` on the LiturgyChantPage wrapper. Each script + // also carries its own multiplier — CJK + Tibetan glyphs benefit from + // a slight upscale so the visual weight matches Latin chant body. + const baseRem = (large ? 1.875 : 1.5) * (SCRIPT_SIZE_MULTIPLIER[script] ?? 1); const fontStack = SCRIPT_FONT[script] ?? SCRIPT_FONT.Latn; const tokens = (() => { @@ -1241,7 +1261,9 @@ const SegmentRow: React.FC<{ className="text-slate-300 italic leading-relaxed" style={{ fontFamily: SERIF_STACK, - fontSize: `calc(1.125rem * var(--liturgy-scale, 1))`, + // English translation line — 1.125rem base × ENGLISH_LINE_MULTIPLIER + // (1.4 by default) so the gloss reads as easily as the chant. + fontSize: `calc(${1.125 * ENGLISH_LINE_MULTIPLIER}rem * var(--liturgy-scale, 1))`, }} > Date: Tue, 19 May 2026 13:02:28 -0400 Subject: [PATCH 08/12] feat(liturgy): finer-grained morpheme hover on Heart Sutra mantra + Sho Sai MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit User feedback: 'sas shouldbe a seperate segment I can hover on, why are you packing in a lot of stuff into one tool top, learn from https://read.adityaarpitha.com/sutta/demo endpoint, mn10 does a good job trying to make it as fine grained as possivle we can really improve this'. Author morphemes[] arrays on compound terms that previously rendered as a single hover-glob: Sho Sai: - śāsanānām → śās (√root) + ana (noun-forming) + ānām (gen. plural) - apratihata: a + pratihata → a + prati + hata (was 2 morphemes, now 3) Heart Sutra (mantra crescendo + selected compounds): - mahāmantraḥ → mahā + mantraḥ - mahāvidyāmantraḥ → mahā + vidyā + mantraḥ - anuttaramantraḥ → an + uttara + mantraḥ - asamasamamantraḥ → a + sama + sama + mantraḥ (the 4-morpheme paradox) - sarvaduḥkhapraśamanaḥ → sarva + duḥkha + praśamanaḥ - prajñāpāramitā → prajñā + pāramitā - prajñāpāramitāyām → prajñā + pāramitā + yām (locative) - jñātavyaṃ → jñā (√root) + tavyaṃ (gerundive) - ukto → ukt (√vac past part.) + o (nom.) - mantraḥ → man (√root) + traḥ (instrument suffix) - avidyākṣayo → a + vidyā + kṣayo - jarāmaraṇakṣayaḥ → jarā + maraṇa + kṣayaḥ - niṣṭhānirvāṇaḥ → niṣṭhā + nir + vāṇaḥ - āśritya → ā + śri (√root) + tya (gerund) - anuttarāṃ → an + uttarāṃ Each morpheme carries pronunciation + gloss, surfacing root verbs (√man, √vac, √śri, √jñā, √vid, √śam, √mṛ, √vā, √han, √śās) where applicable. Hover now decomposes the meaning instead of dumping the whole etymology in one tooltip. This is a partial pass — Heart Sutra still has ~30 monolithic words (simple stems where breakdown adds little; particles; some compounds in the negation litany). Future passes can extend to Hōkyō Zanmai, Song of Zazen, Shin Jin No Mei, Enmei Jikku, etc. --- data/liturgy/heart-sutra.ts | 160 +++++++++++++++++++-- data/liturgy/sho-sai-myo-kichijo-darani.ts | 8 +- 2 files changed, 157 insertions(+), 11 deletions(-) diff --git a/data/liturgy/heart-sutra.ts b/data/liturgy/heart-sutra.ts index 0ba9719..aa9faf7 100644 --- a/data/liturgy/heart-sutra.ts +++ b/data/liturgy/heart-sutra.ts @@ -2030,6 +2030,11 @@ export const heartSutra: LiturgyDoc = { pronunciation: 'ah-VEED-yah-KSHAH-yoh', etymology: '*avidyā* "ignorance" + *kṣaya* "ending, exhaustion"', gloss: 'end of ignorance — both the cause and its cessation are negated', + morphemes: [ + { text: 'a', type: 'prefix', gloss: 'not', pronunciation: 'ah' }, + { text: 'vidyā', type: 'stem', root: '√vid', gloss: 'knowledge — *avidyā* = "not-knowing", the first link of dependent origination', pronunciation: 'VEED-yah' }, + { text: 'kṣayo', type: 'stem', gloss: 'ending, exhaustion (nominative)', pronunciation: 'KSHAH-yoh' }, + ], }, ], }, @@ -2117,6 +2122,11 @@ export const heartSutra: LiturgyDoc = { pronunciation: 'jah-RAH-mah-RAH-nah-KSHAH-yah', etymology: '*jarā-maraṇa* "aging-death" + *kṣaya* "ending"', gloss: 'end of aging-and-death — both the chain and its cessation are negated', + morphemes: [ + { text: 'jarā', type: 'stem', gloss: 'aging', pronunciation: 'jah-RAH' }, + { text: 'maraṇa', type: 'stem', root: '√mṛ', gloss: 'death — twelfth and final link of dependent origination', pronunciation: 'mah-RAH-nah' }, + { text: 'kṣayaḥ', type: 'stem', gloss: 'ending, exhaustion (nominative)', pronunciation: 'KSHAH-yahh' }, + ], }, ], }, @@ -2798,6 +2808,11 @@ export const heartSutra: LiturgyDoc = { etymology: '*niṣṭhā* "completion, end" + *nirvāṇa* "extinguishing"', gloss: 'final/complete nirvāṇa — the extinguishing of grasping that is the end of suffering', accent: 'violet', + morphemes: [ + { text: 'niṣṭhā', type: 'stem', gloss: 'completion, fixation, final state', pronunciation: 'neesh-TAH' }, + { text: 'nir', type: 'prefix', gloss: 'out, away, without', pronunciation: 'near' }, + { text: 'vāṇaḥ', type: 'stem', root: '√vā', gloss: 'blown — together *nirvāṇa* = "blown out, extinguished" (the metaphor of an oil lamp going out)', pronunciation: 'VAH-nahh' }, + ], citations: [wikipediaCitation('Nirvana_(Buddhism)')], }, ], @@ -3000,6 +3015,11 @@ export const heartSutra: LiturgyDoc = { pronunciation: 'AH-shree-tyah', etymology: '*ā-* "toward" + *√śri* "to rest on, depend on"', gloss: 'having taken refuge in, relying on (gerund)', + morphemes: [ + { text: 'ā', type: 'prefix', gloss: 'toward, near', pronunciation: 'ah' }, + { text: 'śri', type: 'root', root: '√śri', gloss: 'to rest on, take refuge in, depend on', pronunciation: 'shree' }, + { text: 'tya', type: 'suffix', gloss: 'gerund / absolutive ending — "having Xed"', pronunciation: 'tyah' }, + ], }, ], }, @@ -3074,6 +3094,10 @@ export const heartSutra: LiturgyDoc = { pronunciation: 'ah-NOOT-tah-rahm', etymology: '*a-* "not" + *uttara* "higher, superior" — "than which nothing is higher"', gloss: 'unsurpassed, supreme', + morphemes: [ + { text: 'an', type: 'prefix', gloss: 'not (assimilated *a-* before vowel)', pronunciation: 'ahn' }, + { text: 'uttarāṃ', type: 'stem', gloss: 'higher, superior (accusative) — "than which nothing is higher"', pronunciation: 'OOT-tah-rahm' }, + ], }, { form: 'samyaksaṃbodhim', @@ -3140,8 +3164,29 @@ export const heartSutra: LiturgyDoc = { ], words: [ { form: 'tasmāj', scriptAlt: 'तस्माज्', scriptAlts: { 'zh-Hant': '故', 'ja-Jpan': '故' }, pronunciation: 'tahs-MAHJ', gloss: 'therefore (ablative of *tat* "that")' }, - { form: 'jñātavyaṃ', scriptAlt: 'ज्ञातव्यं', scriptAlts: { 'zh-Hant': '知', 'ja-Jpan': '知' }, pronunciation: 'GYAH-tahv-yahm', gloss: 'should be known (gerundive)' }, - { form: 'prajñāpāramitā', scriptAlt: 'प्रज्ञापारमिता', scriptAlts: { 'zh-Hant': '般若波羅蜜多', 'ja-Jpan': '般若波羅蜜多' }, pronunciation: 'prahj-NYAH-pah-rah-mee-TAH', gloss: 'the Perfection of Wisdom (nominative)', accent: 'sky' }, + { + form: 'jñātavyaṃ', + scriptAlt: 'ज्ञातव्यं', + scriptAlts: { 'zh-Hant': '知', 'ja-Jpan': '知' }, + pronunciation: 'GYAH-tahv-yahm', + gloss: 'should be known (gerundive)', + morphemes: [ + { text: 'jñā', type: 'root', root: '√jñā', gloss: 'to know', pronunciation: 'gyah' }, + { text: 'tavyaṃ', type: 'suffix', gloss: 'gerundive suffix — "should/must be Xed"', pronunciation: 'TAHV-yahm' }, + ], + }, + { + form: 'prajñāpāramitā', + scriptAlt: 'प्रज्ञापारमिता', + scriptAlts: { 'zh-Hant': '般若波羅蜜多', 'ja-Jpan': '般若波羅蜜多' }, + pronunciation: 'prahj-NYAH-pah-rah-mee-TAH', + gloss: 'the Perfection of Wisdom (nominative)', + accent: 'sky', + morphemes: [ + { text: 'prajñā', type: 'stem', root: '√jñā', gloss: 'wisdom — *pra-* "forth" + *√jñā* "to know"', pronunciation: 'prahj-NYAH' }, + { text: 'pāramitā', type: 'stem', gloss: 'perfection, "gone-to-the-other-shore" (*pāram* "the far shore" + *itā* "gone")', pronunciation: 'pah-rah-mee-TAH' }, + ], + }, ], }, @@ -3163,7 +3208,18 @@ export const heartSutra: LiturgyDoc = { { by: 'Thich Nhat Hanh (2014)', text: 'is a Great Mantra,', alignTo: [-1, -1, 0, 0], url: 'https://plumvillage.org/sutra/the-other-shore', license: 'Plum Village translation, quoted with attribution' }, ], words: [ - { form: 'mahāmantraḥ', scriptAlt: 'महामन्त्रः', scriptAlts: { 'zh-Hant': '大神咒', 'ja-Jpan': '大神咒' }, pronunciation: 'mah-HAH-mahn-trahh', etymology: '*mahā* "great" + *mantra* "spell, sacred utterance"', gloss: 'the great mantra' }, + { + form: 'mahāmantraḥ', + scriptAlt: 'महामन्त्रः', + scriptAlts: { 'zh-Hant': '大神咒', 'ja-Jpan': '大神咒' }, + pronunciation: 'mah-HAH-mahn-trahh', + etymology: '*mahā* "great" + *mantra* "spell, sacred utterance"', + gloss: 'the great mantra', + morphemes: [ + { text: 'mahā', type: 'prefix', gloss: 'great', pronunciation: 'mah-HAH' }, + { text: 'mantraḥ', type: 'stem', root: '√man', gloss: 'mantra, instrument of thought (nominative)', pronunciation: 'MAHN-trahh' }, + ], + }, ], }, @@ -3185,7 +3241,19 @@ export const heartSutra: LiturgyDoc = { { by: 'Thich Nhat Hanh (2014)', text: 'the most illuminating mantra,', alignTo: [-1, -1, -1, 0], url: 'https://plumvillage.org/sutra/the-other-shore', license: 'Plum Village translation, quoted with attribution' }, ], words: [ - { form: 'mahāvidyāmantraḥ', scriptAlt: 'महाविद्यामन्त्रः', scriptAlts: { 'zh-Hant': '大明咒', 'ja-Jpan': '大明咒' }, pronunciation: 'mah-HAH-veed-YAH-mahn-trahh', etymology: '*mahā* "great" + *vidyā* "knowledge, illumination" + *mantra*. *Vidyā* shares its root √vid with the 明 (míng "bright, clear")', gloss: 'the great knowledge-mantra — knowledge here is illumination, not propositional content' }, + { + form: 'mahāvidyāmantraḥ', + scriptAlt: 'महाविद्यामन्त्रः', + scriptAlts: { 'zh-Hant': '大明咒', 'ja-Jpan': '大明咒' }, + pronunciation: 'mah-HAH-veed-YAH-mahn-trahh', + etymology: '*mahā* "great" + *vidyā* "knowledge, illumination" + *mantra*. *Vidyā* shares its root √vid with the 明 (míng "bright, clear")', + gloss: 'the great knowledge-mantra — knowledge here is illumination, not propositional content', + morphemes: [ + { text: 'mahā', type: 'prefix', gloss: 'great', pronunciation: 'mah-HAH' }, + { text: 'vidyā', type: 'stem', root: '√vid', gloss: 'knowledge, illumination — same root as Chinese 明 (míng "bright, clear")', pronunciation: 'veed-YAH' }, + { text: 'mantraḥ', type: 'stem', root: '√man', gloss: 'mantra (nominative)', pronunciation: 'MAHN-trahh' }, + ], + }, ], }, @@ -3207,7 +3275,19 @@ export const heartSutra: LiturgyDoc = { { by: 'Thich Nhat Hanh (2014)', text: 'the highest mantra,', alignTo: [-1, -1, 0], url: 'https://plumvillage.org/sutra/the-other-shore', license: 'Plum Village translation, quoted with attribution' }, ], words: [ - { form: 'anuttaramantraḥ', scriptAlt: 'अनुत्तरमन्त्रः', scriptAlts: { 'zh-Hant': '無上咒', 'ja-Jpan': '無上咒' }, pronunciation: 'ah-NOOT-tah-rah-mahn-trahh', etymology: 'same *anuttara* "unsurpassed" as in *anuttarā samyaksaṃbodhi*', gloss: 'the unsurpassed mantra — nothing surpasses it' }, + { + form: 'anuttaramantraḥ', + scriptAlt: 'अनुत्तरमन्त्रः', + scriptAlts: { 'zh-Hant': '無上咒', 'ja-Jpan': '無上咒' }, + pronunciation: 'ah-NOOT-tah-rah-mahn-trahh', + etymology: 'same *anuttara* "unsurpassed" as in *anuttarā samyaksaṃbodhi*', + gloss: 'the unsurpassed mantra — nothing surpasses it', + morphemes: [ + { text: 'an', type: 'prefix', gloss: 'not (assimilated form of *a-* before vowel)', pronunciation: 'ahn' }, + { text: 'uttara', type: 'stem', gloss: 'higher, superior', pronunciation: 'OOT-tah-rah' }, + { text: 'mantraḥ', type: 'stem', root: '√man', gloss: 'mantra (nominative)', pronunciation: 'MAHN-trahh' }, + ], + }, ], }, @@ -3229,7 +3309,20 @@ export const heartSutra: LiturgyDoc = { { by: 'Thich Nhat Hanh (2014)', text: 'the mantra which is the equal of the unequalled,', alignTo: [-1, -1, -1, -1, -1, -1, -1, -1, 0], url: 'https://plumvillage.org/sutra/the-other-shore', license: 'Plum Village translation, quoted with attribution' }, ], words: [ - { form: 'asamasamamantraḥ', scriptAlt: 'असमसममन्त्रः', scriptAlts: { 'zh-Hant': '無等等咒', 'ja-Jpan': '無等等咒' }, pronunciation: 'ah-SAH-mah-SAH-mah-mahn-trahh', etymology: '*a-* "not" + *sama* "equal" + *sama* "equal" — "having no equal", "equal to the unequaled"', gloss: 'the unequaled-equal mantra — paradoxical formula: equal to what has no equal' }, + { + form: 'asamasamamantraḥ', + scriptAlt: 'असमसममन्त्रः', + scriptAlts: { 'zh-Hant': '無等等咒', 'ja-Jpan': '無等等咒' }, + pronunciation: 'ah-SAH-mah-SAH-mah-mahn-trahh', + etymology: '*a-* "not" + *sama* "equal" + *sama* "equal" — "having no equal", "equal to the unequaled"', + gloss: 'the unequaled-equal mantra — paradoxical formula: equal to what has no equal', + morphemes: [ + { text: 'a', type: 'prefix', gloss: 'not', pronunciation: 'ah' }, + { text: 'sama', type: 'stem', gloss: 'equal — first occurrence: "no equal"', pronunciation: 'SAH-mah' }, + { text: 'sama', type: 'stem', gloss: 'equal — second occurrence: "equal to [the unequaled]"', pronunciation: 'SAH-mah' }, + { text: 'mantraḥ', type: 'stem', root: '√man', gloss: 'mantra (nominative)', pronunciation: 'MAHN-trahh' }, + ], + }, ], }, @@ -3251,7 +3344,19 @@ export const heartSutra: LiturgyDoc = { { by: 'Thich Nhat Hanh (2014)', text: 'a Mantra which is able to allay all suffering.', alignTo: [-1, -1, -1, -1, -1, 0, 0, 0, 0], url: 'https://plumvillage.org/sutra/the-other-shore', license: 'Plum Village translation, quoted with attribution' }, ], words: [ - { form: 'sarvaduḥkhapraśamanaḥ', scriptAlt: 'सर्वदुःखप्रशमनः', scriptAlts: { 'zh-Hant': '除一切苦', 'ja-Jpan': '除一切苦' }, pronunciation: 'sahr-vah-DOOH-khah-prah-SHAH-mah-nahh', etymology: '*sarva* "all" + *duḥkha* "suffering" + *praśamana* "calming, stilling"', gloss: 'allayer of all suffering — what calms every kind of suffering' }, + { + form: 'sarvaduḥkhapraśamanaḥ', + scriptAlt: 'सर्वदुःखप्रशमनः', + scriptAlts: { 'zh-Hant': '除一切苦', 'ja-Jpan': '除一切苦' }, + pronunciation: 'sahr-vah-DOOH-khah-prah-SHAH-mah-nahh', + etymology: '*sarva* "all" + *duḥkha* "suffering" + *praśamana* "calming, stilling"', + gloss: 'allayer of all suffering — what calms every kind of suffering', + morphemes: [ + { text: 'sarva', type: 'prefix', gloss: 'all, every', pronunciation: 'SAHR-vah' }, + { text: 'duḥkha', type: 'stem', gloss: 'suffering, dis-ease — the First Noble Truth term', pronunciation: 'DOOH-khah' }, + { text: 'praśamanaḥ', type: 'stem', root: '√śam', gloss: 'calming, stilling, allayer (nominative)', pronunciation: 'prah-SHAH-mah-nahh' }, + ], + }, ], }, @@ -3296,9 +3401,44 @@ export const heartSutra: LiturgyDoc = { { by: 'Thich Nhat Hanh (2014)', text: 'so let us proclaim a mantra to praise the Insight that brings us to the Other Shore.', alignTo: [-1, -1, -1, 1, -1, 2, -1, -1, -1, 0, -1, -1, -1, -1, -1, -1, -1], url: 'https://plumvillage.org/sutra/the-other-shore', license: 'Plum Village translation, quoted with attribution' }, ], words: [ - { form: 'prajñāpāramitāyām', scriptAlt: 'प्रज्ञापारमितायाम्', scriptAlts: { 'zh-Hant': '般若波羅蜜多', 'ja-Jpan': '般若波羅蜜多' }, pronunciation: 'prahj-NYAH-pah-rah-mee-TAH-yahm', etymology: 'locative of *prajñāpāramitā* — "in / from the Perfection of Wisdom"', gloss: 'in the Perfection of Wisdom (locative)', accent: 'sky' }, - { form: 'ukto', scriptAlt: 'उक्तो', scriptAlts: { 'zh-Hant': '說', 'ja-Jpan': '說' }, pronunciation: 'OOK-toh', etymology: 'past participle of √vac "to speak"', gloss: 'spoken, declared' }, - { form: 'mantraḥ', scriptAlt: 'मन्त्रः', scriptAlts: { 'zh-Hant': '咒', 'ja-Jpan': '咒' }, pronunciation: 'MAHN-trahh', etymology: '*man-* "to think" + *-tra* instrument suffix — "instrument of thought"', gloss: 'the mantra (nominative)' }, + { + form: 'prajñāpāramitāyām', + scriptAlt: 'प्रज्ञापारमितायाम्', + scriptAlts: { 'zh-Hant': '般若波羅蜜多', 'ja-Jpan': '般若波羅蜜多' }, + pronunciation: 'prahj-NYAH-pah-rah-mee-TAH-yahm', + etymology: 'locative of *prajñāpāramitā* — "in / from the Perfection of Wisdom"', + gloss: 'in the Perfection of Wisdom (locative)', + accent: 'sky', + morphemes: [ + { text: 'prajñā', type: 'stem', root: '√jñā', gloss: 'wisdom', pronunciation: 'prahj-NYAH' }, + { text: 'pāramitā', type: 'stem', gloss: 'perfection, the going-beyond', pronunciation: 'pah-rah-mee-TAH' }, + { text: 'yām', type: 'suffix', gloss: 'locative case ending — "in / from"', pronunciation: 'yahm' }, + ], + }, + { + form: 'ukto', + scriptAlt: 'उक्तो', + scriptAlts: { 'zh-Hant': '說', 'ja-Jpan': '說' }, + pronunciation: 'OOK-toh', + etymology: 'past participle of √vac "to speak"', + gloss: 'spoken, declared', + morphemes: [ + { text: 'ukt', type: 'root', root: '√vac', gloss: 'spoken (past participle of *√vac* "to speak")', pronunciation: 'ookt' }, + { text: 'o', type: 'suffix', gloss: 'masculine nominative singular ending', pronunciation: 'oh' }, + ], + }, + { + form: 'mantraḥ', + scriptAlt: 'मन्त्रः', + scriptAlts: { 'zh-Hant': '咒', 'ja-Jpan': '咒' }, + pronunciation: 'MAHN-trahh', + etymology: '*man-* "to think" + *-tra* instrument suffix — "instrument of thought"', + gloss: 'the mantra (nominative)', + morphemes: [ + { text: 'man', type: 'root', root: '√man', gloss: 'to think', pronunciation: 'mahn' }, + { text: 'traḥ', type: 'suffix', gloss: '*-tra* instrument suffix + *-aḥ* nominative — "instrument of [thought]"', pronunciation: 'TRAHH' }, + ], + }, ], }, diff --git a/data/liturgy/sho-sai-myo-kichijo-darani.ts b/data/liturgy/sho-sai-myo-kichijo-darani.ts index 6b9b471..8b3245c 100644 --- a/data/liturgy/sho-sai-myo-kichijo-darani.ts +++ b/data/liturgy/sho-sai-myo-kichijo-darani.ts @@ -175,7 +175,8 @@ export const shoSaiMyoKichijoDarani: LiturgyDoc = { gloss: 'unimpeded, unobstructed — literally "not struck against"', morphemes: [ { text: 'a', type: 'prefix', gloss: 'not', pronunciation: 'ah' }, - { text: 'pratihata', type: 'stem', gloss: 'struck against, obstructed', pronunciation: 'prah-tee-HAH-tah' }, + { text: 'prati', type: 'prefix', gloss: 'against, toward', pronunciation: 'prah-tee' }, + { text: 'hata', type: 'stem', root: '√han', gloss: 'struck (past participle)', pronunciation: 'HAH-tah' }, ], }, { @@ -195,6 +196,11 @@ export const shoSaiMyoKichijoDarani: LiturgyDoc = { pronunciation: 'shah-sah-NAH-nahm', etymology: '*śās* "to teach, instruct" → *śāsana* "teaching" + *-ānām* (genitive plural)', gloss: 'of the teachings (genitive plural) — together: "of-those-with-unimpeded-teachings"', + morphemes: [ + { text: 'śās', type: 'root', root: '√śās', gloss: 'to teach, instruct', pronunciation: 'shahs' }, + { text: 'ana', type: 'suffix', gloss: 'noun-forming — yields *śāsana* "teaching"', pronunciation: 'ah-nah' }, + { text: 'ānām', type: 'suffix', gloss: 'genitive plural ending — "of those …"', pronunciation: 'AH-nahm' }, + ], }, ], }, From 666c3f6c993682f6fb7a75f1977f9e72757b7810 Mon Sep 17 00:00:00 2001 From: Aditya Date: Tue, 19 May 2026 13:04:50 -0400 Subject: [PATCH 09/12] =?UTF-8?q?refactor(sutta-studio):=20move=20demoPack?= =?UTF-8?q?et.json=20=E2=86=92=20content/references/sutta/mn10.json?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The mn10 reference packet now lives in a content-oriented directory that scales as we add other sutta references. The TS wrapper at components/sutta-studio/demoPacket.ts stays as the canonical import entry-point (preserving DEMO_PACKET_MN10 across all consumers); only its internal JSON import path changes. Also updates the lookup-phase.ts CLI default path + help string. --- components/sutta-studio/demoPacket.ts | 2 +- .../demoPacket.json => content/references/sutta/mn10.json | 0 scripts/sutta-studio/lookup-phase.ts | 4 ++-- 3 files changed, 3 insertions(+), 3 deletions(-) rename components/sutta-studio/demoPacket.json => content/references/sutta/mn10.json (100%) diff --git a/components/sutta-studio/demoPacket.ts b/components/sutta-studio/demoPacket.ts index 68d5262..8d1acce 100644 --- a/components/sutta-studio/demoPacket.ts +++ b/components/sutta-studio/demoPacket.ts @@ -1,3 +1,3 @@ import type { DeepLoomPacket } from '../../types/suttaStudio'; -import demoData from './demoPacket.json'; +import demoData from '../../content/references/sutta/mn10.json'; export const DEMO_PACKET_MN10: DeepLoomPacket = demoData as unknown as DeepLoomPacket; diff --git a/components/sutta-studio/demoPacket.json b/content/references/sutta/mn10.json similarity index 100% rename from components/sutta-studio/demoPacket.json rename to content/references/sutta/mn10.json diff --git a/scripts/sutta-studio/lookup-phase.ts b/scripts/sutta-studio/lookup-phase.ts index ddddbf2..fee7dbc 100644 --- a/scripts/sutta-studio/lookup-phase.ts +++ b/scripts/sutta-studio/lookup-phase.ts @@ -56,7 +56,7 @@ interface CliArgs { const parseArgs = (argv: string[]): CliArgs => { const out: CliArgs = { emitJson: false, - demoPacketPath: path.join(REPO_ROOT, 'components', 'sutta-studio', 'demoPacket.json'), + demoPacketPath: path.join(REPO_ROOT, 'content', 'references', 'sutta', 'mn10.json'), }; for (let i = 0; i < argv.length; i++) { const a = argv[i]; @@ -98,7 +98,7 @@ Options: human-readable report. --demo-packet Override the demoPacket location (default: - components/sutta-studio/demoPacket.json). + content/references/sutta/mn10.json). `); }; From 9effdb782869e4c0258fb288bd0e416ce3dbfbbd Mon Sep 17 00:00:00 2001 From: Aditya Date: Tue, 19 May 2026 14:08:38 -0400 Subject: [PATCH 10/12] chore(liturgy): drop stale 'Framing' comment header in om-mani-padme-hum --- data/liturgy/om-mani-padme-hum.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/data/liturgy/om-mani-padme-hum.ts b/data/liturgy/om-mani-padme-hum.ts index f1880fc..86decb0 100644 --- a/data/liturgy/om-mani-padme-hum.ts +++ b/data/liturgy/om-mani-padme-hum.ts @@ -46,9 +46,6 @@ export const omManiPadmeHum: LiturgyDoc = { }, curator: 'Curation by Aditya. Per-syllable readings cite the Dalai Lama\'s framework where invoked; the Sanskrit literal reading follows Monier-Williams (via Wikipedia).', sections: [ - // ───────────────────────────────────────────────────────────────────── - // 1. Framing — what this mantra is, why we say it - // ───────────────────────────────────────────────────────────────────── // ───────────────────────────────────────────────────────────────────── // 1. The mantra — multi-script, hover for per-syllable readings // ───────────────────────────────────────────────────────────────────── From 2d441b82035fa121ae44aef6e5735d42c2659577 Mon Sep 17 00:00:00 2001 From: Aditya Date: Tue, 19 May 2026 14:09:59 -0400 Subject: [PATCH 11/12] fix(liturgy): order Om Mani after Four Great Vows in MAPLE index User noted: 'after meal is before sleep can you change this order'. Bump om-mani order from 6 to 8 so the index reads chronologically: - Metta Sutta (6, before every meal) - Four Great Vows (7, after every meal) - Om Mani Padme Hum (8, evening, before sleep) --- data/liturgy/om-mani-padme-hum.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/liturgy/om-mani-padme-hum.ts b/data/liturgy/om-mani-padme-hum.ts index 86decb0..af664c1 100644 --- a/data/liturgy/om-mani-padme-hum.ts +++ b/data/liturgy/om-mani-padme-hum.ts @@ -23,7 +23,7 @@ import { export const omManiPadmeHum: LiturgyDoc = { slug: 'om-mani-padme-hum', sangha: 'maple', - order: 6, + order: 8, time: 'evening, before sleep', title: 'Oṃ Maṇi Padme Hūṃ', subtitle: 'The heart-mantra of Avalokiteśvara', From e2d9c543673ab0d96f69e9569bea20705af20c98 Mon Sep 17 00:00:00 2001 From: Aditya Date: Tue, 19 May 2026 14:13:17 -0400 Subject: [PATCH 12/12] fix(liturgy): Four Great Vows transliteration matches active script MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Hanzi script variant's transliteration was bundling Sino-Japanese romaji + Mandarin pinyin into one line, so when the reader cycled to Hanzi they saw both readings layered together (confusing — they're cycling scripts to focus on one). Now: when Hanzi is active, only the Mandarin pinyin shows under the characters. The Sino-Japanese variant carries Roman text directly so no extra transliteration is needed for it. Applied to all four vows in both MAPLE (vows.ts) and Bodhi Sangha (bodhi-vows.ts) renderings. --- data/liturgy/bodhi-vows.ts | 8 ++++---- data/liturgy/vows.ts | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/data/liturgy/bodhi-vows.ts b/data/liturgy/bodhi-vows.ts index c663672..8721200 100644 --- a/data/liturgy/bodhi-vows.ts +++ b/data/liturgy/bodhi-vows.ts @@ -42,7 +42,7 @@ export const bodhiVows: LiturgyDoc = { pali: 'Shujō muhen sē gan do', scripts: [ { lang: 'ja-Jpan', label: 'Sino-Japanese', text: 'Shujō muhen sē gan do', tokens: ['Shujō', 'muhen', 'sē gan', 'do'] }, - { lang: 'zh-Hant', label: 'Hanzi', text: '衆生無邊誓願度', tokens: ['衆生', '無邊', '誓願', '度'], transliteration: 'Shujō muhen sē gan do' }, + { lang: 'zh-Hant', label: 'Hanzi', text: '衆生無邊誓願度', tokens: ['衆生', '無邊', '誓願', '度'], transliteration: 'zhòng shēng wú biān shì yuàn dù (Mandarin pinyin)' }, ], witnesses: [ { @@ -64,7 +64,7 @@ export const bodhiVows: LiturgyDoc = { pali: 'Bonnō mujin sē gan dan', scripts: [ { lang: 'ja-Jpan', label: 'Sino-Japanese', text: 'Bonnō mujin sē gan dan', tokens: ['Bonnō', 'mujin', 'sē gan', 'dan'] }, - { lang: 'zh-Hant', label: 'Hanzi', text: '煩惱無盡誓願斷', tokens: ['煩惱', '無盡', '誓願', '斷'], transliteration: 'Bonnō mujin sē gan dan' }, + { lang: 'zh-Hant', label: 'Hanzi', text: '煩惱無盡誓願斷', tokens: ['煩惱', '無盡', '誓願', '斷'], transliteration: 'fán nǎo wú jìn shì yuàn duàn (Mandarin pinyin)' }, ], witnesses: [ { @@ -86,7 +86,7 @@ export const bodhiVows: LiturgyDoc = { pali: 'Hōmon muryō sē gan gaku', scripts: [ { lang: 'ja-Jpan', label: 'Sino-Japanese', text: 'Hōmon muryō sē gan gaku', tokens: ['Hōmon', 'muryō', 'sē gan', 'gaku'] }, - { lang: 'zh-Hant', label: 'Hanzi', text: '法門無量誓願學', tokens: ['法門', '無量', '誓願', '學'], transliteration: 'Hōmon muryō sē gan gaku' }, + { lang: 'zh-Hant', label: 'Hanzi', text: '法門無量誓願學', tokens: ['法門', '無量', '誓願', '學'], transliteration: 'fǎ mén wú liàng shì yuàn xué (Mandarin pinyin)' }, ], witnesses: [ { @@ -108,7 +108,7 @@ export const bodhiVows: LiturgyDoc = { pali: 'Butsudō mujō sē gan jō', scripts: [ { lang: 'ja-Jpan', label: 'Sino-Japanese', text: 'Butsudō mujō sē gan jō', tokens: ['Butsudō', 'mujō', 'sē gan', 'jō'] }, - { lang: 'zh-Hant', label: 'Hanzi', text: '佛道無上誓願成', tokens: ['佛道', '無上', '誓願', '成'], transliteration: 'Butsudō mujō sē gan jō' }, + { lang: 'zh-Hant', label: 'Hanzi', text: '佛道無上誓願成', tokens: ['佛道', '無上', '誓願', '成'], transliteration: 'fó dào wú shàng shì yuàn chéng (Mandarin pinyin)' }, ], witnesses: [ { diff --git a/data/liturgy/vows.ts b/data/liturgy/vows.ts index fdf3fb3..043ae99 100644 --- a/data/liturgy/vows.ts +++ b/data/liturgy/vows.ts @@ -66,7 +66,7 @@ export const vows: LiturgyDoc = { label: 'Hanzi', text: '衆生無邊誓願度', tokens: ['衆生', '無邊', '誓願', '度'], - transliteration: 'Shujō muhen sē gan do (zhòng shēng wú biān shì yuàn dù in Mandarin)', + transliteration: 'zhòng shēng wú biān shì yuàn dù (Mandarin pinyin)', }, ], witnesses: [ @@ -117,7 +117,7 @@ export const vows: LiturgyDoc = { label: 'Hanzi', text: '煩惱無盡誓願斷', tokens: ['煩惱', '無盡', '誓願', '斷'], - transliteration: 'Bonnō mujin sē gan dan (fán nǎo wú jìn shì yuàn duàn in Mandarin)', + transliteration: 'fán nǎo wú jìn shì yuàn duàn (Mandarin pinyin)', }, ], witnesses: [ @@ -168,7 +168,7 @@ export const vows: LiturgyDoc = { label: 'Hanzi', text: '法門無量誓願學', tokens: ['法門', '無量', '誓願', '學'], - transliteration: 'Hōmon muryō sē gan gaku (fǎ mén wú liàng shì yuàn xué in Mandarin)', + transliteration: 'fǎ mén wú liàng shì yuàn xué (Mandarin pinyin)', }, ], witnesses: [ @@ -219,7 +219,7 @@ export const vows: LiturgyDoc = { label: 'Hanzi', text: '佛道無上誓願成', tokens: ['佛道', '無上', '誓願', '成'], - transliteration: 'Butsudō mujō sē gan jō (fó dào wú shàng shì yuàn chéng in Mandarin)', + transliteration: 'fó dào wú shàng shì yuàn chéng (Mandarin pinyin)', }, ], witnesses: [