Hover-only tooltips + plain-first batch a-d + perf cleanup#47
Merged
Conversation
…segment sources Per user feedback 2026-05-12: "I don't want tool tips to persist, if I move my cursor away it should go away." Drops the persistent-pin model shipped earlier this session (commits 29d5c35 + 8df4aba + 0515dd4 — collectively the pin + audit-pill arc) and reverts the Sutta Studio reader to a hover-only interaction model. Changes: - Tooltip.tsx: stripped to {text, facetIndex, facetTotal}. Removed the pinned-state styling (emerald border, × unpin button), audit pill (ⓘ N expander), sources footer, and citations prop entirely. - PaliWord.tsx: removed pin state from segment click; click now only cycles tooltip facets + segment senses (no pin side-effect). Removed citationsById prop threading and pinned-segment ring styling. - EnglishWord.tsx: removed pinned/setPinned props; the focus = pinned ?? hovered chain becomes hovered alone. - SuttaStudioView.tsx: removed pinned useState, the citationsById useMemo (Sense.sourceCitationIds still lives in packet.json for the LLM compiler and future renderer features, just not surfaced in the reading UI), XarrowUpdater dep on pinned, and Escape-clears-pin keyboard handler. Citations remain in components/sutta-studio/demoPacket.json (18 entries across phases a-d) and continue to flow to the LLM compiler. They're no longer rendered per-segment. Per issue #45 — the audit layer's right home is one click deeper than the reading interaction; without a pin, that layer needs a separate surface (e.g., About-this-text expansion), to be designed if/when needed. Tests: 220 component tests pass; no regressions. TS clean on touched files. Verified in browser via Playwright: hover → tooltip; cursor leave → gone. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…relation-label override
User feedback: hovering "me" showed "Heard BY" on both facet 1/2 and 2/2 —
the relation arrow label was overriding the segment's own tooltips, so the
facet cycle had no visible effect (useless redundancy).
Two changes:
1. PaliWord.tsx — rawTooltip precedence reordered. Was:
segSenseText → relation.label → facetTooltip → fallback
Now:
segSenseText → facetTooltip → relation.label → fallback
The relation.label belongs to the grammar arrow's visual; if a segment
has its own tooltips, those should display. relation.label remains a
useful fallback for segments without tooltips that have an arrow.
2. demoPacket.json a2s1 ("me") — replaced the two near-redundant tooltips
with two distinct facets:
1/2: "Colored differently because it's a small connector word.
Pāli wraps 'by', 'of', 'to' into the noun's ending rather
than spelling them out as separate words."
2/2: "Form is 'of me' (genitive case); function here is 'by me' —
Pāli uses the genitive to mark who did the action when the
verb is passive, like 'was heard'."
First facet explains the function-word color difference (per user
request 2026-05-12). Second facet keeps the grammar reading, plain-
first per CURATION_PROTOCOL §3.4. Pay-rent on "genitive case" — the
reader gets a working definition in the same sentence.
Verified via Playwright: hover me → 1/2 color-explanation; click → cycle
to 2/2 grammar reading. 220 component tests pass.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Per user request 2026-05-12: a visible legend for the color-coding system
that the reader uses implicitly. Lives inside the existing expand-to-show
About panel; no new affordance, no new modal — same reveal pattern as
provenance + acknowledgments.
The new "Color & affordance guide" section covers, in order:
- Word color: content (emerald) / function (slate-200) / vocative (yellow)
— each row shows a live "aaa" swatch in its actual rendering color.
- Word emphasis: anchor (amber underline + medium weight), refrain
(matching-color underline across phases), hover (white-border indicator).
- English scaffolding (ghost words): the italic + faded styling and the
four underline kinds — auxiliary (solid soft), pronoun_from_verb (dotted),
interpretive (no underline), required (dotted thin). Each illustrated
with a real example word.
- Grammar arrows (study mode): the 4 RelationType colors with their
glyphs (●→▢◆) and case-relation hooks (OF / TO·FOR / IN·AT / BY·WITH).
- Closing reminder: hover for tooltip, click to cycle facets (with a
live "1/2" facet-indicator chip rendering inline).
Tests: 220 component pass. Pre-existing React-namespace TS warnings in
AboutThisText are unchanged.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ag ~67%
User flagged unresponsive/laggy interactions. Profiling showed first-hover
latency of 842ms with a 765ms main-thread task; the smoking gun was 775
framer-motion divs with active layout-tracking transforms across the
51-phase render (no virtualization, all phases mounted eagerly).
Three changes, no semantic difference:
- PaliWord.tsx: removed layoutId={`${phaseId}-${wordData.id}`} from the
word wrapper motion.div. layoutId opted PaliWord into framer's
shared-layout animation system, which measured + animated layout on
every state change touching the tree. At ~350 PaliWord instances this
was the dominant cost.
- EnglishWord.tsx: removed `layout` prop from the token motion.div
(same family of expensive layout-animation work).
- SuttaStudioView.tsx: removed <LayoutGroup> wrapper + import; no longer
needed once layoutId is gone.
Profiling results (6 hovers across the 51 phases, real Chrome via
Playwright + PerformanceObserver):
metric before after Δ
────────────────────────────────────────────────
first hover (phase-a top) 842 ms 264 ms -69%
hover phase-b 348 ms 106 ms -70%
longest main-thread task 765 ms 255 ms -67%
long-task total 2467 ms 1578 ms -36%
motion divs w/ transform 775 254 -67%
DOM element count 3327 3167 -5%
Still over the 100ms INP target on first hovers — next lever is lifting
hover state out of SuttaStudioView (eliminates the parent-cascade
re-render across all 51 phases). Tracked as task #23 follow-up.
Tests: 220 component pass. No TS regressions in touched files.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…color facet
Apply CURATION_PROTOCOL §3.4 register-check across phase-a tooltips:
- reader profile: thoughtful adult, no Pāli training
- pay-rent: drop technical terms that don't earn precision
- layering: plain prose carries the load; chips/jargon optional
Specific changes:
- a1s1 evaṁ: replaced "adverbial deictic" framing with plain "framing
word that points forward." Added new facet 1/3 that explains why evaṁ
is colored differently (function-word framing role) — parallel to the
color-explanation pattern established for "me" in 44eef4e.
- a1s2 ṁ: dropped "[Niggahīta]" jargon; describes the sound directly
and notes evaṁ vs eva distinction.
- a3s1 su: kept "root" (pays rent — recurring Pāli concept) + glossed
the present-tense form (suṇāti). Replaced √ symbol with prose.
- a3s2 ta: dropped "[Past participle]" bracket prefix; describes the
-ta ending's effect plainly + explains the dual heard/what-was-heard
reading without invoking "participial form" jargon.
- a3s3 ṁ: dropped "[Neuter nom/acc singular] Declensional ending" plus
"[oblique agent + past participle] / function substantively" jargon
in the second facet. Rewrites both facets to teach the Pāli/English
compression pattern plainly.
Function-word color-explanation facets now exist on:
- phase-a a1 evaṁ (this commit)
- phase-a a2 me (44eef4e)
Remaining function-word color-explanations queued for b1 ekaṁ + d2 nāma.
phase-b/c/d plain-first rewrites coming in follow-up commits.
Tests: 220 component pass.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…color facet
Apply CURATION_PROTOCOL §3.4 across phase-b tooltips:
- b1s1 ekaṁ: added color-explanation facet 1/3 (function/modifier role —
parallel to me + evaṁ pattern). Rewrote facets 2-3 plainly (dropped
"[Adjective]" bracket prefix, "Modifies samayaṁ" cryptic).
- b1s2 ṁ: dropped "[Accusative of Time]" jargon; describes the time-
marker plainly + cross-references samayaṁ next.
- b2s1 sam: replaced cryptic "Not a root!" with a plain explanation of
how prefixes attach to roots in Pāli word-building.
- b2s2 aya: replaced √ symbols with prose. Each facet teaches one piece
of the prefix + root + suffix → "occasion" derivation.
- b2s3 ṁ: dropped "[Accusative of Time]" jargon; ties the marker to
the same -ṁ on ekaṁ → "at one occasion".
- b3s1 bhaga: replaced √bhaj with prose.
- b3s2 vā: dropped "[Possessive suffix]" jargon; explains -vā as
"one who has / is endowed with" plainly.
Refrain-color facet for bhagavā NOT added — bhagavā has refrainId='bhagava'
but only appears in 1 phase across batch a-d. Per protocol §3.3 a refrain
needs ≥2-phase recurrence; revisit when later batches surface the word.
Function-word color-explanations now on a1 evaṁ + a2 me + b1 ekaṁ.
Remaining: d2 nāma (phase-d only function word in batch a-d).
Tests: JSON valid. Component tests pending verification after phase-d.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Apply CURATION_PROTOCOL §3.4 across phase-c tooltips. Addresses the
specific failures phase-c.md §6 flagged + extends the plain-first
discipline to all phase-c segments.
- c1s1 kurū: dropped "[Stem]" bracket; described the Kuru people +
vowel-lengthening sandhi plainly. Glossed "mahājanapada" as "Great
Nations" with cultural context.
- c1s2 su: dropped "[Locative Plural]" jargon; explained the place-
where marker plainly (Pāli marks 'place where' on the noun itself
— same pattern as the 'me' color-facet idea: case-on-noun vs
English preposition).
- c2s1 vi: dropped "[Prefix]" bracket; explained the prefix + how it
shifts the root's meaning, with a clear "like English 'a-' in
'apart'" anchor.
- c2s2 har: replaced √hṛ symbol with prose ("'hṛ' is a root meaning").
Both facets describe meaning shifts clearly.
- c2s3 a: FIXED phase-c.md §6's explicit complaint — was
"[Thematic vowel] Class I verb marker" which strips to empty when
grammar-terms is off. Now describes the connector-vowel role
plainly (lets 'vihar' join '-ti' smoothly).
- c2s4 ti: dropped "[Present 3rd singular]" jargon; explains the
person-on-verb pattern + the historical-present narrative
convention in plain language.
Resolves phase-c.md §6 + phase-c §3.4 plain-register observations.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…color facet
Apply CURATION_PROTOCOL §3.4 across phase-d tooltips. Closes the
plain-first rewrite for batch a-d.
- d1s1 Kammāsa: glossed "porisāda" with prose; expanded the Jātaka
reference (gloss "Jātaka" for default reader).
- d1s2 dhamma: replaced √dam with prose. Better connection between
the etymology and the place-name story. Clarified the "Sanskritized
spelling" note.
- d1s3 ṁ: fixed phase-d.md §6's "Name ending" complaint. Three facets
now each teach something distinct: closes the name, signals the
naming relationship, and admits the nom/acc ambiguity (without
using those terms in plain prose).
- d2s1 nāma: added color-explanation facet 1/3 (function-word linking
role) — final function-word color-explanation in batch a-d.
Replaced "X nāma Y = Y named X" formula syntax with prose example.
- d3s1 kurū: dropped "[Stem]" jargon; cross-references the earlier
kurūsu in phase-c (same stem, different case-ending).
- d3s2 naṁ: fixed phase-d.md §6's "[Genitive Plural] Possession"
complaint. Names the -naṁ ending plainly + contrasts with phase-c's
-su to show how Pāli marks different relations on the same stem.
- d4s1 ni: dropped "[Prefix]" bracket; explains the prefix role.
- d4s2 gam: replaced √gam with prose. Better narrative about the
"going down to" → "market town" derivation.
- d4s3 o: dropped "[Nominative Singular] Subject marker" jargon;
explains the role as "marks this as the subject" + provides the
pedagogical framing ("everything else describes which town").
Function-word color-explanations complete for batch a-d:
- a1 evaṁ (framing)
- a2 me (case-on-noun)
- b1 ekaṁ (modifier)
- d2 nāma (linking)
Phase-c had no function-class words in its content; viharati's anchor
status is documented via the legend section in About-this-text.
Tests: 220 component pass. JSON valid.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
anantham
added a commit
that referenced
this pull request
May 13, 2026
Captures the strategic-economic analysis that emerged from MN10 batches
1-4 hand-curation. The conversation surfaced ~14 distinct insights about
pipeline vs hand-curation economics, cost telemetry, scaling, and the
strategic pivot — none of which lived in the codebase until this commit.
docs/sutta-studio/COMPILER_STRATEGY.md (289 lines, new):
§1 The economic shape — quality bands (35% v1 / 65% v2 / 85% +post-passes
/ 100% hand), Pareto distribution (10-15 phases pedagogically critical,
35-40 are routine recurrences), per-compile cost estimates ($0.10-0.30
Gemini Flash / $1-3 Sonnet / $3-10 Opus per MN10).
§2 What the pipeline does today vs what it could do — 11-row matrix
classifying each hand-curation move as: learnable by prompt /
deterministic post-processable / irreducibly human.
§3 What's irreducibly human — translator-tradition citations,
pedagogical taste, curation-log narrative. ~5-8 phases per sutta
fall in this bucket.
§4 Cost telemetry — surprised discovery that services/apiMetricsService.ts
already records every API call with tokens+cost+apiType=sutta_studio
to IndexedDB. Missing: phaseId attribution, UI, prompt caching,
local-vs-LLM split beyond DPD. 3-step plan to close gaps. ccusage
for Claude-Code-side conversation cost.
§5 Scaling roadmap — 5 stages: hand-curate MN10 exemplar (in progress)
→ wire v2 overlay → build 4 deterministic post-passes → run on DN22
with selective polish (~5-6 hr vs ~30 hr from scratch) → satipaṭṭhāna
sub-corpus → cross-pattern (~20-30 patterns covering most of the canon).
§6 Open questions — translator-tradition DB, DPD Lookup-gap pattern
resolution, prompt-caching tradeoff, when to wire v2, pedagogical-
fidelity floor for routine phases.
docs/HANDOVER.md (180 lines, replaces prior 2026-05-12 handover):
- Full 17-commit inventory across 3 branches (PR #47 from prior session,
PR #48 batch-3 from today, batch-4 branch from today)
- DPD root-cause fix details (coverage 86.9% → 89.5%, 458 sqlite-lookup
vs 20 heuristic-fallback vs 56 unmatched, better-sqlite3 dep,
one-time 168 MB download)
- Schema tensions status (#1 RESOLVED at root, #7 RESOLVED prior,
#12 RESOLVED via documentation, Lookup-gap as new observation)
- 3 protocol amendments codified (§9.1, §3.4.1, FEATURES §1.3)
- 5 phase logs added (e/f/g/h/1)
- Refrain status (bhikkhu 5/9, bhagavā 4/9, viharati 1/9)
- 10 pending threads in priority order with effort estimates
- The pending strategic pivot decision flagged for next session
- Worktree convention + bash sandbox quirk + 3-branch base structure
documented as non-obvious context
- Resume instructions branch on pivot decision
Both docs written by parallel subagents with full context briefings;
reviewed and committed by main session. Companion to the v2 prompt
overlay (2d198f6) and the protocol amendments (c6b150f + 9830ef1).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Three arcs in one focused commit chain:
[Past participle],[Locative Plural], …) in favor of plain prose that earns its technical terms. Specific failures flagged in phase-c.md §6 + phase-d.md §6 are resolved.me,evaṁ,ekaṁ,nāmaeach now have a cycled facet explaining why they're colored differently (function-word role: connectors, modifiers, framers, linkers).Also: color & affordance guide lives in the About-this-text panel (word color, anchor/refrain/hover styling, ghost-word kinds, grammar-arrow palette), and a perf fix dropping framer-motion
layoutId/layoutcut first-hover latency 67% (842ms → 264ms; longest task 765ms → 255ms).Commits
Test plan
/sutta/demo— verify tooltips appear on hover and disappear on cursor leave (no pin persistence)me,evaṁ,ekaṁ,nāma— confirm color-explanation facet 1/N renders firstResolves
Notes
🤖 Generated with Claude Code