Skip to content

Hover-only tooltips + plain-first batch a-d + perf cleanup#47

Merged
anantham merged 8 commits into
mainfrom
feat/opus-tooltip-plain-first
May 13, 2026
Merged

Hover-only tooltips + plain-first batch a-d + perf cleanup#47
anantham merged 8 commits into
mainfrom
feat/opus-tooltip-plain-first

Conversation

@anantham
Copy link
Copy Markdown
Owner

Summary

Three arcs in one focused commit chain:

  1. Tooltip UX reversal — pin model removed; tooltips are hover-only; per-segment citation chips dropped. The audit layer is no longer surfaced inline.
  2. Plain-first content rewrite across phase-a/b/c/d per CURATION_PROTOCOL §3.4 — drops jargon brackets ([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.
  3. Function-word color-explanation facets added consistently — me, evaṁ, ekaṁ, nāma each 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/layout cut first-hover latency 67% (842ms → 264ms; longest task 765ms → 255ms).

Commits

ced66b2  phase-d plain-first rewrite + nāma color facet
f3efd81  phase-c plain-first rewrite (resolves §6)
ef2072d  phase-b plain-first rewrite + ekaṁ color facet
6900ca2  phase-a plain-first rewrite + evaṁ color facet
7652942  perf — drop layoutId/layout (-67% hover lag)
de6ca2b  color & affordance guide in About panel
44eef4e  me tooltip distinct facets + relation-label precedence
63f2dc3  hover-only tooltips, drop pin + sources

Test plan

  • Open /sutta/demo — verify tooltips appear on hover and disappear on cursor leave (no pin persistence)
  • Hover me, evaṁ, ekaṁ, nāma — confirm color-explanation facet 1/N renders first
  • Click those segments — confirm facets cycle (1/N → 2/N → …)
  • Expand About-this-text → verify "Color & affordance guide" section renders with all swatches
  • Hover sustained interaction across phases — should feel substantially less laggy than before
  • Verify other phases (e-onward) unaffected since no content changes there

Resolves

Notes

  • 220 component tests pass; pre-existing TS errors in AboutThisText (React namespace) unchanged.
  • `Sense.sourceCitationIds` still in packet.json (compiler still uses it); just not threaded into reader UI components.
  • Performance follow-up backlog: lift hover state out of `SuttaStudioView` for further latency cuts (issue worth filing).

🤖 Generated with Claude Code

anantham and others added 8 commits May 12, 2026 17:37
…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>
@vercel
Copy link
Copy Markdown

vercel Bot commented May 13, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
lexicon-forge Ready Ready Preview, Comment May 13, 2026 1:19am

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>
@anantham anantham merged commit 3ed21ab into main May 13, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant