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/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/components/liturgy/shapes/SoundFormula.tsx b/components/liturgy/shapes/SoundFormula.tsx index 12c4052..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'; @@ -54,8 +65,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..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('-'); @@ -174,7 +192,7 @@ const TransliterationLine: React.FC<{ if (!respelling) return null; return (
@@ -186,7 +204,7 @@ const TransliterationLine: React.FC<{ if (!variant.transliteration) return null; return (
@@ -573,7 +591,11 @@ 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. 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 = (() => { @@ -615,8 +637,8 @@ const PaliLine: React.FC<{ return (
{tokens.map((t, i) => { @@ -1236,8 +1258,13 @@ const SegmentRow: React.FC<{ title={segment.witnesses.length > 1 ? 'Click to switch translation' : undefined} >
{ 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). `); };