@the-inclusionist/engine 9.0.0 → 11.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (532) hide show
  1. package/README.md +120 -78
  2. package/app/css/style.css +761 -377
  3. package/app/public/vendor/fonts/playwrite-cu.woff2 +0 -0
  4. package/app/public/vendor/fonts/playwrite-es-deco.woff2 +0 -0
  5. package/app/public/vendor/fonts/playwrite-es.woff2 +0 -0
  6. package/app/public/vendor/fonts/playwrite-gb-j.woff2 +0 -0
  7. package/app/public/vendor/fonts/playwrite-gb-s.woff2 +0 -0
  8. package/app/public/vendor/fonts/playwrite-pe.woff2 +0 -0
  9. package/app/public/vendor/fonts/playwrite-pt.woff2 +0 -0
  10. package/app/public/vendor/fonts-licences/NOTICE.txt +166 -0
  11. package/app/public/vendor/fonts-licences/OFL-1.1.txt +86 -0
  12. package/app/public/vendor/fonts.css +36 -84
  13. package/dist-pkg/boot/create-game.d.ts +499 -219
  14. package/dist-pkg/boot/create-game.js +3944 -562
  15. package/dist-pkg/core/a11y-sr.d.ts +25 -3
  16. package/dist-pkg/core/a11y-sr.js +38 -19
  17. package/dist-pkg/core/accessible-label.d.ts +17 -0
  18. package/dist-pkg/core/accessible-label.js +37 -0
  19. package/dist-pkg/core/accommodation-subjects.d.ts +26 -0
  20. package/dist-pkg/core/accommodation-subjects.js +32 -0
  21. package/dist-pkg/core/accommodations.d.ts +125 -0
  22. package/dist-pkg/core/accommodations.js +195 -0
  23. package/dist-pkg/core/actions.d.ts +108 -55
  24. package/dist-pkg/core/actions.js +122 -71
  25. package/dist-pkg/core/calm-mode.d.ts +31 -0
  26. package/dist-pkg/core/calm-mode.js +47 -0
  27. package/dist-pkg/core/camera-cycle.d.ts +15 -0
  28. package/dist-pkg/core/camera-cycle.js +7 -0
  29. package/dist-pkg/core/caption-duration.d.ts +15 -0
  30. package/dist-pkg/core/caption-duration.js +19 -0
  31. package/dist-pkg/core/cartridge-problems.d.ts +34 -0
  32. package/dist-pkg/core/cartridge-problems.js +53 -0
  33. package/dist-pkg/core/constants.d.ts +0 -54
  34. package/dist-pkg/core/constants.js +9 -76
  35. package/dist-pkg/core/contract.d.ts +142 -164
  36. package/dist-pkg/core/contract.js +222 -208
  37. package/dist-pkg/core/dom-query.d.ts +4 -4
  38. package/dist-pkg/core/dom-query.js +12 -20
  39. package/dist-pkg/core/entity.d.ts +62 -77
  40. package/dist-pkg/core/entity.js +18 -32
  41. package/dist-pkg/core/escape-html.d.ts +9 -10
  42. package/dist-pkg/core/escape-html.js +16 -20
  43. package/dist-pkg/core/flash-threshold.d.ts +17 -0
  44. package/dist-pkg/core/flash-threshold.js +113 -0
  45. package/dist-pkg/core/game-speed.d.ts +11 -0
  46. package/dist-pkg/core/game-speed.js +16 -0
  47. package/dist-pkg/core/genres.d.ts +20 -0
  48. package/dist-pkg/core/genres.js +44 -0
  49. package/dist-pkg/core/i18n.d.ts +71 -60
  50. package/dist-pkg/core/i18n.js +186 -200
  51. package/dist-pkg/core/loop.d.ts +17 -6
  52. package/dist-pkg/core/loop.js +26 -26
  53. package/dist-pkg/core/pause-icon-catalogue.d.ts +15 -0
  54. package/dist-pkg/core/pause-icon-catalogue.js +54 -0
  55. package/dist-pkg/core/ring.d.ts +17 -0
  56. package/dist-pkg/core/ring.js +29 -0
  57. package/dist-pkg/core/rng.d.ts +7 -12
  58. package/dist-pkg/core/rng.js +23 -53
  59. package/dist-pkg/core/route.d.ts +26 -26
  60. package/dist-pkg/core/route.js +126 -121
  61. package/dist-pkg/core/scenes.d.ts +37 -40
  62. package/dist-pkg/core/scenes.js +41 -43
  63. package/dist-pkg/core/screens.d.ts +4 -4
  64. package/dist-pkg/core/screens.js +11 -16
  65. package/dist-pkg/core/session-clock.d.ts +23 -0
  66. package/dist-pkg/core/session-clock.js +37 -0
  67. package/dist-pkg/core/setting-defaults.d.ts +61 -0
  68. package/dist-pkg/core/setting-defaults.js +66 -0
  69. package/dist-pkg/core/speech-rate.d.ts +29 -0
  70. package/dist-pkg/core/speech-rate.js +47 -0
  71. package/dist-pkg/core/state.d.ts +118 -118
  72. package/dist-pkg/core/state.js +322 -297
  73. package/dist-pkg/core/visual-cycles.d.ts +30 -0
  74. package/dist-pkg/core/visual-cycles.js +52 -0
  75. package/dist-pkg/core/visual-state.d.ts +13 -0
  76. package/dist-pkg/core/visual-state.js +6 -0
  77. package/dist-pkg/educational/activities-registry.d.ts +1 -1
  78. package/dist-pkg/educational/activities-registry.js +9 -8
  79. package/dist-pkg/educational/adaptive-engine.d.ts +11 -11
  80. package/dist-pkg/educational/adaptive-engine.js +17 -17
  81. package/dist-pkg/educational/segment-bar.d.ts +12 -12
  82. package/dist-pkg/educational/segment-bar.js +9 -9
  83. package/dist-pkg/i18n/en.js +324 -223
  84. package/dist-pkg/i18n/es.js +323 -223
  85. package/dist-pkg/i18n/pt.js +348 -226
  86. package/dist-pkg/input/default-bindings.d.ts +37 -38
  87. package/dist-pkg/input/default-bindings.js +127 -144
  88. package/dist-pkg/input/devices.d.ts +7 -7
  89. package/dist-pkg/input/devices.js +17 -16
  90. package/dist-pkg/input/edges.d.ts +23 -32
  91. package/dist-pkg/input/edges.js +23 -28
  92. package/dist-pkg/input/empathy-filter.d.ts +22 -0
  93. package/dist-pkg/input/empathy-filter.js +34 -0
  94. package/dist-pkg/input/face-map.d.ts +96 -0
  95. package/dist-pkg/input/face-map.js +255 -0
  96. package/dist-pkg/input/face-signals.d.ts +40 -0
  97. package/dist-pkg/input/face-signals.js +48 -0
  98. package/dist-pkg/input/gamepad.d.ts +195 -145
  99. package/dist-pkg/input/gamepad.js +383 -556
  100. package/dist-pkg/input/gaze-cycle.d.ts +64 -0
  101. package/dist-pkg/input/gaze-cycle.js +133 -0
  102. package/dist-pkg/input/gaze-relative.d.ts +68 -0
  103. package/dist-pkg/input/gaze-relative.js +142 -0
  104. package/dist-pkg/input/hand-map.d.ts +28 -0
  105. package/dist-pkg/input/hand-map.js +142 -0
  106. package/dist-pkg/input/input-cooldown.d.ts +17 -0
  107. package/dist-pkg/input/input-cooldown.js +39 -0
  108. package/dist-pkg/input/key-default.d.ts +30 -0
  109. package/dist-pkg/input/key-default.js +60 -0
  110. package/dist-pkg/input/keyboard-runtime.d.ts +15 -21
  111. package/dist-pkg/input/keyboard-runtime.js +23 -27
  112. package/dist-pkg/input/keyboard.d.ts +68 -63
  113. package/dist-pkg/input/keyboard.js +83 -105
  114. package/dist-pkg/input/keydown.d.ts +123 -137
  115. package/dist-pkg/input/keydown.js +284 -289
  116. package/dist-pkg/input/latch-edge.d.ts +33 -21
  117. package/dist-pkg/input/latch-edge.js +34 -35
  118. package/dist-pkg/input/latch-scope.d.ts +51 -50
  119. package/dist-pkg/input/latch-scope.js +61 -82
  120. package/dist-pkg/input/latch-store.d.ts +26 -30
  121. package/dist-pkg/input/latch-store.js +42 -50
  122. package/dist-pkg/input/latch-sync.d.ts +29 -29
  123. package/dist-pkg/input/latch-sync.js +25 -25
  124. package/dist-pkg/input/latch.d.ts +14 -17
  125. package/dist-pkg/input/latch.js +29 -37
  126. package/dist-pkg/input/pad-defaults.d.ts +13 -16
  127. package/dist-pkg/input/pad-defaults.js +21 -28
  128. package/dist-pkg/input/pad-reading.d.ts +76 -0
  129. package/dist-pkg/input/pad-reading.js +169 -0
  130. package/dist-pkg/input/pad-wizard.d.ts +99 -0
  131. package/dist-pkg/input/pad-wizard.js +256 -0
  132. package/dist-pkg/input/pointer-space.d.ts +19 -20
  133. package/dist-pkg/input/pointer-space.js +27 -32
  134. package/dist-pkg/input/pointer.d.ts +39 -40
  135. package/dist-pkg/input/pointer.js +42 -45
  136. package/dist-pkg/input/state.d.ts +101 -89
  137. package/dist-pkg/input/state.js +54 -134
  138. package/dist-pkg/input/switch-scan.d.ts +59 -0
  139. package/dist-pkg/input/switch-scan.js +67 -0
  140. package/dist-pkg/input/synthetic-source.d.ts +42 -0
  141. package/dist-pkg/input/synthetic-source.js +57 -0
  142. package/dist-pkg/input/touch-bindings.d.ts +127 -116
  143. package/dist-pkg/input/touch-bindings.js +158 -173
  144. package/dist-pkg/input/touch.d.ts +147 -72
  145. package/dist-pkg/input/touch.js +362 -126
  146. package/dist-pkg/input/transport-in-use.d.ts +107 -0
  147. package/dist-pkg/input/transport-in-use.js +130 -0
  148. package/dist-pkg/input/transports.d.ts +90 -117
  149. package/dist-pkg/input/transports.js +104 -106
  150. package/dist-pkg/input/virtual-controller.d.ts +82 -0
  151. package/dist-pkg/input/virtual-controller.js +69 -0
  152. package/dist-pkg/input/vocabulary-migration.d.ts +50 -49
  153. package/dist-pkg/input/vocabulary-migration.js +80 -79
  154. package/dist-pkg/input/voice-map.d.ts +59 -0
  155. package/dist-pkg/input/voice-map.js +123 -0
  156. package/dist-pkg/platform/audio-ambient.d.ts +13 -2
  157. package/dist-pkg/platform/audio-ambient.js +14 -14
  158. package/dist-pkg/platform/audio-earcons.d.ts +20 -19
  159. package/dist-pkg/platform/audio-earcons.js +51 -42
  160. package/dist-pkg/platform/audio-jingles.js +9 -10
  161. package/dist-pkg/platform/audio-mixer.d.ts +14 -2
  162. package/dist-pkg/platform/audio-mixer.js +31 -39
  163. package/dist-pkg/platform/audio-sonar.d.ts +49 -152
  164. package/dist-pkg/platform/audio-sonar.js +124 -302
  165. package/dist-pkg/platform/audio.d.ts +62 -19
  166. package/dist-pkg/platform/audio.js +193 -168
  167. package/dist-pkg/platform/choose-by-voice.d.ts +70 -0
  168. package/dist-pkg/platform/choose-by-voice.js +157 -0
  169. package/dist-pkg/platform/flash-sampler.d.ts +19 -0
  170. package/dist-pkg/platform/flash-sampler.js +79 -0
  171. package/dist-pkg/platform/font-library.d.ts +77 -0
  172. package/dist-pkg/platform/font-library.js +98 -0
  173. package/dist-pkg/platform/font-library.json +721 -0
  174. package/dist-pkg/platform/heavy-catalogue.d.ts +77 -0
  175. package/dist-pkg/platform/heavy-catalogue.js +256 -0
  176. package/dist-pkg/platform/heavy-mirror.d.ts +20 -0
  177. package/dist-pkg/platform/heavy-mirror.js +73 -0
  178. package/dist-pkg/platform/heavy.d.ts +136 -0
  179. package/dist-pkg/platform/heavy.js +324 -0
  180. package/dist-pkg/platform/interruptible-speech.d.ts +23 -16
  181. package/dist-pkg/platform/interruptible-speech.js +77 -54
  182. package/dist-pkg/platform/kokoro-port.d.ts +27 -0
  183. package/dist-pkg/platform/kokoro-port.js +50 -0
  184. package/dist-pkg/platform/kokoro-runtime.d.ts +20 -0
  185. package/dist-pkg/platform/kokoro-runtime.js +52 -0
  186. package/dist-pkg/platform/kokoro.d.ts +70 -0
  187. package/dist-pkg/platform/kokoro.js +133 -0
  188. package/dist-pkg/platform/listener-scope.d.ts +12 -0
  189. package/dist-pkg/platform/listener-scope.js +90 -0
  190. package/dist-pkg/platform/locale-host.d.ts +14 -0
  191. package/dist-pkg/platform/locale-host.js +45 -0
  192. package/dist-pkg/platform/microphone.d.ts +51 -0
  193. package/dist-pkg/platform/microphone.js +118 -0
  194. package/dist-pkg/platform/onnx-runtime.d.ts +34 -0
  195. package/dist-pkg/platform/onnx-runtime.js +42 -0
  196. package/dist-pkg/platform/reading-in-worker.d.ts +64 -0
  197. package/dist-pkg/platform/reading-in-worker.js +125 -0
  198. package/dist-pkg/platform/reading-model.d.ts +94 -0
  199. package/dist-pkg/platform/reading-model.js +272 -0
  200. package/dist-pkg/platform/reading-runtime.d.ts +24 -0
  201. package/dist-pkg/platform/reading-runtime.js +164 -0
  202. package/dist-pkg/platform/reading-worker.d.ts +41 -0
  203. package/dist-pkg/platform/reading-worker.js +58 -0
  204. package/dist-pkg/platform/reading.d.ts +80 -0
  205. package/dist-pkg/platform/reading.js +136 -0
  206. package/dist-pkg/platform/speech-recognition.d.ts +60 -0
  207. package/dist-pkg/platform/speech-recognition.js +104 -0
  208. package/dist-pkg/platform/speech.d.ts +23 -1
  209. package/dist-pkg/platform/speech.js +29 -18
  210. package/dist-pkg/platform/storage-keys.d.ts +96 -0
  211. package/dist-pkg/platform/storage-keys.js +106 -0
  212. package/dist-pkg/platform/storage.d.ts +46 -111
  213. package/dist-pkg/platform/storage.js +104 -169
  214. package/dist-pkg/platform/tts.d.ts +85 -39
  215. package/dist-pkg/platform/tts.js +447 -127
  216. package/dist-pkg/platform/vision-loop.d.ts +23 -0
  217. package/dist-pkg/platform/vision-loop.js +56 -0
  218. package/dist-pkg/platform/vision.d.ts +132 -0
  219. package/dist-pkg/platform/vision.js +117 -0
  220. package/dist-pkg/platform/voice-listener.d.ts +40 -0
  221. package/dist-pkg/platform/voice-listener.js +88 -0
  222. package/dist-pkg/platform/voice-plan.d.ts +15 -98
  223. package/dist-pkg/platform/voice-plan.js +56 -143
  224. package/dist-pkg/platform/vosk-runtime.d.ts +96 -0
  225. package/dist-pkg/platform/vosk-runtime.js +151 -0
  226. package/dist-pkg/platform/vosk-vocabulary.d.ts +6 -0
  227. package/dist-pkg/platform/vosk-vocabulary.js +178 -0
  228. package/dist-pkg/render/canvas.d.ts +13 -7
  229. package/dist-pkg/render/canvas.js +13 -13
  230. package/dist-pkg/render/crt.d.ts +48 -12
  231. package/dist-pkg/render/crt.js +78 -80
  232. package/dist-pkg/render/cvd-matrices.d.ts +22 -18
  233. package/dist-pkg/render/cvd-matrices.js +37 -38
  234. package/dist-pkg/render/hc-role-data.d.ts +7 -7
  235. package/dist-pkg/render/hc-role-data.js +14 -14
  236. package/dist-pkg/render/high-contrast.d.ts +67 -56
  237. package/dist-pkg/render/high-contrast.js +226 -217
  238. package/dist-pkg/render/low-vision-drawing.d.ts +5 -0
  239. package/dist-pkg/render/low-vision-drawing.js +46 -0
  240. package/dist-pkg/render/lq-filter.d.ts +32 -20
  241. package/dist-pkg/render/lq-filter.js +59 -65
  242. package/dist-pkg/render/port.d.ts +86 -88
  243. package/dist-pkg/render/port.js +17 -23
  244. package/dist-pkg/render/screen-pipeline.d.ts +42 -42
  245. package/dist-pkg/render/screen-pipeline.js +80 -87
  246. package/dist-pkg/render/sprite-fx.d.ts +2 -1
  247. package/dist-pkg/render/sprite-fx.js +16 -14
  248. package/dist-pkg/render/viewports.d.ts +20 -15
  249. package/dist-pkg/render/viewports.js +83 -114
  250. package/dist-pkg/render/viz-axes-labels.d.ts +47 -0
  251. package/dist-pkg/render/viz-axes-labels.js +88 -0
  252. package/dist-pkg/render/viz-axes.d.ts +89 -86
  253. package/dist-pkg/render/viz-axes.js +128 -116
  254. package/dist-pkg/render/viz-modes.d.ts +28 -29
  255. package/dist-pkg/render/viz-modes.js +40 -45
  256. package/dist-pkg/render/viz-refusal.d.ts +32 -0
  257. package/dist-pkg/render/viz-refusal.js +57 -0
  258. package/dist-pkg/render/viz-setters.d.ts +104 -66
  259. package/dist-pkg/render/viz-setters.js +182 -191
  260. package/dist-pkg/ui/aac-sets.d.ts +45 -0
  261. package/dist-pkg/ui/aac-sets.js +41 -0
  262. package/dist-pkg/ui/audio-choices.d.ts +68 -0
  263. package/dist-pkg/ui/audio-choices.js +98 -0
  264. package/dist-pkg/ui/audio-rows-that-apply.d.ts +12 -0
  265. package/dist-pkg/ui/audio-rows-that-apply.js +43 -0
  266. package/dist-pkg/ui/camera-control.d.ts +53 -0
  267. package/dist-pkg/ui/camera-control.js +48 -0
  268. package/dist-pkg/ui/changed-mark.d.ts +9 -8
  269. package/dist-pkg/ui/changed-mark.js +22 -53
  270. package/dist-pkg/ui/control-choices.d.ts +37 -0
  271. package/dist-pkg/ui/control-choices.js +84 -0
  272. package/dist-pkg/ui/debug-panel.d.ts +59 -43
  273. package/dist-pkg/ui/debug-panel.js +68 -69
  274. package/dist-pkg/ui/declared-words.d.ts +21 -0
  275. package/dist-pkg/ui/declared-words.js +66 -0
  276. package/dist-pkg/ui/dom.d.ts +10 -14
  277. package/dist-pkg/ui/dom.js +10 -47
  278. package/dist-pkg/ui/drawing-problems.d.ts +25 -0
  279. package/dist-pkg/ui/drawing-problems.js +94 -0
  280. package/dist-pkg/ui/eye-control.d.ts +36 -0
  281. package/dist-pkg/ui/eye-control.js +178 -0
  282. package/dist-pkg/ui/face-control.d.ts +25 -0
  283. package/dist-pkg/ui/face-control.js +183 -0
  284. package/dist-pkg/ui/focus-trap.d.ts +39 -49
  285. package/dist-pkg/ui/focus-trap.js +56 -65
  286. package/dist-pkg/ui/fonts.d.ts +157 -68
  287. package/dist-pkg/ui/fonts.js +305 -115
  288. package/dist-pkg/ui/footer-scroll-driver.d.ts +14 -0
  289. package/dist-pkg/ui/footer-scroll-driver.js +201 -0
  290. package/dist-pkg/ui/footer-scroll.d.ts +38 -0
  291. package/dist-pkg/ui/footer-scroll.js +55 -0
  292. package/dist-pkg/ui/game-options.d.ts +47 -0
  293. package/dist-pkg/ui/game-options.js +158 -0
  294. package/dist-pkg/ui/gaze-overlay.d.ts +64 -0
  295. package/dist-pkg/ui/gaze-overlay.js +165 -0
  296. package/dist-pkg/ui/hand-control.d.ts +25 -0
  297. package/dist-pkg/ui/hand-control.js +143 -0
  298. package/dist-pkg/ui/help-panel.d.ts +87 -0
  299. package/dist-pkg/ui/help-panel.js +242 -0
  300. package/dist-pkg/ui/hud-bands.d.ts +62 -0
  301. package/dist-pkg/ui/hud-bands.js +146 -0
  302. package/dist-pkg/ui/hud-row.d.ts +34 -0
  303. package/dist-pkg/ui/hud-row.js +80 -0
  304. package/dist-pkg/ui/hud.d.ts +73 -73
  305. package/dist-pkg/ui/hud.js +94 -98
  306. package/dist-pkg/ui/item-announcement.d.ts +13 -12
  307. package/dist-pkg/ui/item-announcement.js +25 -26
  308. package/dist-pkg/ui/layout.d.ts +103 -28
  309. package/dist-pkg/ui/layout.js +117 -99
  310. package/dist-pkg/ui/libras-avatar-clip.d.ts +30 -0
  311. package/dist-pkg/ui/libras-avatar-clip.js +86 -0
  312. package/dist-pkg/ui/libras-avatar-load.d.ts +52 -0
  313. package/dist-pkg/ui/libras-avatar-load.js +134 -0
  314. package/dist-pkg/ui/libras-avatar-plan.d.ts +102 -0
  315. package/dist-pkg/ui/libras-avatar-plan.js +211 -0
  316. package/dist-pkg/ui/libras-avatar-player.d.ts +28 -0
  317. package/dist-pkg/ui/libras-avatar-player.js +226 -0
  318. package/dist-pkg/ui/libras-avatar-stage.d.ts +37 -0
  319. package/dist-pkg/ui/libras-avatar-stage.js +208 -0
  320. package/dist-pkg/ui/libras-glosses.d.ts +28 -0
  321. package/dist-pkg/ui/libras-glosses.js +161 -0
  322. package/dist-pkg/ui/locale-flags.d.ts +16 -0
  323. package/dist-pkg/ui/locale-flags.js +30 -0
  324. package/dist-pkg/ui/loop-crash.d.ts +17 -17
  325. package/dist-pkg/ui/loop-crash.js +33 -62
  326. package/dist-pkg/ui/menu-intent.d.ts +61 -0
  327. package/dist-pkg/ui/menu-intent.js +88 -0
  328. package/dist-pkg/ui/menu-items.d.ts +20 -0
  329. package/dist-pkg/ui/menu-items.js +51 -0
  330. package/dist-pkg/ui/menu-nav.d.ts +98 -92
  331. package/dist-pkg/ui/menu-nav.js +398 -286
  332. package/dist-pkg/ui/mobility-choices.d.ts +26 -0
  333. package/dist-pkg/ui/mobility-choices.js +41 -0
  334. package/dist-pkg/ui/motion-choices.d.ts +31 -0
  335. package/dist-pkg/ui/motion-choices.js +68 -0
  336. package/dist-pkg/ui/motion-scene.d.ts +24 -19
  337. package/dist-pkg/ui/motion-scene.js +29 -61
  338. package/dist-pkg/ui/mount-panel.d.ts +81 -0
  339. package/dist-pkg/ui/mount-panel.js +61 -0
  340. package/dist-pkg/ui/panel-shell.d.ts +65 -31
  341. package/dist-pkg/ui/panel-shell.js +92 -66
  342. package/dist-pkg/ui/panel-widgets.d.ts +150 -0
  343. package/dist-pkg/ui/panel-widgets.js +294 -0
  344. package/dist-pkg/ui/pause-buttons.d.ts +35 -0
  345. package/dist-pkg/ui/pause-buttons.js +66 -0
  346. package/dist-pkg/ui/pause-icons.d.ts +261 -347
  347. package/dist-pkg/ui/pause-icons.js +671 -601
  348. package/dist-pkg/ui/pause-markup.d.ts +86 -0
  349. package/dist-pkg/ui/pause-markup.js +125 -0
  350. package/dist-pkg/ui/reach-notice.d.ts +22 -23
  351. package/dist-pkg/ui/reach-notice.js +55 -58
  352. package/dist-pkg/ui/scan-overlay.d.ts +23 -0
  353. package/dist-pkg/ui/scan-overlay.js +50 -0
  354. package/dist-pkg/ui/screen-text.d.ts +25 -0
  355. package/dist-pkg/ui/screen-text.js +152 -0
  356. package/dist-pkg/ui/session-clock.d.ts +32 -0
  357. package/dist-pkg/ui/session-clock.js +67 -0
  358. package/dist-pkg/ui/settings-aac.d.ts +70 -0
  359. package/dist-pkg/ui/settings-aac.js +208 -0
  360. package/dist-pkg/ui/settings-audio.d.ts +97 -114
  361. package/dist-pkg/ui/settings-audio.js +493 -425
  362. package/dist-pkg/ui/settings-controls.d.ts +53 -96
  363. package/dist-pkg/ui/settings-controls.js +143 -215
  364. package/dist-pkg/ui/settings-empathy.d.ts +39 -30
  365. package/dist-pkg/ui/settings-empathy.js +53 -60
  366. package/dist-pkg/ui/settings-mobility.d.ts +192 -0
  367. package/dist-pkg/ui/settings-mobility.js +332 -0
  368. package/dist-pkg/ui/settings-motion.d.ts +91 -70
  369. package/dist-pkg/ui/settings-motion.js +287 -198
  370. package/dist-pkg/ui/settings-panel.d.ts +58 -45
  371. package/dist-pkg/ui/settings-panel.js +189 -94
  372. package/dist-pkg/ui/settings-typo.d.ts +29 -78
  373. package/dist-pkg/ui/settings-typo.js +158 -129
  374. package/dist-pkg/ui/settings-visual.d.ts +29 -87
  375. package/dist-pkg/ui/settings-visual.js +240 -193
  376. package/dist-pkg/ui/shell.d.ts +112 -135
  377. package/dist-pkg/ui/shell.js +148 -217
  378. package/dist-pkg/ui/simulation-list.d.ts +27 -0
  379. package/dist-pkg/ui/simulation-list.js +76 -0
  380. package/dist-pkg/ui/simulation-over-the-world.d.ts +23 -0
  381. package/dist-pkg/ui/simulation-over-the-world.js +131 -0
  382. package/dist-pkg/ui/simulation-refusal.d.ts +5 -31
  383. package/dist-pkg/ui/simulation-refusal.js +8 -56
  384. package/dist-pkg/ui/switchable-control.d.ts +11 -0
  385. package/dist-pkg/ui/switchable-control.js +19 -0
  386. package/dist-pkg/ui/title.d.ts +3 -12
  387. package/dist-pkg/ui/title.js +49 -18
  388. package/dist-pkg/ui/top-band.d.ts +26 -0
  389. package/dist-pkg/ui/top-band.js +96 -0
  390. package/dist-pkg/ui/typo-choices.d.ts +71 -0
  391. package/dist-pkg/ui/typo-choices.js +85 -0
  392. package/dist-pkg/ui/visual-axes-panel.d.ts +11 -47
  393. package/dist-pkg/ui/visual-axes-panel.js +12 -94
  394. package/dist-pkg/ui/visual-choices.d.ts +77 -0
  395. package/dist-pkg/ui/visual-choices.js +107 -0
  396. package/dist-pkg/ui/vlibras.d.ts +77 -10
  397. package/dist-pkg/ui/vlibras.js +130 -81
  398. package/dist-pkg/ui/voice-control.d.ts +68 -0
  399. package/dist-pkg/ui/voice-control.js +276 -0
  400. package/dist-pkg/ui/voice-settings.d.ts +95 -0
  401. package/dist-pkg/ui/voice-settings.js +352 -0
  402. package/dist-pkg/ui/where-the-child-is.d.ts +31 -0
  403. package/dist-pkg/ui/where-the-child-is.js +70 -0
  404. package/docs/CREDITS.md +300 -44
  405. package/docs/LICENSES.md +189 -145
  406. package/package.json +51 -27
  407. package/scripts/check-cartridge.mjs +78 -0
  408. package/scripts/game-build.d.mts +25 -0
  409. package/scripts/game-build.mjs +144 -0
  410. package/scripts/heavy-into-the-delivery.mjs +388 -0
  411. package/scripts/libras-avatar.json +680 -0
  412. package/scripts/libras-avatar.mjs +246 -0
  413. package/scripts/libras-glosses/gloss.py +95 -0
  414. package/scripts/libras-glosses/pyproject.toml +32 -0
  415. package/scripts/libras-glosses/uv.lock +781 -0
  416. package/scripts/libras-glosses.mjs +351 -0
  417. package/scripts/licences/Apache-2.0.txt +176 -0
  418. package/scripts/licences/GPL-3.0.txt +674 -0
  419. package/scripts/licences/MIT.txt +17 -0
  420. package/scripts/licences/OFL-1.1.txt +86 -0
  421. package/scripts/licences/UFL-1.0.txt +96 -0
  422. package/scripts/licences/fonts.mjs +389 -0
  423. package/scripts/licences/third-party.mjs +301 -0
  424. package/scripts/licences/vosk-browser.NOTICE.txt +268 -0
  425. package/app/public/vendor/fonts/comicneue-400.woff2 +0 -0
  426. package/app/public/vendor/fonts/comicneue-700.woff2 +0 -0
  427. package/app/public/vendor/fonts/fondamento-400-ext.woff2 +0 -0
  428. package/app/public/vendor/fonts/fondamento-400.woff2 +0 -0
  429. package/app/public/vendor/fonts/inter-400.woff2 +0 -0
  430. package/app/public/vendor/fonts/inter-700.woff2 +0 -0
  431. package/app/public/vendor/fonts/lato-400.woff2 +0 -0
  432. package/app/public/vendor/fonts/lato-700.woff2 +0 -0
  433. package/app/public/vendor/fonts/literata-400.woff2 +0 -0
  434. package/app/public/vendor/fonts/literata-700.woff2 +0 -0
  435. package/app/public/vendor/fonts/newsreader-400.woff2 +0 -0
  436. package/app/public/vendor/fonts/newsreader-700.woff2 +0 -0
  437. package/app/public/vendor/fonts/opendyslexic-400.woff2 +0 -0
  438. package/app/public/vendor/fonts/opensans-400.woff2 +0 -0
  439. package/app/public/vendor/fonts/opensans-700.woff2 +0 -0
  440. package/app/public/vendor/fonts/pinyon-400.woff2 +0 -0
  441. package/app/public/vendor/fonts/pressstart-400.woff2 +0 -0
  442. package/app/public/vendor/fonts/quattro-400.woff2 +0 -0
  443. package/app/public/vendor/fonts/quattro-700.woff2 +0 -0
  444. package/app/public/vendor/fonts/sourcesans-400.woff2 +0 -0
  445. package/app/public/vendor/fonts/sourcesans-700.woff2 +0 -0
  446. package/app/public/vendor/fonts/sourceserif-400.woff2 +0 -0
  447. package/app/public/vendor/fonts/sourceserif-700.woff2 +0 -0
  448. package/app/public/vendor/fonts/ufmag-400.woff2 +0 -0
  449. package/dist-pkg/core/anel.d.ts +0 -17
  450. package/dist-pkg/core/anel.js +0 -31
  451. package/dist-pkg/core/collision.d.ts +0 -21
  452. package/dist-pkg/core/collision.js +0 -62
  453. package/dist-pkg/core/layers.d.ts +0 -63
  454. package/dist-pkg/core/layers.js +0 -95
  455. package/dist-pkg/core/letter-grid.d.ts +0 -55
  456. package/dist-pkg/core/letter-grid.js +0 -116
  457. package/dist-pkg/core/password.d.ts +0 -34
  458. package/dist-pkg/core/password.js +0 -205
  459. package/dist-pkg/core/rotulo-acessivel.d.ts +0 -17
  460. package/dist-pkg/core/rotulo-acessivel.js +0 -41
  461. package/dist-pkg/core/run-state.d.ts +0 -115
  462. package/dist-pkg/core/run-state.js +0 -40
  463. package/dist-pkg/core/tiles.d.ts +0 -12
  464. package/dist-pkg/core/tiles.js +0 -61
  465. package/dist-pkg/core/world.d.ts +0 -4
  466. package/dist-pkg/core/world.js +0 -58
  467. package/dist-pkg/input/origem-sintetica.d.ts +0 -44
  468. package/dist-pkg/input/origem-sintetica.js +0 -60
  469. package/dist-pkg/input/transporte-em-uso.d.ts +0 -101
  470. package/dist-pkg/input/transporte-em-uso.js +0 -130
  471. package/dist-pkg/platform/audio-nav.d.ts +0 -51
  472. package/dist-pkg/platform/audio-nav.js +0 -99
  473. package/dist-pkg/platform/guide-intensity.d.ts +0 -40
  474. package/dist-pkg/platform/guide-intensity.js +0 -73
  475. package/dist-pkg/platform/pesados-catalogo.d.ts +0 -14
  476. package/dist-pkg/platform/pesados-catalogo.js +0 -177
  477. package/dist-pkg/platform/pesados.d.ts +0 -31
  478. package/dist-pkg/platform/pesados.js +0 -75
  479. package/dist-pkg/platform/vozes-prontas.d.ts +0 -28
  480. package/dist-pkg/platform/vozes-prontas.js +0 -61
  481. package/dist-pkg/render/camera.d.ts +0 -58
  482. package/dist-pkg/render/camera.js +0 -105
  483. package/dist-pkg/render/cenario-data.d.ts +0 -127
  484. package/dist-pkg/render/cenario-data.js +0 -145
  485. package/dist-pkg/render/city-tex.d.ts +0 -63
  486. package/dist-pkg/render/city-tex.js +0 -228
  487. package/dist-pkg/render/city-tiles.d.ts +0 -11
  488. package/dist-pkg/render/city-tiles.js +0 -140
  489. package/dist-pkg/render/draw.d.ts +0 -149
  490. package/dist-pkg/render/draw.js +0 -231
  491. package/dist-pkg/render/fx.d.ts +0 -63
  492. package/dist-pkg/render/fx.js +0 -123
  493. package/dist-pkg/render/minimap.d.ts +0 -11
  494. package/dist-pkg/render/minimap.js +0 -94
  495. package/dist-pkg/render/parallax.d.ts +0 -85
  496. package/dist-pkg/render/parallax.js +0 -158
  497. package/dist-pkg/render/player-anim.d.ts +0 -71
  498. package/dist-pkg/render/player-anim.js +0 -152
  499. package/dist-pkg/render/recycling-tex.d.ts +0 -48
  500. package/dist-pkg/render/recycling-tex.js +0 -164
  501. package/dist-pkg/render/scene-city.d.ts +0 -77
  502. package/dist-pkg/render/scene-city.js +0 -181
  503. package/dist-pkg/render/scene-parallax.d.ts +0 -72
  504. package/dist-pkg/render/scene-parallax.js +0 -426
  505. package/dist-pkg/render/scene-sky.d.ts +0 -126
  506. package/dist-pkg/render/scene-sky.js +0 -295
  507. package/dist-pkg/render/set-cenario.d.ts +0 -54
  508. package/dist-pkg/render/set-cenario.js +0 -103
  509. package/dist-pkg/render/textures.d.ts +0 -75
  510. package/dist-pkg/render/textures.js +0 -240
  511. package/dist-pkg/render/title-scene.d.ts +0 -46
  512. package/dist-pkg/render/title-scene.js +0 -75
  513. package/dist-pkg/render/weather.d.ts +0 -96
  514. package/dist-pkg/render/weather.js +0 -171
  515. package/dist-pkg/render/wheelchair-sprites.d.ts +0 -32
  516. package/dist-pkg/render/wheelchair-sprites.js +0 -69
  517. package/dist-pkg/render/world-tex.d.ts +0 -18
  518. package/dist-pkg/render/world-tex.js +0 -87
  519. package/dist-pkg/ui/activities-menu.d.ts +0 -258
  520. package/dist-pkg/ui/activities-menu.js +0 -648
  521. package/dist-pkg/ui/caa-sets.d.ts +0 -39
  522. package/dist-pkg/ui/caa-sets.js +0 -65
  523. package/dist-pkg/ui/latch-refusal.d.ts +0 -32
  524. package/dist-pkg/ui/latch-refusal.js +0 -60
  525. package/dist-pkg/ui/map-hub.d.ts +0 -56
  526. package/dist-pkg/ui/map-hub.js +0 -138
  527. package/dist-pkg/ui/settings-caa.d.ts +0 -45
  528. package/dist-pkg/ui/settings-caa.js +0 -137
  529. package/dist-pkg/ui/settings-motor.d.ts +0 -175
  530. package/dist-pkg/ui/settings-motor.js +0 -342
  531. package/dist-pkg/ui/webcam.d.ts +0 -7
  532. package/dist-pkg/ui/webcam.js +0 -93
@@ -1,5 +1,5 @@
1
1
  // SPDX-License-Identifier: AGPL-3.0-or-later
2
- // Locale en — SEED (só as chaves-piloto; completar UI+Matemática+Lúdico na Etapa 4). Ver docs/plano-i18n.md.
2
+ // Locale en — SEED (só as chaves-piloto; completar UI+Matemática+Lúdico na Etapa 4). Ver docs/1-Discovery/plan-i18n.md.
3
3
  // Parcial de propósito: as chaves ausentes caem no fallback pt (core/i18n).
4
4
  const en = {
5
5
  // ===================== SCREEN-READER ANNOUNCEMENTS (`sr.*`) =====================
@@ -13,15 +13,11 @@ const en = {
13
13
  'sr.player.entered': 'Player {n} joined!',
14
14
  // Recycling (ADR-0049 §1). The four colours are curricular content (CONAMA 275/2001 — the Brazilian street
15
15
  // standard), so the announcement NAMES the colour instead of just saying right or wrong.
16
- 'sr.lixo.pegou': 'You picked up: {o}.',
17
16
  'sr.lixo.soltou': 'You put down: {o}.',
18
- 'sr.lixo.acertou': 'Right! {o} goes in the {cor} bin. One point.',
19
- 'sr.lixo.errou': 'That is not the bin for {o}. Try another colour.',
20
17
  'sr.lixo.solta': 'No littering here. You dropped it by the sign.',
21
18
  'sr.lixo.barreira': 'The sign will not let the litter through.',
22
19
  'lixo.obj.papel': 'cardboard box',
23
20
  'lixo.obj.plastico': 'PET bottle',
24
- 'lixo.obj.metal': 'aluminium can',
25
21
  'lixo.obj.vidro': 'glass jar',
26
22
  'lixo.cor.azul': 'blue',
27
23
  'lixo.cor.vermelha': 'red',
@@ -29,65 +25,76 @@ const en = {
29
25
  'lixo.cor.verde': 'green',
30
26
  'sr.print.on': 'Print mode: see the screen without menus. Press any button to go back.',
31
27
  'sr.player.pressToJoin': 'Player {n}: press a button to join.',
28
+ 'hud.waitBadge': 'Player {n}: press a button on YOUR keyboard, or on a free controller, to join',
29
+ 'menu.help': 'Help',
30
+ 'help.grupo.rotulo': 'This game’s buttons',
31
+ 'help.noKey': 'no key',
32
+ 'help.slide.tecla': 'Key {k}',
32
33
  'sr.libras.loading': 'The sign-language interpreter is still loading — try again in a moment.',
33
- 'sr.eyes.loadFailed': 'WebGazer did not load.',
34
- 'sr.eyes.calibrate': 'Play with your eyes: look around the screen and click a few spots to calibrate. Looking left and right walks; looking up jumps.',
35
- 'sr.eyes.needsInternet': 'WebGazer could not be loaded (it needs the internet the first time).',
34
+ 'sr.deaf.noSigning': 'No sign-language interpreter right now: the captions and the text stay on screen.',
35
+ 'sr.deaf.interpreter': 'Libras sign-language interpreter',
36
+ 'sr.eyes.needsInternet': 'Eye control has not reached this device yet: it downloads the first time the game opens with internet.',
37
+ 'sr.eyes.failed': 'Eye control could not start on this device.',
38
+ // the eye control's words over the game (ADR-0213 §6): a region tells a preparing look which way to go, the opposite of itself
39
+ 'gaze.lookHere': 'Look here',
40
+ 'gaze.loading': 'Loading...',
41
+ 'gaze.prepare.up': 'Go down!',
42
+ 'gaze.prepare.right': 'Go left!',
43
+ 'gaze.prepare.down': 'Go up!',
44
+ 'gaze.prepare.left': 'Go right!',
45
+ 'sr.face.lookMiddle': 'Look at the middle of the screen and keep your face still until I say ready.',
46
+ 'sr.face.ready': 'Ready: you can play with your face.',
47
+ 'sr.face.noCamera': 'Face control needs the camera, and it did not open. Allow the camera for this page.',
48
+ 'sr.face.needsInternet': 'Face control has not reached this device yet: it comes down the first time the game opens online.',
49
+ 'sr.face.failed': 'Face control could not start on this device.',
50
+ 'sr.face.stopped': 'Face control stopped getting pictures from the camera.',
51
+ 'sr.face.slow': 'Face control is slow on this device and may not answer.',
52
+ 'sr.eyes.lookMiddle': 'Look at the middle of the screen and keep your eyes still until I say ready.',
53
+ 'sr.eyes.ready': 'Ready: you can play with your eyes.',
54
+ 'sr.eyes.noCamera': 'Eye control needs the camera, and it did not open. Allow the camera for this page.',
55
+ 'sr.eyes.stopped': 'Eye control stopped getting pictures from the camera.',
56
+ 'sr.eyes.slow': 'Eye control is slow on this device and may not answer.',
36
57
  'sr.typo.font': 'Typeface: {fam}.',
58
+ 'sr.icon.velocidade': 'Game speed: {pct}%.',
37
59
  'sr.visual.contrast': 'High contrast: {v}.',
38
60
  'sr.visual.lq': 'Contrast boost: {v}.',
39
- 'sr.gate.open': 'Gate open!',
40
- 'sr.key.taken': '{who}picked up the key. Touch the gate to open it.',
41
- 'sr.key.returned': 'The key went back to where it started.',
42
- 'sr.power.swapHint': '{msg} (Swap power cycles through the ones you have.)',
43
- 'sr.round.multi': '{n} players, one per screen. Race for the coins.',
44
- 'sr.round.somasub': 'Add-and-Subtract mode. Touch the shapes and solve the sums.',
45
- 'sr.round.silabas': 'Syllables mode. Touch the letters and build the words.',
46
- 'sr.round.ludico': 'New round. Collect 10 coins.',
47
- 'sr.screens.mobileOnly': 'On a phone the game runs on a single screen.',
48
- 'sr.screens.alreadyN': '{n} screens already active.',
49
- 'sr.screens.already1': 'One screen.',
50
- 'sr.screens.wontFitN': '{n} screens do not fit in this window — each screen needs at least 640 by 360. Make the window bigger or go full screen.',
51
61
  'sr.screens.wontFitOneMore': 'One more screen does not fit in this window — each screen needs at least 640 by 360. Make the window bigger or go full screen.',
52
- 'sr.screens.activeN': '{n} screens active.',
53
- 'sr.screens.newRoundN': '{n} screens active — new round.',
54
- 'sr.screens.newRound1': 'One screen — new round.',
55
62
  'sr.screens.maxPlayers': 'There are already 4 players.',
56
- 'sr.player.restarted': 'Player {n} started over on this screen.',
57
- 'sr.player.joined': 'Player {n} joined the game in progress.',
58
- 'sr.player.quit': 'Player {n} left the game.',
59
63
  // HUD objective (DOM text; same decision tree as the round announcement)
60
- 'hud.objective.multi': '{n} players — race for the {alvo} coins',
61
- 'hud.objective.somasub': 'Solve 10 sums',
62
- 'hud.objective.silabas': 'Build 10 words',
63
- 'hud.objective.ludico': 'Collect 10 coins',
64
64
  'hud.contador': '{have} of {need} {nome}',
65
- 'hud.nome.moedas': 'coins',
66
- 'hud.nome.moeda': 'coin',
65
+ 'hud.numero': '{nome}: {valor}',
66
+ 'hud.barra': '{nome}: {azuis} right first time, {verdes} with help, {vermelhos} not right',
67
+ 'hud.barra.sobe': 'the level goes up',
68
+ 'hud.barra.desce': 'the level goes down',
69
+ // The score in the HUD row is drawn as five digits (ADR-0238, ADR-0239); a listener hears the number itself, not the zeros.
70
+ 'hud.points': '{count} {name}',
71
+ // The session clock's accessible name (ADR-0236): the time left in words, never «0:45». Rewritten each whole minute.
72
+ 'clock.left': 'Play time: {minutes} minutes left',
73
+ 'clock.left.one': 'Play time: 1 minute left',
74
+ 'clock.over': 'Play time: over',
75
+ 'clock.label': 'TIME', // the small word over the clock's digits (ADR-0239)
67
76
  'pause.nivel': '📚 Level {n} · {nome}',
68
- 'sfx.jump': '🔊 Jump',
69
- 'sfx.coin': '🔊 Collected',
70
- 'sfx.hurt': '🔊 Ouch! Hurt',
71
- 'sfx.win': '🔊 You win!',
72
- 'sfx.correct': '🔊 Correct!',
73
- 'sfx.wrong': '🔊 Try again',
74
- 'sfx.power': '🔊 Power-up!',
75
- 'sfx.key': '🔊 Key',
76
- 'sfx.gate': '🔊 Gate opened',
77
77
  'skip.toGame': 'Skip to the game',
78
- 'menu.ludico': 'Free Play',
79
- 'menu.alfabetizacao': 'Literacy',
80
- 'menu.matematica': 'Math',
81
78
  // Touch controls — the 9 slot labels, the 9 mappable actions (#touchcfg panel) and the announcements.
82
79
  'touch.slot.up': 'D-pad ↑ (up)',
83
80
  'touch.slot.down': 'D-pad ↓ (down)',
84
81
  'touch.slot.left': 'D-pad ← (left)',
85
82
  'touch.slot.right': 'D-pad → (right)',
86
83
  'touch.slot.start': 'START (enter)',
84
+ 'touch.start': 'START',
85
+ 'touch.nome.up': 'Up',
86
+ 'touch.nome.down': 'Down',
87
+ 'touch.nome.left': 'Left',
88
+ 'touch.nome.right': 'Right',
89
+ 'touch.select': 'SELECT',
87
90
  'touch.slot.b0': 'Button 0 (bottom)',
88
91
  'touch.slot.b1': 'Button 1 (right)',
89
92
  'touch.slot.b2': 'Button 2 (left)',
90
93
  'touch.slot.b3': 'Button 3 (top)',
94
+ 'touch.slot.bl2': 'L2 (left trigger)',
95
+ 'touch.slot.bl1': 'L1 (left shoulder)',
96
+ 'touch.slot.br2': 'R2 (right trigger)',
97
+ 'touch.slot.br1': 'R1 (right shoulder)',
91
98
  'touch.slot.fallback': 'Button',
92
99
  'touch.act.left': 'Walk left',
93
100
  'touch.act.right': 'Walk right',
@@ -97,7 +104,6 @@ const en = {
97
104
  'touch.act.run': 'Run / interact',
98
105
  'touch.act.especial': 'Special',
99
106
  'touch.act.swap': 'Swap power',
100
- 'touch.act.pause': 'Pause (START)',
101
107
  'touch.dir.cross': 'cross (D-pad)',
102
108
  'touch.dir.stick': 'analogue stick',
103
109
  'sr.touch.slotSet': '{slot}: {acao}.',
@@ -134,7 +140,6 @@ const en = {
134
140
  'audio.sinksUnsupported': 'This browser cannot switch audio output (e.g. Safari/iOS).',
135
141
  'audio.voiceSample': 'Hello! This is the Inclusionist narration voice. One, two, three, testing.',
136
142
  'tts.engine.webspeech': 'Browser voice (Web Speech)',
137
- 'tts.engine.piper': 'Piper (neural, offline) — downloads on first use',
138
143
  'tts.engine.kokoro': 'Kokoro-82M (neural) — downloads on first use',
139
144
  'tts.engine.kitten': 'Kitten (neural) — downloads on first use',
140
145
  'tts.engine.espeak': 'eSpeak NG (built in)',
@@ -151,18 +156,69 @@ const en = {
151
156
  'sr.audio.voicePicked': 'Voice selected.',
152
157
  'sr.audio.testingVoice': 'Testing the selected voice.',
153
158
  // Accessibility icon bar (pause menu and splash) + the levels it cycles through.
154
- 'icon.blind': 'Blind mode (audio navigation)',
155
- 'icon.tts': 'Voice narration (TTS)',
156
- 'icon.libras': 'Deaf mode (Brazilian Sign Language)',
157
- 'icon.tea': 'Autism mode (calm / silent)',
158
- 'icon.altmove': 'Toggle keys',
159
+ 'icon.blind': 'Blind mode',
160
+ 'icon.tts': 'Voice narration',
161
+ 'icon.libras': 'Deaf mode',
162
+ 'icon.tea': 'Autism mode',
163
+ // ☝️ stopped being a switch and became three positions (ADR-0218): the name says the SUBJECT, the value says the position.
164
+ 'icon.altmove': 'How you press',
165
+ 'input.standard': 'standard',
166
+ 'input.sticky': 'no holding needed',
167
+ 'scan.nothing': 'cancel',
168
+ // One-button scanning inside a menu: that menu's own steps (ADR-0218 erratum of 2026-09-26, interface log).
169
+ 'scan.menu.next': 'next',
170
+ 'scan.menu.confirm': 'confirm',
171
+ 'scan.menu.back': 'back',
172
+ 'scan.menu.previous': 'previous',
173
+ // ...and, on a control with a value, the sideways step (the interface log's entry on the sideways step).
174
+ 'scan.menu.increase': 'increase',
175
+ 'scan.menu.decrease': 'decrease',
176
+ // ...and the engine's two doors, offered in play after the game's own words (ADR-0218 §3).
177
+ 'scan.door.menus': 'menu',
178
+ 'scan.door.pause': 'pause',
179
+ 'input.scan': 'one button only',
159
180
  'icon.contrast': 'High contrast',
160
- 'icon.cvd': 'Colour-blindness correction (protan/deutan/tritan)',
161
- 'icon.face': 'Webcam — face',
162
- 'icon.eyes': 'Webcam — eyes',
181
+ 'icon.cvd': 'Colour-blindness correction',
163
182
  'icon.voice': 'Voice command',
183
+ 'icon.tipografia': 'Communication',
184
+ 'icon.velocidade': 'Game speed',
185
+ 'icon.velocidade.valor': '{pct}%',
186
+ 'icon.blind.dica': 'Play by sound: audio navigation tells what the screen shows.',
187
+ 'icon.tts.dica': 'The game reads out loud what is written on the screen.',
188
+ 'icon.libras.dica': 'Sounds get captions, and the sonar calls a sign-language interpreter to sign what is on screen.',
189
+ 'icon.tea.dica': 'Makes the game calmer or silent, for those overloaded by stimuli.',
190
+ 'icon.altmove.dica': 'How your presses are read: the standard way; or one tap to turn on and another to turn off, with no holding; or with one button only, where the game shows one thing at a time and you press on the one you want.',
191
+ 'sr.icon.inputMode': 'How you press: {v}.',
192
+ 'icon.contrast.dica': 'Increases the difference between what matters and the background: 3:1, 4.5:1 or 7:1.',
193
+ 'icon.cvd.dica': 'Adjusts colours for those who confuse red and green (protan, deutan) or blue and yellow (tritan).',
194
+ 'icon.idioma': 'Language',
195
+ 'icon.idioma.dica': 'Change the game\'s language: menus, explanations, voice and speech recognition.',
196
+ 'icon.camera': 'Webcam',
197
+ 'icon.camera.dica': 'Play through the webcam: with hand gestures, your face or your eyes. The lines show what the camera reads.',
198
+ 'camera.hands': 'hand gestures',
199
+ 'camera.face': 'face',
200
+ 'camera.eyes': 'eyes',
201
+ 'sr.icon.voice': 'Voice command: {v}.',
202
+ 'sr.icon.camera': 'Playing through the webcam: {v}.',
203
+ 'sr.voice.ready': 'Ready: you can play by speaking.',
204
+ 'sr.voice.noMicrophone': 'Voice control needs the microphone, and it did not open. Allow the microphone for this page.',
205
+ 'sr.voice.failed': 'Voice control could not start on this device.',
206
+ 'sr.voice.needsInternet': 'Voice control has not reached this device yet: it comes down the first time the game opens online.',
207
+ 'sr.reading.failed': 'Reading aloud could not start in this language on this device.',
208
+ 'sr.hands.ready': 'Ready: you can play with hand gestures.',
209
+ 'sr.hands.noCamera': 'Gesture control needs the camera, and it did not open. Allow the camera for this page.',
210
+ 'sr.hands.needsInternet': 'Gesture control has not reached this device yet: it comes down the first time the game opens online.',
211
+ 'sr.hands.failed': 'Gesture control could not start on this device.',
212
+ 'sr.hands.stopped': 'Gesture control stopped getting pictures from the camera.',
213
+ 'sr.hands.slow': 'Gesture control is slow on this device and may not answer.',
214
+ 'icon.menu': 'Menu',
215
+ 'icon.menu.dica': 'Open the menus: help, inclusion settings, game options and quit.',
216
+ 'sr.icon.idioma': 'Language: {v}.',
217
+ 'icon.voice.dica': 'Control the game by speaking.',
218
+ 'icon.tipografia.dica': 'Changes the shape of the letters: capitals, more readable letters or your country\'s handwriting.',
219
+ 'icon.velocidade.dica': 'Slows the whole game down: the time, the world and the moment to act.',
164
220
  'icon.state': '{nome}: {v}',
165
- 'icon.soon': '{nome} (under construction)',
221
+ 'ui.soon': 'coming soon',
166
222
  'state.on': 'on',
167
223
  'state.off': 'off',
168
224
  'calm.off': 'off',
@@ -177,6 +233,29 @@ const en = {
177
233
  'contrast.3': '3:1',
178
234
  'contrast.45': '4.5:1',
179
235
  'contrast.7': '7:1',
236
+ 'visual.lq': 'Contrast enhancement',
237
+ 'visual.lq.dica': 'A tone curve over the whole screen: linear stretches the contrast, quadratic brings out shadows and highlights, and mixed sits between them. Applies to every player.',
238
+ 'menu.visual': 'Visual accessibility',
239
+ 'menu.empathy': 'Empathy mode',
240
+ 'empathy.grupo.rotulo': 'Simulations',
241
+ 'empathy.simulacao.dica': 'Shows the game as someone with the chosen disability sees it.',
242
+ 'empathy.hearing': 'Simulate hearing loss',
243
+ 'empathy.hearing.dica': 'Soft sounds are muffled and high pitches are cut, as heard by someone with hearing loss.',
244
+ 'empathy.onebtn': 'Simulate one button at a time',
245
+ 'empathy.onebtn.dica': 'While one button is held, the game does not accept a second, as for someone who cannot press two at once.',
246
+ 'empathy.semforca': 'Simulate no strength to hold',
247
+ 'empathy.semforca.dica': 'Holding a button counts as a single tap, as for someone without the strength to keep it pressed.',
248
+ 'empathy.select': 'Select',
249
+ 'empathy.selected': '✓ Selected',
250
+ 'visual.grupo.rotulo': 'Visual settings',
251
+ 'visual.cbsafe': 'Colour-blind safe palette',
252
+ 'visual.cbsafe.dica': 'Swaps the colours of the menus and the HUD for a palette that stays distinct in every kind of colour blindness (Okabe-Ito).',
253
+ 'visual.dono': 'Items in their owner\'s colour',
254
+ 'visual.dono.dica': 'In multiplayer, each player sees their own items in their own colour. Off: everyone sees the original colours.',
255
+ 'visual.papeis': 'Colour-blocking colours',
256
+ 'visual.papeis.dica': 'In the high-contrast modes, choose the colour of each role. ↺ restores the default.',
257
+ 'visual.papel.cor': 'Colour of {papel}',
258
+ 'visual.papel.repor': 'Restore the default colours',
180
259
  'lq.off': 'off',
181
260
  'lq.linear': 'linear',
182
261
  'lq.mixed': 'mixed',
@@ -193,49 +272,34 @@ const en = {
193
272
  'icon.cvd.short': 'Colour-blindness correction',
194
273
  'pause.iconBarAria': 'Accessibility shortcuts',
195
274
  // Activities menu (splash) — activity, scenario, player count and fraction notations.
196
- 'fnot.v': 'Stacked fraction',
197
- 'fnot.d': 'Slanted fraction',
198
- 'fnot.dec': 'Decimal',
199
- 'fnot.pct': 'Percentage',
200
- 'fnot.mix': 'Mixed number',
201
- 'menu.playerCountAria': 'Number of players: {n}. Click on the left for fewer, on the right for more.',
202
- 'sr.menu.pickScenario': 'Choose the scenery.',
203
- 'sr.menu.gameStarted': '{atividade}. Game started.',
204
- 'sr.menu.pickNumbers': '{atividade}: choose the numbers.',
205
- 'sr.menu.player1': '{n} player.',
206
- 'sr.menu.playersN': '{n} players.',
207
275
  'sr.menu.index': '{n} of {m}',
276
+ 'sr.papel.botao': 'button',
277
+ 'sr.papel.interruptor': 'switch',
278
+ 'sr.papel.lista': 'list',
279
+ 'sr.papel.cursor': 'slider',
280
+ 'sr.papel.passos': 'stepper',
281
+ 'sr.papel.opcao': 'option',
282
+ 'sr.estado.selecionado': 'selected',
208
283
  'sr.menu.indexOn': 'List position on.',
209
284
  'sr.menu.indexOff': 'List position off.',
210
- 'sr.a11y.barEnter': 'Accessibility bar. Use the directions to choose and confirm to switch. To go back to the game, press back or START.',
285
+ 'sr.a11y.barEnter': 'Game paused. Accessibility bar. Use the directions to choose and confirm to switch. To go back to the game, press back or START.',
211
286
  'sr.a11y.barExit': 'Back to the game.',
287
+ 'sr.a11y.quickPause': 'Game paused. To go back to the game, press START.',
212
288
  'pad.glyph.cross': 'cross',
213
289
  'pad.glyph.circle': 'circle',
214
290
  'pad.glyph.square': 'square',
215
291
  'pad.glyph.triangle': 'triangle',
216
292
  'pad.wiz.step': '{n} of {total} — press: {acao}',
293
+ 'pad.wiz.stepStart': '{n} of {total} — press the button you want as START (it pauses the game)',
294
+ 'pad.wiz.stepSelect': '{n} of {total} — press the button you want as SELECT (it opens the menus)',
217
295
  'pad.wiz.mapped': 'Mapped: {lista}',
218
296
  'pad.wiz.pressAny': 'Press ANY button on the controller you want to map.',
219
297
  'pad.wiz.detected': 'New controller detected: {id}. The game paused so you can set it up. RELEASE everything to start.',
220
298
  'pad.wiz.releaseAll': 'Controller: {id}. Now RELEASE everything.',
221
299
  'menu.legendSpoken': 'Button {sim} to select, button {nao} to go back.',
222
- 'sr.menu.fractionsIntro': 'Adding and subtracting fractions: choose the notation and the type.',
223
- 'sr.menu.keepOneNotation': 'Keep at least one notation on.',
224
- 'sr.menu.notationOn': '{notacao} on.',
225
- 'sr.menu.notationOff': '{notacao} off.',
226
- 'sr.menu.pickOneNumber': 'Choose at least one number to practise.',
227
- 'sr.menu.numberOn': 'Number {n} on.',
228
- 'sr.menu.numberOff': 'Number {n} off.',
229
- 'fnot.desc.v': 'Shows fractions stacked, one number above the other.',
230
- 'fnot.desc.d': 'Shows fractions on one line, with a slash.',
231
300
  'fnot.desc.dec': 'Shows numbers that always carry one decimal place.',
232
- 'fnot.desc.pct': 'Shows percentages.',
233
- 'fnot.desc.mix': 'Shows whole numbers together with reduced fractions.',
234
- 'menu.notationGroupAria': 'Notation',
235
301
  // Physics (lava, spider cling), audio navigation and the attract-mode demo.
236
- 'sr.physics.lava': 'Careful! You touched the lava. The coins moved back to random places.',
237
302
  'sr.physics.spiderOn': 'Spider mode! You crawl on walls and ceilings and round corners. {botao} lets go.',
238
- 'sr.physics.spiderOff': 'Let go of the surface.',
239
303
  'sr.nav.noTargetNear': 'Nothing nearby.',
240
304
  // The loop stopped because a frame threw (ADR-0054). A blind child does not see a frozen screen:
241
305
  // without this sentence, "crashed" and "thinking" are the same silence.
@@ -250,6 +314,7 @@ const en = {
250
314
  'eixo.correcao.tricro': 'Trichromatic vision',
251
315
  'viz.escolher': 'Select',
252
316
  'viz.escolhido': '✓ Selected',
317
+ 'sim.indisponivel.alternancia': 'To see the no-strength-to-hold simulation, toggle keys need to be off: with them on, the demonstration would show the accommodation and not the difficulty.',
253
318
  'sim.indisponivel.tema': 'To see the simulation, the theme needs to be at its default: over high contrast it would show what the theme does, not what the condition does.',
254
319
  'sim.indisponivel.correcao': 'To see the simulation, colour correction needs to be at trichromatic vision: from an already-corrected screen it would show neither the condition nor the correction.',
255
320
  'sim.indisponivel.ambos': 'To see the simulation, both the theme and colour correction need to be at their defaults: over an adjustment, the demonstration shows the adjustment and not the condition.',
@@ -260,18 +325,9 @@ const en = {
260
325
  'reach.nome.gamepad': 'gamepad',
261
326
  'reach.nome.teclado': 'keyboard',
262
327
  'reach.nome.toque': 'on-screen control',
263
- 'sr.attract.demo': 'Demo.',
264
- 'sr.attract.recorded': '30-second demo recorded for {cenario}.',
265
328
  // Title submenu chrome and the scenery names.
266
329
  'menu.back': 'Back',
267
- 'menu.play': 'Play',
268
330
  'menu.alf': 'Literacy',
269
- 'menu.mat': 'Maths',
270
- 'menu.frac': 'Fractions',
271
- 'menu.fracTitle': 'Adding and subtracting fractions',
272
- 'menu.tab': 'Times tables',
273
- 'menu.tabHint': 'Choose the numbers to practise',
274
- 'menu.cen': 'Scenery',
275
331
  'cen.cidade': 'City',
276
332
  'cen.campo': 'Day in the Fields',
277
333
  'cen.cemiterio': 'Daybreak in the Fields',
@@ -279,55 +335,130 @@ const en = {
279
335
  'cen.floresta': 'Forest',
280
336
  // Voice narration (TTS).
281
337
  'audio.noSystemVoices': '(no system voices)',
282
- 'sr.tts.engineNoLanguage': 'This engine does not speak this language yet — for now, use Piper (neural) or the browser voice.',
338
+ 'sr.tts.engineNoLanguage': 'This engine does not speak this language yet — for now, use the browser voice.',
283
339
  'sr.tts.noNeuralForLanguage': 'There is no neural voice for this language yet — carrying on with the browser voice, which speaks it.',
340
+ 'sr.tts.noVoiceForLanguage': 'This device has no voice in {language}: that part is not read aloud, but it stays on the screen.',
284
341
  'sr.tts.neuralNotBundled': 'This build of the game ships no neural voice — carrying on with the browser voice.',
285
342
  'sr.tts.downloading': 'Downloading the neural voice (needs the internet on the first use only)…',
286
- 'sr.tts.progress': 'Neural voice: {pct}%.',
287
343
  'sr.tts.ready': 'Neural voice ready, in {s} seconds.',
288
344
  'sr.tts.loadFailed': 'The neural voice could not be loaded (it needs the internet on the first use) — carrying on with the browser voice.',
289
345
  // Quiz — the FRAME only; the literacy curriculum itself stays in pt-BR by decision.
290
- 'sr.quiz.tryAgain': 'Try again.',
291
- 'sr.quiz.erase': 'erase',
292
346
  'sr.quiz.ok': 'ok',
293
347
  'sr.blind.on': 'Blind mode on: cane and audio cues active. The first power item becomes the running cane.',
294
348
  'sr.blind.off': 'Blind mode off.',
295
349
  'sr.motor.oneButtonOn': 'One button at a time on: only one key or button at once.',
296
- 'sr.motor.oneButtonOff': 'One button at a time off.',
297
- 'sr.motor.wheelchairOn': 'Wheelchair mode on: no jumping; ramps and lifts instead of steps and ladders; coins on the ground; flight and super-run only.',
298
- 'sr.motor.wheelchairOff': 'Wheelchair mode off.',
299
- 'sr.visual.ownerColorsOn': 'Items coloured by owner: on.',
300
- 'sr.visual.ownerColorsOff': 'Items coloured by owner: off — everything in its original colour.',
301
- 'sr.visual.cbSafeOn': 'Colour-blind safe palette on (Okabe-Ito).',
302
- 'sr.visual.cbSafeOff': 'Colour-blind safe palette off.',
303
- 'sr.visual.outlineFg': 'Foreground outline: {v}.',
304
- 'sr.visual.outlineBg': 'Background outline: {v}.',
305
- 'outline.none': 'none',
306
- 'outline.thin': 'thin',
307
- 'outline.thick': 'thick',
308
- 'sr.captions.on': 'Captions on.',
309
- 'sr.captions.off': 'Captions off.',
310
350
  // Quiz — MATHS: the whole prompt translates, operators included (2+3 is language-independent).
311
- 'math.howManyDots': 'How many dots?',
312
- 'math.op.plus': 'plus',
313
- 'math.op.minus': 'minus',
314
- 'math.op.times': 'times',
315
- 'math.op.dividedBy': 'divided by',
316
- 'sr.math.howManyDots': 'How many dots do you see?',
317
- 'sr.math.howMuchIs': 'What is {a} {op} {b}?',
318
351
  // Quiz — LITERACY: the FRAME translates; the word, the letter and the Braille cell travel through as
319
352
  // parameters, in pt-BR, because they are the subject matter of a language discipline.
320
- 'sr.quiz.who': 'Player {n}: ',
321
- 'sr.quiz.wins': '{n} of 3 correct towards the coin',
322
353
  'sr.quiz.buildWord': 'Letter {letra}. Build the word: {palavra}.',
323
354
  'sr.quiz.whichSpelling': '{palavra}. Which spelling is right? The game spells out each option.',
324
355
  'sr.quiz.writeWord': 'Write the word: {palavra}. {n} letters.',
325
356
  'sr.quiz.brailleDictation': '{palavra}. {celas} Jump to collect.',
326
357
  'sr.quiz.wellDone': 'Well done! {palavra}. {n} out of 3.',
327
- 'sr.quiz.correctSoFar': 'Correct! {n} out of 3 to win the coin.',
328
358
  'menu.restoreDefaults': 'Restore this menu to its defaults',
329
359
  'menu.close': 'Close',
330
360
  'menu.typo': 'Typography',
361
+ // The panel TITLE, without the emoji: `pause.caa` labels the BUTTON on the pause card, where a symbol helps
362
+ // tell seven items apart at a glance. Inside the panel you already know where you are, and an emoji in the
363
+ // `<h2>` is read aloud before the name of what it opened.
364
+ 'menu.caa': 'Communication',
365
+ 'aac.grupo.rotulo': 'Communication choices',
366
+ // Named for what a person feels, not for what the code does: whoever needs this panel arrives through nausea
367
+ // or a seizure risk, not through curiosity about frame rates.
368
+ 'menu.animation': 'Visual sensitivity',
369
+ 'animation.grupo.rotulo': 'Motion and animation',
370
+ // ===================== THE MOTOR PANEL'S ROWS =====================
371
+ // Short label, and the explanation in a single hint the shell moves to the footer (CLAUDE.md §4). The hints
372
+ // are the same sentences the `sr.motor.*On` announcements already say, in the present instead of the past:
373
+ // two wordings of one choice drift apart, and whoever hears the announcement after reading the row deserves
374
+ // to recognise it.
375
+ 'motor.facil': 'Easy Mode',
376
+ 'motor.facil.dica': 'Lower gravity, higher jump, forgiving pickup, coins on the ground, no hazards and no accidental falls.',
377
+ 'motor.altmove': 'How you press',
378
+ 'motor.espera': 'Wait between presses',
379
+ 'motora.camera': 'Play with the camera',
380
+ 'motora.camera.dica': 'The camera stays on this device: nothing it sees leaves. Choose what plays — the hands, the face or the eyes.',
381
+ 'motora.voz': 'Play by speaking',
382
+ 'motora.voz.dica': 'The microphone stays on the device: what the child says is heard here and does not leave. Say the name of what you want — «up», «confirm» — or the name of the menu item in sight.',
383
+ 'motor.espera.dica': 'After a press, waits half a second before taking the next one — for when a hand shakes and one press arrives twice.',
384
+ 'motor.altmove.dica': 'One tap turns it on and another turns it off, instead of keeping the button pressed.',
385
+ 'motor.togglerun': 'Run toggle',
386
+ 'motor.togglerun.dica': 'The run button stays on with one tap, instead of having to be held down.',
387
+ 'motor.grupo.rotulo': 'Movement choices',
388
+ 'motora.pad': 'Controller size',
389
+ 'motora.pad.dica': 'Choose by the hand that plays: small child up to 6, older child around 12. A small child gets the largest buttons, because small children still land far from the centre.',
390
+ 'motora.pad.crianca-pequena': 'small child',
391
+ 'motora.pad.crianca-grande': 'older child',
392
+ 'motora.pad.adulto-pequeno': 'small adult',
393
+ 'motora.pad.adulto-maos-grandes': 'adult with large hands',
394
+ 'motora.teclado.1': 'Map the keyboard — 1 player',
395
+ 'motora.teclado.2': 'Map the keyboard — 2 players',
396
+ 'motora.teclado.34': 'Map the keyboard — 3–4 players',
397
+ 'motora.controle': 'Map gamepad',
398
+ 'motora.toque': 'Map touch',
399
+ 'motora.abrir': 'Open',
400
+ 'ctrl.assento': 'Keyboard of',
401
+ 'ctrl.jogador': 'Player {n}',
402
+ 'menu.motora': 'Motor accessibility',
403
+ // ===================== THE AUDIO PANEL'S ROWS =====================
404
+ // Where a word for the thing already existed it is REUSED — `icon.blind` and `icon.tts` name these same two
405
+ // settings on the accessibility bar. Two names for one setting on two screens of the same engine is how a
406
+ // child stops recognising what she already learned.
407
+ 'audio.som': 'Sound',
408
+ 'audio.som.dica': 'Turns all game sound off at once, without touching the per-kind choices.',
409
+ 'audio.volume': 'Overall volume',
410
+ 'audio.modocego': 'Blind mode',
411
+ 'audio.narracao': 'Voice narration',
412
+ 'audio.cat.music': 'Music',
413
+ 'audio.cat.ambient': 'Ambient sounds',
414
+ 'audio.cat.interact': 'Interaction effects',
415
+ 'audio.cat.earcons': 'Earcons',
416
+ 'audio.cat.tts': 'Narration',
417
+ 'audio.cat.sonar': 'Sonar',
418
+ 'audio.cat.volumeDe': '{c} volume',
419
+ 'audio.navsound.grupo': 'Navigation sounds',
420
+ 'audio.cane': 'Cane tap spacing',
421
+ 'audio.cane.dica': 'How much ground between cane taps. One per block is calmer; every half block gives more detail.',
422
+ 'audio.cane.block': 'one per block',
423
+ 'audio.cane.halfBlock': 'every half block',
424
+ 'audio.menuindex': 'Spoken menu index',
425
+ 'audio.menuindex.dica': 'The screen reader says "3 of 7" as you move through a menu, so you know where you are without counting.',
426
+ 'audio.tts.dica': 'The game reads out loud what is written on the screen.',
427
+ 'audio.ttsEngine': 'Voice engine',
428
+ 'audio.ttsEngine.dica': 'The browser voice works right away; the neural ones sound better and download on first use.',
429
+ 'audio.ttsVoice': 'Voice',
430
+ 'audio.ttsVol': 'Narration volume',
431
+ 'audio.ttsPpm': 'Speech rate',
432
+ 'audio.ttsPpm.dica': 'How many words a minute the narration speaks.',
433
+ 'tts.kokoro.teste': 'Hello.', // the short sentence that tests whether WebGPU speaks (ADR-0198 §4)
434
+ 'visual.captions': 'Captions',
435
+ 'visual.legenda.ritmo': 'Caption speed',
436
+ 'visual.legenda.ppm': '{n} WPM',
437
+ 'visual.legenda.ritmo.dica': 'How long a caption stays on screen, in words per minute.',
438
+ 'visual.contorno.fg': 'Foreground outline',
439
+ 'visual.contorno.bg': 'Background outline',
440
+ 'visual.contorno.fg.dica': 'In high contrast, outlines what moves and what can be picked up.',
441
+ 'visual.contorno.bg.dica': 'In high contrast, outlines where you can walk and where you cannot.',
442
+ 'visual.contorno.0': 'none',
443
+ 'visual.contorno.1': 'thin',
444
+ 'visual.contorno.2': 'thick',
445
+ 'visual.captions.dica': 'Writes the game’s sounds on the screen.',
446
+ 'sr.visual.captionsOn': 'Captions on.',
447
+ 'sr.visual.captionsOff': 'Captions off.',
448
+ 'audio.voz': 'Voice',
449
+ 'audio.voz.nenhuma': 'No voice',
450
+ 'audio.semVoz': 'No voice speaks this language.',
451
+ 'audio.comVoz': 'A voice now speaks this language.',
452
+ 'sr.audio.voz': 'Voice: {nome}.',
453
+ 'audio.ttsTest': 'Test the voice',
454
+ 'audio.ttsTest.dica': 'Speaks a sample sentence with the voice chosen right now.',
455
+ 'audio.sinks.grupo': 'Audio output per player',
456
+ 'audio.detect': 'Detect outputs',
457
+ 'menu.audio': 'Hearing accessibility',
458
+ 'menu.som': 'Hearing comfort',
459
+ 'audio.grupo.rotulo': 'Game sounds',
460
+ // Every panel footer's RESTING text — what it says while nobody is pointing at any row.
461
+ 'menu.explainIdle': 'Hover or move through the options to see the explanation.',
331
462
  'sr.audio.reset': 'Hearing accessibility restored to its defaults. The other menus did not change.',
332
463
  'sr.empathy.reset': 'Empathy mode restored to its defaults: simulations off. Colour-blindness corrections and the other menus did not change.',
333
464
  'sr.motor.reset': 'Easy Mode and latched movement restored to their defaults. Eye control and the key mapping are unchanged.',
@@ -335,20 +466,32 @@ const en = {
335
466
  'a11y.changed': 'changed',
336
467
  'sr.visual.reset': 'Visual accessibility restored to its defaults: contrast, enhancement, colours and outlines. Captions and the other menus did not change.',
337
468
  'sr.motion.reset': 'Visual sensitivity restored to its defaults: animations and CRT look. Animations go back to what your system asks for.',
338
- 'caa.emPreparo': 'in preparation',
339
- 'caa.aguardandoNegociacao': 'awaiting negotiation',
340
- 'caa.secao.agora': 'Available now',
341
- 'caa.secao.agoraTag': 'works with no network',
342
- 'caa.secao.preparo': 'In preparation',
343
- 'caa.secao.preparoTag': 'licence settled; the work is ours',
344
- 'caa.secao.negociacao': 'Awaiting negotiation',
345
- 'caa.secao.negociacaoTag': 'the permission is not ours to give',
346
- 'sr.caa.escolha': 'Communication: {v}.',
347
- 'sr.caa.reset': 'Communication restored to its default: uppercase letters, where literacy usually starts.',
348
- 'pause.caa': '🔠 Communication',
349
- 'sr.caa.caixaAltaOn': 'Uppercase letters on: the whole game in capitals.',
350
- 'sr.caa.caixaAltaOff': 'Uppercase letters off: capitals and lowercase.',
351
- 'sr.quiz.bemVindo': 'Quiz. Use the arrow keys to choose and Enter to answer.',
469
+ 'aac.letras': 'Capital letters',
470
+ 'aac.letras.dica': 'On: the whole game in capitals, the way early literacy usually starts. '
471
+ + 'Off: capitals and lower case, everyday writing.',
472
+ 'aac.noLicence': 'no licence',
473
+ 'aac.secao.agora': 'Available now',
474
+ 'aac.secao.agoraTag': 'works with no network',
475
+ 'aac.section.pictograms': 'Pictograms',
476
+ 'aac.section.pictogramsTag': 'each one only with a licence',
477
+ 'sr.aac.escolha': 'Communication: {v}.',
478
+ 'sr.aac.reset': 'Communication restored to its default: uppercase letters, where literacy usually starts.',
479
+ 'pause.caa': 'Communication',
480
+ 'sr.aac.caixaAltaOn': 'Uppercase letters on: the whole game in capitals.',
481
+ 'sr.aac.caixaAltaOff': 'Uppercase letters off: capitals and lowercase.',
482
+ 'sr.quiz.bemVindo': 'Quiz. Use {mover} to choose and {responder} to answer.',
483
+ 'sr.quiz.bemVindo.soEscolher': 'Quiz. Use {mover} to choose.',
484
+ 'sr.quiz.bemVindo.soResponder': 'Quiz. Use {responder} to answer.',
485
+ 'sr.quiz.bemVindo.semTeclas': 'Quiz. Tap an answer to give it.',
486
+ 'sr.quiz.teclas.duas': '{a} and {b}',
487
+ // The quiz's questions — keys, not sentences, so that changing the flag reaches the ACTIVITY and not only the
488
+ // engine's frame (ADR-0225). A quiz is not a language subject, so nothing here is exempt from translating.
489
+ 'quiz.pageTitle': 'The Inclusionist — demo quiz',
490
+ 'quiz.carregando': 'Loading…',
491
+ 'quiz.ouvindo': 'I am listening. Say the answer.',
492
+ 'quiz.ouviNada': 'I heard nothing. Say it again or choose with the arrows.',
493
+ 'quiz.semLeitura': 'This device cannot listen right now. Choose with the arrows.',
494
+ 'quiz.alternativas': 'Options',
352
495
  'sr.nav.sonarFound': 'Sonar: {alvo} {lado}, {dist}.',
353
496
  'sr.nav.coin': 'coin',
354
497
  'sr.nav.target': 'target',
@@ -367,42 +510,36 @@ const en = {
367
510
  'sr.player.prefix': 'Player {n}: ',
368
511
  'sr.empathy.hearingOn': 'Hearing-loss simulation on: quiet sounds are muffled and the highs are cut; speech becomes hard to follow.',
369
512
  'sr.empathy.hearingOff': 'Hearing-loss simulation off.',
370
- 'sr.pad.disconnected': 'The controller for Player {n} disconnected — the keyboard still works. Press START to pair it again.',
371
- 'sr.quiz.levelSet': 'Level {n}: {v}.',
372
- 'sr.visual.roleColorSet': 'Colour of {v} changed.',
373
- 'sr.visual.roleColorsReset': 'Colour-blocking colours restored to their defaults.',
374
- 'sr.visual.defaultColors': 'Default colours restored.',
375
- 'sr.pad.connected': 'Controller connected: {v} layout.',
376
- 'sr.pad.design': 'Button design: {v}.',
377
- 'sr.eyes.loading': 'Play with your eyes: loading the webcam (please allow access).',
378
- 'sr.eyes.off': 'Play with your eyes off.',
379
- 'sr.boot.loaded': 'Game loaded. Collect {n} coins. Climb ladders with W/S, swim by holding jump in water.',
513
+ 'sr.empathy.onebtnOn': 'One-button-at-a-time simulation on: a second button pressed together does not count.',
514
+ 'sr.empathy.onebtnOff': 'One-button-at-a-time simulation off.',
515
+ 'sr.empathy.semforcaOn': 'No-strength-to-hold simulation on: holding a button counts as a single tap.',
516
+ 'sr.empathy.semforcaOff': 'No-strength-to-hold simulation off.',
380
517
  // ===================== POWER-UPS =====================
381
518
  'sr.power.superjump': 'Super jump! Your jump always reaches its highest point.',
382
519
  'sr.power.ultrajump': 'Ultra jump! Enormous leaps across the gap.',
383
520
  'sr.power.turbo': 'Super run! Running makes you much faster.',
384
521
  'sr.power.fly': 'Flight! In the air, press Jump to start flying; press Jump again to stop.',
385
522
  'sr.power.wallcling': 'Spider climb! In the air, press {botao} near a wall or ceiling to stick; you crawl and round corners; {botao} again lets go.',
386
- 'sr.power.none': 'No power active.',
387
- 'sr.power.generic': 'Power activated!',
388
523
  'hud.power.off': '—',
389
524
  'hud.power.superjump': '🐇 Super jump',
390
525
  'hud.power.ultrajump': '🦘 Ultra jump',
391
526
  'hud.power.turbo': '👟 Super run',
392
- 'hud.power.fly': '🎈 Flight',
393
527
  'hud.power.wallcling': '🕷️ Climb',
394
528
  'hud.power.runcane': '👟 Running cane',
395
529
  // ===================== REDUCED MOTION (WCAG 2.3.3) + CRT =====================
396
530
  'rm.parallax': 'Background parallax',
397
- 'rm.decor': 'Decoration (clouds, grass)',
398
- 'rm.items': 'Item animation (coins)',
399
- 'rm.walk': 'Character in motion (walk, climb, swim, jump)',
400
- 'rm.breath': 'Breathing (standing still)',
401
- 'rm.flavor': 'Idle antics (resting animations)',
531
+ 'rm.decor': 'Decoration',
532
+ 'rm.items': 'Item animation',
533
+ 'rm.walk': 'Character in motion',
534
+ 'rm.breath': 'Breathing',
535
+ 'rm.flavor': 'Idle antics',
402
536
  'rm.particles': 'Particles and sparkle',
403
537
  'rm.crt.scan': 'Scanlines',
404
538
  'rm.crt.vig': 'Vignette',
405
539
  'rm.crt.round': 'Rounded corners',
540
+ 'crt.round.off': 'off',
541
+ 'crt.round.small': 'small',
542
+ 'crt.round.large': 'large',
406
543
  'rm.sec.all': 'all players',
407
544
  'sr.rm.frozen': '{alvo} frozen.',
408
545
  'sr.rm.animated': '{alvo} animated.',
@@ -412,32 +549,19 @@ const en = {
412
549
  'sr.crt.off': '{efeito} off.',
413
550
  'sr.crt.round': '{efeito}: {nivel}.',
414
551
  // ===================== ON / OFF =====================
415
- 'ui.toggle.on': '❚❚ On',
416
- 'ui.toggle.off': '▶ Off',
552
+ 'ui.toggle.on': 'On',
553
+ 'ui.toggle.off': 'Off',
417
554
  'ui.toggle.ariaOn': '{alvo}: on',
418
555
  'ui.toggle.ariaOff': '{alvo}: off',
419
556
  // ===================== THE TWO PER-PLAYER MOTOR CHOICES =====================
420
557
  'sr.motor.easyOn': 'Easy Mode on: lower gravity, higher jump, forgiving pickup, coins on the ground, no hazards and no accidental falls (hold ↓ to climb down).',
421
558
  'sr.motor.easyOff': 'Easy Mode off.',
422
- 'sr.motor.toggleMoveOn': 'Tap-to-move on: tap a direction to walk without holding; tap again to stop; hold to go faster. Jumping does not interrupt the walk.',
423
- 'sr.motor.toggleMoveOff': 'Tap-to-move off.',
424
- 'alt.exigida.olhos': 'Gaze control needs tap-to-move to work.',
425
- 'alt.exigida.rosto': 'Face control needs tap-to-move to work.',
426
- 'alt.exigida.gestos': 'Gesture control needs tap-to-move to work.',
427
- 'alt.exigida.fala': 'Voice command needs tap-to-move to work.',
559
+ 'sr.motor.toggleMoveOn': 'No holding needed, on: one tap turns it on and another turns it off.',
560
+ 'sr.motor.toggleMoveOff': 'No holding needed, off.',
428
561
  'sr.motor.toggleRunOn': 'Run toggle on.',
429
562
  'sr.motor.toggleRunOff': 'Run toggle off.',
430
- 'sr.physics.runLatchOn': 'Running.',
431
- 'sr.physics.runLatchOff': 'Walking.',
432
563
  // ===================== HELP (pause menu) + level label =====================
433
564
  'pause.level': '📚 Level {n} · {v}',
434
- 'help.controls': 'Your controls',
435
- 'help.controlsPlayer': 'Your controls · Player {n}',
436
- 'help.keyboard': 'keyboard',
437
- 'help.buildNotes': 'Notes on this build',
438
- 'help.powerups': 'Power-ups: 👟 super run · 🕷️ climb · 🎈 flight · 🐇 super jump · 🦘 ultra jump · 🔑 the key opens the 🚪 gate.',
439
- 'help.multiplayer': '2–4 players: screens side by side, each with its own menu and its own settings.',
440
- 'help.tech': 'v{v} — PixiJS (WebGL, Canvas fallback) · text/UI in the DOM (accessibility) · offline via PWA.',
441
565
  'menu.yes': 'Yes',
442
566
  'menu.no': 'No',
443
567
  // ===================== THE 16 VISION MODES =====================
@@ -476,16 +600,17 @@ const en = {
476
600
  // ===================== O QUE FALTAVA (item 14, rodada final) =====================
477
601
  // Estas 18 chaves existiam só em pt e caíam no fallback — e são as MAIS VISTAS do jogo: o menu de pausa
478
602
  // inteiro, o título e a tela de vitória. Quem escolhesse inglês via a pausa em português.
479
- 'title.byline': 'by Prof. José Rocha',
480
- 'title.wait': 'Wait for Player 1 to choose the game',
481
- 'win.title': '🎉 You collected all 10 coins!',
482
- 'win.again': 'Play again',
483
603
  'pause.title': 'Paused',
484
- 'pause.resume': '▶ Resume',
485
- 'pause.acessibilidade': '♿ Accessibility',
486
- 'pause.options': '⚙ Options',
487
- 'pause.pmback': '↩ Back',
604
+ 'pause.resume': 'Back',
605
+ 'pause.quick': 'PAUSED',
606
+ 'pause.quick.legenda': '2: confirm · 3: back · 4: menu · START: back to the game',
607
+ 'pause.card.legenda': '2: confirm · 3: back',
608
+ 'pause.acessibilidade': 'Accessibility',
609
+ 'pause.options': 'Inclusion settings',
610
+ 'pause.opcoesdojogo': 'Game options',
611
+ 'pause.pmback': 'Back',
488
612
  'pause.cardAria': 'Player {n} pause menu',
613
+ 'pause.cardSeat': ' · Player {n}',
489
614
  /* --- ACTIVITY CATALOG: everything except literacy. The five literacy activities stay raw pt-BR in
490
615
  `educational/activities-registry` — the word and the syllable ARE the subject matter (pillar 3). --- */
491
616
  'act.ludico.nome': 'Collect 10 coins',
@@ -513,54 +638,27 @@ const en = {
513
638
  'act.fr632.d': 'Add and subtract sixths, thirds and halves.',
514
639
  'act.fr2a6.nome': 'Adding and subtracting fractions from halves to sixths',
515
640
  'act.fr2a6.d': 'Add and subtract fractions from halves to sixths.',
516
- 'pause.tipo': '🔤 Typography',
517
- 'pause.addplayer': '👥 Add player',
518
- 'pause.audio': '🦻 Hearing accessibility',
519
- 'pause.motora': '♿ Motor accessibility',
520
- 'pause.anim': '🎞 Visual sensitivity',
521
- 'pause.visual': '🎨 Visual accessibility',
522
- 'pause.empatia': '🫂 Empathy mode',
523
- 'pause.ajuda': '❓ Help',
524
- 'pause.print': '📷 Print (see the screen)',
525
- 'pause.quit': '🚪 Quit the game',
526
- 'a11y.gameRegion': 'Game area. Move with A and D or the arrow keys; jump with L or Space; climb ladders up and down (and swim in water) with W and S or the arrow keys; run with P or Shift. Collect 10 coins.',
527
- 'game.instructions': 'Move the character through the cave and collect 10 coins. No time limit. Controls: A and D or the arrow keys move; L or Space jump; W and S (or up/down arrows) climb ladders and swim; P or Shift run.',
641
+ 'pause.tipo': 'Typography',
642
+ 'pause.addplayer': 'Number of players',
643
+ 'pause.audio': 'Hearing accessibility',
644
+ 'pause.som': 'Hearing comfort',
645
+ 'pause.motora': 'Motor accessibility',
646
+ 'pause.anim': 'Visual sensitivity',
647
+ 'pause.visual': 'Visual accessibility',
648
+ 'pause.empatia': 'Empathy mode',
649
+ 'pause.ajuda': 'Help — How to play',
650
+ 'pause.print': 'Print (see the screen)',
651
+ 'pause.quit': 'Quit the game',
652
+ 'pause.motivo': 'This game does not use this option.',
653
+ 'pause.motivo.ajuda': 'This game has not said yet what each button does.',
654
+ 'pause.motivo.addplayer': 'The game decides how many players can play.',
655
+ 'pause.motivo.opcoesdojogo': 'This game has no options of its own.',
656
+ 'pause.motivo.caa': 'Menu disabled',
528
657
  // ===================== ARIA-LABELS FROM index.html =====================
529
- 'a11y.choosePlayer': 'Choose the player',
530
- 'a11y.animations': 'Animations',
531
- 'a11y.literacy': 'Literacy',
532
- 'a11y.shortcuts': 'Accessibility shortcuts',
533
- 'a11y.hearing': 'Hearing',
534
- 'a11y.actionButtons': 'Action buttons',
535
- 'a11y.screenButtons': 'On-screen buttons (touch)',
536
- 'a11y.touchButtons': 'On-screen touch buttons',
537
- 'a11y.audioCategories': 'Audio categories',
538
658
  'a11y.communication': 'Communication: letters and symbols',
539
- 'a11y.outlineFg': 'Foreground outline',
540
- 'a11y.outlineBg': 'Background outline',
541
- 'a11y.outlines': 'High-contrast outlines',
542
- 'a11y.touchControls': 'Touch controls',
543
- 'a11y.padDesign': 'Button layout',
544
- 'a11y.chooseScenery': 'Choose the scenery',
545
- 'a11y.chooseGame': 'Choose the game',
546
- 'a11y.chooseNumbers': 'Choose the numbers',
547
- 'a11y.hideDebug': 'Hide the debug tools',
548
- 'a11y.btnSpecial': 'Special (button 1)',
549
- 'a11y.fraction': 'Fraction',
550
- 'a11y.touchRoles': 'What each touch button does',
551
- 'a11y.btnRun': 'Interact / run (button 2)',
552
- 'a11y.eyeGaze': 'Play with your eyes',
553
- 'a11y.mapControls': 'Map controls (per player)',
554
- 'a11y.math': 'Maths',
555
659
  'a11y.pauseMenu': 'Pause menu',
556
- 'a11y.simActive': 'Simulation mode on. Tap twice to go back to normal colours.',
557
660
  'a11y.stopAll': 'Stop all animations',
558
- 'a11y.btnJump': 'Jump (button 0)',
559
- 'a11y.audioOut': 'Audio output per player',
560
- 'a11y.visualSim': 'Visual simulation',
561
- 'a11y.switchScreens': 'Switch the number of screens (players)',
562
- 'a11y.btnSwap': 'Switch power (button 3)',
563
- 'menu.playerCount': '◀ Number of players: {n} ▶',
661
+ 'a11y.resumeAll': 'Resume all animations',
564
662
  // ===================== CONTROL LEGEND (row under the title) =====================
565
663
  'legend.move': 'move',
566
664
  'legend.pause': 'pause',
@@ -570,13 +668,16 @@ const en = {
570
668
  'legend.swap': 'switch',
571
669
  // ===================== FONT CATALOGUE =====================
572
670
  'font.grupo.rotulo': 'Letter family',
671
+ // A PANGRAM, not a translation: the sample exists to put the whole alphabet in front of a child who is
672
+ // asking «can I read this?», and a literal translation would leave letters out of the very language they
673
+ // are about to read in.
674
+ 'font.amostra': 'The quick brown fox jumps over the lazy dog',
573
675
  'font.group.sans': 'Sans serif',
574
676
  'font.group.serif': 'Serif',
575
677
  'font.group.hand': 'Handwritten',
576
678
  'font.group.arcade': 'Arcade',
577
679
  'font.desc.atkinson': 'made by the Braille Institute for people with low vision (the game default)',
578
680
  'font.desc.lexend': 'made to reduce visual stress and serve dyslexic readers (turns on the extra spacing)',
579
- 'font.desc.quattro': 'built to ease the eye strain of long hours on a screen',
580
681
  'font.desc.andika': 'based on Sassoon; the fruit of research into how children read and write',
581
682
  'font.desc.opendyslexic': 'Letters weighted at the bottom, so they do not flip upside down as you read.',
582
683
  'font.desc.fondamento': 'Pen calligraphy, for the handwriting activities.',
@@ -589,13 +690,13 @@ const en = {
589
690
  'font.desc.pw.cl': 'School cursive taught in Chile.',
590
691
  'font.desc.pw.co': 'School cursive taught in Colombia.',
591
692
  'font.desc.ronde': 'French ronde, the joined handwriting taught at school.',
592
- 'font.off.ronde': 'Install one of these three on the device: Ronde Script, OPTIFrench-Script or Merveille. '
593
- + 'They are free for personal use, which is why they cannot ship inside the game.',
693
+ 'font.notice.ronde': 'Install one of these three on the device: Ronde Script, OPTIFrench-Script or Merveille. '
694
+ + 'They are free for personal use, which is why they cannot ship inside the game. '
695
+ + 'Without them, the game shows Cookie: a similar joined hand, but not the ronde taught at school.',
594
696
  'font.desc.greatvibes': 'English calligraphy',
595
697
  'font.desc.pinyon': 'English calligraphy',
596
698
  'font.desc.ufcook': 'German blackletter',
597
699
  'font.desc.ufmag': 'German blackletter',
598
- 'font.desc.comicneue': 'ball and stick (early literacy)',
599
700
  'font.desc.pressstart': '8-bit pixel (game HUD and title)',
600
701
  'font.desc.learningcurve': 'English cursive',
601
702
  'font.desc.kindergarten': 'Brazilian cursive',