1. Fix RU_TO_EN keyboard map in keyboardLayout.ts:
- ч was mapped to 'c' (wrong), now correctly 'x'
- с was mapped to 'v' (wrong), now correctly 'c'
- ю was mapped to '.' (wrong), now correctly ','
- Full rewrite with standard QWERTY/ЙЦУКЕН positional mapping
- Examples: dthcnfr→верстак, руддщ→hello, цщкдв→world all correct now
2. Root cause of search breaking after 3-4 chars:
Old map had ч:'c', с:'v' swapped. So dthcnfr → 'верчиак' (wrong).
Each character was mapped to wrong Cyrillic equivalent.
3. Add unit tests: keyboardLayout.test.js (39 tests, node-runner):
- EN→RU: dthcnfr, ghbdtn, ntcn
- RU→EN: руддщ, цщкдв, ышеш
- Unicode safety: Latin c (U+0063) ≠ Cyrillic с (U+0441)
- expandKeyboardVariants for mixed inputs
- Edge cases: empty, single char, mixed case, numbers
4. InternalLinkPicker type tabs → filters (not search modes):
- Store rawResults (all) + filtered results by activeType
- Switching type tab no longer clears query or triggers new search
- Just filters existing rawResults by selected type
- Shows 'Нет результатов для этого типа' when filtered empty
5. Both GlobalSearch and InternalLinkPicker use same expandKeyboardVariants()
All tests PASS, full build OK.