@the-inclusionist/engine 10.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 (528) hide show
  1. package/README.md +32 -1
  2. package/app/css/style.css +216 -42
  3. package/app/public/vendor/fonts-licences/NOTICE.txt +166 -0
  4. package/app/public/vendor/fonts-licences/OFL-1.1.txt +86 -0
  5. package/app/public/vendor/fonts.css +11 -1175
  6. package/dist-pkg/boot/create-game.d.ts +84 -33
  7. package/dist-pkg/boot/create-game.js +708 -307
  8. package/dist-pkg/core/a11y-sr.d.ts +1 -1
  9. package/dist-pkg/core/a11y-sr.js +3 -5
  10. package/dist-pkg/core/accommodations.d.ts +26 -8
  11. package/dist-pkg/core/accommodations.js +27 -10
  12. package/dist-pkg/core/actions.d.ts +39 -10
  13. package/dist-pkg/core/actions.js +28 -6
  14. package/dist-pkg/core/contract.d.ts +0 -2
  15. package/dist-pkg/core/contract.js +0 -2
  16. package/dist-pkg/core/i18n.d.ts +36 -71
  17. package/dist-pkg/core/i18n.js +131 -198
  18. package/dist-pkg/core/session-clock.d.ts +23 -0
  19. package/dist-pkg/core/session-clock.js +37 -0
  20. package/dist-pkg/i18n/en.js +44 -49
  21. package/dist-pkg/i18n/es.js +44 -49
  22. package/dist-pkg/i18n/pt.js +49 -54
  23. package/dist-pkg/input/gamepad.d.ts +42 -11
  24. package/dist-pkg/input/gamepad.js +50 -15
  25. package/dist-pkg/input/key-default.d.ts +30 -0
  26. package/dist-pkg/input/key-default.js +60 -0
  27. package/dist-pkg/input/keyboard-runtime.d.ts +0 -4
  28. package/dist-pkg/input/keyboard.d.ts +0 -1
  29. package/dist-pkg/input/keydown.d.ts +5 -11
  30. package/dist-pkg/input/keydown.js +3 -3
  31. package/dist-pkg/input/latch-edge.d.ts +10 -2
  32. package/dist-pkg/input/latch-edge.js +4 -3
  33. package/dist-pkg/input/latch-scope.d.ts +27 -22
  34. package/dist-pkg/input/latch-scope.js +25 -37
  35. package/dist-pkg/input/latch-store.d.ts +9 -12
  36. package/dist-pkg/input/latch-store.js +13 -18
  37. package/dist-pkg/input/latch-sync.d.ts +5 -4
  38. package/dist-pkg/input/latch-sync.js +5 -5
  39. package/dist-pkg/input/pad-reading.js +7 -2
  40. package/dist-pkg/input/pad-wizard.d.ts +4 -1
  41. package/dist-pkg/input/pad-wizard.js +60 -9
  42. package/dist-pkg/input/switch-scan.d.ts +29 -12
  43. package/dist-pkg/input/switch-scan.js +15 -2
  44. package/dist-pkg/input/touch-bindings.d.ts +3 -6
  45. package/dist-pkg/input/touch.d.ts +17 -2
  46. package/dist-pkg/input/touch.js +55 -17
  47. package/dist-pkg/input/transport-in-use.d.ts +5 -5
  48. package/dist-pkg/input/transport-in-use.js +5 -5
  49. package/dist-pkg/input/transports.d.ts +0 -9
  50. package/dist-pkg/input/transports.js +1 -1
  51. package/dist-pkg/input/virtual-controller.d.ts +39 -3
  52. package/dist-pkg/input/virtual-controller.js +32 -4
  53. package/dist-pkg/input/voice-map.d.ts +27 -11
  54. package/dist-pkg/input/voice-map.js +41 -43
  55. package/dist-pkg/platform/audio-ambient.d.ts +0 -1
  56. package/dist-pkg/platform/audio-ambient.js +3 -1
  57. package/dist-pkg/platform/audio-mixer.js +4 -9
  58. package/dist-pkg/platform/audio-sonar.d.ts +8 -94
  59. package/dist-pkg/platform/audio-sonar.js +22 -207
  60. package/dist-pkg/platform/audio.d.ts +10 -1
  61. package/dist-pkg/platform/audio.js +35 -2
  62. package/dist-pkg/platform/choose-by-voice.d.ts +70 -0
  63. package/dist-pkg/platform/choose-by-voice.js +157 -0
  64. package/dist-pkg/platform/font-library.d.ts +77 -0
  65. package/dist-pkg/platform/font-library.js +98 -0
  66. package/dist-pkg/platform/font-library.json +721 -0
  67. package/dist-pkg/platform/heavy-catalogue.d.ts +46 -0
  68. package/dist-pkg/platform/heavy-catalogue.js +47 -14
  69. package/dist-pkg/platform/heavy-mirror.d.ts +3 -9
  70. package/dist-pkg/platform/heavy-mirror.js +14 -17
  71. package/dist-pkg/platform/heavy.d.ts +40 -8
  72. package/dist-pkg/platform/heavy.js +177 -22
  73. package/dist-pkg/platform/interruptible-speech.d.ts +15 -8
  74. package/dist-pkg/platform/interruptible-speech.js +37 -13
  75. package/dist-pkg/platform/listener-scope.js +22 -13
  76. package/dist-pkg/platform/locale-host.d.ts +7 -3
  77. package/dist-pkg/platform/locale-host.js +13 -2
  78. package/dist-pkg/platform/reading-in-worker.d.ts +24 -0
  79. package/dist-pkg/platform/reading-in-worker.js +38 -0
  80. package/dist-pkg/platform/reading-model.d.ts +21 -0
  81. package/dist-pkg/platform/reading-model.js +25 -0
  82. package/dist-pkg/platform/reading-runtime.js +13 -8
  83. package/dist-pkg/platform/reading.d.ts +12 -1
  84. package/dist-pkg/platform/reading.js +9 -1
  85. package/dist-pkg/platform/speech-recognition.d.ts +10 -1
  86. package/dist-pkg/platform/speech-recognition.js +29 -9
  87. package/dist-pkg/platform/speech.d.ts +10 -1
  88. package/dist-pkg/platform/speech.js +24 -13
  89. package/dist-pkg/platform/tts.d.ts +37 -4
  90. package/dist-pkg/platform/tts.js +279 -57
  91. package/dist-pkg/platform/voice-listener.d.ts +6 -2
  92. package/dist-pkg/platform/voice-listener.js +1 -1
  93. package/dist-pkg/platform/voice-plan.d.ts +13 -0
  94. package/dist-pkg/platform/voice-plan.js +57 -2
  95. package/dist-pkg/platform/vosk-runtime.d.ts +25 -0
  96. package/dist-pkg/platform/vosk-runtime.js +59 -1
  97. package/dist-pkg/platform/vosk-vocabulary.d.ts +6 -0
  98. package/dist-pkg/platform/vosk-vocabulary.js +178 -0
  99. package/dist-pkg/render/crt.d.ts +11 -9
  100. package/dist-pkg/render/crt.js +6 -10
  101. package/dist-pkg/render/cvd-matrices.d.ts +5 -1
  102. package/dist-pkg/render/cvd-matrices.js +5 -1
  103. package/dist-pkg/render/high-contrast.d.ts +1 -2
  104. package/dist-pkg/render/high-contrast.js +5 -1
  105. package/dist-pkg/render/viz-axes.d.ts +9 -0
  106. package/dist-pkg/render/viz-axes.js +15 -2
  107. package/dist-pkg/ui/aac-sets.d.ts +29 -24
  108. package/dist-pkg/ui/aac-sets.js +22 -30
  109. package/dist-pkg/ui/audio-choices.d.ts +10 -5
  110. package/dist-pkg/ui/audio-choices.js +14 -10
  111. package/dist-pkg/ui/camera-control.d.ts +47 -0
  112. package/dist-pkg/ui/camera-control.js +35 -1
  113. package/dist-pkg/ui/declared-words.d.ts +21 -0
  114. package/dist-pkg/ui/declared-words.js +66 -0
  115. package/dist-pkg/ui/drawing-problems.js +4 -3
  116. package/dist-pkg/ui/eye-control.js +17 -17
  117. package/dist-pkg/ui/face-control.js +15 -15
  118. package/dist-pkg/ui/fonts.d.ts +42 -8
  119. package/dist-pkg/ui/fonts.js +58 -24
  120. package/dist-pkg/ui/footer-scroll-driver.d.ts +14 -0
  121. package/dist-pkg/ui/footer-scroll-driver.js +201 -0
  122. package/dist-pkg/ui/footer-scroll.d.ts +38 -0
  123. package/dist-pkg/ui/footer-scroll.js +55 -0
  124. package/dist-pkg/ui/game-options.d.ts +14 -9
  125. package/dist-pkg/ui/game-options.js +41 -21
  126. package/dist-pkg/ui/hand-control.js +15 -15
  127. package/dist-pkg/ui/help-panel.d.ts +19 -8
  128. package/dist-pkg/ui/help-panel.js +15 -5
  129. package/dist-pkg/ui/hud-bands.d.ts +29 -12
  130. package/dist-pkg/ui/hud-bands.js +63 -25
  131. package/dist-pkg/ui/hud-row.d.ts +34 -0
  132. package/dist-pkg/ui/hud-row.js +80 -0
  133. package/dist-pkg/ui/hud.d.ts +0 -3
  134. package/dist-pkg/ui/layout.js +5 -2
  135. package/dist-pkg/ui/libras-avatar-clip.d.ts +30 -0
  136. package/dist-pkg/ui/libras-avatar-clip.js +86 -0
  137. package/dist-pkg/ui/libras-avatar-load.d.ts +52 -0
  138. package/dist-pkg/ui/libras-avatar-load.js +134 -0
  139. package/dist-pkg/ui/libras-avatar-plan.d.ts +102 -0
  140. package/dist-pkg/ui/libras-avatar-plan.js +211 -0
  141. package/dist-pkg/ui/libras-avatar-player.d.ts +28 -0
  142. package/dist-pkg/ui/libras-avatar-player.js +226 -0
  143. package/dist-pkg/ui/libras-avatar-stage.d.ts +37 -0
  144. package/dist-pkg/ui/libras-avatar-stage.js +208 -0
  145. package/dist-pkg/ui/libras-glosses.d.ts +28 -0
  146. package/dist-pkg/ui/libras-glosses.js +161 -0
  147. package/dist-pkg/ui/menu-intent.d.ts +29 -0
  148. package/dist-pkg/ui/menu-intent.js +35 -1
  149. package/dist-pkg/ui/menu-items.d.ts +10 -0
  150. package/dist-pkg/ui/menu-items.js +29 -0
  151. package/dist-pkg/ui/menu-nav.d.ts +40 -4
  152. package/dist-pkg/ui/menu-nav.js +132 -47
  153. package/dist-pkg/ui/panel-widgets.d.ts +34 -0
  154. package/dist-pkg/ui/panel-widgets.js +86 -0
  155. package/dist-pkg/ui/pause-icons.d.ts +30 -14
  156. package/dist-pkg/ui/pause-icons.js +106 -45
  157. package/dist-pkg/ui/scan-overlay.d.ts +3 -3
  158. package/dist-pkg/ui/scan-overlay.js +11 -3
  159. package/dist-pkg/ui/screen-text.d.ts +25 -0
  160. package/dist-pkg/ui/screen-text.js +152 -0
  161. package/dist-pkg/ui/session-clock.d.ts +32 -0
  162. package/dist-pkg/ui/session-clock.js +67 -0
  163. package/dist-pkg/ui/settings-aac.d.ts +3 -1
  164. package/dist-pkg/ui/settings-aac.js +32 -13
  165. package/dist-pkg/ui/settings-audio.d.ts +10 -5
  166. package/dist-pkg/ui/settings-audio.js +101 -35
  167. package/dist-pkg/ui/settings-controls.d.ts +0 -4
  168. package/dist-pkg/ui/settings-mobility.d.ts +3 -6
  169. package/dist-pkg/ui/settings-mobility.js +4 -46
  170. package/dist-pkg/ui/settings-motion.js +2 -2
  171. package/dist-pkg/ui/settings-panel.d.ts +10 -0
  172. package/dist-pkg/ui/settings-panel.js +25 -1
  173. package/dist-pkg/ui/settings-typo.d.ts +5 -6
  174. package/dist-pkg/ui/settings-typo.js +20 -11
  175. package/dist-pkg/ui/settings-visual.js +2 -2
  176. package/dist-pkg/ui/shell.d.ts +1 -3
  177. package/dist-pkg/ui/shell.js +8 -4
  178. package/dist-pkg/ui/title.d.ts +2 -11
  179. package/dist-pkg/ui/title.js +39 -6
  180. package/dist-pkg/ui/top-band.d.ts +5 -3
  181. package/dist-pkg/ui/top-band.js +21 -25
  182. package/dist-pkg/ui/typo-choices.d.ts +3 -3
  183. package/dist-pkg/ui/typo-choices.js +9 -8
  184. package/dist-pkg/ui/vlibras.d.ts +71 -27
  185. package/dist-pkg/ui/vlibras.js +116 -44
  186. package/dist-pkg/ui/voice-control.d.ts +23 -1
  187. package/dist-pkg/ui/voice-control.js +149 -16
  188. package/dist-pkg/ui/voice-settings.d.ts +2 -3
  189. package/dist-pkg/ui/voice-settings.js +53 -3
  190. package/dist-pkg/ui/where-the-child-is.js +2 -2
  191. package/docs/CREDITS.md +122 -10
  192. package/docs/LICENSES.md +36 -7
  193. package/package.json +34 -9
  194. package/scripts/check-cartridge.mjs +78 -0
  195. package/scripts/game-build.d.mts +25 -0
  196. package/scripts/game-build.mjs +144 -0
  197. package/scripts/heavy-into-the-delivery.mjs +284 -40
  198. package/scripts/libras-avatar.json +680 -0
  199. package/scripts/libras-avatar.mjs +246 -0
  200. package/scripts/libras-glosses/gloss.py +95 -0
  201. package/scripts/libras-glosses/pyproject.toml +32 -0
  202. package/scripts/libras-glosses/uv.lock +781 -0
  203. package/scripts/libras-glosses.mjs +351 -0
  204. package/scripts/licences/OFL-1.1.txt +86 -0
  205. package/scripts/licences/UFL-1.0.txt +96 -0
  206. package/scripts/licences/fonts.mjs +389 -0
  207. package/scripts/licences/third-party.mjs +35 -21
  208. package/app/public/vendor/fonts/bitter-var-ext.woff2 +0 -0
  209. package/app/public/vendor/fonts/bitter-var.woff2 +0 -0
  210. package/app/public/vendor/fonts/bodonimoda-var-ext.woff2 +0 -0
  211. package/app/public/vendor/fonts/bodonimoda-var.woff2 +0 -0
  212. package/app/public/vendor/fonts/cat-abril_fatface-400-ext.woff2 +0 -0
  213. package/app/public/vendor/fonts/cat-abril_fatface-400.woff2 +0 -0
  214. package/app/public/vendor/fonts/cat-adlam_display-400-ext.woff2 +0 -0
  215. package/app/public/vendor/fonts/cat-adlam_display-400.woff2 +0 -0
  216. package/app/public/vendor/fonts/cat-agu_display-400-ext.woff2 +0 -0
  217. package/app/public/vendor/fonts/cat-agu_display-400.woff2 +0 -0
  218. package/app/public/vendor/fonts/cat-alfa_slab_one-400-ext.woff2 +0 -0
  219. package/app/public/vendor/fonts/cat-alfa_slab_one-400.woff2 +0 -0
  220. package/app/public/vendor/fonts/cat-are_you_serious-400-ext.woff2 +0 -0
  221. package/app/public/vendor/fonts/cat-are_you_serious-400.woff2 +0 -0
  222. package/app/public/vendor/fonts/cat-asimovian-400-ext.woff2 +0 -0
  223. package/app/public/vendor/fonts/cat-asimovian-400.woff2 +0 -0
  224. package/app/public/vendor/fonts/cat-atkinson_hyperlegible_next-400-ext.woff2 +0 -0
  225. package/app/public/vendor/fonts/cat-atkinson_hyperlegible_next-400.woff2 +0 -0
  226. package/app/public/vendor/fonts/cat-bakbak_one-400-ext.woff2 +0 -0
  227. package/app/public/vendor/fonts/cat-bakbak_one-400.woff2 +0 -0
  228. package/app/public/vendor/fonts/cat-bangers-400-ext.woff2 +0 -0
  229. package/app/public/vendor/fonts/cat-bangers-400.woff2 +0 -0
  230. package/app/public/vendor/fonts/cat-barriecito-400-ext.woff2 +0 -0
  231. package/app/public/vendor/fonts/cat-barriecito-400.woff2 +0 -0
  232. package/app/public/vendor/fonts/cat-berkshire_swash-400-ext.woff2 +0 -0
  233. package/app/public/vendor/fonts/cat-berkshire_swash-400.woff2 +0 -0
  234. package/app/public/vendor/fonts/cat-bevan-400-ext.woff2 +0 -0
  235. package/app/public/vendor/fonts/cat-bevan-400.woff2 +0 -0
  236. package/app/public/vendor/fonts/cat-bitcount-400-ext.woff2 +0 -0
  237. package/app/public/vendor/fonts/cat-bitcount-400.woff2 +0 -0
  238. package/app/public/vendor/fonts/cat-bowlby_one_sc-400-ext.woff2 +0 -0
  239. package/app/public/vendor/fonts/cat-bowlby_one_sc-400.woff2 +0 -0
  240. package/app/public/vendor/fonts/cat-bungee_shade-400-ext.woff2 +0 -0
  241. package/app/public/vendor/fonts/cat-bungee_shade-400.woff2 +0 -0
  242. package/app/public/vendor/fonts/cat-charm-400-ext.woff2 +0 -0
  243. package/app/public/vendor/fonts/cat-charm-400.woff2 +0 -0
  244. package/app/public/vendor/fonts/cat-charm-700-ext.woff2 +0 -0
  245. package/app/public/vendor/fonts/cat-charm-700.woff2 +0 -0
  246. package/app/public/vendor/fonts/cat-cherry_bomb_one-400-ext.woff2 +0 -0
  247. package/app/public/vendor/fonts/cat-cherry_bomb_one-400.woff2 +0 -0
  248. package/app/public/vendor/fonts/cat-chokokutai-400-ext.woff2 +0 -0
  249. package/app/public/vendor/fonts/cat-chokokutai-400.woff2 +0 -0
  250. package/app/public/vendor/fonts/cat-chonburi-400-ext.woff2 +0 -0
  251. package/app/public/vendor/fonts/cat-chonburi-400.woff2 +0 -0
  252. package/app/public/vendor/fonts/cat-climate_crisis-400-ext.woff2 +0 -0
  253. package/app/public/vendor/fonts/cat-climate_crisis-400.woff2 +0 -0
  254. package/app/public/vendor/fonts/cat-cookie-400.woff2 +0 -0
  255. package/app/public/vendor/fonts/cat-dela_gothic_one-400-ext.woff2 +0 -0
  256. package/app/public/vendor/fonts/cat-dela_gothic_one-400.woff2 +0 -0
  257. package/app/public/vendor/fonts/cat-fascinate_inline-400-ext.woff2 +0 -0
  258. package/app/public/vendor/fonts/cat-fascinate_inline-400.woff2 +0 -0
  259. package/app/public/vendor/fonts/cat-ga_maamli-400-ext.woff2 +0 -0
  260. package/app/public/vendor/fonts/cat-ga_maamli-400.woff2 +0 -0
  261. package/app/public/vendor/fonts/cat-itim-400-ext.woff2 +0 -0
  262. package/app/public/vendor/fonts/cat-itim-400.woff2 +0 -0
  263. package/app/public/vendor/fonts/cat-jacquard_24-400-ext.woff2 +0 -0
  264. package/app/public/vendor/fonts/cat-jacquard_24-400.woff2 +0 -0
  265. package/app/public/vendor/fonts/cat-kablammo-400-ext.woff2 +0 -0
  266. package/app/public/vendor/fonts/cat-kablammo-400.woff2 +0 -0
  267. package/app/public/vendor/fonts/cat-kalam-400-ext.woff2 +0 -0
  268. package/app/public/vendor/fonts/cat-kalam-400.woff2 +0 -0
  269. package/app/public/vendor/fonts/cat-kalam-700-ext.woff2 +0 -0
  270. package/app/public/vendor/fonts/cat-kalam-700.woff2 +0 -0
  271. package/app/public/vendor/fonts/cat-katibeh-400-ext.woff2 +0 -0
  272. package/app/public/vendor/fonts/cat-katibeh-400.woff2 +0 -0
  273. package/app/public/vendor/fonts/cat-lemonada-400-ext.woff2 +0 -0
  274. package/app/public/vendor/fonts/cat-lemonada-400.woff2 +0 -0
  275. package/app/public/vendor/fonts/cat-lilita_one-400-ext.woff2 +0 -0
  276. package/app/public/vendor/fonts/cat-lilita_one-400.woff2 +0 -0
  277. package/app/public/vendor/fonts/cat-lobster-400-ext.woff2 +0 -0
  278. package/app/public/vendor/fonts/cat-lobster-400.woff2 +0 -0
  279. package/app/public/vendor/fonts/cat-luckiest_guy-400-ext.woff2 +0 -0
  280. package/app/public/vendor/fonts/cat-luckiest_guy-400.woff2 +0 -0
  281. package/app/public/vendor/fonts/cat-marhey-400-ext.woff2 +0 -0
  282. package/app/public/vendor/fonts/cat-marhey-400.woff2 +0 -0
  283. package/app/public/vendor/fonts/cat-modak-400-ext.woff2 +0 -0
  284. package/app/public/vendor/fonts/cat-modak-400.woff2 +0 -0
  285. package/app/public/vendor/fonts/cat-momo_signature-400-ext.woff2 +0 -0
  286. package/app/public/vendor/fonts/cat-momo_signature-400.woff2 +0 -0
  287. package/app/public/vendor/fonts/cat-monofett-400-ext.woff2 +0 -0
  288. package/app/public/vendor/fonts/cat-monofett-400.woff2 +0 -0
  289. package/app/public/vendor/fonts/cat-monomakh-400-ext.woff2 +0 -0
  290. package/app/public/vendor/fonts/cat-monomakh-400.woff2 +0 -0
  291. package/app/public/vendor/fonts/cat-monoton-400-ext.woff2 +0 -0
  292. package/app/public/vendor/fonts/cat-monoton-400.woff2 +0 -0
  293. package/app/public/vendor/fonts/cat-nerko_one-400-ext.woff2 +0 -0
  294. package/app/public/vendor/fonts/cat-nerko_one-400.woff2 +0 -0
  295. package/app/public/vendor/fonts/cat-noto_sans_adlam-400-ext.woff2 +0 -0
  296. package/app/public/vendor/fonts/cat-noto_sans_adlam-400.woff2 +0 -0
  297. package/app/public/vendor/fonts/cat-noto_sans_arabic-400-ext.woff2 +0 -0
  298. package/app/public/vendor/fonts/cat-noto_sans_arabic-400.woff2 +0 -0
  299. package/app/public/vendor/fonts/cat-noto_sans_devanagari-400-ext.woff2 +0 -0
  300. package/app/public/vendor/fonts/cat-noto_sans_devanagari-400.woff2 +0 -0
  301. package/app/public/vendor/fonts/cat-noto_sans_hebrew-400-ext.woff2 +0 -0
  302. package/app/public/vendor/fonts/cat-noto_sans_hebrew-400.woff2 +0 -0
  303. package/app/public/vendor/fonts/cat-noto_sans_jp-400-ext.woff2 +0 -0
  304. package/app/public/vendor/fonts/cat-noto_sans_jp-400.woff2 +0 -0
  305. package/app/public/vendor/fonts/cat-noto_sans_khmer-400-ext.woff2 +0 -0
  306. package/app/public/vendor/fonts/cat-noto_sans_khmer-400.woff2 +0 -0
  307. package/app/public/vendor/fonts/cat-noto_sans_kr-400-ext.woff2 +0 -0
  308. package/app/public/vendor/fonts/cat-noto_sans_kr-400.woff2 +0 -0
  309. package/app/public/vendor/fonts/cat-noto_sans_sc-400-ext.woff2 +0 -0
  310. package/app/public/vendor/fonts/cat-noto_sans_sc-400.woff2 +0 -0
  311. package/app/public/vendor/fonts/cat-noto_sans_thai-400-ext.woff2 +0 -0
  312. package/app/public/vendor/fonts/cat-noto_sans_thai-400.woff2 +0 -0
  313. package/app/public/vendor/fonts/cat-ole-400-ext.woff2 +0 -0
  314. package/app/public/vendor/fonts/cat-ole-400.woff2 +0 -0
  315. package/app/public/vendor/fonts/cat-pacifico-400-ext.woff2 +0 -0
  316. package/app/public/vendor/fonts/cat-pacifico-400.woff2 +0 -0
  317. package/app/public/vendor/fonts/cat-patrick_hand-400-ext.woff2 +0 -0
  318. package/app/public/vendor/fonts/cat-patrick_hand-400.woff2 +0 -0
  319. package/app/public/vendor/fonts/cat-petit_formal_script-400-ext.woff2 +0 -0
  320. package/app/public/vendor/fonts/cat-petit_formal_script-400.woff2 +0 -0
  321. package/app/public/vendor/fonts/cat-pixelify_sans-400-ext.woff2 +0 -0
  322. package/app/public/vendor/fonts/cat-pixelify_sans-400.woff2 +0 -0
  323. package/app/public/vendor/fonts/cat-plaster-400-ext.woff2 +0 -0
  324. package/app/public/vendor/fonts/cat-plaster-400.woff2 +0 -0
  325. package/app/public/vendor/fonts/cat-playwrite_ar_guides-400-0.woff2 +0 -0
  326. package/app/public/vendor/fonts/cat-playwrite_at-400-0.woff2 +0 -0
  327. package/app/public/vendor/fonts/cat-playwrite_at_guides-400-0.woff2 +0 -0
  328. package/app/public/vendor/fonts/cat-playwrite_au_nsw-400-0.woff2 +0 -0
  329. package/app/public/vendor/fonts/cat-playwrite_au_nsw_guides-400-0.woff2 +0 -0
  330. package/app/public/vendor/fonts/cat-playwrite_au_qld-400-0.woff2 +0 -0
  331. package/app/public/vendor/fonts/cat-playwrite_au_qld_guides-400-0.woff2 +0 -0
  332. package/app/public/vendor/fonts/cat-playwrite_au_sa-400-0.woff2 +0 -0
  333. package/app/public/vendor/fonts/cat-playwrite_au_sa_guides-400-0.woff2 +0 -0
  334. package/app/public/vendor/fonts/cat-playwrite_au_tas-400-0.woff2 +0 -0
  335. package/app/public/vendor/fonts/cat-playwrite_au_tas_guides-400-0.woff2 +0 -0
  336. package/app/public/vendor/fonts/cat-playwrite_au_vic-400-0.woff2 +0 -0
  337. package/app/public/vendor/fonts/cat-playwrite_au_vic_guides-400-0.woff2 +0 -0
  338. package/app/public/vendor/fonts/cat-playwrite_be_vlg-400-0.woff2 +0 -0
  339. package/app/public/vendor/fonts/cat-playwrite_be_vlg_guides-400-0.woff2 +0 -0
  340. package/app/public/vendor/fonts/cat-playwrite_be_wal-400-0.woff2 +0 -0
  341. package/app/public/vendor/fonts/cat-playwrite_be_wal_guides-400-0.woff2 +0 -0
  342. package/app/public/vendor/fonts/cat-playwrite_br_guides-400-0.woff2 +0 -0
  343. package/app/public/vendor/fonts/cat-playwrite_ca_guides-400-0.woff2 +0 -0
  344. package/app/public/vendor/fonts/cat-playwrite_cl_guides-400-0.woff2 +0 -0
  345. package/app/public/vendor/fonts/cat-playwrite_co_guides-400-0.woff2 +0 -0
  346. package/app/public/vendor/fonts/cat-playwrite_cu_guides-400-0.woff2 +0 -0
  347. package/app/public/vendor/fonts/cat-playwrite_cz-400-0.woff2 +0 -0
  348. package/app/public/vendor/fonts/cat-playwrite_cz_guides-400-0.woff2 +0 -0
  349. package/app/public/vendor/fonts/cat-playwrite_de_grund-400-0.woff2 +0 -0
  350. package/app/public/vendor/fonts/cat-playwrite_de_grund_guides-400-0.woff2 +0 -0
  351. package/app/public/vendor/fonts/cat-playwrite_de_la-400-0.woff2 +0 -0
  352. package/app/public/vendor/fonts/cat-playwrite_de_la_guides-400-0.woff2 +0 -0
  353. package/app/public/vendor/fonts/cat-playwrite_de_sas-400-0.woff2 +0 -0
  354. package/app/public/vendor/fonts/cat-playwrite_de_sas_guides-400-0.woff2 +0 -0
  355. package/app/public/vendor/fonts/cat-playwrite_de_va-400-0.woff2 +0 -0
  356. package/app/public/vendor/fonts/cat-playwrite_de_va_guides-400-0.woff2 +0 -0
  357. package/app/public/vendor/fonts/cat-playwrite_dk_loopet-400-0.woff2 +0 -0
  358. package/app/public/vendor/fonts/cat-playwrite_dk_loopet_guides-400-0.woff2 +0 -0
  359. package/app/public/vendor/fonts/cat-playwrite_dk_uloopet-400-0.woff2 +0 -0
  360. package/app/public/vendor/fonts/cat-playwrite_dk_uloopet_guides-400-0.woff2 +0 -0
  361. package/app/public/vendor/fonts/cat-playwrite_es_deco_guides-400-0.woff2 +0 -0
  362. package/app/public/vendor/fonts/cat-playwrite_es_guides-400-0.woff2 +0 -0
  363. package/app/public/vendor/fonts/cat-playwrite_fr_moderne-400-0.woff2 +0 -0
  364. package/app/public/vendor/fonts/cat-playwrite_fr_moderne_guides-400-0.woff2 +0 -0
  365. package/app/public/vendor/fonts/cat-playwrite_fr_trad-400-0.woff2 +0 -0
  366. package/app/public/vendor/fonts/cat-playwrite_fr_trad_guides-400-0.woff2 +0 -0
  367. package/app/public/vendor/fonts/cat-playwrite_gb_j_guides-400-0.woff2 +0 -0
  368. package/app/public/vendor/fonts/cat-playwrite_gb_s_guides-400-0.woff2 +0 -0
  369. package/app/public/vendor/fonts/cat-playwrite_hr-400-0.woff2 +0 -0
  370. package/app/public/vendor/fonts/cat-playwrite_hr_guides-400-0.woff2 +0 -0
  371. package/app/public/vendor/fonts/cat-playwrite_hr_lijeva-400-0.woff2 +0 -0
  372. package/app/public/vendor/fonts/cat-playwrite_hr_lijeva_guides-400-0.woff2 +0 -0
  373. package/app/public/vendor/fonts/cat-playwrite_hu-400-0.woff2 +0 -0
  374. package/app/public/vendor/fonts/cat-playwrite_hu_guides-400-0.woff2 +0 -0
  375. package/app/public/vendor/fonts/cat-playwrite_id-400-0.woff2 +0 -0
  376. package/app/public/vendor/fonts/cat-playwrite_id_guides-400-0.woff2 +0 -0
  377. package/app/public/vendor/fonts/cat-playwrite_ie-400-0.woff2 +0 -0
  378. package/app/public/vendor/fonts/cat-playwrite_ie_guides-400-0.woff2 +0 -0
  379. package/app/public/vendor/fonts/cat-playwrite_in-400-0.woff2 +0 -0
  380. package/app/public/vendor/fonts/cat-playwrite_in_guides-400-0.woff2 +0 -0
  381. package/app/public/vendor/fonts/cat-playwrite_is-400-0.woff2 +0 -0
  382. package/app/public/vendor/fonts/cat-playwrite_is_guides-400-0.woff2 +0 -0
  383. package/app/public/vendor/fonts/cat-playwrite_it_moderna-400-0.woff2 +0 -0
  384. package/app/public/vendor/fonts/cat-playwrite_it_moderna_guides-400-0.woff2 +0 -0
  385. package/app/public/vendor/fonts/cat-playwrite_it_trad-400-0.woff2 +0 -0
  386. package/app/public/vendor/fonts/cat-playwrite_it_trad_guides-400-0.woff2 +0 -0
  387. package/app/public/vendor/fonts/cat-playwrite_mx_guides-400-0.woff2 +0 -0
  388. package/app/public/vendor/fonts/cat-playwrite_ng_modern-400-0.woff2 +0 -0
  389. package/app/public/vendor/fonts/cat-playwrite_ng_modern_guides-400-0.woff2 +0 -0
  390. package/app/public/vendor/fonts/cat-playwrite_nl-400-0.woff2 +0 -0
  391. package/app/public/vendor/fonts/cat-playwrite_nl_guides-400-0.woff2 +0 -0
  392. package/app/public/vendor/fonts/cat-playwrite_no-400-0.woff2 +0 -0
  393. package/app/public/vendor/fonts/cat-playwrite_no_guides-400-0.woff2 +0 -0
  394. package/app/public/vendor/fonts/cat-playwrite_nz-400-0.woff2 +0 -0
  395. package/app/public/vendor/fonts/cat-playwrite_nz_basic-400-0.woff2 +0 -0
  396. package/app/public/vendor/fonts/cat-playwrite_nz_basic_guides-400-0.woff2 +0 -0
  397. package/app/public/vendor/fonts/cat-playwrite_nz_guides-400-0.woff2 +0 -0
  398. package/app/public/vendor/fonts/cat-playwrite_pe_guides-400-0.woff2 +0 -0
  399. package/app/public/vendor/fonts/cat-playwrite_pl-400-0.woff2 +0 -0
  400. package/app/public/vendor/fonts/cat-playwrite_pl_guides-400-0.woff2 +0 -0
  401. package/app/public/vendor/fonts/cat-playwrite_pt_guides-400-0.woff2 +0 -0
  402. package/app/public/vendor/fonts/cat-playwrite_ro-400-0.woff2 +0 -0
  403. package/app/public/vendor/fonts/cat-playwrite_ro_guides-400-0.woff2 +0 -0
  404. package/app/public/vendor/fonts/cat-playwrite_sk-400-0.woff2 +0 -0
  405. package/app/public/vendor/fonts/cat-playwrite_sk_guides-400-0.woff2 +0 -0
  406. package/app/public/vendor/fonts/cat-playwrite_tz-400-0.woff2 +0 -0
  407. package/app/public/vendor/fonts/cat-playwrite_tz_guides-400-0.woff2 +0 -0
  408. package/app/public/vendor/fonts/cat-playwrite_us_modern_guides-400-0.woff2 +0 -0
  409. package/app/public/vendor/fonts/cat-playwrite_us_trad_guides-400-0.woff2 +0 -0
  410. package/app/public/vendor/fonts/cat-playwrite_vn-400-0.woff2 +0 -0
  411. package/app/public/vendor/fonts/cat-playwrite_vn_guides-400-0.woff2 +0 -0
  412. package/app/public/vendor/fonts/cat-playwrite_za-400-0.woff2 +0 -0
  413. package/app/public/vendor/fonts/cat-playwrite_za_guides-400-0.woff2 +0 -0
  414. package/app/public/vendor/fonts/cat-potta_one-400-ext.woff2 +0 -0
  415. package/app/public/vendor/fonts/cat-potta_one-400.woff2 +0 -0
  416. package/app/public/vendor/fonts/cat-ranchers-400-ext.woff2 +0 -0
  417. package/app/public/vendor/fonts/cat-ranchers-400.woff2 +0 -0
  418. package/app/public/vendor/fonts/cat-ranga-400-ext.woff2 +0 -0
  419. package/app/public/vendor/fonts/cat-ranga-400.woff2 +0 -0
  420. package/app/public/vendor/fonts/cat-ranga-700-ext.woff2 +0 -0
  421. package/app/public/vendor/fonts/cat-ranga-700.woff2 +0 -0
  422. package/app/public/vendor/fonts/cat-risque-400-ext.woff2 +0 -0
  423. package/app/public/vendor/fonts/cat-risque-400.woff2 +0 -0
  424. package/app/public/vendor/fonts/cat-rowdies-400-ext.woff2 +0 -0
  425. package/app/public/vendor/fonts/cat-rowdies-400.woff2 +0 -0
  426. package/app/public/vendor/fonts/cat-rowdies-700-ext.woff2 +0 -0
  427. package/app/public/vendor/fonts/cat-rowdies-700.woff2 +0 -0
  428. package/app/public/vendor/fonts/cat-ruge_boogie-400-ext.woff2 +0 -0
  429. package/app/public/vendor/fonts/cat-ruge_boogie-400.woff2 +0 -0
  430. package/app/public/vendor/fonts/cat-ruslan_display-400-ext.woff2 +0 -0
  431. package/app/public/vendor/fonts/cat-ruslan_display-400.woff2 +0 -0
  432. package/app/public/vendor/fonts/cat-sacramento-400-ext.woff2 +0 -0
  433. package/app/public/vendor/fonts/cat-sacramento-400.woff2 +0 -0
  434. package/app/public/vendor/fonts/cat-sancreek-400-ext.woff2 +0 -0
  435. package/app/public/vendor/fonts/cat-sancreek-400.woff2 +0 -0
  436. package/app/public/vendor/fonts/cat-sankofa_display-400-ext.woff2 +0 -0
  437. package/app/public/vendor/fonts/cat-sankofa_display-400.woff2 +0 -0
  438. package/app/public/vendor/fonts/cat-sedgwick_ave_display-400-ext.woff2 +0 -0
  439. package/app/public/vendor/fonts/cat-sedgwick_ave_display-400.woff2 +0 -0
  440. package/app/public/vendor/fonts/cat-shantell_sans-400-ext.woff2 +0 -0
  441. package/app/public/vendor/fonts/cat-shantell_sans-400.woff2 +0 -0
  442. package/app/public/vendor/fonts/cat-smokum-400-ext.woff2 +0 -0
  443. package/app/public/vendor/fonts/cat-smokum-400.woff2 +0 -0
  444. package/app/public/vendor/fonts/cat-solitreo-400-ext.woff2 +0 -0
  445. package/app/public/vendor/fonts/cat-solitreo-400.woff2 +0 -0
  446. package/app/public/vendor/fonts/cat-spicy_rice-400-ext.woff2 +0 -0
  447. package/app/public/vendor/fonts/cat-spicy_rice-400.woff2 +0 -0
  448. package/app/public/vendor/fonts/cat-sriracha-400-ext.woff2 +0 -0
  449. package/app/public/vendor/fonts/cat-sriracha-400.woff2 +0 -0
  450. package/app/public/vendor/fonts/cat-srisakdi-400-ext.woff2 +0 -0
  451. package/app/public/vendor/fonts/cat-srisakdi-400.woff2 +0 -0
  452. package/app/public/vendor/fonts/cat-srisakdi-700-ext.woff2 +0 -0
  453. package/app/public/vendor/fonts/cat-srisakdi-700.woff2 +0 -0
  454. package/app/public/vendor/fonts/cat-stix_two_math-400-0.woff2 +0 -0
  455. package/app/public/vendor/fonts/cat-tillana-400-ext.woff2 +0 -0
  456. package/app/public/vendor/fonts/cat-tillana-400.woff2 +0 -0
  457. package/app/public/vendor/fonts/cat-tillana-700-ext.woff2 +0 -0
  458. package/app/public/vendor/fonts/cat-tillana-700.woff2 +0 -0
  459. package/app/public/vendor/fonts/cat-titan_one-400-ext.woff2 +0 -0
  460. package/app/public/vendor/fonts/cat-titan_one-400.woff2 +0 -0
  461. package/app/public/vendor/fonts/cat-yatra_one-400-ext.woff2 +0 -0
  462. package/app/public/vendor/fonts/cat-yatra_one-400.woff2 +0 -0
  463. package/app/public/vendor/fonts/cat-yomogi-400-ext.woff2 +0 -0
  464. package/app/public/vendor/fonts/cat-yomogi-400.woff2 +0 -0
  465. package/app/public/vendor/fonts/dmserifdisplay-400-ext.woff2 +0 -0
  466. package/app/public/vendor/fonts/dmserifdisplay-400.woff2 +0 -0
  467. package/app/public/vendor/fonts/domine-var-ext.woff2 +0 -0
  468. package/app/public/vendor/fonts/domine-var.woff2 +0 -0
  469. package/app/public/vendor/fonts/fondamento-400-ext.woff2 +0 -0
  470. package/app/public/vendor/fonts/fondamento-400.woff2 +0 -0
  471. package/app/public/vendor/fonts/fraunces-var-ext.woff2 +0 -0
  472. package/app/public/vendor/fonts/fraunces-var.woff2 +0 -0
  473. package/app/public/vendor/fonts/fredoka-var-ext.woff2 +0 -0
  474. package/app/public/vendor/fonts/fredoka-var.woff2 +0 -0
  475. package/app/public/vendor/fonts/inter-400.woff2 +0 -0
  476. package/app/public/vendor/fonts/inter-700.woff2 +0 -0
  477. package/app/public/vendor/fonts/jakarta-var-ext.woff2 +0 -0
  478. package/app/public/vendor/fonts/jakarta-var.woff2 +0 -0
  479. package/app/public/vendor/fonts/lato-400.woff2 +0 -0
  480. package/app/public/vendor/fonts/lato-700.woff2 +0 -0
  481. package/app/public/vendor/fonts/literata-400.woff2 +0 -0
  482. package/app/public/vendor/fonts/literata-700.woff2 +0 -0
  483. package/app/public/vendor/fonts/lora-var-ext.woff2 +0 -0
  484. package/app/public/vendor/fonts/lora-var.woff2 +0 -0
  485. package/app/public/vendor/fonts/merriweather-var-ext.woff2 +0 -0
  486. package/app/public/vendor/fonts/merriweather-var.woff2 +0 -0
  487. package/app/public/vendor/fonts/newsreader-400.woff2 +0 -0
  488. package/app/public/vendor/fonts/newsreader-700.woff2 +0 -0
  489. package/app/public/vendor/fonts/notosans-var-ext.woff2 +0 -0
  490. package/app/public/vendor/fonts/notosans-var.woff2 +0 -0
  491. package/app/public/vendor/fonts/nunito-var-ext.woff2 +0 -0
  492. package/app/public/vendor/fonts/nunito-var.woff2 +0 -0
  493. package/app/public/vendor/fonts/opendyslexic-400.woff2 +0 -0
  494. package/app/public/vendor/fonts/opensans-400.woff2 +0 -0
  495. package/app/public/vendor/fonts/opensans-700.woff2 +0 -0
  496. package/app/public/vendor/fonts/pinyon-400.woff2 +0 -0
  497. package/app/public/vendor/fonts/playfair-var-ext.woff2 +0 -0
  498. package/app/public/vendor/fonts/playfair-var.woff2 +0 -0
  499. package/app/public/vendor/fonts/pressstart-400.woff2 +0 -0
  500. package/app/public/vendor/fonts/quattro-400.woff2 +0 -0
  501. package/app/public/vendor/fonts/quattro-700.woff2 +0 -0
  502. package/app/public/vendor/fonts/quicksand-var-ext.woff2 +0 -0
  503. package/app/public/vendor/fonts/quicksand-var.woff2 +0 -0
  504. package/app/public/vendor/fonts/robotoflex-var-ext.woff2 +0 -0
  505. package/app/public/vendor/fonts/robotoflex-var.woff2 +0 -0
  506. package/app/public/vendor/fonts/sora-var-ext.woff2 +0 -0
  507. package/app/public/vendor/fonts/sora-var.woff2 +0 -0
  508. package/app/public/vendor/fonts/sourcesans-400.woff2 +0 -0
  509. package/app/public/vendor/fonts/sourcesans-700.woff2 +0 -0
  510. package/app/public/vendor/fonts/sourceserif-400.woff2 +0 -0
  511. package/app/public/vendor/fonts/sourceserif-700.woff2 +0 -0
  512. package/app/public/vendor/fonts/spacegrotesk-var-ext.woff2 +0 -0
  513. package/app/public/vendor/fonts/spacegrotesk-var.woff2 +0 -0
  514. package/app/public/vendor/fonts/spectral-400-ext.woff2 +0 -0
  515. package/app/public/vendor/fonts/spectral-400.woff2 +0 -0
  516. package/app/public/vendor/fonts/spectral-700-ext.woff2 +0 -0
  517. package/app/public/vendor/fonts/spectral-700.woff2 +0 -0
  518. package/app/public/vendor/fonts/teachers-var-ext.woff2 +0 -0
  519. package/app/public/vendor/fonts/teachers-var.woff2 +0 -0
  520. package/app/public/vendor/fonts/ubuntu-400-ext.woff2 +0 -0
  521. package/app/public/vendor/fonts/ubuntu-400.woff2 +0 -0
  522. package/app/public/vendor/fonts/ubuntu-700-ext.woff2 +0 -0
  523. package/app/public/vendor/fonts/ubuntu-700.woff2 +0 -0
  524. package/app/public/vendor/fonts/ufmag-400.woff2 +0 -0
  525. package/dist-pkg/platform/guide-intensity.d.ts +0 -39
  526. package/dist-pkg/platform/guide-intensity.js +0 -71
  527. package/dist-pkg/ui/latch-refusal.d.ts +0 -33
  528. package/dist-pkg/ui/latch-refusal.js +0 -60
package/README.md CHANGED
@@ -56,6 +56,37 @@ npm run preview # serves the built dist/
56
56
  npm test # Vitest tests (node + browser via Playwright); npm run test:node = the logic only
57
57
  ```
58
58
 
59
+ ## Building a game on the engine — the two targets (ADR-0253)
60
+
61
+ A game is built twice from one source (ADR-0140): the **APP**, its standalone PWA with the engine bundled — the route for
62
+ developing, testing, auditing and demonstrating that repository, never for delivering to children — and the **CARTRIDGE**,
63
+ what the platform installs, with the engine and the shared render libraries (`pixi.js`, `zdog`) left external. **The engine
64
+ builds the cartridge; the game declares it once**, by wrapping the Vite config it already has:
65
+
66
+ ```ts
67
+ // vite.config.ts of a game
68
+ import { defineGameBuild } from '@the-inclusionist/engine/build';
69
+ import { VitePWA } from 'vite-plugin-pwa';
70
+
71
+ export default defineGameBuild({
72
+ cartridge: 'src/index.ts', // the entry, relative to the repository root
73
+ config: { root: 'app', plugins: [VitePWA({ /* the game's manifest */ })], build: { outDir: '../dist' } },
74
+ });
75
+ ```
76
+
77
+ - `vite build` → the **app**: the game's `config`, untouched.
78
+ - `vite build --mode cartridge` → **`dist-lib/cartridge.js`** and **`dist-lib/cartridge.d.ts`** (types emitted with the game's
79
+ own `tsconfig.json`, for the entry's import graph only). The game's plugins, `define` and `resolve` still apply; the engine
80
+ lays over them what a cartridge must be: `@the-inclusionist/engine`, `pixi.js` and `zdog` external as prefixes, no `public/`
81
+ (a cartridge declares no delivery, ADR-0117) and no service worker (the PWA plugin is dropped).
82
+ - The entry's **default export is the cartridge** of ADR-0139 §2: `{ slug, declaration, hooks, create(ctx) }`. Nothing runs on
83
+ import.
84
+ - **`npx inclusionist-check-cartridge`** imports `dist-lib/cartridge.js` in Node and runs on it the refusals `createGame` and
85
+ `mount()` apply at boot (`cartridgeRefusals`), one line per problem.
86
+
87
+ The shared CI a game calls (`.github/workflows/game-ci.yml`) runs both builds and the checker, **required**: a game without a
88
+ cartridge target is red until it adopts this build. The migration is in `docs/6-DevOps-SRE/Breaking-Changes.md`.
89
+
59
90
  ## CI/CD
60
91
 
61
92
  - **CI** — **GitHub Actions** (`.github/workflows/ci.yml`), on every push to `main` and on every pull request.
@@ -64,7 +95,7 @@ npm test # Vitest tests (node + browser via Playwright); npm run test:
64
95
  | job | what it blocks |
65
96
  |---|---|
66
97
  | `gate` | `npm audit --omit=dev`, typecheck, Vitest (node + browser), build, precache budget |
67
- | `adr` | the records' validator — eight checks, among them the bidirectional supersession pointer. The records live in `the-inclusionist-docs`, so the job is dormant (a warning, not a pass) until the `DOCS_READ_TOKEN` secret exists |
98
+ | `adr` | the records' validator — eight checks, among them the bidirectional supersession pointer. The engine's records live here, in `docs/2-Architecture/adr/` (ADR-0242), and are checked on every push; what crosses into `the-inclusionist-docs` is opened only with the `DOCS_READ_TOKEN` secret, and until it exists those steps are a warning, not a pass |
68
99
  | `a11y` | axe against the **served** app, not against the source |
69
100
  | `dco` | `Signed-off-by` on every PR (ADR-0078); the maintainer's pushes are left out |
70
101
  | `secrets` | **gitleaks** over the WHOLE history (`fetch-depth: 0`), with `--redact` |
package/app/css/style.css CHANGED
@@ -107,11 +107,16 @@ body.at-title #game-hud,body.at-title .start-tips,body.at-title .hud{display:non
107
107
  .title-wrap{position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:center;max-height:none}
108
108
  .title-legend{position:absolute;left:0;right:0;bottom:8px} /* FOOTER, like the pause legend */
109
109
  .title-menu{display:flex;flex-direction:column;gap:.35em;align-items:stretch;padding:2px;width:13em;margin:0 auto} /* a fixed, LEAN width */
110
+ /* NO MENU LEAVES THE CANVAS (ADR-0130 rule 5): every opening menu scrolls when its items outgrow the frame — a RULE of the
111
+ class, so a menu a game adds inherits it. The main menu had no scroll: with twenty items it ran 208 px above and 288 px
112
+ below a 360 px stage, and its first and last items could not be reached. */
113
+ .title-menu{max-height:72%;overflow-y:auto;overflow-x:hidden}
110
114
  .title-menu[hidden]{display:none}
111
- /* The main menu at TWICE the base width (13em → 26em): at 13em the labels wrapped onto TWO lines, and a two-line
112
- button changes height with the language — the same screen with one geometry in pt-BR and another in Spanish.
113
- Whoever finds their way by alignment loses the reference; whoever listens never knew it existed. */
114
- #tm-main{width:26em}
115
+ /* THE WIDTH FOLLOWS THE WIDEST ITEM (ADR-0130 rule 6, issue #134). A fixed width is a translation defect that only
116
+ shows after translation: a label that fits in Portuguese wraps onto two lines, or is cut, in a longer language — and a
117
+ two-line button changes height with the language. `fit-content` is the widest label's own width, capped by the room
118
+ there is, so a label wraps only when the frame itself is narrower than it and the menu never leaves the canvas. */
119
+ #tm-main{width:fit-content}
115
120
  /* ===================== THE OPENING SUBMENUS: A VERTICAL LIST THAT SCROLLS (ADR-0044) =====================
116
121
  They were two-column GRIDS, and the arrow moves in DOM order: “down” jumped to the right-hand column, across the
117
122
  screen. The ring of item 1 was already right in the code (`nextTitleIndex` wraps around) — it was the LAYOUT that
@@ -123,7 +128,7 @@ body.at-title #game-hud,body.at-title .start-tips,body.at-title .hud{display:non
123
128
 
124
129
  The panel is OPAQUE for the same reason as the pause veil: the attract mode runs behind the opening, and text over a
125
130
  changing frame has whatever contrast the frame allows — an average of luck, not a guarantee. */
126
- #tm-alf,#tm-mat,#tm-tab,#tm-fr,#tm-cen{width:26em;max-height:72%;overflow-y:auto;overflow-x:hidden;background:var(--bg-solid);border-radius:10px;padding:.5em .7em}
131
+ #tm-alf,#tm-mat,#tm-tab,#tm-fr,#tm-cen{width:fit-content;max-height:72%;overflow-y:auto;overflow-x:hidden;background:var(--bg-solid);border-radius:10px;padding:.5em .7em}
127
132
  /* The submenu's title STICKS to the top: in a scrolling list, a heading that scrolls away takes with it the only
128
133
  “where am I” cue that someone reading with residual vision has. */
129
134
  #tm-alf .tm-title,#tm-mat .tm-title,#tm-tab .tm-title,#tm-fr .tm-title,#tm-cen .tm-title{position:sticky;top:-.5em;z-index:1;background:var(--bg-solid);padding:.35em 0 .25em;margin:0}
@@ -180,6 +185,9 @@ body.at-title #game-hud,body.at-title .start-tips,body.at-title .hud{display:non
180
185
  #title-icons .pause-icons-cap{position:absolute;top:100%;line-height:1.25;left:50%;transform:translateX(-50%);margin:0;text-align:center;font-size:1em;color:#f6f5f0;pointer-events:none;white-space:nowrap;min-height:0;padding:calc(var(--ui-fs,16px) * .2) calc(var(--ui-fs,16px) * .6)}
181
186
  /* the padding stays when empty: the room `createGame` reserves under the bar reads it (issue #160) */
182
187
  #title-icons .pause-icons-cap:not(:empty){background:rgba(8,8,16,.92);border-radius:8px}
188
+ /* While a name shows, the bar rises over the HUD so the name covers the mission under it, not the other way round (ADR-0239
189
+ erratum: the name is momentary, and it is what the child is pointing at). Only then: at rest the bar keeps its layer. */
190
+ #title-icons:has(.pause-icons-cap:not(:empty)),.screen-a11y:has(.pause-icons-cap:not(:empty)){z-index:13}
183
191
  /* Player-count selector = ONE button ("◀ No. of players: X ▶"); the side clicked decides +1/−1 */
184
192
  #np-btn{letter-spacing:var(--ls)}
185
193
  #np-btn #np-n{display:inline-block;min-width:1.1em;text-align:center}
@@ -263,6 +271,18 @@ body:not(.dbg) .topbar{display:none} /* the PAGE title only under ?debug=true (t
263
271
  six items fitted and its card shrank to them, 46 px shorter than the submenu at 640×360 (measured); it now holds the whole
264
272
  height too, its items from the top, as a panel's rows are. */
265
273
  .screen-pause .pause-card{height:100%;box-sizing:border-box}
274
+ /* THE EDGE MARGIN (interface log 2026-09-26): the card's CONTENT starts at the margin — its 2 px border just above it, no
275
+ padding under the border — so neither its title nor an item scrolled up under its top edge comes nearer the region's edge
276
+ than the margin (a padding inside the card would not do: a scrolled list shows through its own padding). 📏 The card had
277
+ 3 px to spare at 640×360 (pause-target-44px); the border and the old .25rem padding give back what the margin takes. */
278
+ .screen-pause{padding-top:calc(var(--margem-borda,8px) - 2px)}
279
+ .screen-pause .pause-card{padding-top:0}
280
+ /* THE CARD RUNS UNDER THE BUTTON LEGEND AT THE FOOT OF THE SCREEN, as a panel runs under its explanation (issue #134): the
281
+ room at its end and the scroll padding let its LAST item, and the one under the cursor, come to rest above the band —
282
+ and above the HUD row under it (`--rodape-h`), which is drawn over the card too. Measured at 640×360 before: «Sair do jogo»
283
+ at 288–332 px under a legend at 313–342, a third of it covered. */
284
+ .screen-pause .pause-card{scroll-padding-bottom:calc(var(--rodape-h,0px) + var(--footer-band-h,50px))}
285
+ .screen-pause .pause-card::after{content:"";display:block;height:calc(var(--rodape-h,0px) + var(--footer-band-h,50px))}
266
286
  .screen-pause .pause-card h2{font-size:1em;line-height:1.25;margin:0 0 .1rem}
267
287
  .screen-pause .pause-menu{gap:.3rem}
268
288
  /* The per-player frame tightens the PADDING, never the minimum height: the tight frame is the one of a game with four
@@ -549,7 +569,10 @@ main{flex:1;display:flex;flex-direction:column;width:100%;margin:0 auto;padding:
549
569
  /* THE QUIZ STARTS BELOW THE QUICK BAR (ADR-0148). The engine declares `--barra-a11y-h` on `#game-region`; the bar sits
550
570
  10 px from the top (`#title-icons`), and the statement was drawn behind it — measured on a screenshot of the Dev's. */
551
571
  /* Since issue #160 the variable is the WHOLE room (the bar's offset, the bar, the icon name line and a light gap): read as is. */
552
- .quiz-app{padding-top:var(--barra-a11y-h,0px);padding-bottom:var(--rodape-h,0px)} /* the footer band is its own zone (ADR-0164) */
572
+ .quiz-app{padding-top:var(--barra-a11y-h,0px);padding-bottom:var(--rodape-h,0px)} /* the HUD row is always there; the footer bands overlay (ADR-0239 erratum) */
573
+ /* THE EDGE MARGIN (interface log 2026-09-26; `--margem-borda`, written by `ui/layout` from k): the Dev, «os textos estão tocando
574
+ na borda do jogo». The sides get it here; the top is the quick bar's room and the bottom the HUD row's, which keeps its own. */
575
+ .quiz-app{padding-left:var(--margem-borda,8px);padding-right:var(--margem-borda,8px)}
553
576
  /* ADR-0163: at 640×360 the bar, the statement, four 44 px options and the footer band had 404 px to fit in 360 (measured).
554
577
  The spacing goes, not the targets or the 16 px floor: the statement keeps its size on a 1.25 line and no outer margins. */
555
578
  .quiz-pergunta{margin:0 0 calc(.25rem * var(--espaco-fixo,1));line-height:1.25}
@@ -587,27 +610,63 @@ main{flex:1;display:flex;flex-direction:column;width:100%;margin:0 auto;padding:
587
610
  lines of text. The Dev saw a three-line explanation in the middle of the screen, over a quiz option, with outlined
588
611
  letters and no background. White on black at .82 over pure white composes to ~13:1 (the panel footer's arithmetic).
589
612
  With the quick-pause legend also showing, each keeps ONE line, so the band never grows past two.
590
- `--rodape-h` is the room it takes, declared so a game's workspace can end above it (the `--barra-a11y-h` model). */
591
- #game-region{--rodape-h:calc(var(--ui-fs,16px) * 2.6 + 8px)}
613
+ `--footer-band-h` is the room those two lines take: the engine's panels keep it free under their last row.
614
+ 🔴 `--rodape-h` is what a GAME leaves free at the bottom, and since ADR-0239's erratum it is the HUD ROW's room only — its
615
+ height plus how far the pad lifts it. The caption, the legend and the explanation are MOMENTARY and overlay the workspace
616
+ while they show: «a legenda é momentânea» (the Dev). Counting them made a band that is off most of the time take the
617
+ game's floor for good (the demo quiz lost its last option at 640×360). */
618
+ #game-region{--footer-band-h:calc(var(--ui-fs,16px) * 2.6 + 4px + var(--margem-borda,8px));--rodape-h:calc(var(--hud-row-bottom,0px) + var(--hud-row-h,0px))}
592
619
  /* ADR-0163 rule 3: the region's text grows with the scale the engine forces — 16 px at 640×360, 32 at 1280×720 — times the
593
620
  communication cycle's type scale, which the root size also carries. Without it everything in the region read the ROOT
594
621
  16 px: measured at 1280×720, quiz options at 16 px and the bar's emoji at 20 px under a `--ui-fs` of 32. */
595
622
  #game-region{font-size:calc(var(--ui-fs,16px) * var(--fonte-escala,1))}
596
623
  /* ADR-0164 as the Dev corrected it: the EXPLANATION stands on a full-width dark band at the lowest edge (rule 2, rule 4);
597
624
  the BUTTON LEGEND runs the full width with NO band, a dark background only behind each «name: function» (rule 3), and
598
- sits above the explanation. The column itself paints nothing. Padding adds to 8 px, so two lines fit `--rodape-h`. */
599
- /* THE HUD the engine mounts from a cartridge's `hud` (ADR-0168, ADR-0175; issue #162): two columns level with the quick bar —
600
- points and mission top left, power top right — each narrowed by the root so it never reaches the bar. State on dark chips, like the
601
- icon's name; no pointer events, so a finger passes through to the game. */
625
+ sits above the explanation. The column itself paints nothing. Padding adds to 8 px, so two lines fit `--footer-band-h`. */
626
+ /* THE PAD'S SHOULDER COLUMNS, as what else stands on the region must keep clear of them: while the pad shows them they own the
627
+ TOP CORNERS (ADR-0160; drawn only when the game names them, ADR-0162), and they are placed for REACH — a thumb finds a corner
628
+ without looking — so where they and anything else meet, the other thing moves. A shoulder is a `.touch-btn`, 56 px with the
629
+ target floor under it; a column holds one or two, 6 px apart. `--shoulders-*-reach` is how far down a column reaches, the edge
630
+ margin under it counted: 0 while that corner holds none. */
631
+ #game-region,.game-region{--shoulder-size:max(56px,var(--alvo-min,44px));--shoulders-left-reach:0px;--shoulders-right-reach:0px}
632
+ #game-region:has(#touch-controls:not([hidden]) > .touch-ombros--esq),.game-region:has(#touch-controls:not([hidden]) > .touch-ombros--esq){
633
+ --shoulders-left-reach:calc(var(--margem-borda,8px) * 2 + var(--shoulder-size))}
634
+ #game-region:has(#touch-controls:not([hidden]) > .touch-ombros--esq > :nth-child(2)),.game-region:has(#touch-controls:not([hidden]) > .touch-ombros--esq > :nth-child(2)){
635
+ --shoulders-left-reach:calc(var(--margem-borda,8px) * 2 + var(--shoulder-size) * 2 + 6px)}
636
+ #game-region:has(#touch-controls:not([hidden]) > .touch-ombros--dir),.game-region:has(#touch-controls:not([hidden]) > .touch-ombros--dir){
637
+ --shoulders-right-reach:calc(var(--margem-borda,8px) * 2 + var(--shoulder-size))}
638
+ #game-region:has(#touch-controls:not([hidden]) > .touch-ombros--dir > :nth-child(2)),.game-region:has(#touch-controls:not([hidden]) > .touch-ombros--dir > :nth-child(2)){
639
+ --shoulders-right-reach:calc(var(--margem-borda,8px) * 2 + var(--shoulder-size) * 2 + 6px)}
640
+ /* THE HUD the engine mounts from a cartridge's `hud` (ADR-0168; issue #162): the mission at the top centre, just under the quick
641
+ bar, and the rest in the HUD row at the bottom (ADR-0239 and its erratum; the row's rules are below). Where a caller mounts the
642
+ bands with no row they stand on the region: the points and the power down the right edge, the learning bars at the bottom
643
+ centre. State on dark chips, like the icon's name; no pointer events, so a finger passes through to the game.
644
+ 📌 What it keeps clear of: the quick bar, which owns the top (ADR-0239's driver: «the top belongs to the quick accessibility
645
+ bar; the HUD no longer shares it») — `--barra-a11y-h` is the band `ui/top-band` measures —, the pad's shoulder columns (above),
646
+ and the pad itself, which the row stands above (ADR-0239 §6). */
647
+ /* Where the bands have no row, the right edge's stack (the points, the power under them) starts under the bar's band and under
648
+ the right shoulders — whichever reaches lower — and never nearer the top than the edge margin. */
649
+ #game-region,.game-region{--hud-corner-top:max(var(--margem-borda,8px),var(--barra-a11y-h,0px),var(--shoulders-right-reach))}
602
650
  .hud-faixa{position:absolute;z-index:12;margin:0;pointer-events:none;font-size:var(--ui-fs,16px);line-height:1.25;display:flex;gap:2px}
603
651
  .hud-faixa[hidden]{display:none}
604
- .hud-esquerda{top:0;left:4px;flex-direction:column;align-items:flex-start}
605
- .hud-direita{top:0;right:4px;flex-direction:column;align-items:flex-end;text-align:right}
606
- /* The learning bars (ADR-0049 §5): one ten-segment bar per skill, side by side, centred at the bottom — under the footer
607
- column, which comes later in the region on the same layer and covers them. Okabe-Ito colours, and a second cue beside
608
- each, so no state is told by colour alone (WCAG 1.4.1): green carries a dot, red stripes, an empty slot only its outline;
609
- a purple bar a ▲, an orange one a ▼. */
610
- .hud-aprendizagem{left:50%;bottom:4px;transform:translateX(-50%);flex-direction:row;gap:.75em}
652
+ /* The MISSION sits at the TOP CENTRE, just under the quick bar (ADR-0239 erratum): `ui/top-band` writes its `top` from the
653
+ bar's box. The class keeps its old name — a page-surface name is not renamed in passing. The bar's momentary name line is
654
+ drawn over it while a name shows (the Dev: «a legenda é momentânea, a escrita da missão aparece o tempo todo»). */
655
+ /* THE EDGE MARGIN (interface log 2026-09-26) where a caller mounts the bands on the region, with no row: `--margem-borda` from
656
+ the side, and from the top the same place under the bar the root's mission takes (`--hud-mission-top`, which `ui/top-band`
657
+ writes; 0 with no bar) — at the margin it stood behind the bar's icons. Where the root mounts the mission, `ui/top-band`
658
+ writes that `top` on the element itself. */
659
+ .hud-esquerda{top:max(var(--margem-borda,8px),var(--hud-mission-top,0px));left:50%;transform:translateX(-50%);max-width:calc(100% - 2 * var(--margem-borda,8px));flex-direction:column;align-items:center;text-align:center}
660
+ .hud-direita{top:var(--hud-corner-top,8px);right:var(--margem-borda,8px);flex-direction:column;align-items:flex-end;text-align:right}
661
+ /* The learning bars (ADR-0049 §5): one ten-segment bar per skill, one skill a line as in the row (ADR-0239 §1), centred at the
662
+ bottom — under the footer column, which comes later in the region on the same layer and covers them. Okabe-Ito colours, and
663
+ a second cue beside each, so no state is told by colour alone (WCAG 1.4.1): green carries a dot, red stripes, an empty slot
664
+ only its outline; a purple bar a ▲, an orange one a ▼. 📏 Side by side (ADR-0168 §3's footer, superseded), three bars were
665
+ 501 px wide at 640×360 and, lifted above the pad, ran into the points and the power under the right shoulders. */
666
+ .hud-aprendizagem{left:50%;bottom:var(--margem-borda,8px);transform:translateX(-50%);flex-direction:column;align-items:center;gap:2px}
667
+ /* …and with no row, ABOVE the on-screen pad while it shows, as the row would stand (ADR-0239 §6): `--hud-row-bottom` is how high
668
+ the pad's lower parts reach (`ui/hud-row`). 📏 At the lower edge they stood under the START and SELECT pills. */
669
+ .game-region > .hud-aprendizagem,#game-region > .hud-aprendizagem{bottom:calc(var(--hud-row-bottom,0px) + var(--margem-borda,8px))}
611
670
  /* The explanation band is 82% opaque: the bars showed through under its words. While it shows they are not drawn at all —
612
671
  the explanation has priority (ADR-0168 §3), and a segment behind a letter is noise for the child reading it. */
613
672
  .game-region:has(.barra-explicacao:not([hidden])) .hud-aprendizagem,#game-region:has(.barra-explicacao:not([hidden])) .hud-aprendizagem{visibility:hidden}
@@ -623,22 +682,110 @@ main{flex:1;display:flex;flex-direction:column;width:100%;margin:0 auto;padding:
623
682
  .hud-barra[data-cor="roxa"]::after{content:"▲"}
624
683
  .hud-barra[data-cor="laranja"]::after{content:"▼"}
625
684
  .hud-numero{margin:0;padding:0 .3em;color:#f6f5f0;background:rgba(8,8,16,.92);border-radius:8px;max-width:100%;overflow-wrap:anywhere}
685
+ /* ===================== THE HUD ROW AT THE BOTTOM (ADR-0239; issue #94) =====================
686
+ One row along the lower edge, left to right: the learning bars · the session clock, centred · the power over the score ·
687
+ the game's map. `ui/hud-row` writes where it stands (`--hud-row-bottom`: above the on-screen pad while it shows) and its
688
+ height (`--hud-row-h`, which the footer and `--rodape-h` read — the row is all a game must leave free). Three columns of which the outer two are equal, so the
689
+ clock is at the true centre; `minmax(0,…)` so a long cell never pushes it off. No pointer events: a finger passes through
690
+ to the game. Empty — no clock, no band, no map — it is not drawn. */
691
+ .hud-row{position:absolute;left:0;right:0;bottom:var(--hud-row-bottom,0px);z-index:12;pointer-events:none;box-sizing:border-box;
692
+ display:grid;grid-template-columns:minmax(0,1fr) auto minmax(0,1fr);align-items:end;column-gap:8px;
693
+ padding:0 var(--margem-borda,8px) var(--margem-borda,8px); /* the edge margin (interface log 2026-09-26) */
694
+ font-family:var(--font);font-size:var(--ui-fs,16px)}
695
+ /* …and while the pad shows a shoulder column on a side, the row's cells stand clear of it on that side: lifted above the pad at
696
+ 640×360 the row reaches up to the shoulders (the pad's directional is 179 px tall), and they keep their corner for reach
697
+ (ADR-0160). 📏 The power over the score stood 5 px into R1. */
698
+ #game-region:has(#touch-controls:not([hidden]) > .touch-ombros--esq) > .hud-row,.game-region:has(#touch-controls:not([hidden]) > .touch-ombros--esq) > .hud-row{
699
+ padding-left:calc(var(--margem-borda,8px) * 2 + var(--shoulder-size))}
700
+ #game-region:has(#touch-controls:not([hidden]) > .touch-ombros--dir) > .hud-row,.game-region:has(#touch-controls:not([hidden]) > .touch-ombros--dir) > .hud-row{
701
+ padding-right:calc(var(--margem-borda,8px) * 2 + var(--shoulder-size))}
702
+ .hud-row:not(:has(.session-clock, .hud-faixa:not([hidden]), .hud-map > *)){display:none}
703
+ .hud-row-learning{justify-self:start;min-width:0}
704
+ .hud-row-clock{justify-self:center}
705
+ .hud-row-end{display:grid;grid-template-columns:minmax(0,1fr) auto;align-items:end;column-gap:8px;min-width:0}
706
+ .hud-score{justify-self:center;display:flex;flex-direction:column;align-items:center;gap:2px;min-width:0}
707
+ .hud-map{display:flex;align-items:flex-end} /* empty, it is 0 px wide: nothing is drawn until a game mounts its map */
708
+ /* In the row the bands are laid out by their cell, not placed on the region; the learning bars stack, one skill a line,
709
+ because three side by side do not fit a third of 640 px. */
710
+ .hud-row .hud-faixa{position:static;transform:none}
711
+ .hud-row .hud-aprendizagem{flex-direction:column;align-items:flex-start;gap:2px}
712
+ .hud-row .hud-direita{align-items:center;text-align:center}
713
+ /* The explanation band covers the row while it shows (a menu is open, the game is paused): the row is not drawn under its
714
+ translucent band, and the band sits where the row stands. The caption and the legend otherwise stand ABOVE the row. */
715
+ .game-region:has(.barra-explicacao:not([hidden])) .hud-row,#game-region:has(.barra-explicacao:not([hidden])) .hud-row{visibility:hidden}
716
+ /* THE LOOK OF THE CLOCK AND THE SCORE: a small label over bold digits, white with a dark outline — the reference is Super
717
+ Mario World's HUD, and nothing of its art or face is taken: the engine's own faces, the mathematics one with tabular
718
+ figures for the digits, so they never change width. Text at the 16 px floor and above (ADR-0163); white on its black
719
+ outline, so it holds its contrast over any scene. */
720
+ .session-clock-text,.hud-points .hud-numero{color:#fff;font-weight:800;-webkit-text-stroke:.06em #000;paint-order:stroke fill;
721
+ text-shadow:2px 0 #000,-2px 0 #000,0 2px #000,0 -2px #000,2px 2px #000,-2px 2px #000,2px -2px #000,-2px -2px #000}
722
+ .session-clock-digits,.hud-points .hud-numero{font-family:var(--font-math);font-variant-numeric:tabular-nums;
723
+ font-size:calc(var(--ui-fs,16px) * 1.25);line-height:1.1;white-space:nowrap}
724
+ .hud-points .hud-numero{background:none;padding:0}
725
+ .hud-points{top:var(--hud-corner-top,8px);right:var(--margem-borda,8px);flex-direction:column;align-items:flex-end} /* only where a caller mounts the bands with no row; `--hud-corner-top` above */
726
+ /* …and there, at the top edge, the digits get a line that holds their glyphs: at 1.1 the face's box rose 1 px over the line
727
+ (measured: 24 px of glyph box on a 22 px line at 640×360, 46 on 44 at 1280×720), into the edge margin */
728
+ .game-region > .hud-points .hud-numero,#game-region > .hud-points .hud-numero{line-height:1.2}
729
+ /* …and the POWER, which in the row stands over the points (ADR-0239 §3), has no room over them there: the same pair reads
730
+ top-down, the points first and the power directly under them, on the same right edge — both at one `top` drew one box over
731
+ the other. The points' line is one line of digits, 1.25 × the text size on a 1.2 line (above); 2 px apart, as in the row's
732
+ cell. With no points shown the power is the stack's first line. */
733
+ .game-region:has(> .hud-points:not([hidden]) > .hud-numero:not([hidden])) > .hud-direita,
734
+ #game-region:has(> .hud-points:not([hidden]) > .hud-numero:not([hidden])) > .hud-direita{top:calc(var(--hud-corner-top,8px) + var(--ui-fs,16px) * 1.25 * 1.2 + 2px)}
735
+ /* THE SESSION CLOCK (ADR-0236, ADR-0239): the label over the time left, and the Time Timer pie to their right, as tall as a
736
+ target. The pie is the share still to go (`--left`, written by `ui/session-clock`), green on a white face (ADR-0050 §3)
737
+ inside a dark rim and a white ring, drawn inside its box. At the end the WHOLE pie turns red — an almost empty face
738
+ becoming a full one, so the change is not told by colour alone (WCAG 1.4.1). Okabe-Ito green and vermillion. */
739
+ .session-clock{display:flex;align-items:center;gap:6px;pointer-events:none}
740
+ .session-clock-text{display:flex;flex-direction:column;align-items:center;line-height:1.1}
741
+ /* The label stays at the 16 px text floor (ADR-0163) and loses weight instead, and the digits are an eighth over the floor:
742
+ the Dev found «TEMPO» too big and wants the label-and-digits block no wider than two and a half pies (ADR-0239 errata). */
743
+ .session-clock-label{font-size:var(--ui-fs,16px);letter-spacing:var(--ls);font-weight:600}
744
+ .session-clock-digits{font-size:calc(var(--ui-fs,16px) * 1.125)}
745
+ .session-clock-pie{flex:none;box-sizing:border-box;width:var(--alvo-min,44px);height:var(--alvo-min,44px);border-radius:50%;
746
+ border:2px solid #08080f;box-shadow:inset 0 0 0 2px #f6f5f0;
747
+ background:conic-gradient(#f6f5f0 0 calc((1 - var(--left,1)) * 1turn),#009E73 0)}
748
+ /* The spent share is the face from twelve o'clock CLOCKWISE, and the green is what is left up to twelve: the edge moves
749
+ clockwise as time passes, like a Time Timer (the Dev, 2026-09-25: it was emptying anticlockwise). */
750
+ /* The end is red and still — no pulse, no lock (ADR-0240). */
751
+ .session-clock[data-look="red"] .session-clock-pie{background:#D55E00}
626
752
  .rodape-da-tela{position:absolute;left:0;right:0;bottom:0;z-index:12;display:flex;flex-direction:column;gap:0;pointer-events:none}
753
+ /* WITH THE HUD ROW (ADR-0239 point 6): the caption and the legend stand ABOVE the row; while the explanation shows, the column
754
+ comes down to where the row stands, and the explanation covers it. */
755
+ #game-region:has(> .hud-row) .rodape-da-tela{bottom:calc(var(--hud-row-bottom,0px) + var(--hud-row-h,0px))}
756
+ #game-region:has(> .hud-row) .rodape-da-tela:has(> .barra-explicacao:not([hidden])){bottom:var(--hud-row-bottom,0px)}
627
757
  .rodape-da-tela:not(:has(> :not([hidden]))){display:none}
628
- .pausa-legenda,.barra-explicacao{color:#fff;font-family:var(--font);font-weight:700;font-size:var(--ui-fs,16px);
629
- line-height:1.3;text-align:center;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;overflow:hidden}
630
- .barra-explicacao{order:2;padding:4px .6em;background:rgba(0,0,0,.82)}
758
+ /* `--footer-lines` is how many lines a footer text shows (ADR-0164): the clamp reads it, and so do the scrolling box below and
759
+ `ui/footer-scroll-driver`, which must know the view it scrolls a longer text through (ADR-0245). */
760
+ .pausa-legenda,.barra-explicacao{color:#fff;font-family:var(--font);font-weight:700;font-size:var(--ui-fs,16px);--footer-lines:2;
761
+ line-height:1.3;text-align:center;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:var(--footer-lines);overflow:hidden}
762
+ /* The band reaches the edges; its WORDS stand the edge margin off them (interface log 2026-09-26) — `--footer-band-h` counts it.
763
+ At the sides .6em is already more than the margin (4.8·k against 4·k); under them the margin is a transparent BORDER the
764
+ band's colour shows through, not padding: the two-line clamp clips at the padding box, and a padding there would show the
765
+ top of a third line. */
766
+ .barra-explicacao{order:2;padding:4px .6em 0;border-bottom:var(--margem-borda,8px) solid transparent;background:rgba(0,0,0,.82)}
631
767
  .pausa-legenda{order:1;padding:0 .6em}
632
- .rodape-da-tela:not(:has(> .barra-explicacao:not([hidden]))) > .pausa-legenda{padding-bottom:8px}
768
+ .rodape-da-tela:not(:has(> .barra-explicacao:not([hidden]))) > .pausa-legenda{padding-bottom:var(--margem-borda,8px)}
633
769
  .pausa-legenda .lg-nome{background:rgba(0,0,0,.82);padding:0 .35em;border-radius:4px;-webkit-box-decoration-break:clone;box-decoration-break:clone}
634
770
  /* The SOUND CAPTION (study item D3) tops the column — ADR-0164 rule 4: «the sound caption above, the explanation below
635
771
  it» — on a dark background behind its words only, two lines at most (rule 5). */
636
772
  .legenda-de-som{order:0;align-self:center;max-width:100%;box-sizing:border-box;margin:0 0 4px;padding:2px .6em;border-radius:6px;
637
773
  background:rgba(0,0,0,.82);color:#fff;font-family:var(--font);font-weight:700;font-size:var(--ui-fs,16px);line-height:1.3;
638
- text-align:center;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;overflow:hidden}
774
+ text-align:center;display:-webkit-box;-webkit-box-orient:vertical;--footer-lines:2;-webkit-line-clamp:var(--footer-lines);overflow:hidden}
775
+ /* the caption as the column's lowest line (no legend, no explanation under it): the edge margin under it, not 4 px */
776
+ .rodape-da-tela:not(:has(> .barra-explicacao:not([hidden]), > .pausa-legenda:not([hidden]))) > .legenda-de-som{margin-bottom:var(--margem-borda,8px)}
639
777
  /* two or more lines of the footer showing at once: one line each, so the footer does not climb into the workspace */
640
- .rodape-da-tela:has(> :not([hidden]) ~ :not([hidden])) > *{-webkit-line-clamp:1}
778
+ .rodape-da-tela:has(> :not([hidden]) ~ :not([hidden])) > *{--footer-lines:1}
641
779
  .pausa-legenda[hidden],.barra-explicacao[hidden],.legenda-de-som[hidden]{display:none}
780
+ /* ADR-0245: AN EXPLANATION LONGER THAN ITS LINES MOVES INSIDE THEM. `ui/footer-scroll-driver` marks it `data-scroll`: a glide
781
+ translates the words' `.footer-scroll-text` block (a Web Animation, sub-pixel — a transform needs a block, an inline span
782
+ ignores it), reduced motion turns pages by `scrollTop`, at once. The box stays the clamped one to the pixel: a block of
783
+ exactly its lines (`1lh` each, no clamp and so no ellipsis), with the 4 px over the words as a transparent BORDER instead of
784
+ padding — the view clips at the padding box, and a padding would show a slice of the next line. Pointer events come back to
785
+ the band while it moves, so a pointer over it can hold it (WCAG 2.2.2). */
786
+ .barra-explicacao[data-scroll],#game-region .opt-explain[data-scroll]{display:block;-webkit-line-clamp:none;box-sizing:content-box;
787
+ height:calc(var(--footer-lines,2) * 1lh);padding-top:0;border-top:4px solid transparent;pointer-events:auto}
788
+ .barra-explicacao[data-scroll] > .footer-scroll-text,#game-region .opt-explain[data-scroll] > .footer-scroll-text{display:block}
642
789
  /* A PANEL WEARS THE PAUSE CARD (interface log, 2026-09-13). The Dev: the settings submenu «mantém a mesma altura e identidade
643
790
  visual», and every panel it opens had «outra identidade visual, com alturas menores, título maior e cores diferentes».
644
791
  So a panel in the region takes `.screen-pause .pause-card` as it is: the whole height, the same dark card and gold border,
@@ -647,7 +794,7 @@ main{flex:1;display:flex;flex-direction:column;width:100%;margin:0 auto;padding:
647
794
  spacing (ADR-0149) «◀ Realce de contraste: desligado ▶» is wider than the pause list's 26em. */
648
795
  #game-region .overlay__card{background:#0e1626;border:2px solid #ffd23f;border-radius:14px;padding:.25rem .7rem;width:auto;
649
796
  max-width:94%;height:100%;max-height:100%;box-sizing:border-box;
650
- scrollbar-gutter:stable both-edges;box-shadow:0 8px 30px rgba(0,0,0,.5);scroll-padding-bottom:var(--rodape-h,50px)}
797
+ scrollbar-gutter:stable both-edges;box-shadow:0 8px 30px rgba(0,0,0,.5);scroll-padding-bottom:var(--footer-band-h,50px)}
651
798
  #game-region .overlay__card h2{font-size:1em;line-height:1.25;margin:0 0 .1rem;color:#ffd23f}
652
799
  #game-region .overlay__back{width:100%;margin:0 0 2px;justify-content:center;background:#1a2740;border:1px solid #6a7a96;border-radius:10px;color:#eaf2f8}
653
800
  #game-region .overlay__back:hover,#game-region .overlay__back:focus{background:#2a3a5e;border-color:#ffd23f;outline:2px solid #ffd23f;outline-offset:1px}
@@ -659,7 +806,7 @@ main{flex:1;display:flex;flex-direction:column;width:100%;margin:0 auto;padding:
659
806
  #game-region .ctrl-row:hover,#game-region .ctrl-row:focus-within{background:#2a3a5e;border-color:#ffd23f}
660
807
  /* The card runs under the explanation band, as the pause card runs under its legend: the room at the end of the card and
661
808
  the scroll padding let the last row, and the focused one, come to rest above the band. */
662
- #game-region .overlay__card::after{content:"";display:block;height:var(--rodape-h,50px)}
809
+ #game-region .overlay__card::after{content:"";display:block;height:var(--footer-band-h,50px)}
663
810
  /* HELP IS A SLIDE SHOW (interface log, 2026-09-13; `ui/help-panel`): «textos, figuras e no máximo animações», not a menu. One stop
664
811
  with the page arrows at its sides; the slide holds the child's key drawn as a key cap, the game's word and its sentence, and
665
812
  dots that say where the child is by fill and not by colour alone. The key cap presses itself now and then — the one animation,
@@ -686,20 +833,25 @@ main{flex:1;display:flex;flex-direction:column;width:100%;margin:0 auto;padding:
686
833
  (composition: 1-0.82=0.18 → L≈0.027 → ~13:1), without being 100% opaque. Fixed at the card's foot. */
687
834
  .opt-explain{position:sticky;bottom:calc(-1 * var(--card-pad,1.5rem));margin:.8rem calc(-1 * var(--card-pad,1.5rem)) calc(-1 * var(--card-pad,1.5rem));padding:.6rem .9rem;min-height:2.8rem;text-align:left;
688
835
  background:rgba(0,0,0,.82);color:#fff;font-size:1em;line-height:1.35;border-top:1px solid rgba(255,255,255,.18);border-radius:0 0 9px 9px;backdrop-filter:blur(1px);
689
- /* ADR-0164: two lines at most — a longer explanation is cut here and has to be rewritten to fit */
690
- display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;overflow:hidden}
836
+ /* ADR-0164: two lines at most — in the region a longer explanation scrolls through them (ADR-0245, below) */
837
+ display:-webkit-box;-webkit-box-orient:vertical;--footer-lines:2;-webkit-line-clamp:var(--footer-lines);overflow:hidden}
691
838
  /* ADR-0164 rule 1: a panel's explanation is a footer of the SCREEN, not of the card — «está ajustado ao menu, não ao
692
839
  canvas», the Dev on a screenshot. The card sets no position, so the overlay (the region's size) is the containing block:
693
840
  the band lands at the region's lowest edge, side to side, and does not scroll with the card. The card runs under it,
694
841
  the pause card's height (see the panel rules above). */
695
- #game-region .opt-explain{position:absolute;left:0;right:0;bottom:0;z-index:1;margin:0;padding:4px .6em;min-height:0;
696
- border:0;border-radius:0;text-align:center;line-height:1.3;font-size:var(--ui-fs,16px)}
697
- #game-region .overlay{padding:0}
842
+ #game-region .opt-explain{position:absolute;left:0;right:0;bottom:0;z-index:1;margin:0;padding:4px .6em 0;min-height:0;
843
+ border:0;border-bottom:var(--margem-borda,8px) solid transparent;border-radius:0;text-align:center;line-height:1.3;font-size:var(--ui-fs,16px)}
844
+ /* ↑ the transparent bottom border is the edge margin under the words, as the footer band's (interface log 2026-09-26) */
845
+ /* the card's content from the edge margin down, as the pause card's (interface log 2026-09-26) */
846
+ #game-region .overlay{padding:calc(var(--margem-borda,8px) - 2px) 0 0}
847
+ #game-region .overlay__card{padding-top:0}
698
848
  #game-region .overlay__actions{position:static;background:transparent;padding:.5rem 0 0;margin:0}
699
849
  #visual{background:rgba(0,0,0,.28)} /* colour: a translucent background, to see the effect on the game at once */
700
850
 
701
- /* Simulation indicator (top right corner): white=blindness, green=low vision. A double tap returns to normal. */
702
- #viz-indicator{position:absolute;top:6px;right:6px;z-index:20;width:16px;height:16px;border-radius:50%;border:2px solid rgba(0,0,0,.6);padding:0;cursor:pointer;box-shadow:0 1px 4px rgba(0,0,0,.7)} /* INSIDE the canvas (game-region) — it works as a button */
851
+ /* Simulation indicator (TOP LEFT corner): white=blindness, green=low vision. A double tap returns to normal. The top right is
852
+ the right shoulders' (ADR-0160) and, with no HUD row, the points'; nothing of the HUD sits top left, so the dot is alone
853
+ there — under the left shoulders while the pad shows them (`--shoulders-left-reach`, with the HUD's rules). */
854
+ #viz-indicator{position:absolute;top:max(var(--margem-borda,8px),var(--shoulders-left-reach,0px));left:var(--margem-borda,8px);z-index:20;width:16px;height:16px;border-radius:50%;border:2px solid rgba(0,0,0,.6);padding:0;cursor:pointer;box-shadow:0 1px 4px rgba(0,0,0,.7)} /* INSIDE the canvas (game-region) — it works as a button */
703
855
  #viz-indicator.blind{background:#fff}
704
856
  #viz-indicator.low{background:#36d36a}
705
857
  /* Low vision — 5 simulations (the blur comes from the filter on the canvas; only the overlays are here) */
@@ -724,10 +876,31 @@ body.blind-mode .hud, body.blind-mode #touch-controls, body.blind-mode #start-ti
724
876
  spelling letter by letter, which is what real ALL CAPS causes in NVDA/JAWS. */
725
877
  /* Quiz options take the ENGINE's target floor (ADR-0163 rule 2): 44 px at 640×360, growing with the scale. They had
726
878
  9 mm computed by the quiz (54 px on a desktop), and four of them pushed the last one out of a 360 px region. */
727
- .quiz-alt{min-height:var(--alvo-min,44px);display:block;width:100%;margin:0;padding:calc(var(--ui-fs,16px) * .4) calc(var(--ui-fs,16px) * .9)} /* the list gap spaces them (#160); padding in `--ui-fs`, so a larger face grows the text only (#172) */
879
+ .quiz-alt{min-height:var(--alvo-min,44px);display:block;width:100%;margin:0;padding:calc(var(--ui-fs,16px) * .25) calc(var(--ui-fs,16px) * .5)} /* the list gap spaces them (#160); padding in `--ui-fs`, so a larger face grows the text only (#172) */
880
+ /* 📏 .25/.5 and not .4/.9 since the edge margin (interface log 2026-09-26): with 16 px less width and a HUD row 4 px taller, the
881
+ quiz's own questions ended under the row at 640×360 (quiz-bench-layout); the 44 px floor is `min-height`, untouched. */
728
882
  /* the marked option is not colour alone either (ADR-0159 rule 10): the same base stripe as an icon switched on */
729
883
  .quiz-alt.is-on{box-shadow:inset 0 0 0 3px var(--accent-ink)} /* a ring, not a bottom strip: the strip left the fill looking shifted up (#166) */
730
- .quiz-alts{display:flex;flex-direction:column;gap:calc(.25rem * var(--espaco-fixo,1))}
884
+ /* FIVE OPTIONS IN THREE COLUMNS — «1 2 3» over «4 5», read left to right (`quiz-round.OPTION_COLUMNS`, written as `--quiz-cols`).
885
+ 📏 In one column the fifth ended under the HUD row at 640×360, and in two a two-line statement with its explanation did. */
886
+ .quiz-alts{display:grid;grid-template-columns:repeat(var(--quiz-cols,3),minmax(0,1fr));gap:calc(.25rem * var(--espaco-fixo,1))}
887
+ /* An option already tried is out: struck through as well as dimmed, so it is not told by colour alone (WCAG 1.4.1); an inactive
888
+ control is outside the contrast minimum (WCAG 1.4.3). The answer to COPY (ADR-0049 §6) carries a mark before its words. */
889
+ .quiz-alt.is-off{opacity:.55;text-decoration:line-through;cursor:default}
890
+ .quiz-alt.is-answer{outline:3px solid var(--accent);outline-offset:2px}
891
+ .quiz-alt.is-answer::before{content:"➜ "}
892
+ /* The explanation after the third wrong attempt, and the copy line: under the statement, at the text size, not bold. While it
893
+ shows, the statement comes down to the text size too: 📏 a two-line statement at its heading size, a three-line explanation
894
+ and two rows of options ended under the HUD row at 640×360 (quiz-bench-layout). */
895
+ .quiz-note{margin:0 0 calc(.25rem * var(--espaco-fixo,1));line-height:1.25;font-weight:400}
896
+ .quiz-app:has(.quiz-note) .quiz-pergunta{font-size:1em}
897
+ /* THE START SCREEN (the Dev: «Tela inicial para escolher a habilidade via sigla da BNCC»): each stage's name over a grid of
898
+ `--quiz-cols` codes (`quiz-round.SKILL_COLUMNS`), the engine's target size; a code never overflows its button. */
899
+ .quiz-stage{margin:0}
900
+ .quiz-stage-name{margin:0;font-size:1em;line-height:1.25}
901
+ .quiz-skills{display:grid;grid-template-columns:repeat(var(--quiz-cols,5),minmax(0,1fr));gap:calc(.25rem * var(--espaco-fixo,1));margin:0 0 calc(.25rem * var(--espaco-fixo,1))}
902
+ .quiz-skill{min-height:var(--alvo-min,44px);margin:0;padding:calc(var(--ui-fs,16px) * .3);overflow-wrap:anywhere;line-height:1.15}
903
+ .quiz-skill.is-on{box-shadow:inset 0 0 0 3px var(--accent-ink)}
731
904
  :root[data-letras="upper"] body,
732
905
  :root[data-letras="upper"] button,
733
906
  :root[data-letras="upper"] select,
@@ -793,12 +966,12 @@ select.vol:focus, .overlay__card select:focus{outline:3px solid var(--accent);ou
793
966
  .ctrl-col input[type=range]{width:100%;min-height:var(--alvo-min,44px);accent-color:var(--accent)}
794
967
 
795
968
  /* touch controls (mobile) — an overlay on the bottom edges, not covering the centre */
796
- .touch{position:absolute;inset:0;z-index:14;display:flex;justify-content:space-between;align-items:flex-end;gap:8px;padding:6px 8px;pointer-events:none}
969
+ .touch{position:absolute;inset:0;z-index:14;display:flex;justify-content:space-between;align-items:flex-end;gap:8px;padding:var(--margem-borda,8px);pointer-events:none}
797
970
  /* ADR-0160: the shoulders in the TOP corners of the region, the trigger (2) above the bumper (1). `.touch` covers the whole
798
971
  region since then (`inset:0`, still `pointer-events:none`) so a corner is the region's corner, not the pad strip's. */
799
- .touch-ombros{position:absolute;top:8px;display:flex;flex-direction:column;gap:6px;pointer-events:auto}
800
- .touch-ombros--esq{left:8px}
801
- .touch-ombros--dir{right:8px}
972
+ .touch-ombros{position:absolute;top:var(--margem-borda,8px);display:flex;flex-direction:column;gap:6px;pointer-events:auto}
973
+ .touch-ombros--esq{left:var(--margem-borda,8px)}
974
+ .touch-ombros--dir{right:var(--margem-borda,8px)}
802
975
  /* ADR-0160: the action buttons sit by ACTION NUMBER — 1 and 4 on top, 2 and 3 below — whatever slot fires them.
803
976
  `margin-left:auto` keeps the block on the right when the game names no direction (ADR-0162). */
804
977
  .touch-pad{display:grid;grid-template-areas:"a1 a4" "a2 a3";gap:8px;margin-left:auto;pointer-events:auto}
@@ -827,9 +1000,10 @@ select.vol:focus, .overlay__card select:focus{outline:3px solid var(--accent);ou
827
1000
  (`#game-region .overlay`, 60) covered the pad (14), and a tap on an arrow landed on the veil. `--z-menu-max` is the top
828
1001
  of the menu band, and that is the pad's role while a menu is open — a slot and not a new literal. */
829
1002
  #game-region:has(.overlay:not([hidden])) .touch{z-index:var(--z-menu-max)}
830
- .touch-sistema{position:absolute;left:50%;bottom:6px;transform:translateX(-50%);display:flex;gap:10px;pointer-events:none}
1003
+ /* the two pills stand the edge margin off the bottom (interface log 2026-09-26) — alone or side by side */
1004
+ .touch-sistema{position:absolute;left:50%;bottom:var(--margem-borda,8px);transform:translateX(-50%);display:flex;gap:10px;pointer-events:none}
831
1005
  .touch-sistema .touch-start,.touch-sistema .touch-select{position:static;transform:none}
832
- .touch-start,.touch-select{position:absolute;left:50%;bottom:6px;transform:translateX(-50%);width:auto;min-width:var(--alvo-min,44px);white-space:nowrap;min-height:calc(var(--pad-btn,66px)*.7);box-sizing:border-box;display:inline-flex;align-items:center;justify-content:center;pointer-events:auto;border-radius:999px;padding:0 22px;font-weight:800;font-size:1em;letter-spacing:var(--ls);background:rgba(13,17,32,.92);color:#fff;border:2px solid rgba(255,255,255,.75);cursor:pointer;z-index:15}
1006
+ .touch-start,.touch-select{position:absolute;left:50%;bottom:var(--margem-borda,8px);transform:translateX(-50%);width:auto;min-width:var(--alvo-min,44px);white-space:nowrap;min-height:calc(var(--pad-btn,66px)*.7);box-sizing:border-box;display:inline-flex;align-items:center;justify-content:center;pointer-events:auto;border-radius:999px;padding:0 22px;font-weight:800;font-size:1em;letter-spacing:var(--ls);background:rgba(13,17,32,.92);color:#fff;border:2px solid rgba(255,255,255,.75);cursor:pointer;z-index:15}
833
1007
  .touch-start:active{background:var(--accent);color:var(--accent-ink);border-color:var(--accent)}
834
1008
  /* digital joystick: base (larger circle) + knob (smaller circle) */
835
1009
  /* Directional (analogue/"lever"): base = surface + travel; knob = contact surface. Both in mm (JS). */
@@ -0,0 +1,166 @@
1
+ The fonts in vendor/fonts/: notices and licences
2
+ =============================================
3
+
4
+ The Inclusionist engine redistributes 19 font families, in 29 files, from this directory. Each
5
+ family is listed below with the files it covers, its licence, where that licence was read, and its copyright
6
+ notice as the font's own `name` table states it (name ID 0). The licence texts sit beside this file:
7
+
8
+ OFL-1.1.txt SIL Open Font License, Version 1.1 (19 families)
9
+
10
+ Written by scripts/licences/fonts.mjs from vendor/fonts.css and the fonts themselves;
11
+ tests/font-licences.node.test.js refuses a family without an entry here or a licence without its text.
12
+
13
+ Every other family The Inclusionist offers lives in its font library, one folder per family with its own notice
14
+ and licence, and reaches a game only through a delivery that carries it (ADR-0255).
15
+
16
+ -------------------------------------------------------------------------------
17
+ Family: Atkinson Hyperlegible
18
+ Files: atkinson-400.woff2, atkinson-400-ext.woff2, atkinson-700.woff2, atkinson-700-ext.woff2
19
+ Licence: SIL Open Font License, Version 1.1 (OFL-1.1), see OFL-1.1.txt
20
+ Read from: licence URL (name ID 14): https://scripts.sil.org/OFL
21
+ Copyright:
22
+ Copyright 2020 Braille Institute of America, Inc.
23
+
24
+ -------------------------------------------------------------------------------
25
+ Family: Andika
26
+ Files: andika-400.woff2, andika-400-ext.woff2, andika-700.woff2, andika-700-ext.woff2
27
+ Licence: SIL Open Font License, Version 1.1 (OFL-1.1), see OFL-1.1.txt
28
+ Read from: licence URL (name ID 14): http://scripts.sil.org/OFL
29
+ Copyright:
30
+ Copyright (c) 2004-2022 SIL International
31
+
32
+ -------------------------------------------------------------------------------
33
+ Family: Lexend
34
+ Files: lexend-400.woff2, lexend-400-ext.woff2, lexend-700.woff2, lexend-700-ext.woff2
35
+ Licence: SIL Open Font License, Version 1.1 (OFL-1.1), see OFL-1.1.txt
36
+ Read from: licence URL (name ID 14): https://scripts.sil.org/OFL
37
+ Copyright:
38
+ Copyright 2019 The Lexend Project Authors (https://github.com/googlefonts/lexend)
39
+
40
+ -------------------------------------------------------------------------------
41
+ Family: Atkinson Hyperlegible Mono
42
+ Files: atkinson-mono-400.woff2, atkinson-mono-400-ext.woff2
43
+ Licence: SIL Open Font License, Version 1.1 (OFL-1.1), see OFL-1.1.txt
44
+ Read from: licence URL (name ID 14): https://openfontlicense.org
45
+ Copyright:
46
+ Copyright 2020-2024 The Atkinson Hyperlegible Mono Project Authors (https://github.com/googlefonts/atkinson-hyperlegible-next-mono)
47
+
48
+ -------------------------------------------------------------------------------
49
+ Family: Playwrite BR
50
+ Files: playwrite-br.woff2
51
+ Licence: SIL Open Font License, Version 1.1 (OFL-1.1), see OFL-1.1.txt
52
+ Read from: licence URL (name ID 14): https://openfontlicense.org
53
+ Copyright:
54
+ Copyright 2023 The Playwrite Project Authors (https://github.com/TypeTogether/Playwrite)
55
+
56
+ -------------------------------------------------------------------------------
57
+ Family: Playwrite US Trad
58
+ Files: playwrite-us-trad.woff2
59
+ Licence: SIL Open Font License, Version 1.1 (OFL-1.1), see OFL-1.1.txt
60
+ Read from: licence URL (name ID 14): https://openfontlicense.org
61
+ Copyright:
62
+ Copyright 2023 The Playwrite Project Authors (https://github.com/TypeTogether/Playwrite)
63
+
64
+ -------------------------------------------------------------------------------
65
+ Family: Playwrite US Modern
66
+ Files: playwrite-us-modern.woff2
67
+ Licence: SIL Open Font License, Version 1.1 (OFL-1.1), see OFL-1.1.txt
68
+ Read from: licence URL (name ID 14): https://openfontlicense.org
69
+ Copyright:
70
+ Copyright 2023 The Playwrite Project Authors (https://github.com/TypeTogether/Playwrite)
71
+
72
+ -------------------------------------------------------------------------------
73
+ Family: Playwrite CA
74
+ Files: playwrite-ca.woff2
75
+ Licence: SIL Open Font License, Version 1.1 (OFL-1.1), see OFL-1.1.txt
76
+ Read from: licence URL (name ID 14): https://openfontlicense.org
77
+ Copyright:
78
+ Copyright 2023 The Playwrite Project Authors (https://github.com/TypeTogether/Playwrite)
79
+
80
+ -------------------------------------------------------------------------------
81
+ Family: Playwrite MX
82
+ Files: playwrite-mx.woff2
83
+ Licence: SIL Open Font License, Version 1.1 (OFL-1.1), see OFL-1.1.txt
84
+ Read from: licence URL (name ID 14): https://openfontlicense.org
85
+ Copyright:
86
+ Copyright 2023 The Playwrite Project Authors (https://github.com/TypeTogether/Playwrite)
87
+
88
+ -------------------------------------------------------------------------------
89
+ Family: Playwrite AR
90
+ Files: playwrite-ar.woff2
91
+ Licence: SIL Open Font License, Version 1.1 (OFL-1.1), see OFL-1.1.txt
92
+ Read from: licence URL (name ID 14): https://openfontlicense.org
93
+ Copyright:
94
+ Copyright 2023 The Playwrite Project Authors (https://github.com/TypeTogether/Playwrite)
95
+
96
+ -------------------------------------------------------------------------------
97
+ Family: Playwrite CL
98
+ Files: playwrite-cl.woff2
99
+ Licence: SIL Open Font License, Version 1.1 (OFL-1.1), see OFL-1.1.txt
100
+ Read from: licence URL (name ID 14): https://openfontlicense.org
101
+ Copyright:
102
+ Copyright 2023 The Playwrite Project Authors (https://github.com/TypeTogether/Playwrite)
103
+
104
+ -------------------------------------------------------------------------------
105
+ Family: Playwrite CO
106
+ Files: playwrite-co.woff2
107
+ Licence: SIL Open Font License, Version 1.1 (OFL-1.1), see OFL-1.1.txt
108
+ Read from: licence URL (name ID 14): https://openfontlicense.org
109
+ Copyright:
110
+ Copyright 2023 The Playwrite Project Authors (https://github.com/TypeTogether/Playwrite)
111
+
112
+ -------------------------------------------------------------------------------
113
+ Family: Playwrite ES
114
+ Files: playwrite-es.woff2
115
+ Licence: SIL Open Font License, Version 1.1 (OFL-1.1), see OFL-1.1.txt
116
+ Read from: licence URL (name ID 14): https://openfontlicense.org
117
+ Copyright:
118
+ Copyright 2023 The Playwrite Project Authors (https://github.com/TypeTogether/Playwrite)
119
+
120
+ -------------------------------------------------------------------------------
121
+ Family: Playwrite ES Deco
122
+ Files: playwrite-es-deco.woff2
123
+ Licence: SIL Open Font License, Version 1.1 (OFL-1.1), see OFL-1.1.txt
124
+ Read from: licence URL (name ID 14): https://openfontlicense.org
125
+ Copyright:
126
+ Copyright 2023 The Playwrite Project Authors (https://github.com/TypeTogether/Playwrite)
127
+
128
+ -------------------------------------------------------------------------------
129
+ Family: Playwrite PT
130
+ Files: playwrite-pt.woff2
131
+ Licence: SIL Open Font License, Version 1.1 (OFL-1.1), see OFL-1.1.txt
132
+ Read from: licence URL (name ID 14): https://openfontlicense.org
133
+ Copyright:
134
+ Copyright 2023 The Playwrite Project Authors (https://github.com/TypeTogether/Playwrite)
135
+
136
+ -------------------------------------------------------------------------------
137
+ Family: Playwrite GB J
138
+ Files: playwrite-gb-j.woff2
139
+ Licence: SIL Open Font License, Version 1.1 (OFL-1.1), see OFL-1.1.txt
140
+ Read from: licence URL (name ID 14): https://openfontlicense.org
141
+ Copyright:
142
+ Copyright 2023 The Playwrite Project Authors (https://github.com/TypeTogether/Playwrite)
143
+
144
+ -------------------------------------------------------------------------------
145
+ Family: Playwrite GB S
146
+ Files: playwrite-gb-s.woff2
147
+ Licence: SIL Open Font License, Version 1.1 (OFL-1.1), see OFL-1.1.txt
148
+ Read from: licence URL (name ID 14): https://openfontlicense.org
149
+ Copyright:
150
+ Copyright 2023 The Playwrite Project Authors (https://github.com/TypeTogether/Playwrite)
151
+
152
+ -------------------------------------------------------------------------------
153
+ Family: Playwrite CU
154
+ Files: playwrite-cu.woff2
155
+ Licence: SIL Open Font License, Version 1.1 (OFL-1.1), see OFL-1.1.txt
156
+ Read from: licence URL (name ID 14): https://openfontlicense.org
157
+ Copyright:
158
+ Copyright 2023 The Playwrite Project Authors (https://github.com/TypeTogether/Playwrite)
159
+
160
+ -------------------------------------------------------------------------------
161
+ Family: Playwrite PE
162
+ Files: playwrite-pe.woff2
163
+ Licence: SIL Open Font License, Version 1.1 (OFL-1.1), see OFL-1.1.txt
164
+ Read from: licence URL (name ID 14): https://openfontlicense.org
165
+ Copyright:
166
+ Copyright 2023 The Playwrite Project Authors (https://github.com/TypeTogether/Playwrite)