feat(overlay): Anki maturity-based known-word highlighting

Color known-word subtitle highlights by Anki card maturity (new,
learning, young, mature) like asbplayer (#171). Notes are classified
server-side with Anki search filters (prop:ivl, is:learn) during the
known-word cache refresh, so no per-card data is fetched. A word's tier
is its most mature matching card/note, with the same reading-aware
matching as boolean known-word lookups.

- known-word cache v4 state persists per-note tiers; lifecycle key only
  gains the maturity field while enabled so existing caches survive
- ankiConnect.knownWords.maturityEnabled + matureThresholdDays (21)
- subtitleStyle.knownWordMaturityColors with catppuccin defaults
- word-maturity-<tier> class rides on word-known so hover/selection
  rules keep applying; falls back to knownWordColor without tier data
- runtime toggle subtitle.annotation.knownWords.maturityEnabled
This commit is contained in:
2026-07-17 23:41:40 -07:00
parent 08c6807cb1
commit bc8dce870b
31 changed files with 1238 additions and 47 deletions
+16
View File
@@ -35,6 +35,22 @@ export function buildRuntimeOptionRegistry(
},
}),
},
{
id: 'subtitle.annotation.knownWords.maturityEnabled',
path: 'ankiConnect.knownWords.maturityEnabled',
label: 'Known Word Maturity Colors',
scope: 'subtitle',
valueType: 'boolean',
allowedValues: [true, false],
defaultValue: defaultConfig.ankiConnect.knownWords.maturityEnabled,
requiresRestart: false,
formatValueForOsd: (value) => (value === true ? 'On' : 'Off'),
toAnkiPatch: (value) => ({
knownWords: {
maturityEnabled: value === true,
},
}),
},
{
id: 'subtitle.annotation.nPlusOne',
path: 'ankiConnect.nPlusOne.enabled',