Set tooth toothNo's Miller mobility grade on the active chart from
OUTSIDE the tooth-info panel. The panel's own #mobilitySelect writes
mobility through applyToSelected(), which applies to the bulk
selectedTeeth set — unusable here, since the full-mouth perio-chart
overlay grid (P2 Task 2) edits one specific tooth at a time that is not
necessarily activeTooth or selected on the base chart. This reuses the
EXACT SAME mutation + render + notify steps that path takes
(applyStateToSvg, updateToothTileNumber, re-syncing the panel when
toothNo happens to be the active tooth, notifyStateChange) — no new
mobility derivation or render logic, just a single-tooth entry point into
it. Lazily initializes a never-touched tooth's state first, exactly like
setPerioSite does. An unrecognized value (not in VALID_MOBILITY)
is a silent no-op, exactly like every other per-tooth enum setter here.
Set tooth
toothNo's Miller mobility grade on the active chart from OUTSIDE the tooth-info panel. The panel's own#mobilitySelectwrites mobility throughapplyToSelected(), which applies to the bulkselectedTeethset — unusable here, since the full-mouth perio-chart overlay grid (P2 Task 2) edits one specific tooth at a time that is not necessarilyactiveToothor selected on the base chart. This reuses the EXACT SAME mutation + render + notify steps that path takes (applyStateToSvg,updateToothTileNumber, re-syncing the panel whentoothNohappens to be the active tooth,notifyStateChange) — no new mobility derivation or render logic, just a single-tooth entry point into it. Lazily initializes a never-touched tooth's state first, exactly likesetPerioSitedoes. An unrecognizedvalue(not in VALID_MOBILITY) is a silent no-op, exactly like every other per-tooth enum setter here.