@the-inclusionist/engine 8.0.0 → 10.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.
- package/README.md +89 -78
- package/app/css/style.css +584 -374
- package/app/public/vendor/fonts/bitter-var-ext.woff2 +0 -0
- package/app/public/vendor/fonts/bitter-var.woff2 +0 -0
- package/app/public/vendor/fonts/bodonimoda-var-ext.woff2 +0 -0
- package/app/public/vendor/fonts/bodonimoda-var.woff2 +0 -0
- package/app/public/vendor/fonts/cat-abril_fatface-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-abril_fatface-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-adlam_display-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-adlam_display-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-agu_display-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-agu_display-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-alfa_slab_one-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-alfa_slab_one-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-are_you_serious-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-are_you_serious-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-asimovian-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-asimovian-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-atkinson_hyperlegible_next-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-atkinson_hyperlegible_next-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-bakbak_one-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-bakbak_one-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-bangers-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-bangers-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-barriecito-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-barriecito-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-berkshire_swash-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-berkshire_swash-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-bevan-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-bevan-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-bitcount-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-bitcount-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-bowlby_one_sc-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-bowlby_one_sc-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-bungee_shade-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-bungee_shade-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-charm-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-charm-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-charm-700-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-charm-700.woff2 +0 -0
- package/app/public/vendor/fonts/cat-cherry_bomb_one-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-cherry_bomb_one-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-chokokutai-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-chokokutai-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-chonburi-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-chonburi-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-climate_crisis-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-climate_crisis-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-cookie-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-dela_gothic_one-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-dela_gothic_one-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-fascinate_inline-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-fascinate_inline-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-ga_maamli-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-ga_maamli-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-itim-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-itim-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-jacquard_24-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-jacquard_24-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-kablammo-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-kablammo-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-kalam-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-kalam-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-kalam-700-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-kalam-700.woff2 +0 -0
- package/app/public/vendor/fonts/cat-katibeh-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-katibeh-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-lemonada-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-lemonada-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-lilita_one-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-lilita_one-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-lobster-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-lobster-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-luckiest_guy-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-luckiest_guy-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-marhey-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-marhey-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-modak-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-modak-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-momo_signature-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-momo_signature-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-monofett-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-monofett-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-monomakh-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-monomakh-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-monoton-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-monoton-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-nerko_one-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-nerko_one-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-noto_sans_adlam-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-noto_sans_adlam-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-noto_sans_arabic-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-noto_sans_arabic-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-noto_sans_devanagari-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-noto_sans_devanagari-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-noto_sans_hebrew-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-noto_sans_hebrew-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-noto_sans_jp-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-noto_sans_jp-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-noto_sans_khmer-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-noto_sans_khmer-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-noto_sans_kr-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-noto_sans_kr-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-noto_sans_sc-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-noto_sans_sc-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-noto_sans_thai-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-noto_sans_thai-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-ole-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-ole-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-pacifico-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-pacifico-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-patrick_hand-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-patrick_hand-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-petit_formal_script-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-petit_formal_script-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-pixelify_sans-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-pixelify_sans-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-plaster-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-plaster-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_ar_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_at-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_at_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_au_nsw-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_au_nsw_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_au_qld-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_au_qld_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_au_sa-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_au_sa_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_au_tas-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_au_tas_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_au_vic-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_au_vic_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_be_vlg-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_be_vlg_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_be_wal-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_be_wal_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_br_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_ca_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_cl_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_co_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_cu_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_cz-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_cz_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_de_grund-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_de_grund_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_de_la-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_de_la_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_de_sas-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_de_sas_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_de_va-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_de_va_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_dk_loopet-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_dk_loopet_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_dk_uloopet-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_dk_uloopet_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_es_deco_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_es_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_fr_moderne-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_fr_moderne_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_fr_trad-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_fr_trad_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_gb_j_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_gb_s_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_hr-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_hr_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_hr_lijeva-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_hr_lijeva_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_hu-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_hu_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_id-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_id_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_ie-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_ie_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_in-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_in_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_is-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_is_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_it_moderna-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_it_moderna_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_it_trad-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_it_trad_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_mx_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_ng_modern-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_ng_modern_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_nl-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_nl_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_no-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_no_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_nz-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_nz_basic-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_nz_basic_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_nz_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_pe_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_pl-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_pl_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_pt_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_ro-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_ro_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_sk-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_sk_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_tz-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_tz_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_us_modern_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_us_trad_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_vn-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_vn_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_za-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_za_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-potta_one-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-potta_one-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-ranchers-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-ranchers-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-ranga-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-ranga-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-ranga-700-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-ranga-700.woff2 +0 -0
- package/app/public/vendor/fonts/cat-risque-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-risque-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-rowdies-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-rowdies-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-rowdies-700-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-rowdies-700.woff2 +0 -0
- package/app/public/vendor/fonts/cat-ruge_boogie-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-ruge_boogie-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-ruslan_display-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-ruslan_display-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-sacramento-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-sacramento-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-sancreek-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-sancreek-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-sankofa_display-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-sankofa_display-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-sedgwick_ave_display-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-sedgwick_ave_display-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-shantell_sans-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-shantell_sans-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-smokum-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-smokum-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-solitreo-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-solitreo-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-spicy_rice-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-spicy_rice-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-sriracha-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-sriracha-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-srisakdi-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-srisakdi-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-srisakdi-700-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-srisakdi-700.woff2 +0 -0
- package/app/public/vendor/fonts/cat-stix_two_math-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-tillana-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-tillana-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-tillana-700-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-tillana-700.woff2 +0 -0
- package/app/public/vendor/fonts/cat-titan_one-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-titan_one-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-yatra_one-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-yatra_one-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-yomogi-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-yomogi-400.woff2 +0 -0
- package/app/public/vendor/fonts/dmserifdisplay-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/dmserifdisplay-400.woff2 +0 -0
- package/app/public/vendor/fonts/domine-var-ext.woff2 +0 -0
- package/app/public/vendor/fonts/domine-var.woff2 +0 -0
- package/app/public/vendor/fonts/fraunces-var-ext.woff2 +0 -0
- package/app/public/vendor/fonts/fraunces-var.woff2 +0 -0
- package/app/public/vendor/fonts/fredoka-var-ext.woff2 +0 -0
- package/app/public/vendor/fonts/fredoka-var.woff2 +0 -0
- package/app/public/vendor/fonts/jakarta-var-ext.woff2 +0 -0
- package/app/public/vendor/fonts/jakarta-var.woff2 +0 -0
- package/app/public/vendor/fonts/lora-var-ext.woff2 +0 -0
- package/app/public/vendor/fonts/lora-var.woff2 +0 -0
- package/app/public/vendor/fonts/merriweather-var-ext.woff2 +0 -0
- package/app/public/vendor/fonts/merriweather-var.woff2 +0 -0
- package/app/public/vendor/fonts/notosans-var-ext.woff2 +0 -0
- package/app/public/vendor/fonts/notosans-var.woff2 +0 -0
- package/app/public/vendor/fonts/nunito-var-ext.woff2 +0 -0
- package/app/public/vendor/fonts/nunito-var.woff2 +0 -0
- package/app/public/vendor/fonts/playfair-var-ext.woff2 +0 -0
- package/app/public/vendor/fonts/playfair-var.woff2 +0 -0
- package/app/public/vendor/fonts/playwrite-cu.woff2 +0 -0
- package/app/public/vendor/fonts/playwrite-es-deco.woff2 +0 -0
- package/app/public/vendor/fonts/playwrite-es.woff2 +0 -0
- package/app/public/vendor/fonts/playwrite-gb-j.woff2 +0 -0
- package/app/public/vendor/fonts/playwrite-gb-s.woff2 +0 -0
- package/app/public/vendor/fonts/playwrite-pe.woff2 +0 -0
- package/app/public/vendor/fonts/playwrite-pt.woff2 +0 -0
- package/app/public/vendor/fonts/quicksand-var-ext.woff2 +0 -0
- package/app/public/vendor/fonts/quicksand-var.woff2 +0 -0
- package/app/public/vendor/fonts/robotoflex-var-ext.woff2 +0 -0
- package/app/public/vendor/fonts/robotoflex-var.woff2 +0 -0
- package/app/public/vendor/fonts/sora-var-ext.woff2 +0 -0
- package/app/public/vendor/fonts/sora-var.woff2 +0 -0
- package/app/public/vendor/fonts/spacegrotesk-var-ext.woff2 +0 -0
- package/app/public/vendor/fonts/spacegrotesk-var.woff2 +0 -0
- package/app/public/vendor/fonts/spectral-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/spectral-400.woff2 +0 -0
- package/app/public/vendor/fonts/spectral-700-ext.woff2 +0 -0
- package/app/public/vendor/fonts/spectral-700.woff2 +0 -0
- package/app/public/vendor/fonts/teachers-var-ext.woff2 +0 -0
- package/app/public/vendor/fonts/teachers-var.woff2 +0 -0
- package/app/public/vendor/fonts/ubuntu-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/ubuntu-400.woff2 +0 -0
- package/app/public/vendor/fonts/ubuntu-700-ext.woff2 +0 -0
- package/app/public/vendor/fonts/ubuntu-700.woff2 +0 -0
- package/app/public/vendor/fonts.css +1167 -51
- package/dist-pkg/boot/create-game.d.ts +467 -162
- package/dist-pkg/boot/create-game.js +3563 -426
- package/dist-pkg/core/a11y-sr.d.ts +25 -3
- package/dist-pkg/core/a11y-sr.js +40 -19
- package/dist-pkg/core/accessible-label.d.ts +17 -0
- package/dist-pkg/core/accessible-label.js +37 -0
- package/dist-pkg/core/accommodation-subjects.d.ts +26 -0
- package/dist-pkg/core/accommodation-subjects.js +32 -0
- package/dist-pkg/core/accommodations.d.ts +107 -0
- package/dist-pkg/core/accommodations.js +178 -0
- package/dist-pkg/core/actions.d.ts +75 -51
- package/dist-pkg/core/actions.js +98 -69
- package/dist-pkg/core/calm-mode.d.ts +31 -0
- package/dist-pkg/core/calm-mode.js +47 -0
- package/dist-pkg/core/camera-cycle.d.ts +15 -0
- package/dist-pkg/core/camera-cycle.js +7 -0
- package/dist-pkg/core/caption-duration.d.ts +15 -0
- package/dist-pkg/core/caption-duration.js +19 -0
- package/dist-pkg/core/cartridge-problems.d.ts +34 -0
- package/dist-pkg/core/cartridge-problems.js +53 -0
- package/dist-pkg/core/constants.d.ts +0 -54
- package/dist-pkg/core/constants.js +9 -76
- package/dist-pkg/core/contract.d.ts +143 -163
- package/dist-pkg/core/contract.js +223 -207
- package/dist-pkg/core/dom-query.d.ts +4 -4
- package/dist-pkg/core/dom-query.js +12 -20
- package/dist-pkg/core/entity.d.ts +62 -77
- package/dist-pkg/core/entity.js +18 -32
- package/dist-pkg/core/escape-html.d.ts +9 -10
- package/dist-pkg/core/escape-html.js +16 -20
- package/dist-pkg/core/flash-threshold.d.ts +17 -0
- package/dist-pkg/core/flash-threshold.js +113 -0
- package/dist-pkg/core/game-speed.d.ts +11 -0
- package/dist-pkg/core/game-speed.js +16 -0
- package/dist-pkg/core/genres.d.ts +20 -0
- package/dist-pkg/core/genres.js +44 -0
- package/dist-pkg/core/i18n.d.ts +87 -41
- package/dist-pkg/core/i18n.js +206 -153
- package/dist-pkg/core/loop.d.ts +17 -6
- package/dist-pkg/core/loop.js +26 -26
- package/dist-pkg/core/pause-icon-catalogue.d.ts +15 -0
- package/dist-pkg/core/pause-icon-catalogue.js +54 -0
- package/dist-pkg/core/ring.d.ts +17 -0
- package/dist-pkg/core/ring.js +29 -0
- package/dist-pkg/core/rng.d.ts +7 -12
- package/dist-pkg/core/rng.js +23 -53
- package/dist-pkg/core/route.d.ts +26 -26
- package/dist-pkg/core/route.js +126 -121
- package/dist-pkg/core/scenes.d.ts +37 -40
- package/dist-pkg/core/scenes.js +41 -43
- package/dist-pkg/core/screens.d.ts +4 -4
- package/dist-pkg/core/screens.js +11 -16
- package/dist-pkg/core/setting-defaults.d.ts +61 -0
- package/dist-pkg/core/setting-defaults.js +66 -0
- package/dist-pkg/core/speech-rate.d.ts +29 -0
- package/dist-pkg/core/speech-rate.js +47 -0
- package/dist-pkg/core/state.d.ts +118 -118
- package/dist-pkg/core/state.js +322 -297
- package/dist-pkg/core/visual-cycles.d.ts +30 -0
- package/dist-pkg/core/visual-cycles.js +52 -0
- package/dist-pkg/core/visual-state.d.ts +13 -0
- package/dist-pkg/core/visual-state.js +6 -0
- package/dist-pkg/educational/activities-registry.d.ts +1 -1
- package/dist-pkg/educational/activities-registry.js +9 -8
- package/dist-pkg/educational/adaptive-engine.d.ts +11 -11
- package/dist-pkg/educational/adaptive-engine.js +17 -17
- package/dist-pkg/educational/segment-bar.d.ts +12 -12
- package/dist-pkg/educational/segment-bar.js +9 -9
- package/dist-pkg/i18n/en.js +321 -215
- package/dist-pkg/i18n/es.js +320 -215
- package/dist-pkg/i18n/pt.js +342 -215
- package/dist-pkg/input/default-bindings.d.ts +37 -38
- package/dist-pkg/input/default-bindings.js +127 -144
- package/dist-pkg/input/devices.d.ts +7 -7
- package/dist-pkg/input/devices.js +17 -16
- package/dist-pkg/input/edges.d.ts +23 -32
- package/dist-pkg/input/edges.js +23 -28
- package/dist-pkg/input/empathy-filter.d.ts +22 -0
- package/dist-pkg/input/empathy-filter.js +34 -0
- package/dist-pkg/input/face-map.d.ts +96 -0
- package/dist-pkg/input/face-map.js +255 -0
- package/dist-pkg/input/face-signals.d.ts +40 -0
- package/dist-pkg/input/face-signals.js +48 -0
- package/dist-pkg/input/gamepad.d.ts +164 -145
- package/dist-pkg/input/gamepad.js +351 -559
- package/dist-pkg/input/gaze-cycle.d.ts +64 -0
- package/dist-pkg/input/gaze-cycle.js +133 -0
- package/dist-pkg/input/gaze-relative.d.ts +68 -0
- package/dist-pkg/input/gaze-relative.js +142 -0
- package/dist-pkg/input/hand-map.d.ts +28 -0
- package/dist-pkg/input/hand-map.js +142 -0
- package/dist-pkg/input/input-cooldown.d.ts +17 -0
- package/dist-pkg/input/input-cooldown.js +39 -0
- package/dist-pkg/input/keyboard-runtime.d.ts +18 -20
- package/dist-pkg/input/keyboard-runtime.js +23 -27
- package/dist-pkg/input/keyboard.d.ts +68 -62
- package/dist-pkg/input/keyboard.js +83 -105
- package/dist-pkg/input/keydown.d.ts +124 -132
- package/dist-pkg/input/keydown.js +283 -288
- package/dist-pkg/input/latch-edge.d.ts +25 -21
- package/dist-pkg/input/latch-edge.js +33 -35
- package/dist-pkg/input/latch-scope.d.ts +43 -47
- package/dist-pkg/input/latch-scope.js +66 -75
- package/dist-pkg/input/latch-store.d.ts +28 -29
- package/dist-pkg/input/latch-store.js +44 -47
- package/dist-pkg/input/latch-sync.d.ts +28 -29
- package/dist-pkg/input/latch-sync.js +25 -25
- package/dist-pkg/input/latch.d.ts +14 -17
- package/dist-pkg/input/latch.js +29 -37
- package/dist-pkg/input/pad-defaults.d.ts +13 -16
- package/dist-pkg/input/pad-defaults.js +21 -28
- package/dist-pkg/input/pad-reading.d.ts +76 -0
- package/dist-pkg/input/pad-reading.js +164 -0
- package/dist-pkg/input/pad-wizard.d.ts +96 -0
- package/dist-pkg/input/pad-wizard.js +205 -0
- package/dist-pkg/input/pointer-space.d.ts +19 -20
- package/dist-pkg/input/pointer-space.js +27 -32
- package/dist-pkg/input/pointer.d.ts +39 -40
- package/dist-pkg/input/pointer.js +42 -45
- package/dist-pkg/input/state.d.ts +101 -89
- package/dist-pkg/input/state.js +54 -134
- package/dist-pkg/input/switch-scan.d.ts +42 -0
- package/dist-pkg/input/switch-scan.js +54 -0
- package/dist-pkg/input/synthetic-source.d.ts +42 -0
- package/dist-pkg/input/synthetic-source.js +57 -0
- package/dist-pkg/input/touch-bindings.d.ts +127 -113
- package/dist-pkg/input/touch-bindings.js +158 -173
- package/dist-pkg/input/touch.d.ts +130 -70
- package/dist-pkg/input/touch.js +321 -123
- package/dist-pkg/input/transport-in-use.d.ts +107 -0
- package/dist-pkg/input/transport-in-use.js +130 -0
- package/dist-pkg/input/transports.d.ts +96 -114
- package/dist-pkg/input/transports.js +104 -106
- package/dist-pkg/input/virtual-controller.d.ts +46 -0
- package/dist-pkg/input/virtual-controller.js +41 -0
- package/dist-pkg/input/vocabulary-migration.d.ts +50 -49
- package/dist-pkg/input/vocabulary-migration.js +80 -79
- package/dist-pkg/input/voice-map.d.ts +43 -0
- package/dist-pkg/input/voice-map.js +125 -0
- package/dist-pkg/platform/audio-ambient.d.ts +13 -1
- package/dist-pkg/platform/audio-ambient.js +11 -13
- package/dist-pkg/platform/audio-earcons.d.ts +20 -19
- package/dist-pkg/platform/audio-earcons.js +51 -42
- package/dist-pkg/platform/audio-jingles.js +9 -10
- package/dist-pkg/platform/audio-mixer.d.ts +14 -2
- package/dist-pkg/platform/audio-mixer.js +36 -39
- package/dist-pkg/platform/audio-sonar.d.ts +96 -113
- package/dist-pkg/platform/audio-sonar.js +245 -238
- package/dist-pkg/platform/audio.d.ts +53 -19
- package/dist-pkg/platform/audio.js +161 -169
- package/dist-pkg/platform/flash-sampler.d.ts +19 -0
- package/dist-pkg/platform/flash-sampler.js +79 -0
- package/dist-pkg/platform/guide-intensity.d.ts +26 -27
- package/dist-pkg/platform/guide-intensity.js +50 -52
- package/dist-pkg/platform/heavy-catalogue.d.ts +31 -0
- package/dist-pkg/platform/heavy-catalogue.js +223 -0
- package/dist-pkg/platform/heavy-mirror.d.ts +26 -0
- package/dist-pkg/platform/heavy-mirror.js +76 -0
- package/dist-pkg/platform/heavy.d.ts +104 -0
- package/dist-pkg/platform/heavy.js +169 -0
- package/dist-pkg/platform/interruptible-speech.d.ts +16 -16
- package/dist-pkg/platform/interruptible-speech.js +50 -51
- package/dist-pkg/platform/kokoro-port.d.ts +27 -0
- package/dist-pkg/platform/kokoro-port.js +50 -0
- package/dist-pkg/platform/kokoro-runtime.d.ts +20 -0
- package/dist-pkg/platform/kokoro-runtime.js +52 -0
- package/dist-pkg/platform/kokoro.d.ts +70 -0
- package/dist-pkg/platform/kokoro.js +133 -0
- package/dist-pkg/platform/listener-scope.d.ts +12 -0
- package/dist-pkg/platform/listener-scope.js +81 -0
- package/dist-pkg/platform/locale-host.d.ts +10 -0
- package/dist-pkg/platform/locale-host.js +34 -0
- package/dist-pkg/platform/microphone.d.ts +51 -0
- package/dist-pkg/platform/microphone.js +118 -0
- package/dist-pkg/platform/onnx-runtime.d.ts +34 -0
- package/dist-pkg/platform/onnx-runtime.js +42 -0
- package/dist-pkg/platform/reading-in-worker.d.ts +40 -0
- package/dist-pkg/platform/reading-in-worker.js +87 -0
- package/dist-pkg/platform/reading-model.d.ts +73 -0
- package/dist-pkg/platform/reading-model.js +247 -0
- package/dist-pkg/platform/reading-runtime.d.ts +24 -0
- package/dist-pkg/platform/reading-runtime.js +159 -0
- package/dist-pkg/platform/reading-worker.d.ts +41 -0
- package/dist-pkg/platform/reading-worker.js +58 -0
- package/dist-pkg/platform/reading.d.ts +69 -0
- package/dist-pkg/platform/reading.js +128 -0
- package/dist-pkg/platform/speech-recognition.d.ts +51 -0
- package/dist-pkg/platform/speech-recognition.js +84 -0
- package/dist-pkg/platform/speech.d.ts +14 -1
- package/dist-pkg/platform/speech.js +13 -13
- package/dist-pkg/platform/storage-keys.d.ts +96 -0
- package/dist-pkg/platform/storage-keys.js +106 -0
- package/dist-pkg/platform/storage.d.ts +46 -111
- package/dist-pkg/platform/storage.js +104 -169
- package/dist-pkg/platform/tts.d.ts +51 -38
- package/dist-pkg/platform/tts.js +217 -119
- package/dist-pkg/platform/vision-loop.d.ts +23 -0
- package/dist-pkg/platform/vision-loop.js +56 -0
- package/dist-pkg/platform/vision.d.ts +132 -0
- package/dist-pkg/platform/vision.js +117 -0
- package/dist-pkg/platform/voice-listener.d.ts +36 -0
- package/dist-pkg/platform/voice-listener.js +88 -0
- package/dist-pkg/platform/voice-plan.d.ts +6 -102
- package/dist-pkg/platform/voice-plan.js +9 -151
- package/dist-pkg/platform/vosk-runtime.d.ts +71 -0
- package/dist-pkg/platform/vosk-runtime.js +93 -0
- package/dist-pkg/render/canvas.d.ts +13 -7
- package/dist-pkg/render/canvas.js +13 -13
- package/dist-pkg/render/crt.d.ts +46 -12
- package/dist-pkg/render/crt.js +82 -80
- package/dist-pkg/render/cvd-matrices.d.ts +18 -18
- package/dist-pkg/render/cvd-matrices.js +33 -38
- package/dist-pkg/render/hc-role-data.d.ts +7 -7
- package/dist-pkg/render/hc-role-data.js +14 -14
- package/dist-pkg/render/high-contrast.d.ts +66 -54
- package/dist-pkg/render/high-contrast.js +221 -216
- package/dist-pkg/render/low-vision-drawing.d.ts +5 -0
- package/dist-pkg/render/low-vision-drawing.js +46 -0
- package/dist-pkg/render/lq-filter.d.ts +32 -20
- package/dist-pkg/render/lq-filter.js +59 -65
- package/dist-pkg/render/port.d.ts +86 -88
- package/dist-pkg/render/port.js +17 -23
- package/dist-pkg/render/screen-pipeline.d.ts +42 -42
- package/dist-pkg/render/screen-pipeline.js +80 -87
- package/dist-pkg/render/sprite-fx.d.ts +2 -1
- package/dist-pkg/render/sprite-fx.js +16 -14
- package/dist-pkg/render/viewports.d.ts +20 -15
- package/dist-pkg/render/viewports.js +83 -114
- package/dist-pkg/render/viz-axes-labels.d.ts +47 -0
- package/dist-pkg/render/viz-axes-labels.js +88 -0
- package/dist-pkg/render/viz-axes.d.ts +80 -86
- package/dist-pkg/render/viz-axes.js +115 -116
- package/dist-pkg/render/viz-modes.d.ts +28 -29
- package/dist-pkg/render/viz-modes.js +40 -45
- package/dist-pkg/render/viz-refusal.d.ts +32 -0
- package/dist-pkg/render/viz-refusal.js +57 -0
- package/dist-pkg/render/viz-setters.d.ts +104 -66
- package/dist-pkg/render/viz-setters.js +182 -191
- package/dist-pkg/ui/aac-sets.d.ts +40 -0
- package/dist-pkg/ui/aac-sets.js +49 -0
- package/dist-pkg/ui/audio-choices.d.ts +63 -0
- package/dist-pkg/ui/audio-choices.js +94 -0
- package/dist-pkg/ui/audio-rows-that-apply.d.ts +12 -0
- package/dist-pkg/ui/audio-rows-that-apply.js +43 -0
- package/dist-pkg/ui/camera-control.d.ts +6 -0
- package/dist-pkg/ui/camera-control.js +14 -0
- package/dist-pkg/ui/changed-mark.d.ts +9 -8
- package/dist-pkg/ui/changed-mark.js +22 -53
- package/dist-pkg/ui/control-choices.d.ts +37 -0
- package/dist-pkg/ui/control-choices.js +84 -0
- package/dist-pkg/ui/debug-panel.d.ts +59 -43
- package/dist-pkg/ui/debug-panel.js +68 -69
- package/dist-pkg/ui/dom.d.ts +10 -14
- package/dist-pkg/ui/dom.js +10 -47
- package/dist-pkg/ui/drawing-problems.d.ts +25 -0
- package/dist-pkg/ui/drawing-problems.js +93 -0
- package/dist-pkg/ui/eye-control.d.ts +36 -0
- package/dist-pkg/ui/eye-control.js +178 -0
- package/dist-pkg/ui/face-control.d.ts +25 -0
- package/dist-pkg/ui/face-control.js +183 -0
- package/dist-pkg/ui/focus-trap.d.ts +39 -49
- package/dist-pkg/ui/focus-trap.js +56 -65
- package/dist-pkg/ui/fonts.d.ts +118 -63
- package/dist-pkg/ui/fonts.js +267 -111
- package/dist-pkg/ui/game-options.d.ts +42 -0
- package/dist-pkg/ui/game-options.js +138 -0
- package/dist-pkg/ui/gaze-overlay.d.ts +64 -0
- package/dist-pkg/ui/gaze-overlay.js +165 -0
- package/dist-pkg/ui/hand-control.d.ts +25 -0
- package/dist-pkg/ui/hand-control.js +143 -0
- package/dist-pkg/ui/help-panel.d.ts +76 -0
- package/dist-pkg/ui/help-panel.js +232 -0
- package/dist-pkg/ui/hud-bands.d.ts +45 -0
- package/dist-pkg/ui/hud-bands.js +108 -0
- package/dist-pkg/ui/hud.d.ts +73 -70
- package/dist-pkg/ui/hud.js +94 -98
- package/dist-pkg/ui/item-announcement.d.ts +13 -12
- package/dist-pkg/ui/item-announcement.js +25 -26
- package/dist-pkg/ui/latch-refusal.d.ts +22 -21
- package/dist-pkg/ui/latch-refusal.js +37 -37
- package/dist-pkg/ui/layout.d.ts +103 -28
- package/dist-pkg/ui/layout.js +114 -99
- package/dist-pkg/ui/locale-flags.d.ts +16 -0
- package/dist-pkg/ui/locale-flags.js +30 -0
- package/dist-pkg/ui/loop-crash.d.ts +17 -17
- package/dist-pkg/ui/loop-crash.js +33 -62
- package/dist-pkg/ui/menu-intent.d.ts +32 -0
- package/dist-pkg/ui/menu-intent.js +54 -0
- package/dist-pkg/ui/menu-items.d.ts +10 -0
- package/dist-pkg/ui/menu-items.js +22 -0
- package/dist-pkg/ui/menu-nav.d.ts +60 -90
- package/dist-pkg/ui/menu-nav.js +301 -274
- package/dist-pkg/ui/mobility-choices.d.ts +26 -0
- package/dist-pkg/ui/mobility-choices.js +41 -0
- package/dist-pkg/ui/motion-choices.d.ts +31 -0
- package/dist-pkg/ui/motion-choices.js +68 -0
- package/dist-pkg/ui/motion-scene.d.ts +24 -19
- package/dist-pkg/ui/motion-scene.js +29 -61
- package/dist-pkg/ui/mount-panel.d.ts +81 -0
- package/dist-pkg/ui/mount-panel.js +61 -0
- package/dist-pkg/ui/panel-shell.d.ts +65 -31
- package/dist-pkg/ui/panel-shell.js +92 -66
- package/dist-pkg/ui/panel-widgets.d.ts +116 -0
- package/dist-pkg/ui/panel-widgets.js +208 -0
- package/dist-pkg/ui/pause-buttons.d.ts +35 -0
- package/dist-pkg/ui/pause-buttons.js +66 -0
- package/dist-pkg/ui/pause-icons.d.ts +250 -343
- package/dist-pkg/ui/pause-icons.js +614 -605
- package/dist-pkg/ui/pause-markup.d.ts +86 -0
- package/dist-pkg/ui/pause-markup.js +125 -0
- package/dist-pkg/ui/reach-notice.d.ts +22 -23
- package/dist-pkg/ui/reach-notice.js +55 -58
- package/dist-pkg/ui/scan-overlay.d.ts +23 -0
- package/dist-pkg/ui/scan-overlay.js +42 -0
- package/dist-pkg/ui/settings-aac.d.ts +68 -0
- package/dist-pkg/ui/settings-aac.js +189 -0
- package/dist-pkg/ui/settings-audio.d.ts +91 -113
- package/dist-pkg/ui/settings-audio.js +407 -405
- package/dist-pkg/ui/settings-controls.d.ts +53 -92
- package/dist-pkg/ui/settings-controls.js +143 -215
- package/dist-pkg/ui/settings-empathy.d.ts +39 -30
- package/dist-pkg/ui/settings-empathy.js +53 -60
- package/dist-pkg/ui/settings-mobility.d.ts +195 -0
- package/dist-pkg/ui/settings-mobility.js +374 -0
- package/dist-pkg/ui/settings-motion.d.ts +91 -70
- package/dist-pkg/ui/settings-motion.js +287 -198
- package/dist-pkg/ui/settings-panel.d.ts +48 -45
- package/dist-pkg/ui/settings-panel.js +164 -93
- package/dist-pkg/ui/settings-typo.d.ts +28 -76
- package/dist-pkg/ui/settings-typo.js +145 -125
- package/dist-pkg/ui/settings-visual.d.ts +29 -87
- package/dist-pkg/ui/settings-visual.js +240 -193
- package/dist-pkg/ui/shell.d.ts +113 -134
- package/dist-pkg/ui/shell.js +143 -216
- package/dist-pkg/ui/simulation-list.d.ts +27 -0
- package/dist-pkg/ui/simulation-list.js +76 -0
- package/dist-pkg/ui/simulation-over-the-world.d.ts +23 -0
- package/dist-pkg/ui/simulation-over-the-world.js +131 -0
- package/dist-pkg/ui/simulation-refusal.d.ts +5 -31
- package/dist-pkg/ui/simulation-refusal.js +8 -56
- package/dist-pkg/ui/switchable-control.d.ts +11 -0
- package/dist-pkg/ui/switchable-control.js +19 -0
- package/dist-pkg/ui/title.d.ts +4 -4
- package/dist-pkg/ui/title.js +11 -13
- package/dist-pkg/ui/top-band.d.ts +24 -0
- package/dist-pkg/ui/top-band.js +100 -0
- package/dist-pkg/ui/typo-choices.d.ts +71 -0
- package/dist-pkg/ui/typo-choices.js +84 -0
- package/dist-pkg/ui/visual-axes-panel.d.ts +11 -47
- package/dist-pkg/ui/visual-axes-panel.js +12 -94
- package/dist-pkg/ui/visual-choices.d.ts +77 -0
- package/dist-pkg/ui/visual-choices.js +107 -0
- package/dist-pkg/ui/vlibras.d.ts +33 -10
- package/dist-pkg/ui/vlibras.js +58 -81
- package/dist-pkg/ui/voice-control.d.ts +46 -0
- package/dist-pkg/ui/voice-control.js +143 -0
- package/dist-pkg/ui/voice-settings.d.ts +96 -0
- package/dist-pkg/ui/voice-settings.js +302 -0
- package/dist-pkg/ui/where-the-child-is.d.ts +31 -0
- package/dist-pkg/ui/where-the-child-is.js +70 -0
- package/docs/CREDITS.md +198 -54
- package/docs/LICENSES.md +160 -145
- package/package.json +24 -25
- package/scripts/heavy-into-the-delivery.mjs +144 -0
- package/scripts/licences/Apache-2.0.txt +176 -0
- package/scripts/licences/GPL-3.0.txt +674 -0
- package/scripts/licences/MIT.txt +17 -0
- package/scripts/licences/third-party.mjs +287 -0
- package/scripts/licences/vosk-browser.NOTICE.txt +268 -0
- package/app/public/vendor/fonts/comicneue-400.woff2 +0 -0
- package/app/public/vendor/fonts/comicneue-700.woff2 +0 -0
- package/dist-pkg/core/anel.d.ts +0 -17
- package/dist-pkg/core/anel.js +0 -31
- package/dist-pkg/core/collision.d.ts +0 -21
- package/dist-pkg/core/collision.js +0 -62
- package/dist-pkg/core/layers.d.ts +0 -63
- package/dist-pkg/core/layers.js +0 -95
- package/dist-pkg/core/letter-grid.d.ts +0 -55
- package/dist-pkg/core/letter-grid.js +0 -116
- package/dist-pkg/core/password.d.ts +0 -34
- package/dist-pkg/core/password.js +0 -205
- package/dist-pkg/core/rotulo-acessivel.d.ts +0 -17
- package/dist-pkg/core/rotulo-acessivel.js +0 -41
- package/dist-pkg/core/run-state.d.ts +0 -115
- package/dist-pkg/core/run-state.js +0 -40
- package/dist-pkg/core/tiles.d.ts +0 -12
- package/dist-pkg/core/tiles.js +0 -61
- package/dist-pkg/core/world.d.ts +0 -4
- package/dist-pkg/core/world.js +0 -58
- package/dist-pkg/input/origem-sintetica.d.ts +0 -44
- package/dist-pkg/input/origem-sintetica.js +0 -60
- package/dist-pkg/input/transporte-em-uso.d.ts +0 -101
- package/dist-pkg/input/transporte-em-uso.js +0 -130
- package/dist-pkg/platform/audio-nav.d.ts +0 -51
- package/dist-pkg/platform/audio-nav.js +0 -99
- package/dist-pkg/platform/pesados-catalogo.d.ts +0 -14
- package/dist-pkg/platform/pesados-catalogo.js +0 -177
- package/dist-pkg/platform/pesados.d.ts +0 -31
- package/dist-pkg/platform/pesados.js +0 -75
- package/dist-pkg/platform/vozes-prontas.d.ts +0 -28
- package/dist-pkg/platform/vozes-prontas.js +0 -61
- package/dist-pkg/render/camera.d.ts +0 -58
- package/dist-pkg/render/camera.js +0 -105
- package/dist-pkg/render/cenario-data.d.ts +0 -127
- package/dist-pkg/render/cenario-data.js +0 -145
- package/dist-pkg/render/city-tex.d.ts +0 -63
- package/dist-pkg/render/city-tex.js +0 -228
- package/dist-pkg/render/city-tiles.d.ts +0 -11
- package/dist-pkg/render/city-tiles.js +0 -140
- package/dist-pkg/render/draw.d.ts +0 -149
- package/dist-pkg/render/draw.js +0 -231
- package/dist-pkg/render/fx.d.ts +0 -63
- package/dist-pkg/render/fx.js +0 -123
- package/dist-pkg/render/minimap.d.ts +0 -11
- package/dist-pkg/render/minimap.js +0 -94
- package/dist-pkg/render/parallax.d.ts +0 -85
- package/dist-pkg/render/parallax.js +0 -158
- package/dist-pkg/render/player-anim.d.ts +0 -71
- package/dist-pkg/render/player-anim.js +0 -152
- package/dist-pkg/render/recycling-tex.d.ts +0 -48
- package/dist-pkg/render/recycling-tex.js +0 -164
- package/dist-pkg/render/scene-city.d.ts +0 -77
- package/dist-pkg/render/scene-city.js +0 -181
- package/dist-pkg/render/scene-parallax.d.ts +0 -72
- package/dist-pkg/render/scene-parallax.js +0 -426
- package/dist-pkg/render/scene-sky.d.ts +0 -126
- package/dist-pkg/render/scene-sky.js +0 -295
- package/dist-pkg/render/set-cenario.d.ts +0 -54
- package/dist-pkg/render/set-cenario.js +0 -103
- package/dist-pkg/render/textures.d.ts +0 -75
- package/dist-pkg/render/textures.js +0 -240
- package/dist-pkg/render/title-scene.d.ts +0 -46
- package/dist-pkg/render/title-scene.js +0 -75
- package/dist-pkg/render/weather.d.ts +0 -96
- package/dist-pkg/render/weather.js +0 -171
- package/dist-pkg/render/wheelchair-sprites.d.ts +0 -32
- package/dist-pkg/render/wheelchair-sprites.js +0 -69
- package/dist-pkg/render/world-tex.d.ts +0 -18
- package/dist-pkg/render/world-tex.js +0 -87
- package/dist-pkg/ui/activities-menu.d.ts +0 -258
- package/dist-pkg/ui/activities-menu.js +0 -648
- package/dist-pkg/ui/caa-sets.d.ts +0 -39
- package/dist-pkg/ui/caa-sets.js +0 -65
- package/dist-pkg/ui/map-hub.d.ts +0 -56
- package/dist-pkg/ui/map-hub.js +0 -138
- package/dist-pkg/ui/settings-caa.d.ts +0 -45
- package/dist-pkg/ui/settings-caa.js +0 -137
- package/dist-pkg/ui/settings-motor.d.ts +0 -175
- package/dist-pkg/ui/settings-motor.js +0 -342
- package/dist-pkg/ui/webcam.d.ts +0 -7
- package/dist-pkg/ui/webcam.js +0 -93
package/app/css/style.css
CHANGED
|
@@ -1,47 +1,60 @@
|
|
|
1
1
|
/* SPDX-License-Identifier: AGPL-3.0-or-later */
|
|
2
2
|
:root{
|
|
3
|
+
/* The engine stylesheet's sentinel: `createGame` reads it to say in `problems` when a page did not link this file. */
|
|
4
|
+
--incl-engine-stylesheet:1;
|
|
3
5
|
--bg:#0b1020; --panel:#1b2440; --ink:#f5f8ff; --ink-soft:#cdd6f2;
|
|
4
6
|
--accent:#ffd23f; --accent-ink:#1a1400; --focus:#ffd23f; --good:#34e29b;
|
|
5
|
-
--changed:#fff; /* ADR-0029:
|
|
6
|
-
/*
|
|
7
|
-
|
|
7
|
+
--changed:#fff; /* ADR-0029: the frame of a setting that left its default */
|
|
8
|
+
/* High contrast in the DOM (issue #83): the panel veil without transparency, and the button background. They live here,
|
|
9
|
+
beside the other tokens, so the contrast test can read them from the CSS instead of copying them. */
|
|
8
10
|
--bg-solid:#04070f; --panel-btn:#1a2740;
|
|
9
11
|
--maxw:1000px; --tap:44px;
|
|
10
|
-
--ui-fs:16px; /*
|
|
11
|
-
/* =====
|
|
12
|
-
/* 'Noto Color Emoji'
|
|
12
|
+
--ui-fs:16px; /* the UI's base font size (<p>): 16px = the MINIMUM at 640×360; `ui/layout` raises it as the canvas grows */
|
|
13
|
+
/* ===== The engine's typography ===== */
|
|
14
|
+
/* 'Noto Color Emoji' at the end of the stack → consistent emoji (native on Chromebook/Android; the system face elsewhere) */
|
|
13
15
|
--font-fallback:system-ui,"Segoe UI",Roboto,Arial,sans-serif,'Noto Color Emoji';
|
|
14
|
-
--font:'Atkinson Hyperlegible',var(--font-fallback); /*
|
|
15
|
-
--font-math:'Atkinson Hyperlegible Mono',ui-monospace,"Cascadia Mono",Consolas,monospace; /*
|
|
16
|
-
/*
|
|
17
|
-
|
|
18
|
-
|
|
16
|
+
--font:'Atkinson Hyperlegible',var(--font-fallback); /* DEFAULT */
|
|
17
|
+
--font-math:'Atkinson Hyperlegible Mono',ui-monospace,"Cascadia Mono",Consolas,monospace; /* mathematics */
|
|
18
|
+
/* ===== SPACING: THE DEFAULT ROSE FROM THE WCAG FLOOR TO THE BDA'S (ADR-0149 §2) =====
|
|
19
|
+
It was 0.12em/0.16em — the floor of WCAG 2.2 §1.4.12 —, and it is now 0.18em/0.63em, the British Dyslexia
|
|
20
|
+
Association's recommendation: word ≥ 3.5× letter. The Dev's decision on 2026-09-12: «somente fontes
|
|
21
|
+
cursivas não precisam seguir; ao usar todas as outras fontes, é obrigatório seguir».
|
|
22
|
+
|
|
23
|
+
⚠️ THIS USED TO BE THE EXCEPTION OF ONE FACE. The BDA numbers lived only in `[data-fonte="dislexia"]` (Lexend),
|
|
24
|
+
and the DEFAULT face — Atkinson, which every game draws — sat on the WCAG floor. It was not «no spacing at all»,
|
|
25
|
+
as a first version of the record said; it was the lower of the two floors, applied because of a LABEL instead of
|
|
26
|
+
because of a rule about faces.
|
|
27
|
+
|
|
28
|
+
🔴 AND THE REACH OF THIS IS EVERY GAME: changing the default face's spacing changes the metrics of every screen at
|
|
29
|
+
once. It is the right rule, and it is a layout change in every game that uses the engine. */
|
|
30
|
+
--ls:0.18em; /* letter-spacing — BDA */
|
|
31
|
+
--ws:0.63em; /* word-spacing — BDA (≥ 3.5× the letter) */
|
|
19
32
|
--lh:1.5; /* line-height */
|
|
20
33
|
|
|
21
|
-
/* =====
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
⚠️
|
|
43
|
-
|
|
44
|
-
|
|
34
|
+
/* ===== THE Z-ORDER SLOTS — the engine's canonical stacking order (ADR-0020, ADR-0102) =====
|
|
35
|
+
These `--z-*` variables are where the z-order lives now. They were born as the OVERLAY band of the `Z` table in
|
|
36
|
+
`core/layers.ts`; that table was the platformer's world order and left with the tile world (ADR-0228), so the
|
|
37
|
+
slots below are the only copy. `tests/the-skip-link-outranks-the-transition.node.test.js` holds what the engine
|
|
38
|
+
needs of them: the skip link sits on its slot, above the transition and every other slot except the loop-crash
|
|
39
|
+
notice and the debug panel, and no literal `z-index` in this file reaches it.
|
|
40
|
+
|
|
41
|
+
⚠️ MOST SELECTORS STILL CARRY LITERALS, and that is not forgetfulness. Only `.skip-link`, `#incl-parou` and the
|
|
42
|
+
touch pad over an open panel read a slot. Adopting the slots everywhere inverts three orders that hold today, and
|
|
43
|
+
inverting an order is a product decision:
|
|
44
|
+
|
|
45
|
+
· `.caption` (8) is BELOW the touch pad (14). In the slots, captions (26000) are ABOVE touch controls (25000).
|
|
46
|
+
The inversion FIXES a defect — the caption serves deaf players, and a touch control covering it is the wrong
|
|
47
|
+
way round —, but it changes the screen.
|
|
48
|
+
· `.quiz` (12) is BELOW the touch pad (14); in the slots, dialogue (27000) is above.
|
|
49
|
+
· the skip link was already corrected: it sits on `--z-skip-link`, above the modals and the transition.
|
|
50
|
+
|
|
51
|
+
AND TWO THINGS HAVE NO SLOT: the two CRT pseudo-elements (`crt-vig-1::before` at 5 and `crt-scan-1::after` at
|
|
52
|
+
500). Under ADR-0020 the CRT is POST-PROCESSING, not a layer — inventing a number for it would repeat the category
|
|
53
|
+
error the record already names.
|
|
54
|
+
|
|
55
|
+
⚠️ AND CSS `z-index` IS NOT FLAT. `#game-hud` has `z-index:4` and CREATES A STACKING CONTEXT, so `.screen-pause`
|
|
56
|
+
(6) competes only inside it — the pause menu effectively lives at "4" at the root. A flat list of global values
|
|
57
|
+
cannot express that. Adopting the slots means deciding, per element, which context it lives in. */
|
|
45
58
|
--z-hud:24000;
|
|
46
59
|
--z-touch-controls:25000;
|
|
47
60
|
--z-captions:26000;
|
|
@@ -55,326 +68,342 @@
|
|
|
55
68
|
--z-loop-crash:45000;
|
|
56
69
|
--z-debug:90000;
|
|
57
70
|
}
|
|
58
|
-
/* Emoji:
|
|
59
|
-
|
|
60
|
-
@font-face{ font-family:'Noto Color Emoji'; src:local('Noto Color Emoji'); /*
|
|
61
|
-
/*
|
|
71
|
+
/* Emoji: the system's Noto Color Emoji (Chromebook/Android/Linux). No file is shipped for it, so where the system
|
|
72
|
+
lacks it the browser falls back to the OS emoji — without breaking. */
|
|
73
|
+
@font-face{ font-family:'Noto Color Emoji'; src:local('Noto Color Emoji'); /* the system face only; no download (the .woff2 never existed) */ font-display:swap; }
|
|
74
|
+
/* LITERACY mode → Andika */
|
|
62
75
|
:root[data-fonte="alfabetizacao"]{ --font:'Andika',var(--font-fallback); }
|
|
63
|
-
/*
|
|
64
|
-
|
|
65
|
-
:root[data-fonte="dislexia"]{ --font:'Lexend',var(--font-fallback);
|
|
66
|
-
/*
|
|
76
|
+
/* DYSLEXIA/ADHD mode → Lexend. 📌 The BDA spacing is not here: it is the document's default (see `:root`, ADR-0149 §2),
|
|
77
|
+
not this face's exception. The rule keeps only the FAMILY, which is all it ever had of its own. */
|
|
78
|
+
:root[data-fonte="dislexia"]{ --font:'Lexend',var(--font-fallback); }
|
|
79
|
+
/* ===== THE CURSIVE EXCEPTION (ADR-0149 §3) =====
|
|
80
|
+
🔴 Letter spacing on a JOINED face breaks it exactly at the joins that make it cursive: what is meant to help the
|
|
81
|
+
reading would destroy the thing being read. The Dev's words: «para manter os conectores».
|
|
82
|
+
It is not a concession — it is the same rule applied to a face where it inverts.
|
|
83
|
+
⚠️ `normal` and not `0`: `word-spacing:0` is still a spacing declaration; `normal` gives back the metrics the face's
|
|
84
|
+
designer chose, which is precisely what is meant to be preserved. */
|
|
85
|
+
:root[data-cursiva="1"]{ --ls:normal; --ws:normal; }
|
|
86
|
+
/* A COLOUR-VISION-SAFE PALETTE FOR THE MENUS AND THE HUD (ADR-0151) — Okabe-Ito.
|
|
87
|
+
📏 The interface's meaning-by-colour sits in two tokens: `--accent` (selection, «on», choice) and `--good` (the right
|
|
88
|
+
answer revealed). The usual pair, yellow and green, is the one protans and deutans confuse: CIE76 ΔE of 48 and 55
|
|
89
|
+
after Machado's (2009) simulation. Orange and sky blue give 101, 111 and 87 (tritan) — the largest worst case among
|
|
90
|
+
the Okabe-Ito pairs measured — and every contrast stays ≥ 4.5:1 (the tightest is `--good` on the selected button,
|
|
91
|
+
4.88:1). The gate is `tests/okabe-ito-palette.node.test.js`. */
|
|
92
|
+
:root[data-paleta="okabe-ito"]{ --accent:#E69F00; --focus:#E69F00; --good:#56B4E9; }
|
|
93
|
+
/* Typography: any face of the catalogue (its own menu in the pause); --font-custom brings the stack with its fallback */
|
|
67
94
|
:root[data-fonte="custom"]{ --font:var(--font-custom,'Atkinson Hyperlegible'),var(--font-fallback); }
|
|
68
|
-
/*
|
|
95
|
+
/* Typography menu: a white preview box (pangram), dark text */
|
|
69
96
|
.typo-preview{background:#fff;color:#14141f;border:2px solid var(--ink-soft);border-radius:8px;padding:.65rem .9rem;margin:.2rem 0 .6rem;font-size:1.3em;line-height:1.3;text-align:center}
|
|
70
|
-
/*
|
|
71
|
-
#title-overlay{background:transparent;font-size:var(--ui-fs,16px)} /* UI
|
|
72
|
-
body.at-title #game-hud,body.at-title .start-tips,body.at-title .hud{display:none} /* HUD
|
|
97
|
+
/* Title screen: a TRANSPARENT overlay — the scene behind it comes from the canvas */
|
|
98
|
+
#title-overlay{background:transparent;font-size:var(--ui-fs,16px)} /* the splash UI scales with the canvas's integer k (like the pause and the dialogs) — it does NOT stay at 16px */
|
|
99
|
+
body.at-title #game-hud,body.at-title .start-tips,body.at-title .hud{display:none} /* the game's HUD does not leak into the start menu (display: children cannot show themselves again) */
|
|
73
100
|
.title-wrap{display:flex;flex-direction:column;align-items:center;gap:12px;max-height:96%;}
|
|
74
|
-
.game-title{color:#fff;font-size:2em;line-height:1.2;margin:0;text-align:center;letter-spacing:
|
|
101
|
+
.game-title{color:#fff;font-size:2em;line-height:1.2;margin:0;text-align:center;letter-spacing:var(--ls);text-shadow:2px 2px 0 #0d0d1a,-1px -1px 0 #0d0d1a}
|
|
75
102
|
.title-block{display:inline-block}
|
|
76
|
-
.game-byline{color:#f6f5f0;font-size
|
|
77
|
-
.game-version{color:#9999b3;font-size
|
|
78
|
-
.game-subtitle{color:#f6f5f0;font-size
|
|
79
|
-
/*
|
|
103
|
+
.game-byline{color:#f6f5f0;font-size:1em;text-align:right;margin-top:2px;text-shadow:1px 1px 0 #0d0d1a}
|
|
104
|
+
.game-version{color:#9999b3;font-size:1em;text-align:right;letter-spacing:var(--ls);margin-top:2px;text-shadow:1px 1px 0 #0d0d1a}
|
|
105
|
+
.game-subtitle{color:#f6f5f0;font-size:1em;margin:0 0 4px;text-shadow:1px 1px 0 #0d0d1a;text-align:center}
|
|
106
|
+
/* The splash INSIDE the canvas, with NO scrolling. GESTALT (the Dev): a11y in the HEADER · menu in the WORKSPACE · legend in the FOOTER */
|
|
80
107
|
.title-wrap{position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:center;max-height:none}
|
|
81
|
-
.title-legend{position:absolute;left:0;right:0;bottom:8px} /*
|
|
82
|
-
.title-menu{display:flex;flex-direction:column;gap:.35em;align-items:stretch;padding:2px;width:13em;margin:0 auto} /*
|
|
108
|
+
.title-legend{position:absolute;left:0;right:0;bottom:8px} /* FOOTER, like the pause legend */
|
|
109
|
+
.title-menu{display:flex;flex-direction:column;gap:.35em;align-items:stretch;padding:2px;width:13em;margin:0 auto} /* a fixed, LEAN width */
|
|
83
110
|
.title-menu[hidden]{display:none}
|
|
84
|
-
/*
|
|
85
|
-
|
|
86
|
-
|
|
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. */
|
|
87
114
|
#tm-main{width:26em}
|
|
88
|
-
/* =====================
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
115
|
+
/* ===================== THE OPENING SUBMENUS: A VERTICAL LIST THAT SCROLLS (ADR-0044) =====================
|
|
116
|
+
They were two-column GRIDS, and the arrow moves in DOM order: “down” jumped to the right-hand column, across the
|
|
117
|
+
screen. The ring of item 1 was already right in the code (`nextTitleIndex` wraps around) — it was the LAYOUT that
|
|
118
|
+
lied about it. In a list, the order you SEE is the order you MOVE in.
|
|
92
119
|
|
|
93
|
-
|
|
94
|
-
`focus()`
|
|
95
|
-
|
|
120
|
+
Eleven fractions do not fit the frame, so the list SCROLLS — which is what the Dev asked for, and the price is low:
|
|
121
|
+
`focus()` brings the item into view by itself, so whoever moves by keyboard or controller never loses the focus
|
|
122
|
+
out of sight.
|
|
96
123
|
|
|
97
|
-
|
|
98
|
-
|
|
124
|
+
The panel is OPAQUE for the same reason as the pause veil: the attract mode runs behind the opening, and text over a
|
|
125
|
+
changing frame has whatever contrast the frame allows — an average of luck, not a guarantee. */
|
|
99
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}
|
|
100
|
-
/*
|
|
101
|
-
|
|
127
|
+
/* The submenu's title STICKS to the top: in a scrolling list, a heading that scrolls away takes with it the only
|
|
128
|
+
“where am I” cue that someone reading with residual vision has. */
|
|
102
129
|
#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}
|
|
103
|
-
/* …
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
130
|
+
/* …and that is why the items need a SCROLL MARGIN: a sticky heading covers the item the browser has just "brought into
|
|
131
|
+
view", because for the browser the item was already inside the frame. MEASURED in the browser before this line
|
|
132
|
+
existed: wrapping from the last item to the first, the first button stopped with its top at 143px while the heading
|
|
133
|
+
ended at 155 — 12px covered, and the child saw a cut-off item where the focus was. The value covers the heading's
|
|
134
|
+
height (34px ≈ 2.1em) with room to spare. */
|
|
108
135
|
#tm-alf .title-btn,#tm-mat .title-btn,#tm-tab .title-btn,#tm-fr .title-btn,#tm-cen .title-btn{scroll-margin-top:2.4em;scroll-margin-bottom:.5em}
|
|
109
|
-
/*
|
|
110
|
-
|
|
136
|
+
/* The fraction notations stay SIDE BY SIDE: they are five toggles of ONE group, not list items — turning them into a
|
|
137
|
+
column here would lengthen the scroll without adding any order. */
|
|
111
138
|
#tm-fr .frac-nots{display:flex;flex-direction:column;gap:.25em}
|
|
112
|
-
/*
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
139
|
+
/* THE FIVE NOTATIONS ARE SETTINGS, NOT MENU ITEMS (the Dev's request). They used `.title-btn` — the same class as the
|
|
140
|
+
buttons that OPEN an activity — and were stacked right above them: five things that looked like "enter" and in fact
|
|
141
|
+
switch on and off. The frame (`fieldset`/`legend`) is the boundary, and the ☑/☐ mark is the state without relying
|
|
142
|
+
on colour (colour alone fails WCAG 1.4.1). */
|
|
116
143
|
#tm-fr .frac-nots{border:2px solid var(--ink-soft);border-radius:10px;padding:.3em .5em .5em;margin:0 0 .45em}
|
|
117
|
-
#tm-fr .frac-nots legend{padding:0 .4em;font-size
|
|
144
|
+
#tm-fr .frac-nots legend{padding:0 .4em;font-size:1em;font-weight:700;color:var(--ink-soft)}
|
|
118
145
|
#tm-fr .fnot-opt{display:flex;align-items:center;gap:.5em;width:100%;min-height:44px;padding:.2em .4em;background:transparent;color:#fff;border:0;border-radius:8px;font:inherit;cursor:pointer;text-align:left}
|
|
119
146
|
#tm-fr .fnot-opt:hover,#tm-fr .fnot-opt:focus-visible{background:#16233f}
|
|
120
147
|
#tm-fr .fnot-marca{font-size:1.15em;line-height:1;min-width:1.1em}
|
|
121
148
|
#tm-fr .fnot-opt[aria-checked="true"] .fnot-marca{color:var(--accent)}
|
|
122
149
|
#tm-fr .fnot-sym{font-size:1em}
|
|
123
|
-
#tm-fr .fnot-opt .fv{font-size
|
|
124
|
-
.tm-title{color:#fff;font-size:1em;margin:0 0 .1em;text-align:center;text-shadow:1px 1px 0 #0d0d1a} /*
|
|
125
|
-
.title-btn{background:var(--accent);color:var(--accent-ink);border:3px solid #0d0d1a;font-family:inherit;font-weight:bold;font-size
|
|
126
|
-
.title-btn.ghost{background:#e8862b;color:#0d0d1a;border:2px solid #0d0d1a} /*
|
|
127
|
-
.act-sub{display:block;font-size
|
|
128
|
-
/*
|
|
150
|
+
#tm-fr .fnot-opt .fv{font-size:1em}
|
|
151
|
+
.tm-title{color:#fff;font-size:1em;margin:0 0 .1em;text-align:center;text-shadow:1px 1px 0 #0d0d1a} /* the submenu's title */
|
|
152
|
+
.title-btn{background:var(--accent);color:var(--accent-ink);border:3px solid #0d0d1a;font-family:inherit;font-weight:bold;font-size:1em;padding:.4em .6em;border-radius:6px;cursor:pointer;min-width:0;width:100%;min-height:2.3em} /* a thick BLACK outline (3px) = the same colour as the text (the Dev) */
|
|
153
|
+
.title-btn.ghost{background:#e8862b;color:#0d0d1a;border:2px solid #0d0d1a} /* Back = ORANGE fill */
|
|
154
|
+
.act-sub{display:block;font-size:1em;font-weight:600;opacity:.7;letter-spacing:var(--ls);margin-top:.06em;font-family:var(--font-math,inherit);white-space:nowrap} /* the example subtitle (2nd line, NEVER wraps — the button is wide enough) */
|
|
155
|
+
/* A fixed RED selector (blinking removed at the Dev's request). Specificity through #title-overlay. */
|
|
129
156
|
#title-overlay .title-btn:focus-visible,#title-overlay .title-btn:focus{outline:4px solid #ff3b30;outline-offset:2px}
|
|
130
|
-
#title-overlay .title-btn.act-fx{animation:titleAct .22s ease} /*
|
|
157
|
+
#title-overlay .title-btn.act-fx{animation:titleAct .22s ease} /* the ACTIVATION effect (before the screen changes) */
|
|
131
158
|
@keyframes titleAct{0%{transform:scale(.92);filter:brightness(1.6)}60%{transform:scale(1.03)}100%{transform:scale(1)}}
|
|
132
159
|
@media (prefers-reduced-motion: reduce){ #title-overlay .title-btn.act-fx{animation:none;filter:brightness(1.4)} }
|
|
133
160
|
.title-btn.tab-on{box-shadow:inset 0 0 0 3px #14141f}
|
|
134
|
-
/*
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
161
|
+
/* The times-table rows were TWO lines of numbers side by side, and the Dev objected again after seeing the result: a
|
|
162
|
+
"mixed" menu is a menu where "down" sometimes moves sideways. They became a column, like the rest of the opening.
|
|
163
|
+
The selector carries `#tm-tab` in front on purpose — that is what lets the layout gate see this rule as belonging TO
|
|
164
|
+
an opening submenu, instead of a loose class nobody watches. */
|
|
138
165
|
#tm-tab .tab-row{display:flex;flex-direction:column;gap:.35em}
|
|
139
166
|
#tm-tab .tab-row .title-btn{width:100%;padding:.4em .5em}
|
|
140
|
-
/*
|
|
141
|
-
|
|
142
|
-
.tm-desc:not(:empty){position:absolute;left:50%;transform:translateX(-50%);bottom:10px;max-width:88%;color:#f6f5f0;font-size
|
|
167
|
+
/* FOOTER (the same style as the pause menu): the description at the bottom of the canvas, NOT glued to the button group (the Dev).
|
|
168
|
+
A smoked BLACK background → contrast ≥7:1 between the light text (#f6f5f0) and the background (≈#0a0a12). */
|
|
169
|
+
.tm-desc:not(:empty){position:absolute;left:50%;transform:translateX(-50%);bottom:10px;max-width:88%;color:#f6f5f0;font-size:1em;text-align:center;background:rgba(8,8,16,.92);padding:.35em .7em;border-radius:8px;line-height:1.25}
|
|
143
170
|
.tm-desc:empty{position:absolute;left:0;bottom:10px}
|
|
144
|
-
/*
|
|
145
|
-
.title-legend{display:flex;flex-direction:column;gap:.25em;align-items:center;margin:.5em 0 .1em;font-size
|
|
171
|
+
/* Controls legend: the same look and place as the pause menu's legend (chips), on 2 LINES */
|
|
172
|
+
.title-legend{display:flex;flex-direction:column;gap:.25em;align-items:center;margin:.5em 0 .1em;font-size:1em;color:#c3cfe0}
|
|
146
173
|
.title-legend .lg-row{display:flex;gap:1.1em;justify-content:center;flex-wrap:wrap}
|
|
147
174
|
.title-legend .lg{display:inline-flex;align-items:center;gap:.35em}
|
|
148
|
-
.title-legend .lg-ico{display:inline-flex;align-items:center;justify-content:center;min-width:1.35em;height:1.35em;padding:0 .2em;border-radius:.68em;font-weight:800;font-size
|
|
149
|
-
#title-icons{position:absolute;top:
|
|
150
|
-
|
|
151
|
-
|
|
175
|
+
.title-legend .lg-ico{display:inline-flex;align-items:center;justify-content:center;min-width:1.35em;height:1.35em;padding:0 .2em;border-radius:.68em;font-weight:800;font-size:1em;color:#fff;background:rgba(13,13,26,.85);text-shadow:0 1px 1px rgba(0,0,0,.55)}
|
|
176
|
+
#title-icons{position:absolute;top:0;left:50%;transform:translateX(-50%);display:flex;gap:0;justify-content:center;flex-wrap:nowrap;white-space:nowrap} /* header: on the screen's top edge, giving that room to the game (interface log 2026-09-13), ONE row */
|
|
177
|
+
#title-icons.pause-icons{margin:0 0 calc(.35rem * var(--espaco-fixo,1))}
|
|
178
|
+
/* The NAME of the pointed icon, just below the row. Absolute, so the bar's height — the band the game must not draw
|
|
179
|
+
over (ADR-0148) — does not grow when a name appears; the explanation goes to the footer, not here. */
|
|
180
|
+
#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
|
+
/* the padding stays when empty: the room `createGame` reserves under the bar reads it (issue #160) */
|
|
182
|
+
#title-icons .pause-icons-cap:not(:empty){background:rgba(8,8,16,.92);border-radius:8px}
|
|
183
|
+
/* Player-count selector = ONE button ("◀ No. of players: X ▶"); the side clicked decides +1/−1 */
|
|
184
|
+
#np-btn{letter-spacing:var(--ls)}
|
|
152
185
|
#np-btn #np-n{display:inline-block;min-width:1.1em;text-align:center}
|
|
153
|
-
/*
|
|
186
|
+
/* VERTICAL fraction: a number/bar/number stack in plain HTML (zero dependencies) */
|
|
154
187
|
.fv{display:inline-flex;flex-direction:column;align-items:center;vertical-align:middle;line-height:1.05;margin:0 .1em}
|
|
155
188
|
.fv b{font-weight:800;padding:0 .25em}
|
|
156
189
|
.fv b:first-child{border-bottom:2px solid currentColor}
|
|
157
|
-
/*
|
|
158
|
-
:root{--frac-fill:#f2a03d} /*
|
|
190
|
+
/* A fraction as a FIGURE (pie/square): inline SVG, 2-6 equal parts; an improper one = several units side by side */
|
|
191
|
+
:root{--frac-fill:#f2a03d} /* orange: high contrast on white + a black outline (not colour alone — WCAG 1.4.1) */
|
|
159
192
|
.frac-fig{display:inline-flex;align-items:center;gap:.25em;vertical-align:middle}
|
|
160
|
-
.frac-shape{display:inline-flex;align-items:center;gap:.15em} /*
|
|
161
|
-
.frac-op{display:inline-flex;flex-direction:column;align-items:center;gap:.15em;vertical-align:middle} /*
|
|
193
|
+
.frac-shape{display:inline-flex;align-items:center;gap:.15em} /* circle + square of the same fraction, side by side */
|
|
194
|
+
.frac-op{display:inline-flex;flex-direction:column;align-items:center;gap:.15em;vertical-align:middle} /* an operand of the sum: the number ON TOP, the figure below */
|
|
162
195
|
.frac-svg{width:2.4em;height:2.4em;display:inline-block;vertical-align:middle}
|
|
163
196
|
.quiz-choice .frac-svg{width:2.6em;height:2.6em}
|
|
164
197
|
.quiz-prob .frac-svg{width:2.6em;height:2.6em}
|
|
165
198
|
.quiz-dots{font-size:1.3em;letter-spacing:.15em;line-height:1.3;margin:.3rem 0;max-width:12em}
|
|
166
199
|
@media (prefers-contrast: more){
|
|
167
|
-
/*
|
|
168
|
-
|
|
169
|
-
|
|
200
|
+
/* Here `--ink-soft` is ALREADY white: the "changed" frame has to stop being white, or marked and unmarked become the
|
|
201
|
+
same frame — precisely for the child whose settings are most likely to be off the default. A mark whose
|
|
202
|
+
visibility depends on the theme is not a mark (ADR-0029). */
|
|
170
203
|
:root{ --bg:#000; --panel:#000; --ink:#fff; --ink-soft:#fff; --accent:#ffe600; --changed:#ffe600; }
|
|
171
204
|
}
|
|
172
205
|
*{box-sizing:border-box}
|
|
206
|
+
/* A face with a floor above 16 px (`--fonte-escala`, written by the typography cycle and menu; ADR-0176 rule 4) enlarges
|
|
207
|
+
ITS OWN TEXT and not the whole document (interface log 2026-09-13, issue #172): the scale lives on `#game-region`'s
|
|
208
|
+
`font-size`, spacing bound to the text is written in `--ui-fs`, and the root stays 16 px so `rem` does not grow.
|
|
209
|
+
`--espaco-fixo` is the factor of the spaces that do NOT follow the scale — the ones the Dev saw shrink under a 25% browser
|
|
210
|
+
zoom while the text held «mantendo o design muito bom»: 1 at the base, down to that quarter at the 20 px floor. */
|
|
211
|
+
:root{--espaco-fixo:max(.25, 4 - 3 * var(--fonte-escala,1))}
|
|
173
212
|
html,body{margin:0;background:var(--bg);color:var(--ink);font-family:var(--font);font-size:16px;line-height:var(--lh);letter-spacing:var(--ls);word-spacing:var(--ws)}
|
|
174
|
-
/*
|
|
213
|
+
/* THE SPACING IS THE TEXT'S, WHEREVER THE TEXT IS (ADR-0149 erratum, issue #187): «Se dentro de um botão tem texto, as regras de
|
|
214
|
+
espaçamento valem para este texto, mesmo que seja uma única palavra.» The browser's own stylesheet gives controls
|
|
215
|
+
`letter-spacing: normal`, which beat the inheritance — measured: pause items and quiz options had none. Zero specificity, so a
|
|
216
|
+
rule that spaces a control on purpose still decides. */
|
|
217
|
+
:where(button,select,option,input,textarea){letter-spacing:inherit;word-spacing:inherit}
|
|
218
|
+
/* mathematics in tabular mono (aligned, legible digits) */
|
|
175
219
|
.quiz-box--math .quiz-prob,.quiz-box--math .quiz-choice,#hud-coins,#hud-total{font-family:var(--font-math);font-variant-numeric:tabular-nums}
|
|
176
|
-
/*
|
|
220
|
+
/* paragraph spacing ≥2× only in reading blocks (it does not break the HUD or the menus) */
|
|
177
221
|
.overlay__card p + p{margin-top:2em}
|
|
178
|
-
/*
|
|
179
|
-
|
|
222
|
+
/* The page NEVER scrolls (the Dev): height locked to the viewport and overflow hidden — the canvas's excess (a tolerance
|
|
223
|
+
of 5 logical px per side) is cut by .stage-wrap, and the menus scroll INSIDE their cards. */
|
|
180
224
|
body{display:flex;flex-direction:column;height:100vh;height:100dvh;overflow:hidden}
|
|
181
225
|
.sr-only{position:absolute!important;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}
|
|
182
|
-
/*
|
|
183
|
-
|
|
226
|
+
/* The skip link sits on its SLOT, `--z-skip-link`, and not on a literal: above the modals and the transition, below only
|
|
227
|
+
the loop-crash notice and the debug panel. `tests/the-skip-link-outranks-the-transition.node.test.js` holds it (ADR-0102). */
|
|
184
228
|
.skip-link{position:absolute;left:8px;top:-60px;background:var(--accent);color:var(--accent-ink);padding:.6em 1em;border-radius:0 0 10px 10px;font-weight:700;z-index:var(--z-skip-link);transition:top .15s}
|
|
185
229
|
.skip-link:focus{top:0}
|
|
186
230
|
:focus-visible{outline:4px solid var(--focus);outline-offset:2px;border-radius:6px}
|
|
187
231
|
|
|
188
232
|
.topbar{max-width:var(--maxw);margin:0 auto;padding:.6rem 1rem;display:flex;align-items:center;justify-content:space-between;gap:1rem;flex-wrap:wrap}
|
|
189
|
-
body:not(.dbg) .topbar{display:none} /*
|
|
190
|
-
.title{font-size:1.
|
|
191
|
-
.ver{color:var(--ink-soft);font-weight:400;font-size
|
|
192
|
-
.badge{margin:0;color:var(--accent-ink);background:var(--accent);border-radius:999px;padding:.2em .8em;font-weight:700;font-size
|
|
233
|
+
body:not(.dbg) .topbar{display:none} /* the PAGE title only under ?debug=true (the game already shows it on the splash); gives back the vertical room */
|
|
234
|
+
.title{font-size:1.3em;margin:0}
|
|
235
|
+
.ver{color:var(--ink-soft);font-weight:400;font-size:1em}
|
|
236
|
+
.badge{margin:0;color:var(--accent-ink);background:var(--accent);border-radius:999px;padding:.2em .8em;font-weight:700;font-size:1em}
|
|
193
237
|
|
|
194
238
|
.hud{max-width:var(--maxw);margin:0 auto;padding:0 1rem .5rem;display:flex;gap:1.5rem;flex-wrap:wrap}
|
|
195
|
-
.hud__item{margin:0;font-size:1.
|
|
196
|
-
/*
|
|
239
|
+
.hud__item{margin:0;font-size:1.05em}
|
|
240
|
+
/* coins/mission/power moved into each player's screen; they stay sr-only (for the screen reader) */
|
|
197
241
|
.hud__item--sr{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}
|
|
198
|
-
/* HUD
|
|
199
|
-
#game-hud{position:absolute;inset:0;pointer-events:none;z-index:4;font-family:var(--font);font-size:var(--hud-fs,
|
|
200
|
-
/* "
|
|
201
|
-
|
|
242
|
+
/* Per-player HUD OVER the canvas (DOM = high definition, no pixelation). One per viewport; coins in the 1st column, power in the 2nd. */
|
|
243
|
+
#game-hud{position:absolute;inset:0;pointer-events:none;z-index:4;font-family:var(--font);font-size:var(--hud-fs,16px);font-weight:800}
|
|
244
|
+
/* "Player screen": one container per player (placed on that player's slice of the viewport). It hosts the HUD, and the
|
|
245
|
+
pause and menus of that player. The render stays shared (one WebGL context). */
|
|
202
246
|
.player-screen{position:absolute;pointer-events:none}
|
|
203
247
|
.vphud{position:absolute;top:0;left:0;width:100%;display:flex;align-items:flex-start;gap:0;padding:.4em .55em;box-sizing:border-box;color:#fff;text-shadow:0 1px 2px #000,0 0 3px #000,0 0 6px #000;line-height:1.15}
|
|
204
248
|
.vphud-obj,.vphud-power{flex:1 1 50%;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
|
|
205
249
|
.vphud-ico{font-weight:400}
|
|
206
|
-
/*
|
|
207
|
-
.vphud-quit{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;background:#000;color:#cdd6f2;font-family:var(--font);font-weight:800;font-size:var(--hud-fs,
|
|
250
|
+
/* a player who left (multiplayer): a black viewport with "Game abandoned" in the middle; the others carry on */
|
|
251
|
+
.vphud-quit{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;background:#000;color:#cdd6f2;font-family:var(--font);font-weight:800;font-size:var(--hud-fs,16px);text-align:center}
|
|
208
252
|
.vphud-quit[hidden]{display:none}
|
|
209
|
-
/*
|
|
253
|
+
/* PAUSE inside the canvas (screen = canvas) — laid over #game-region, not over the page */
|
|
210
254
|
.pause-incanvas{position:absolute;inset:0;z-index:6;display:flex;align-items:center;justify-content:center;background:var(--bg-solid);font-family:var(--font)}
|
|
211
255
|
.pause-incanvas[hidden]{display:none}
|
|
212
|
-
/*
|
|
213
|
-
.screen-pause{position:absolute;inset:0;z-index:6;display:flex;align-items:center;justify-content:center;background:var(--bg-solid);font-family:var(--font);font-size:var(--ui-fs,16px);pointer-events:auto} /* base = --ui-fs (16
|
|
256
|
+
/* The pause menu PER SCREEN (inside each .player-screen). Each player sees and moves through their own. */
|
|
257
|
+
.screen-pause{position:absolute;inset:0;z-index:6;display:flex;align-items:center;justify-content:center;background:var(--bg-solid);font-family:var(--font);font-size:var(--ui-fs,16px);pointer-events:auto} /* base = --ui-fs (16 at least, scales with the canvas) */
|
|
214
258
|
.screen-pause[hidden]{display:none}
|
|
215
|
-
|
|
216
|
-
|
|
259
|
+
/* ADR-0163: seven 44 px items are 308 of the 360 px at 640×360 (measured). The title keeps the 16 px text floor with a tight
|
|
260
|
+
line (20 px, not 29) and the card may use the whole height. */
|
|
261
|
+
.screen-pause .pause-card{max-width:94%;max-height:100%;padding:.25rem .7rem}
|
|
262
|
+
/* ONE HEIGHT for every card of the menus (interface log, 2026-09-13): the root, its submenu, the panels and the help. The root's
|
|
263
|
+
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
|
+
height too, its items from the top, as a panel's rows are. */
|
|
265
|
+
.screen-pause .pause-card{height:100%;box-sizing:border-box}
|
|
266
|
+
.screen-pause .pause-card h2{font-size:1em;line-height:1.25;margin:0 0 .1rem}
|
|
217
267
|
.screen-pause .pause-menu{gap:.3rem}
|
|
218
|
-
/*
|
|
219
|
-
|
|
220
|
-
|
|
268
|
+
/* The per-player frame tightens the PADDING, never the minimum height: the tight frame is the one of a game with four
|
|
269
|
+
children, where fingers compete for room — the worst possible place to shrink a touch target. The card has
|
|
270
|
+
`overflow:auto` and scrolls; the button does not shrink. */
|
|
221
271
|
.screen-pause .pm-btn{padding:.3rem .7rem}
|
|
222
|
-
.screen-pause .pause-legend{margin:.
|
|
223
|
-
/*
|
|
224
|
-
|
|
225
|
-
.pause-
|
|
226
|
-
/*
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
272
|
+
.screen-pause .pause-legend{margin:.1rem 0 0}
|
|
273
|
+
/* ADR-0163: with 42 px items the seven-item submenu overflowed 640×360 by 28 px (measured). The gap goes, not the target:
|
|
274
|
+
centres stay 44 px apart, far above the 24 px the WCAG 2.5.8 spacing exception protects. */
|
|
275
|
+
.screen-pause .pause-menu{gap:2px}
|
|
276
|
+
/* a11y shortcuts = menu buttons shaped as icons, INSIDE the card (no bar or shadow of their own).
|
|
277
|
+
Reachable by keyboard (up from Continue) and by touch/click. */
|
|
278
|
+
.pause-icons{display:flex;flex-wrap:wrap;gap:0;justify-content:center;align-items:center;margin:.1rem 0 .35rem}
|
|
279
|
+
/* ===================== THE QUICK BAR IN THE HUD (ADR-0044, item 7) =====================
|
|
280
|
+
It lives on the player's screen, available DURING play — which is when a child needs to change a setting that is
|
|
281
|
+
getting in the way, and not after pausing.
|
|
282
|
+
|
|
283
|
+
It is a SIBLING of `.screen-exp` and not a child, and the reason is #82: a CSS `filter` reaches every descendant and a
|
|
284
|
+
child cannot cancel it. Inside the experience, the empathy mode would degrade exactly what exists to GIVE access — and
|
|
285
|
+
simulation is not accessibility, it is its opposite.
|
|
286
|
+
|
|
287
|
+
`pointer-events:auto` because the whole `.player-screen` is `none` (the game receives the touch); the icons are the
|
|
288
|
+
exception, as the pause card already was. */
|
|
289
|
+
/* THE BAR'S HEIGHT, in one token: it is what pushes the HUD down. Without it both were anchored to the top and overlapped
|
|
290
|
+
— the HUD read over the icons, which is what the Dev saw and called terrible. */
|
|
291
|
+
.player-screen{--a11y-h:calc(var(--alvo-min,44px) + .5rem)}
|
|
239
292
|
.screen-a11y{position:absolute;left:0;right:0;top:0;height:var(--a11y-h);z-index:5;pointer-events:auto;font-family:var(--font);font-size:var(--ui-fs,16px)}
|
|
240
|
-
.screen-a11y .pause-icons{flex-wrap:nowrap;white-space:nowrap;gap
|
|
241
|
-
/*
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
.screen-a11y .pause-icons-cap{position:absolute;left:50%;transform:translateX(-50%);top:calc(var(--a11y-h) + .1rem);margin:0;max-width:92%;text-align:center;font-size
|
|
293
|
+
.screen-a11y .pause-icons{flex-wrap:nowrap;white-space:nowrap;gap:0;margin:0;height:100%}
|
|
294
|
+
/* ONLY THE BUTTONS TAKE ROOM. The explanation is ABSOLUTE and stays out of the flow — it appears over the game on mouse
|
|
295
|
+
hover (or when the `accessibility` mode's cursor rests on an icon) and goes without leaving a hole. A strip of text
|
|
296
|
+
reserving height on the game screen is the opposite of what a shortcut bar is for. */
|
|
297
|
+
.screen-a11y .pause-icons-cap{position:absolute;left:50%;transform:translateX(-50%);top:calc(var(--a11y-h) + .1rem);margin:0;max-width:92%;text-align:center;font-size:1em;color:#f6f5f0;pointer-events:none}
|
|
245
298
|
.screen-a11y .pause-icons-cap:not(:empty){background:rgba(8,8,16,.92);border-radius:8px;padding:.2em .6em}
|
|
246
|
-
/*
|
|
247
|
-
|
|
299
|
+
/* The HUD moves BELOW the bar. It is the same sum, and that is why it lives in a token: the two measures cannot
|
|
300
|
+
diverge without one covering the other. */
|
|
248
301
|
.screen-exp .vphud{top:var(--a11y-h)}
|
|
249
|
-
.pi-btn{width:var(--
|
|
250
|
-
/*
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
#padwiz-demo.pw-right #padwiz-demo-img{animation:pwSlideR 1.4s linear infinite}
|
|
256
|
-
#padwiz-demo.pw-up #padwiz-demo-img{animation:pwClimbUp 1.4s linear infinite}
|
|
257
|
-
#padwiz-demo.pw-down #padwiz-demo-img{animation:pwClimbDown 1.4s linear infinite}
|
|
258
|
-
#padwiz-demo.pw-jump #padwiz-demo-img{animation:pwJump .9s cubic-bezier(.3,0,.7,1) infinite}
|
|
259
|
-
#padwiz-demo.pw-run #padwiz-demo-img{animation:pwSlideR .8s linear infinite}
|
|
260
|
-
#padwiz-demo.pw-swap,#padwiz-demo.pw-start{align-items:center}
|
|
261
|
-
#padwiz-demo.pw-swap #padwiz-demo-fx{position:static;white-space:nowrap;font-size:1.7em;animation:pwIcons 4s linear infinite}
|
|
262
|
-
#padwiz-demo.pw-especial #padwiz-demo-fx{animation:pwPulse .8s ease-in-out infinite}
|
|
263
|
-
#padwiz-demo.pw-start #padwiz-demo-fx{position:static;font-weight:800;font-size:1.9em;letter-spacing:.1em;animation:pwBlink 1s steps(2,end) infinite}
|
|
264
|
-
@keyframes pwSlideL{0%{translate:34px 0}100%{translate:-34px 0}}
|
|
265
|
-
@keyframes pwSlideR{0%{translate:-34px 0}100%{translate:34px 0}}
|
|
266
|
-
@keyframes pwClimbUp{0%{translate:0 22px}100%{translate:0 -22px}}
|
|
267
|
-
@keyframes pwClimbDown{0%{translate:0 -22px}100%{translate:0 22px}}
|
|
268
|
-
@keyframes pwJump{0%,100%{translate:0 0}35%{translate:0 -26px}55%{translate:0 -22px}}
|
|
269
|
-
@keyframes pwIcons{0%{translate:60px 0}100%{translate:-60px 0}}
|
|
270
|
-
@keyframes pwPulse{0%,100%{scale:1;opacity:.7}50%{scale:1.5;opacity:1}}
|
|
271
|
-
@keyframes pwBlink{0%,100%{opacity:1}50%{opacity:.25}}
|
|
272
|
-
@media (prefers-reduced-motion: reduce){ #padwiz-demo *{animation:none !important} }
|
|
273
|
-
.pi-btn.pi-on{background:var(--accent);border-color:var(--accent)}
|
|
274
|
-
/* Modo TEA (🧩): pi-on preenchido de amarelo = silencioso · fundo branco = calmo · base (azul) = off.
|
|
275
|
-
(fundo, não borda — a borda é reservada ao realce de seleção :focus/.pi-sel e sobreporia o sinal.) */
|
|
302
|
+
.pi-btn{width:var(--alvo-min,44px);height:var(--alvo-min,44px);min-width:var(--alvo-min,44px);min-height:var(--alvo-min,44px);border-radius:10px;border:2px solid var(--ink-soft);background:#1a2740;color:#f6f5f0;font-size:1.25em;line-height:1;cursor:pointer;display:flex;align-items:center;justify-content:center}
|
|
303
|
+
/* Gamepad wizard: a demonstration with REAL ANIMATION (game frames swapped by JS) + a CSS offset */
|
|
304
|
+
/* ADR-0159 rule 10 / WCAG 1.4.1: «on» is not colour alone — a thick stripe along the base appears with it. */
|
|
305
|
+
.pi-btn.pi-on{background:var(--accent);border-color:var(--accent);box-shadow:inset 0 -5px 0 var(--accent-ink)}
|
|
306
|
+
/* ASD mode (🧩): pi-on filled yellow = silent · white background = calm · base (blue) = off.
|
|
307
|
+
(the background, not the border — the border is kept for the selection highlight :focus/.pi-sel and would hide the signal.) */
|
|
276
308
|
.pi-btn.pi-calm{background:#fff;border-color:var(--ink-soft)}
|
|
277
|
-
/*
|
|
278
|
-
|
|
279
|
-
(
|
|
280
|
-
|
|
309
|
+
/* Colour-vision correction (🚥): a two-colour "diagnostic" background — pairs chosen by search (Machado's 2009 simulation,
|
|
310
|
+
Lab ΔE) so that whoever HAS the target deficiency sees the largest contrast and the other two the smallest. Tritan
|
|
311
|
+
(the blue-yellow axis, on its own) separates cleanly with red/green; protan and deutan share the red-green axis
|
|
312
|
+
→ only a PARTIAL separation (a physical limit). off = base (blue, grey border); a light border = active. */
|
|
281
313
|
.pi-btn.pi-cvd-protan{background:linear-gradient(90deg,#b3671b 0 50%,#b31b41 50% 100%);border-color:var(--ink)}
|
|
282
314
|
.pi-btn.pi-cvd-deuter{background:linear-gradient(90deg,#0000f2 0 50%,#aa61f2 50% 100%);border-color:var(--ink)}
|
|
283
315
|
.pi-btn.pi-cvd-tritan{background:linear-gradient(90deg,#f23d00 0 50%,#1bb341 50% 100%);border-color:var(--ink)}
|
|
284
316
|
.pi-btn.pi-dis{opacity:.35;cursor:not-allowed}
|
|
285
|
-
.pi-btn.pi-soon{opacity:.55}
|
|
286
317
|
.pi-btn.pi-sel,.pi-btn:focus,.pi-btn:focus-visible{outline:2px solid var(--accent);outline-offset:1px;border-color:var(--accent)}
|
|
287
|
-
.pause-icons-cap{text-align:center;margin:0 0 .3rem;font-size
|
|
288
|
-
/* `scrollbar-gutter: stable both-edges` —
|
|
289
|
-
|
|
290
|
-
|
|
318
|
+
.pause-icons-cap{text-align:center;margin:0 0 .3rem;font-size:1em;color:var(--ink-soft);min-height:1.1em}
|
|
319
|
+
/* `scrollbar-gutter: stable both-edges` — MEASURED in the browser after item 6: with the list at 44 px the card starts
|
|
320
|
+
scrolling, the scrollbar eats width on ONE side only, and the centred list sat 7.5 px off centre. Reserving the gutter
|
|
321
|
+
on both sides gives the symmetry back, scrolling or not. */
|
|
291
322
|
.pause-card{background:#0e1626;border:2px solid #ffd23f;border-radius:14px;padding:.8rem 1rem;max-width:88%;max-height:92%;overflow:auto;scrollbar-gutter:stable both-edges;text-align:center;box-shadow:0 8px 30px rgba(0,0,0,.5)}
|
|
292
323
|
.pause-card h2{margin:.1rem 0 .6rem;color:#ffd23f}
|
|
293
|
-
/* =====================
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
324
|
+
/* ===================== THE PAUSE LIST (ADR-0044, item 6) =====================
|
|
325
|
+
It was `grid-template-columns:1fr 1fr`, and the grid told the same lie as the opening submenus: the arrow moves in
|
|
326
|
+
DOM order, so "down" jumped to the right-hand column. One column, and what you see is again the order you move in.
|
|
327
|
+
CENTRED AND WIDER: 26 letters against the 262 px measured before — the number is in the gate, not in an opinion.
|
|
328
|
+
⚠️ IN `em`, NOT `rem` (pointed out by the Dev): the menus' letters grow with the region (`--ui-fs`) and `rem` stays at the
|
|
329
|
+
root's 16 px — measured at 1920×1080, 48 px letters in a 416 px list, and every item wrapped onto two lines.
|
|
330
|
+
`width` and not `min(26em,100%)`: with the icon bar out of the card (item 7), the card shrinks to its content, and a
|
|
331
|
+
`100%` measured against it became circular — the list fell to 182 px. The LIST declares the width; the card follows
|
|
332
|
+
it up to its own `max-width`. */
|
|
333
|
+
.pause-menu{display:flex;flex-direction:column;gap:.45rem;width:26em;max-width:100%;margin:0 auto}
|
|
334
|
+
/* The HIDDEN list has to really disappear: an author's `display:grid` beats the browser's `[hidden]{display:none}`, and
|
|
335
|
+
without this line the two lists of the pause card would show stacked (ADR-0044, item 5). */
|
|
304
336
|
.pause-menu[hidden]{display:none}
|
|
305
|
-
/* 44 px
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
/*
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
⚠️ E ELE USA `--alvo-min` E NÃO `--tap`, que são coisas diferentes: `--tap` é o tamanho PREFERIDO e
|
|
318
|
-
cresce com a escala do canvas (22 × k, nunca menos de 44); `--alvo-min` é o CHÃO por altura. Um botão
|
|
319
|
-
isolado pode ser o preferido; um item de LISTA, que tem de caber inteiro, usa o chão.
|
|
320
|
-
|
|
321
|
-
O `44px` do fallback é o comportamento de antes, para o caso de `layout()` não ter corrido — que era
|
|
322
|
-
exatamente o que acontecia no `quiz.html` até 07/09. */
|
|
323
|
-
.pm-btn{background:#1a2740;color:#eaf2f8;border:1px solid #3a4a6a;border-radius:10px;padding:.5rem .8rem;min-height:var(--alvo-min,44px);display:flex;align-items:center;justify-content:center;font:inherit;font-weight:700;cursor:pointer;white-space:nowrap}
|
|
337
|
+
/* 44 px is NOT the WCAG minimum — 2.5.8 asks for 24×24, and the card already passed that with room to spare. 44 is
|
|
338
|
+
Apple's recommendation (HIG). `min-height` and not `padding` because the earlier height (35.6 px) was declared
|
|
339
|
+
nowhere: it RESULTED from the sum of padding, font and line height. A target nobody wrote down is a target nobody
|
|
340
|
+
defends. */
|
|
341
|
+
/* The menu item's target is `--alvo-min`, never a literal. ADR-0163 superseded ADR-0095's height ruler (24/34/44 px):
|
|
342
|
+
the engine forces the resolution, no screen is under 640×360, and the floor is 22 × k — 44 px there, growing with the
|
|
343
|
+
scale. `applyScale` (`ui/layout`) writes it on the game region; the 44 px fallback is that same floor at k = 2. */
|
|
344
|
+
/* ADR-0159 rule 8 / WCAG 1.4.11: the item's border is its boundary against the card (#0e1626). #3a4a6a measured 2.04:1;
|
|
345
|
+
#6a7a96 is 4.2:1. */
|
|
346
|
+
.pm-btn{background:#1a2740;color:#eaf2f8;border:1px solid #6a7a96;border-radius:10px;padding:.5rem .8rem;min-height:var(--alvo-min,44px);display:flex;align-items:center;justify-content:center;font:inherit;font-weight:700;cursor:pointer;white-space:nowrap}
|
|
347
|
+
/* ADR-0161: a locked item stays in the list, visibly muted; the cursor still lands on it and it says its reason. */
|
|
348
|
+
.pm-btn[aria-disabled="true"]{color:#9aa6b8;border-style:dashed;cursor:not-allowed}
|
|
324
349
|
.pm-btn:hover,.pm-btn:focus,.pm-btn.pm-sel{background:#2a3a5e;border-color:#ffd23f;outline:2px solid #ffd23f;outline-offset:1px}
|
|
325
|
-
/*
|
|
326
|
-
|
|
350
|
+
/* ADR-0167: no item shows a position number — the place is SPOKEN after the name («…, 2 de 6»), never drawn.
|
|
351
|
+
ADR-0159 rule 12: a pause item's glyph is drawn with empty alternative text, out of the name. */
|
|
352
|
+
.pm-btn[data-glifo]::before{content:attr(data-glifo) / "";margin-inline-end:.5em}
|
|
353
|
+
/* Yes/no legend: the button's glyph (from the pad's design) + the word. By POSITION on every design — yes is the south button
|
|
354
|
+
(A · ✕ · B), no is the east one (B · ◯ · A); no design swaps them (the Dev's association, ADR-0013 erratum). */
|
|
355
|
+
.pause-legend{display:flex;gap:1.1rem;justify-content:center;margin:.7rem 0 .1rem;font-size:1em;color:#c3cfe0}
|
|
327
356
|
.pause-legend .lg{display:inline-flex;align-items:center;gap:.35rem}
|
|
328
|
-
.pause-legend .lg-ico{display:inline-flex;align-items:center;justify-content:center;width:1.35rem;height:1.35rem;border-radius:50%;font-weight:800;font-size
|
|
357
|
+
.pause-legend .lg-ico{display:inline-flex;align-items:center;justify-content:center;width:1.35rem;height:1.35rem;border-radius:50%;font-weight:800;font-size:1em;color:#fff;text-shadow:0 1px 1px rgba(0,0,0,.55)}
|
|
329
358
|
.hud__item strong{font-variant-numeric:tabular-nums}
|
|
330
359
|
.hud__fps{color:var(--ink-soft)}
|
|
331
360
|
|
|
332
361
|
main{flex:1;display:flex;flex-direction:column;width:100%;margin:0 auto;padding:0 .25rem .25rem;min-height:0;overflow:hidden}
|
|
333
|
-
/*
|
|
362
|
+
/* screen = priority: it takes all the room; the excess (up to 5px×k per side) is cut without scrolling */
|
|
334
363
|
.stage-wrap{flex:1;display:flex;align-items:center;justify-content:center;min-height:0;padding:0;overflow:hidden}
|
|
335
364
|
.stage{position:relative;display:flex;align-items:center}
|
|
336
|
-
/* =====
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
365
|
+
/* ===== THE DOM LAYER (issue #82) =====
|
|
366
|
+
Everything that is not the canvas. It exists so the accessibility filter can land on a surface that holds the MENUS
|
|
367
|
+
and not the world — a PIXI filter does not reach the DOM, and filtering the whole `#game-region` would apply twice
|
|
368
|
+
on the canvas.
|
|
340
369
|
|
|
341
|
-
`pointer-events:none`
|
|
342
|
-
|
|
370
|
+
`pointer-events:none` because the wrapper covers the whole region and must not swallow clicks; the four children
|
|
371
|
+
that need clicks and did not declare it (they inherited it from `#game-region`) get `auto` just below.
|
|
343
372
|
|
|
344
|
-
`z-index:1`:
|
|
345
|
-
|
|
346
|
-
|
|
373
|
+
`z-index:1`: above the canvas, BELOW the two CRT pseudo-elements (vignette at 5, scanline at 500), which sit on
|
|
374
|
+
`#game-region`. The CRT is a screen effect and goes over everything — which the scanline already did by the Dev's
|
|
375
|
+
decision, and the vignette now follows. */
|
|
347
376
|
#dom-layer{position:absolute;inset:0;z-index:1;pointer-events:none}
|
|
348
377
|
|
|
349
|
-
/* =====
|
|
350
|
-
|
|
351
|
-
|
|
378
|
+
/* ===== HIGH CONTRAST IN THE DOM (issue #83) =====
|
|
379
|
+
High contrast is NOT a filter: it is Direct Rendering, and it repaints the canvas's TEXTURES. The DOM has no texture
|
|
380
|
+
to repaint — the equivalent has to be written, and this is it.
|
|
352
381
|
|
|
353
|
-
|
|
382
|
+
MEASURED, not estimated (WCAG 1.4.3, the ratio over linearised sRGB). What failed, and only at the 7:1 level:
|
|
354
383
|
|
|
355
|
-
·
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
·
|
|
384
|
+
· the pause panel's VEIL was `rgba(4,7,15,.72)` — translucent. The text's ratio over it DEPENDED on the game behind:
|
|
385
|
+
19.17:1 over a black frame and 8.07:1 over a white one. With `--ink-soft`, `--accent` and `--good` the sum fell to
|
|
386
|
+
5.92 / 5.94 / 5.11:1 — AA, not AAA. At the 3:1 and 4.5:1 levels nothing failed.
|
|
387
|
+
· the SELECTED button is `#2a3a5e`, and `--good` on it gives 6.70:1.
|
|
359
388
|
|
|
360
|
-
|
|
389
|
+
Two changes, and neither invents a colour:
|
|
361
390
|
|
|
362
|
-
1.
|
|
363
|
-
|
|
364
|
-
2.
|
|
365
|
-
|
|
366
|
-
|
|
391
|
+
1. THE VEIL IS OPAQUE. That is what "high contrast" means: the half-tone goes, and with it the dependence on what is
|
|
392
|
+
behind. On its own this takes everything to AAA but one case.
|
|
393
|
+
2. THE CURSOR INVERTS — `--accent` background, `--accent-ink` text, 12.71:1. Darkening the selected item would bring
|
|
394
|
+
it closer to the unselected one (`#1a2740`) and the child would LOSE THE CURSOR; inverting solves both at once, and
|
|
395
|
+
it is the high-contrast pattern of every operating system.
|
|
367
396
|
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
397
|
+
Result: the worst pair of the menu goes from 5.11:1 to 10.29:1 (`--ink-soft` on a button). A margin of +47% over
|
|
398
|
+
7:1. `tests/menu-contrast-measured.node.test.js` asserts it on every run, with the ratios computed from this CSS
|
|
399
|
+
itself — not copied into the test.
|
|
371
400
|
|
|
372
|
-
⚠️
|
|
373
|
-
|
|
374
|
-
/* (
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
401
|
+
⚠️ IT HOLDS FOR ALL THREE LEVELS, not only 7:1: at the other two the menu already passed, but it passed BY THE LUCK
|
|
402
|
+
of whatever was on screen. Determinism is a gain at every level. */
|
|
403
|
+
/* (The veil's rule is not here: the veil is opaque AT THE BASE, by the Dev's decision — the title and pause menus have to
|
|
404
|
+
be at 7:1 FROM THE START, because they are precisely where a person with a disability adjusts the controls for
|
|
405
|
+
themselves. A contrast that only arrives after finding the setting arrives late.
|
|
406
|
+
What is left here is what is specific to the mode: the inverted cursor.) */
|
|
378
407
|
#dom-layer.hc .pm-btn{background:var(--panel-btn)}
|
|
379
408
|
#dom-layer.hc .pm-btn:hover,
|
|
380
409
|
#dom-layer.hc .pm-btn:focus,
|
|
@@ -384,63 +413,76 @@ main{flex:1;display:flex;flex-direction:column;width:100%;margin:0 auto;padding:
|
|
|
384
413
|
.game-region{position:relative;background:#05070f;box-shadow:0 0 0 3px var(--ink-soft);border-radius:8px;overflow:hidden;flex:none}
|
|
385
414
|
.libras-slot{flex:none;width:0;height:0;background:#0b1020;border-radius:8px;overflow:hidden}
|
|
386
415
|
.game-region:focus-visible{outline:4px solid var(--focus);outline-offset:3px}
|
|
387
|
-
/* =====
|
|
388
|
-
|
|
389
|
-
|
|
416
|
+
/* ===== THE REACH NOTICE (issue #112) =====
|
|
417
|
+
It reuses `.overlay` and `.overlay__card` whole — the card is born with the same shell as the other dialogs, and
|
|
418
|
+
that is what makes it look like part of the game instead of a browser error. Only the title's emphasis is its own. */
|
|
390
419
|
#reach-notice .reach-notice__titulo{font-weight:700;margin:0 0 .5rem}
|
|
391
420
|
#reach-notice p{margin:0 0 .5rem}
|
|
392
421
|
#reach-notice button{margin-top:.75rem}
|
|
393
|
-
/* =====
|
|
394
|
-
|
|
395
|
-
`
|
|
396
|
-
|
|
397
|
-
⚠️
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
/* ⚠️
|
|
401
|
-
`.game-region.crt-scan-1::after`
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
422
|
+
/* ===== THE LOOP STOPPED (ADR-0054, issue #109) =====
|
|
423
|
+
THE TEXT COMES FROM THE SCRIPT, and that is the point: `ui/loop-crash` writes the sentence ALREADY TRANSLATED (from
|
|
424
|
+
`t()`, through `textContent`), and the CSS only shows it. A notice hard-coded here would be in English for a Brazilian
|
|
425
|
+
child — the defect pillar 3 exists to prevent.
|
|
426
|
+
⚠️ AND THE COLOURS ARE RAW, ON PURPOSE: no `var(--…)`. This notice appears exactly when something broke, and the
|
|
427
|
+
theming machinery is a plausible suspect. White on wine gives 9.5:1, above the 7:1 of 1.4.6, and does not depend on
|
|
428
|
+
anything having survived. */
|
|
429
|
+
/* ⚠️ IT IS AN ELEMENT, NOT A `::after` WITH `content: attr(...)` — that version would never show. The
|
|
430
|
+
`.game-region.crt-scan-1::after` just below is the CRT scanline, on by default — and an element has ONE `::after`
|
|
431
|
+
only. The two rules do not stack; the CRT's comes later and wins. The `::before` is taken by the vignette. An
|
|
432
|
+
ELEMENT competes with nobody for its place — and its text enters the accessibility tree, which `content` does not
|
|
433
|
+
guarantee. Its slot, `--z-loop-crash`, is above the scanline's 500 on purpose. */
|
|
405
434
|
#incl-parou{
|
|
406
435
|
position:absolute;inset:auto 0 0 0;z-index:var(--z-loop-crash);
|
|
407
436
|
padding:14px 18px;
|
|
408
437
|
background:#7f1d1d;color:#fff;border-top:3px solid #fff;
|
|
409
|
-
font:700
|
|
438
|
+
font:700 1em/1.35 system-ui,-apple-system,"Segoe UI",sans-serif;
|
|
410
439
|
text-align:center;text-wrap:balance
|
|
411
440
|
}
|
|
412
441
|
.pixi-mount,.pixi-mount canvas{display:block;width:100%;height:100%}
|
|
413
|
-
/* pixel
|
|
442
|
+
/* crisp pixel art when scaling */
|
|
414
443
|
.pixi-mount canvas{image-rendering:pixelated;image-rendering:crisp-edges}
|
|
415
|
-
/*
|
|
416
|
-
|
|
444
|
+
/* The CRT look (visual sensitivity menu) in 3 levels: -1=small, -2=large. z-index 5 = over the game's canvas/HUD, BELOW the
|
|
445
|
+
in-canvas pause (6) and the dialogs (60) → the menus never lose legibility. */
|
|
417
446
|
.game-region.crt-scan-1::after,
|
|
418
447
|
.game-region.crt-vig-1::before{content:'';position:absolute;inset:0;z-index:5;pointer-events:none}
|
|
419
|
-
/*
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
.game-region.crt-scan-1::after{z-index:500;background:repeating-linear-gradient(to bottom, rgba(0,0,0,.16) 0 var(--scan-line,1px), transparent var(--scan-line,1px) var(--scan-per,3px))} /* z-index
|
|
448
|
+
/* ALIGNED scanlines: period = 1 LOGICAL game pixel (k px), rounded to a PHYSICAL pixel (dpr), and line = 1 physical
|
|
449
|
+
pixel — the JS (`render/crt`, applyCrt) computes --scan-per/--scan-line; without it the 1px/3px gradient in CSS px
|
|
450
|
+
fell off the grid (uneven lines on screens with Windows scaling). */
|
|
451
|
+
.game-region.crt-scan-1::after{z-index:500;background:repeating-linear-gradient(to bottom, rgba(0,0,0,.16) 0 var(--scan-line,1px), transparent var(--scan-line,1px) var(--scan-per,3px))} /* a high z-index = scanlines OVER everything (canvas AND DOM menus), the Dev's request */
|
|
423
452
|
.game-region.crt-vig-1::before{background:radial-gradient(ellipse at center, transparent 60%, rgba(0,0,0,.34) 100%)}
|
|
424
|
-
.game-region.crt-round-0{border-radius:0} /*
|
|
425
|
-
.game-region.crt-round-2{border-radius:24px} /*
|
|
453
|
+
.game-region.crt-round-0{border-radius:0} /* square screen */
|
|
454
|
+
.game-region.crt-round-2{border-radius:24px} /* level 1 (small) = the 8px default, no class */
|
|
426
455
|
@media (prefers-reduced-transparency: reduce){ .game-region.crt-scan-1::after,.game-region.crt-vig-1::before{display:none} }
|
|
427
456
|
|
|
428
|
-
/*
|
|
457
|
+
/* start tips over the canvas */
|
|
429
458
|
.start-tips{position:absolute;left:50%;top:14%;transform:translateX(-50%);
|
|
430
459
|
display:flex;flex-direction:column;gap:.5rem;align-items:center;pointer-events:none;
|
|
431
460
|
transition:opacity .5s ease;z-index:6;max-width:92%}
|
|
432
461
|
.start-tips p{margin:0;background:rgba(5,7,15,.85);color:#fff;border:2px solid rgba(255,255,255,.45);
|
|
433
|
-
border-radius:10px;padding:.4em .9em;font-size:1.
|
|
462
|
+
border-radius:10px;padding:.4em .9em;font-size:1.05em;font-weight:600;text-align:center}
|
|
434
463
|
.start-tips kbd{background:var(--accent);color:var(--accent-ink);border-radius:6px;padding:.05em .5em;font-weight:800}
|
|
435
464
|
.start-tips.hide{opacity:0}
|
|
436
465
|
@media (prefers-reduced-motion: reduce){ .start-tips{transition:none} }
|
|
437
466
|
|
|
438
|
-
/*
|
|
467
|
+
/* mode selector */
|
|
439
468
|
.modes{max-width:var(--maxw);margin:0 auto .5rem;padding:0 1rem;display:flex;gap:.5rem;flex-wrap:wrap}
|
|
440
|
-
.mode-btn{min-height:var(--
|
|
469
|
+
.mode-btn{min-height:var(--alvo-min,44px);padding:.4em .9em;font:inherit;font-weight:700;color:var(--ink);background:var(--panel);border:2px solid var(--ink-soft);border-radius:999px;cursor:pointer}
|
|
441
470
|
.mode-btn.is-on{background:var(--accent);color:var(--accent-ink);border-color:var(--accent)}
|
|
442
|
-
/*
|
|
443
|
-
|
|
471
|
+
/* STEPS ⯇ ⯈ (ADR-0151): choosing between positions with left and right. The arrows are FINGER targets and follow the
|
|
472
|
+
target ruler (`--alvo-min`, ADR-0163); the focus belongs to the whole control, and the end that cannot move is dimmed. */
|
|
473
|
+
.passos{display:inline-flex;align-items:center;gap:.25rem;min-height:var(--alvo-min,44px);border:2px solid var(--ink-soft);border-radius:8px;padding:0 .15rem;background:var(--panel-btn);color:var(--ink);font-weight:700;user-select:none;-webkit-user-select:none}
|
|
474
|
+
.passos:focus,.passos:focus-visible{outline:3px solid var(--focus);outline-offset:2px}
|
|
475
|
+
.passo-seta{display:inline-flex;align-items:center;justify-content:center;min-width:var(--alvo-min,44px);min-height:var(--alvo-min,44px);cursor:pointer;font-size:1.1em;touch-action:manipulation}
|
|
476
|
+
.passo-seta.no-limite{opacity:.35;cursor:default}
|
|
477
|
+
.passo-valor{min-width:6ch;text-align:center;flex:1}
|
|
478
|
+
/* «◀ Label: value ▶» takes the whole ROW (ADR-0130 erratum): there is no label on the left competing for the room. */
|
|
479
|
+
/* 🔴 AND NO BOX INSIDE THE BOX: the ROW is the item. The first version kept `.passos`'s border and background, and the
|
|
480
|
+
text wrapped onto four lines inside a box beside the hint — the Dev: «Por que continua desenhando os botões de seleção
|
|
481
|
+
de <=5 itens do jeito errado?!». On one line, `◀ Label: value ▶`, with no wrapping. */
|
|
482
|
+
.ctrl-row--passos .passos{flex:1;justify-content:space-between;border:0;background:transparent;padding:0;white-space:nowrap}
|
|
483
|
+
.ctrl-row--passos .passo-valor{white-space:nowrap}
|
|
484
|
+
/* TOGGLE (switch): replaces the "icon + On/Off" buttons. State = a track + a knob that slides.
|
|
485
|
+
Toggle-button semantics through aria-pressed (the inner text is hidden by font-size:0). */
|
|
444
486
|
.mode-btn.switch{--sw-w:52px;--sw-h:28px;position:relative;width:var(--sw-w);min-width:var(--sw-w);height:var(--sw-h);min-height:var(--sw-h);padding:0;flex:0 0 auto;border-radius:999px;border:2px solid var(--ink-soft);background:#0e1326;color:transparent;font-size:0;transition:background .18s,border-color .18s}
|
|
445
487
|
.mode-btn.switch::after{content:"";position:absolute;top:50%;left:3px;transform:translateY(-50%);width:calc(var(--sw-h) - 10px);height:calc(var(--sw-h) - 10px);border-radius:50%;background:var(--ink-soft);transition:left .18s,background .18s}
|
|
446
488
|
.mode-btn.switch[aria-pressed="true"]{background:var(--accent);border-color:var(--accent)}
|
|
@@ -448,33 +490,33 @@ main{flex:1;display:flex;flex-direction:column;width:100%;margin:0 auto;padding:
|
|
|
448
490
|
.mode-btn.switch:focus-visible,.mode-btn.switch:focus{outline:3px solid var(--accent);outline-offset:2px}
|
|
449
491
|
@media (prefers-reduced-motion: reduce){ .mode-btn.switch,.mode-btn.switch::after{transition:none} }
|
|
450
492
|
|
|
451
|
-
/*
|
|
493
|
+
/* the quiz challenge (an overlay over the canvas) */
|
|
452
494
|
.quiz{position:absolute;inset:0;z-index:12;display:grid;place-items:center;background:rgba(0,0,0,.55)}
|
|
453
495
|
.quiz-box{position:relative;background:#14141f;color:var(--ink);border:3px solid var(--accent);border-radius:12px;padding:1rem 1.1rem;max-width:90%;text-align:center}
|
|
454
|
-
/* 3
|
|
496
|
+
/* 3 progress lights (top right corner): off = grey; on = yellow with a glow around it */
|
|
455
497
|
.quiz-wins{position:absolute;top:.5rem;right:.6rem;display:flex;gap:.4rem}
|
|
456
498
|
.qw-dot{width:.95rem;height:.95rem;border-radius:50%;background:#3a4152;border:2px solid #0d0d1a}
|
|
457
|
-
.qw-dot.on{background:var(--accent);border-color:#8a6d00;box-shadow:0 0 .55rem .12rem var(--accent)} /*
|
|
499
|
+
.qw-dot.on{background:var(--accent);border-color:#8a6d00;box-shadow:0 0 .55rem .12rem var(--accent)} /* the glow around it (a light that is on) */
|
|
458
500
|
.quiz-wins.celebrate .qw-dot.on{animation:qwPop .6s ease}
|
|
459
501
|
@keyframes qwPop{0%{transform:scale(1)}45%{transform:scale(1.4);box-shadow:0 0 .9rem .3rem var(--accent)}100%{transform:scale(1)}}
|
|
460
502
|
@media (prefers-reduced-motion:reduce){ .quiz-wins.celebrate .qw-dot.on{animation:none} }
|
|
461
503
|
.quiz-shape{color:var(--accent);font-weight:800;text-transform:capitalize}
|
|
462
|
-
.quiz-prob{font-size:1.
|
|
504
|
+
.quiz-prob{font-size:1.6em;font-weight:800;margin:.4rem 0 .8rem}
|
|
463
505
|
.quiz-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:.4rem}
|
|
464
|
-
.quiz-choice{min-height:var(--
|
|
506
|
+
.quiz-choice{min-height:var(--alvo-min,44px);min-width:var(--alvo-min,44px);font:inherit;font-size:1.2em;font-weight:700;color:var(--ink);background:#131a30;border:2px solid var(--ink-soft);border-radius:8px;cursor:pointer}
|
|
465
507
|
.quiz-choice.sel{background:var(--accent);color:var(--accent-ink);border-color:var(--accent)}
|
|
466
508
|
.quiz-choice.reveal{outline:3px solid var(--good);outline-offset:2px}
|
|
467
|
-
.quiz-hint{font-size
|
|
468
|
-
.quiz-emoji{font-size:2.
|
|
469
|
-
/*
|
|
470
|
-
.quiz-word{font-size:2.
|
|
509
|
+
.quiz-hint{font-size:1em;margin-top:.6rem;color:var(--ink-soft)}
|
|
510
|
+
.quiz-emoji{font-size:2.4em;line-height:1}
|
|
511
|
+
/* The top word = a SELECTABLE emoji (jumping on it repeats the speech / VLibras signs it) */
|
|
512
|
+
.quiz-word{font-size:2.4em;line-height:1;background:transparent;border:2px solid transparent;border-radius:12px;padding:.05em .2em;cursor:pointer}
|
|
471
513
|
.quiz-word.sel{border-color:var(--accent);background:rgba(255,230,0,.12)}
|
|
472
|
-
.quiz-letter{font-size
|
|
514
|
+
.quiz-letter{font-size:1em;color:var(--ink-soft);margin:.1rem 0 .4rem}
|
|
473
515
|
.silaba-boxes{display:flex;gap:.4rem;justify-content:center;margin-bottom:.5rem}
|
|
474
|
-
.silaba-box{min-width:34px;min-height:28px;border:2px dashed var(--ink-soft);border-radius:6px;display:flex;align-items:center;justify-content:center;font-weight:800;font-size:1.
|
|
516
|
+
.silaba-box{min-width:34px;min-height:28px;border:2px dashed var(--ink-soft);border-radius:6px;display:flex;align-items:center;justify-content:center;font-weight:800;font-size:1.15em}
|
|
475
517
|
.silaba-box.filled{border-style:solid;border-color:var(--accent);background:rgba(255,255,255,.08)}
|
|
476
518
|
.silaba-actions{display:flex;gap:.4rem;justify-content:center;margin-top:.4rem}
|
|
477
|
-
/*
|
|
519
|
+
/* a Braille cell */
|
|
478
520
|
.bcells{display:flex;gap:.5rem;justify-content:center;flex-wrap:wrap;margin:.4rem 0}
|
|
479
521
|
.bcell{display:flex;flex-direction:column;align-items:center;gap:.2rem}
|
|
480
522
|
.bcell-grid{display:grid;grid-template-columns:repeat(2,10px);grid-auto-rows:10px;gap:3px;padding:4px;background:#0e1326;border:1px solid var(--ink-soft);border-radius:4px}
|
|
@@ -484,94 +526,241 @@ main{flex:1;display:flex;flex-direction:column;width:100%;margin:0 auto;padding:
|
|
|
484
526
|
@media (prefers-contrast: more){ .quiz-box{background:#000} .quiz-choice{background:#000} .quiz-choice.sel{background:#fff;color:#000} }
|
|
485
527
|
|
|
486
528
|
.opts{max-width:var(--maxw);margin:0 auto .5rem;padding:0 1rem;display:flex;gap:.4rem;flex-wrap:wrap;justify-content:center}
|
|
487
|
-
/*
|
|
488
|
-
.opts .mode-btn{padding:.35em .65em;font-size
|
|
529
|
+
/* a compact controls bar → fits on ONE row on common screens (does not affect overlay buttons) */
|
|
530
|
+
.opts .mode-btn{padding:.35em .65em;font-size:1em;white-space:nowrap}
|
|
489
531
|
.caption{position:absolute;left:50%;bottom:8px;transform:translateX(-50%);background:rgba(0,0,0,.82);color:#fff;
|
|
490
|
-
border:2px solid rgba(255,255,255,.5);border-radius:8px;padding:.25em .7em;font-weight:700;font-size
|
|
532
|
+
border:2px solid rgba(255,255,255,.5);border-radius:8px;padding:.25em .7em;font-weight:700;font-size:1em;
|
|
491
533
|
z-index:8;pointer-events:none;max-width:90%;opacity:0;transition:opacity .15s}
|
|
492
534
|
.caption.show{opacity:1}
|
|
493
535
|
@media (prefers-reduced-motion: reduce){ .caption{transition:none} }
|
|
494
536
|
|
|
495
537
|
.help{max-width:var(--maxw);margin:1rem auto 0;color:var(--ink-soft)}
|
|
496
|
-
.help summary{cursor:pointer;font-weight:700;color:var(--ink);min-height:var(--
|
|
538
|
+
.help summary{cursor:pointer;font-weight:700;color:var(--ink);min-height:var(--alvo-min,44px);display:flex;align-items:center}
|
|
497
539
|
.help ul{padding-left:1.1rem}
|
|
498
540
|
.help li{margin:.3rem 0}
|
|
499
541
|
|
|
500
|
-
.btn{min-height:var(--
|
|
542
|
+
.btn{min-height:var(--alvo-min,44px);min-width:var(--alvo-min,44px);padding:.5em 1em;font:inherit;font-weight:600;color:var(--ink);background:var(--panel);border:2px solid var(--ink-soft);border-radius:10px;cursor:pointer}
|
|
501
543
|
.btn--primary{background:var(--accent);color:var(--accent-ink);border-color:var(--accent)}
|
|
502
544
|
|
|
503
545
|
.overlay{position:fixed;inset:0;z-index:50;display:grid;place-items:center;background:rgba(0,0,0,.7);padding:1rem}
|
|
504
|
-
/* "
|
|
505
|
-
|
|
546
|
+
/* "screen = canvas": the a11y dialogs are re-parented into #game-region (JS) and stay held within the canvas's bounds;
|
|
547
|
+
the last one opened goes on top (z-index by JS). Only affects the ones inside. */
|
|
506
548
|
#game-region .overlay{position:absolute;z-index:60;padding:.6rem}
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
.
|
|
511
|
-
|
|
549
|
+
/* THE QUIZ STARTS BELOW THE QUICK BAR (ADR-0148). The engine declares `--barra-a11y-h` on `#game-region`; the bar sits
|
|
550
|
+
10 px from the top (`#title-icons`), and the statement was drawn behind it — measured on a screenshot of the Dev's. */
|
|
551
|
+
/* 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) */
|
|
553
|
+
/* 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
|
+
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
|
+
.quiz-pergunta{margin:0 0 calc(.25rem * var(--espaco-fixo,1));line-height:1.25}
|
|
556
|
+
/* The quiz's MENU button (ADR-0166 erratum), in the top-left corner the bar leaves free: the engine's target size. */
|
|
557
|
+
/* THE QUICK PAUSE (ADR-0155): PAUSED in the middle of the frozen screen — THE WORD ONLY, white, with a BLACK OUTLINE ON
|
|
558
|
+
THE LETTERS and no box: «Borda nas letras, não numa caixa» (the Dev, the record's erratum). The outline is what keeps it
|
|
559
|
+
legible over a light scene; `paint-order` puts the stroke UNDER the fill, so the letter does not get thinner, and the
|
|
560
|
+
shadow in eight directions covers browsers without `-webkit-text-stroke`. z-index 12, the same literal as the quiz
|
|
561
|
+
overlay (`.quiz`), not yet a slot: over the content by document order, under the pad (14) and the panels (60). The
|
|
562
|
+
right slot is `--z-game-msg`, and adopting it alone would put PAUSED over a panel. No pointer events. */
|
|
563
|
+
.pausa-rapida{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);z-index:12;pointer-events:none;
|
|
564
|
+
color:#fff;-webkit-text-stroke:.08em #000;paint-order:stroke fill;
|
|
565
|
+
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;
|
|
566
|
+
font-family:var(--font);font-weight:800;font-size:calc(var(--ui-fs,16px)*2);letter-spacing:var(--ls);white-space:nowrap}
|
|
567
|
+
.pausa-rapida[hidden]{display:none}
|
|
568
|
+
/* WHAT THE SCAN IS OFFERING (ADR-0218, #201): with «um botão só», the child does not choose — they wait, and what they
|
|
569
|
+
wait for has to be in view. The SAME outlined white letters as the quick pause, no box, at the TOP of the region,
|
|
570
|
+
below the bar's band (`--barra-a11y-h`), which is the zone no game uses. No pointer events: it is a notice, not a
|
|
571
|
+
control — what fires it is its single button, wherever that is. */
|
|
572
|
+
/* ⚠️ `--scan-top` and NOT `--barra-a11y-h`: this label makes the band grow, and placing it by the band made a loop — it
|
|
573
|
+
pushed the band, the band pushed it, and it went down the screen on every measure (caught by a test case). `--scan-top`
|
|
574
|
+
is where the bar ends, and does not depend on it (`ui/top-band` writes both). */
|
|
575
|
+
.scan-now{position:absolute;left:50%;top:var(--scan-top,0px);transform:translateX(-50%);z-index:12;
|
|
576
|
+
pointer-events:none;color:#fff;-webkit-text-stroke:.06em #000;paint-order:stroke fill;
|
|
577
|
+
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;
|
|
578
|
+
font-family:var(--font);font-weight:800;font-size:calc(var(--ui-fs,16px)*1.5);letter-spacing:var(--ls);white-space:nowrap}
|
|
579
|
+
.scan-now[hidden]{display:none}
|
|
580
|
+
/* THE FOOTER LEGEND of the quick pause (ADR-0155 erratum): the same outlined white letters, no box, right ABOVE the pad's
|
|
581
|
+
START pill — which stays in view, because it is the way out for someone who only has a finger. ⚠️ `left`/`right` and
|
|
582
|
+
not `left:50%` + `translate`: with that, the box shrank to HALF of the region (measured: 271 px, three lines, over
|
|
583
|
+
PAUSED). */
|
|
584
|
+
/* 🔴 The footer is ONE column (2026-09-12): the explanation of the pointed bar icon above the quick-pause legend. Two
|
|
585
|
+
absolute strips covered each other as soon as one wrapped. */
|
|
586
|
+
/* 🔴 ADR-0164 (2026-09-12): the footer is at the LOWEST edge of the region, over a darkened band, and holds at most TWO
|
|
587
|
+
lines of text. The Dev saw a three-line explanation in the middle of the screen, over a quiz option, with outlined
|
|
588
|
+
letters and no background. White on black at .82 over pure white composes to ~13:1 (the panel footer's arithmetic).
|
|
589
|
+
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)}
|
|
592
|
+
/* 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
|
+
communication cycle's type scale, which the root size also carries. Without it everything in the region read the ROOT
|
|
594
|
+
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
|
+
#game-region{font-size:calc(var(--ui-fs,16px) * var(--fonte-escala,1))}
|
|
596
|
+
/* 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
|
+
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. */
|
|
602
|
+
.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
|
+
.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}
|
|
611
|
+
/* The explanation band is 82% opaque: the bars showed through under its words. While it shows they are not drawn at all —
|
|
612
|
+
the explanation has priority (ADR-0168 §3), and a segment behind a letter is noise for the child reading it. */
|
|
613
|
+
.game-region:has(.barra-explicacao:not([hidden])) .hud-aprendizagem,#game-region:has(.barra-explicacao:not([hidden])) .hud-aprendizagem{visibility:hidden}
|
|
614
|
+
.hud-barra{display:flex;align-items:center;gap:.15em;padding:.2em .3em;background:rgba(8,8,16,.92);border-radius:8px}
|
|
615
|
+
.hud-seg{display:block;width:.8em;height:1em;border-radius:2px;box-sizing:border-box}
|
|
616
|
+
.hud-seg[data-seg="vazio"]{border:1px solid #8a8f98}
|
|
617
|
+
.hud-seg[data-seg="azul"]{background:#0072B2}
|
|
618
|
+
.hud-seg[data-seg="verde"]{background:radial-gradient(circle,#08080f 0 .14em,transparent .16em),#009E73}
|
|
619
|
+
.hud-seg[data-seg="vermelho"]{background:repeating-linear-gradient(45deg,#08080f 0 .12em,transparent .12em .3em),#D55E00}
|
|
620
|
+
.hud-barra[data-cor="roxa"] .hud-seg:not([data-seg="vazio"]){background:#CC79A7}
|
|
621
|
+
.hud-barra[data-cor="laranja"] .hud-seg:not([data-seg="vazio"]){background:#E69F00}
|
|
622
|
+
.hud-barra[data-cor="roxa"]::after,.hud-barra[data-cor="laranja"]::after{color:#f6f5f0;font-size:1em;line-height:1;margin-left:.15em}
|
|
623
|
+
.hud-barra[data-cor="roxa"]::after{content:"▲"}
|
|
624
|
+
.hud-barra[data-cor="laranja"]::after{content:"▼"}
|
|
625
|
+
.hud-numero{margin:0;padding:0 .3em;color:#f6f5f0;background:rgba(8,8,16,.92);border-radius:8px;max-width:100%;overflow-wrap:anywhere}
|
|
626
|
+
.rodape-da-tela{position:absolute;left:0;right:0;bottom:0;z-index:12;display:flex;flex-direction:column;gap:0;pointer-events:none}
|
|
627
|
+
.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)}
|
|
631
|
+
.pausa-legenda{order:1;padding:0 .6em}
|
|
632
|
+
.rodape-da-tela:not(:has(> .barra-explicacao:not([hidden]))) > .pausa-legenda{padding-bottom:8px}
|
|
633
|
+
.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
|
+
/* The SOUND CAPTION (study item D3) tops the column — ADR-0164 rule 4: «the sound caption above, the explanation below
|
|
635
|
+
it» — on a dark background behind its words only, two lines at most (rule 5). */
|
|
636
|
+
.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
|
+
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}
|
|
639
|
+
/* 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}
|
|
641
|
+
.pausa-legenda[hidden],.barra-explicacao[hidden],.legenda-de-som[hidden]{display:none}
|
|
642
|
+
/* A PANEL WEARS THE PAUSE CARD (interface log, 2026-09-13). The Dev: the settings submenu «mantém a mesma altura e identidade
|
|
643
|
+
visual», and every panel it opens had «outra identidade visual, com alturas menores, título maior e cores diferentes».
|
|
644
|
+
So a panel in the region takes `.screen-pause .pause-card` as it is: the whole height, the same dark card and gold border,
|
|
645
|
+
the gold title at the text size, items of `.pm-btn`'s colour, border and radius with the same 2 px gaps. It is at least
|
|
646
|
+
the pause card's width and grows only when a row needs it — a steps row never wraps (ADR-0130 erratum), and with the BDA
|
|
647
|
+
spacing (ADR-0149) «◀ Realce de contraste: desligado ▶» is wider than the pause list's 26em. */
|
|
648
|
+
#game-region .overlay__card{background:#0e1626;border:2px solid #ffd23f;border-radius:14px;padding:.25rem .7rem;width:auto;
|
|
649
|
+
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)}
|
|
651
|
+
#game-region .overlay__card h2{font-size:1em;line-height:1.25;margin:0 0 .1rem;color:#ffd23f}
|
|
652
|
+
#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
|
+
#game-region .overlay__back:hover,#game-region .overlay__back:focus{background:#2a3a5e;border-color:#ffd23f;outline:2px solid #ffd23f;outline-offset:1px}
|
|
654
|
+
#game-region .ctrl-list{gap:2px}
|
|
655
|
+
/* the pause list's width is the floor, as `.pause-menu` declares it: the card follows with the same padding and scrollbar gutters */
|
|
656
|
+
#game-region .overlay__back,#game-region .ctrl-list{min-width:26em;max-width:100%} /* em: grows with the menu's text, like the pause list */
|
|
657
|
+
#game-region .ctrl-row{box-sizing:border-box;min-height:var(--alvo-min,44px);padding:.3rem .7rem;background:#1a2740;border:1px solid #6a7a96;border-radius:10px;color:#eaf2f8;font-weight:700}
|
|
658
|
+
#game-region .overlay__card > .ctrl-row{margin-top:2px}
|
|
659
|
+
#game-region .ctrl-row:hover,#game-region .ctrl-row:focus-within{background:#2a3a5e;border-color:#ffd23f}
|
|
660
|
+
/* 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
|
+
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)}
|
|
663
|
+
/* 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
|
+
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
|
+
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,
|
|
666
|
+
gone under reduced motion. */
|
|
667
|
+
/* a slide explains itself: no footer band telling the child to point at an option, and no room kept for it */
|
|
668
|
+
#help .opt-explain,#help .overlay__card::after{display:none}
|
|
669
|
+
.slides{display:flex;align-items:stretch;gap:.25rem;min-height:11em;border:1px solid #6a7a96;border-radius:10px;background:#1a2740;color:#eaf2f8}
|
|
670
|
+
.slides:focus,.slides:focus-visible{outline:2px solid #ffd23f;outline-offset:1px;border-color:#ffd23f}
|
|
671
|
+
.slides .passo-seta{align-self:center;color:#ffd23f;font-size:1.3em}
|
|
672
|
+
.slide{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:.45em;padding:.5em .2em;text-align:center}
|
|
673
|
+
.slide-tecla{display:inline-flex;align-items:center;justify-content:center;min-width:3em;min-height:2em;padding:.15em .6em;font:inherit;font-size:1.4em;
|
|
674
|
+
font-weight:800;color:#0e1626;background:#eaf2f8;border-radius:10px;box-shadow:0 .22em 0 #6a7a96;animation:tecla-aperta 2.4s ease-in-out infinite}
|
|
675
|
+
.slide-tecla[data-sem-tecla]{color:#c3cfe0;background:transparent;border:2px dashed #6a7a96;box-shadow:none;animation:none}
|
|
676
|
+
@keyframes tecla-aperta{0%,70%,100%{transform:translateY(0);box-shadow:0 .22em 0 #6a7a96}82%{transform:translateY(.16em);box-shadow:0 .06em 0 #6a7a96}}
|
|
677
|
+
@media (prefers-reduced-motion: reduce){ .slide-tecla{animation:none} }
|
|
678
|
+
/* a cartridge's «how to play» figure (ADR-0195): the surface the game draws on, crisp at the pixel scale */
|
|
679
|
+
.slide-figura{display:block;width:min(100%,16em);height:7em;image-rendering:pixelated}
|
|
680
|
+
.slide-palavra{margin:0;font-size:1.2em;font-weight:800;color:#ffd23f}
|
|
681
|
+
.slide-texto{margin:0;max-width:28em;line-height:1.35}
|
|
682
|
+
.slide-pontos{display:flex;gap:.45em;justify-content:center;margin-top:.2em}
|
|
683
|
+
.slide-ponto{width:.6em;height:.6em;border-radius:50%;border:1px solid #eaf2f8;box-sizing:border-box}
|
|
684
|
+
.slide-ponto.is-on{background:#ffd23f;border-color:#ffd23f}
|
|
685
|
+
/* Explanation footer: white on 0.82 translucent black → the white's contrast is >7:1 even over 100% white
|
|
686
|
+
(composition: 1-0.82=0.18 → L≈0.027 → ~13:1), without being 100% opaque. Fixed at the card's foot. */
|
|
687
|
+
.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
|
+
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}
|
|
691
|
+
/* 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
|
+
canvas», the Dev on a screenshot. The card sets no position, so the overlay (the region's size) is the containing block:
|
|
693
|
+
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
|
+
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}
|
|
512
698
|
#game-region .overlay__actions{position:static;background:transparent;padding:.5rem 0 0;margin:0}
|
|
513
|
-
#visual{background:rgba(0,0,0,.28)
|
|
699
|
+
#visual{background:rgba(0,0,0,.28)} /* colour: a translucent background, to see the effect on the game at once */
|
|
514
700
|
|
|
515
|
-
/*
|
|
516
|
-
#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)} /*
|
|
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 */
|
|
517
703
|
#viz-indicator.blind{background:#fff}
|
|
518
704
|
#viz-indicator.low{background:#36d36a}
|
|
519
|
-
/*
|
|
705
|
+
/* Low vision — 5 simulations (the blur comes from the filter on the canvas; only the overlays are here) */
|
|
520
706
|
#viz-overlay{position:absolute;inset:0;z-index:8;pointer-events:none}
|
|
521
|
-
#viz-overlay.lv-blur{background:none} /*
|
|
522
|
-
#viz-overlay.lv-haze{background:rgba(244,246,250,.42)} /*
|
|
523
|
-
#viz-overlay.lv-tunnel{background:radial-gradient(circle at 50% 50%, transparent 0 15%, rgba(0,0,0,.55) 27%, rgba(0,0,0,.99) 42%)} /* glaucoma:
|
|
524
|
-
#viz-overlay.lv-macular{background:radial-gradient(circle at 50% 50%, rgba(12,12,15,.95) 0 10%, rgba(12,12,15,.55) 17%, transparent 28%)} /*
|
|
525
|
-
#viz-overlay.lv-diabetic{background: /*
|
|
707
|
+
#viz-overlay.lv-blur{background:none} /* myopia/astigmatism: blur only */
|
|
708
|
+
#viz-overlay.lv-haze{background:rgba(244,246,250,.42)} /* cataract: a whitish film */
|
|
709
|
+
#viz-overlay.lv-tunnel{background:radial-gradient(circle at 50% 50%, transparent 0 15%, rgba(0,0,0,.55) 27%, rgba(0,0,0,.99) 42%)} /* glaucoma: tunnel vision */
|
|
710
|
+
#viz-overlay.lv-macular{background:radial-gradient(circle at 50% 50%, rgba(12,12,15,.95) 0 10%, rgba(12,12,15,.55) 17%, transparent 28%)} /* macular degeneration: a central blur */
|
|
711
|
+
#viz-overlay.lv-diabetic{background: /* diabetic retinopathy: scattered spots */
|
|
526
712
|
radial-gradient(circle at 22% 30%, rgba(10,10,14,.95) 0 4%, transparent 11%),
|
|
527
713
|
radial-gradient(circle at 64% 22%, rgba(10,10,14,.9) 0 3%, transparent 9%),
|
|
528
714
|
radial-gradient(circle at 80% 58%, rgba(10,10,14,.95) 0 5%, transparent 12%),
|
|
529
715
|
radial-gradient(circle at 40% 70%, rgba(10,10,14,.9) 0 4%, transparent 10%),
|
|
530
716
|
radial-gradient(circle at 16% 80%, rgba(10,10,14,.85) 0 3%, transparent 9%),
|
|
531
717
|
radial-gradient(circle at 54% 48%, rgba(10,10,14,.8) 0 3%, transparent 8%)}
|
|
532
|
-
/*
|
|
718
|
+
/* Total blindness: the canvas turns black (filter brightness(0)); we hide the HUD and the on-screen controls */
|
|
533
719
|
body.blind-mode .hud, body.blind-mode #touch-controls, body.blind-mode #start-tips, body.blind-mode #caption{visibility:hidden}
|
|
534
720
|
[hidden]{display:none!important}
|
|
535
|
-
/*
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
/*
|
|
542
|
-
|
|
543
|
-
.quiz-alt{
|
|
544
|
-
.quiz-alts{display:flex;flex-direction:column;gap
|
|
721
|
+
/* CAPITAL LETTERS (the AAC menu, ADR-0028). What a game draws on the canvas is the game's to capitalise; this rule covers
|
|
722
|
+
what the browser draws in the DOM — menus, HUD, captions. `createGame` writes `data-letras` on the root (ADR-0149 §1).
|
|
723
|
+
`text-transform` and NOT transforming the text: the accessible content stays intact, and a screen reader does not start
|
|
724
|
+
spelling letter by letter, which is what real ALL CAPS causes in NVDA/JAWS. */
|
|
725
|
+
/* Quiz options take the ENGINE's target floor (ADR-0163 rule 2): 44 px at 640×360, growing with the scale. They had
|
|
726
|
+
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) */
|
|
728
|
+
/* the marked option is not colour alone either (ADR-0159 rule 10): the same base stripe as an icon switched on */
|
|
729
|
+
.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))}
|
|
545
731
|
:root[data-letras="upper"] body,
|
|
546
732
|
:root[data-letras="upper"] button,
|
|
547
733
|
:root[data-letras="upper"] select,
|
|
548
734
|
:root[data-letras="upper"] option,
|
|
549
735
|
:root[data-letras="upper"] input,
|
|
550
736
|
:root[data-letras="upper"] textarea{text-transform:uppercase}
|
|
551
|
-
/*
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
/* menus nunca ultrapassam a tela: limitados à altura do viewport e roláveis (rodapé de ações fica fixo embaixo) */
|
|
737
|
+
/* The form controls are on the list because the BROWSER's stylesheet imposes `text-transform:none` on them, and `none`
|
|
738
|
+
in a UA rule beats inheritance. Without them the capitals took the screens' text and failed on every BUTTON — which
|
|
739
|
+
is exactly where the menus' labels live. It is what the Dev saw: «não torna todas as letras do menu maiúsculas». */
|
|
740
|
+
/* menus never overflow the screen: limited to the viewport's height and scrollable (the actions footer stays fixed at the bottom) */
|
|
556
741
|
.overlay__card{background:var(--panel);border:3px solid var(--accent);border-radius:12px;padding:1.5rem;max-width:420px;width:100%;text-align:center;font-size:var(--ui-fs,16px);
|
|
557
|
-
max-height:92dvh;overflow-y:auto;overscroll-behavior:contain} /* base = --ui-fs (16
|
|
742
|
+
max-height:92dvh;overflow-y:auto;overscroll-behavior:contain} /* base = --ui-fs (16 min, scales with the canvas); inner sizes in em */
|
|
558
743
|
.overlay__card h2{margin-top:0}
|
|
744
|
+
/* ADR-0158: «Voltar» is the panel's item 1 — a full-width row above the list, not a pill at the bottom. */
|
|
745
|
+
.overlay__back{display:flex;align-items:center;width:100%;margin:0 0 .45rem;text-align:left;border-radius:8px}
|
|
746
|
+
/* ADR-0167: a panel's stops draw no number; «Voltar»'s glyph stays, out of the accessible name (ADR-0159 rule 12). */
|
|
747
|
+
.overlay__card button[data-glifo]::before{content:attr(data-glifo) / "";margin-inline-end:.5em}
|
|
559
748
|
.topbar__right{display:flex;align-items:center;gap:.6rem;flex-wrap:wrap}
|
|
560
749
|
.title-card{text-align:center}
|
|
561
|
-
.title-big{font-size:
|
|
750
|
+
.title-big{font-size:2em;margin:.2rem 0;color:var(--accent)}
|
|
562
751
|
.title-by{color:var(--ink-soft);margin:.2rem 0 1rem}
|
|
563
|
-
.title-card .btn{margin-top:.4rem;font-size:1.
|
|
752
|
+
.title-card .btn{margin-top:.4rem;font-size:1.1em;padding:.6em 1.6em}
|
|
564
753
|
.overlay__actions{display:flex;gap:.6rem;flex-wrap:wrap;margin-top:1rem;justify-content:flex-end;
|
|
565
754
|
position:sticky;bottom:-1.5rem;background:var(--panel);padding:.6rem 0 1.5rem;margin-bottom:-1.5rem}
|
|
566
|
-
.opt-hint{color:var(--ink-soft);font-size
|
|
567
|
-
.panel-sub{text-align:left;font-size:
|
|
755
|
+
.opt-hint{color:var(--ink-soft);font-size:1em;margin:.2rem 0 .8rem}
|
|
756
|
+
.panel-sub{text-align:left;font-size:1em;margin:1rem 0 .4rem;border-bottom:1px solid var(--accent);padding-bottom:.2rem}
|
|
568
757
|
.panel-sub:first-of-type{margin-top:.4rem}
|
|
569
|
-
.panel-sub__tag{color:var(--ink-soft);font-size
|
|
570
|
-
.vol{width:140px;max-width:45%;accent-color:var(--accent);height:1.5rem;cursor:pointer} /*
|
|
571
|
-
/*
|
|
758
|
+
.panel-sub__tag{color:var(--ink-soft);font-size:1em;font-weight:400}
|
|
759
|
+
.vol{width:140px;max-width:45%;accent-color:var(--accent);height:1.5rem;cursor:pointer} /* the volume bar (range) */
|
|
760
|
+
/* Select boxes with the game's IDENTITY: the chosen face, colours and size (not the OS style) */
|
|
572
761
|
select.vol, .overlay__card select, .ctrl-col select{
|
|
573
|
-
font-family:var(--font);font-size
|
|
574
|
-
width:auto;max-width:100%;height:auto;min-height:var(--
|
|
762
|
+
font-family:var(--font);font-size:1em;font-weight:600;color:var(--ink);
|
|
763
|
+
width:auto;max-width:100%;height:auto;min-height:var(--alvo-min,44px);
|
|
575
764
|
background:#0e1326;border:2px solid var(--ink-soft);border-radius:8px;
|
|
576
765
|
padding:.35em 2em .35em .7em;cursor:pointer;
|
|
577
766
|
-webkit-appearance:none;-moz-appearance:none;appearance:none;
|
|
@@ -580,52 +769,73 @@ select.vol, .overlay__card select, .ctrl-col select{
|
|
|
580
769
|
select.vol:focus, .overlay__card select:focus{outline:3px solid var(--accent);outline-offset:1px;border-color:var(--accent)}
|
|
581
770
|
.overlay__card select option{background:#0e1326;color:var(--ink);font-weight:600}
|
|
582
771
|
.ctrl-players{display:flex;gap:.4rem;flex-wrap:wrap;justify-content:center;margin-bottom:.7rem}
|
|
583
|
-
.ctrl-players .mode-btn{padding:.3em .7em;font-size
|
|
772
|
+
.ctrl-players .mode-btn{padding:.3em .7em;font-size:1em}
|
|
584
773
|
.ctrl-list{display:flex;flex-direction:column;gap:.45rem;text-align:left}
|
|
585
774
|
.ctrl-row{display:flex;align-items:center;justify-content:space-between;gap:.6rem;background:#0e1326;border:2px solid var(--ink-soft);border-radius:8px;padding:.4rem .6rem}
|
|
586
|
-
/* ADR-0029 —
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
775
|
+
/* ADR-0029 — LEFT THE DEFAULT. Two visual channels in the same place: the frame's COLOUR and its SHAPE, which is a
|
|
776
|
+
DOUBLE frame (border, gap, ring). The transparent 2px ring reveals the element's own background and is what makes
|
|
777
|
+
the gap; without it the two rings would touch and become just a thicker border — a difference in thickness nobody
|
|
778
|
+
notices without the unmarked one beside it for comparison. The ring count survives greyscale, colour-vision
|
|
779
|
+
deficiency and every palette of the game, because it is not a hue. */
|
|
591
780
|
.is-changed{border-color:var(--changed)!important;box-shadow:inset 0 0 0 2px transparent,inset 0 0 0 4px var(--changed)}
|
|
592
|
-
/*
|
|
781
|
+
/* The mark YIELDS to the focus: losing your place is worse than losing a hint. */
|
|
593
782
|
.is-changed:focus-visible,.is-changed:focus{box-shadow:none}
|
|
594
783
|
.ctrl-row kbd{background:var(--ink);color:var(--bg);border-radius:5px;padding:.05em .45em;font-weight:700}
|
|
595
|
-
.ctrl-row.row-off{opacity:.42} /* item
|
|
784
|
+
.ctrl-row.row-off{opacity:.42} /* a disabled item (e.g. an unavailable keyboard mode) = light grey only, no extra text */
|
|
596
785
|
.ctrl-row .mode-btn[disabled]{cursor:not-allowed;opacity:.7}
|
|
597
786
|
.ctrl-row.ctrl-col{flex-direction:column;align-items:stretch;gap:.4rem}
|
|
598
787
|
.ctrl-row.ctrl-col label{font-weight:700}
|
|
599
788
|
.pad-presets{display:flex;gap:.5rem;flex-wrap:wrap}
|
|
600
|
-
.pad-tag{font-size
|
|
789
|
+
.pad-tag{font-size:1em;font-weight:700;padding:.05em .5em;border-radius:999px;background:#20304e;color:#bcd}
|
|
601
790
|
.pad-tag[data-who="crianca"]{background:#2a4a2e;color:#bfe9c2}
|
|
602
791
|
.pad-tag[data-who="adulto"]{background:#2a3a5e;color:#c3d4f0}
|
|
603
|
-
.pad-warn{font-size
|
|
604
|
-
.ctrl-col input[type=range]{width:100%;min-height:var(--
|
|
605
|
-
|
|
606
|
-
/*
|
|
607
|
-
.touch{position:absolute;inset:
|
|
608
|
-
.touch
|
|
609
|
-
|
|
792
|
+
.pad-warn{font-size:1em;color:#ffdf9e;background:#3a2e12;border:1px solid #6a5220;border-radius:8px;padding:.45rem .6rem}
|
|
793
|
+
.ctrl-col input[type=range]{width:100%;min-height:var(--alvo-min,44px);accent-color:var(--accent)}
|
|
794
|
+
|
|
795
|
+
/* 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}
|
|
797
|
+
/* ADR-0160: the shoulders in the TOP corners of the region, the trigger (2) above the bumper (1). `.touch` covers the whole
|
|
798
|
+
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}
|
|
802
|
+
/* ADR-0160: the action buttons sit by ACTION NUMBER — 1 and 4 on top, 2 and 3 below — whatever slot fires them.
|
|
803
|
+
`margin-left:auto` keeps the block on the right when the game names no direction (ADR-0162). */
|
|
804
|
+
.touch-pad{display:grid;grid-template-areas:"a1 a4" "a2 a3";gap:8px;margin-left:auto;pointer-events:auto}
|
|
805
|
+
.touch-btn[data-acao="action1"]{grid-area:a1}
|
|
806
|
+
.touch-btn[data-acao="action4"]{grid-area:a4}
|
|
807
|
+
.touch-btn[data-acao="action2"]{grid-area:a2}
|
|
808
|
+
.touch-btn[data-acao="action3"]{grid-area:a3}
|
|
809
|
+
.touch-btn{width:56px;height:56px;min-width:var(--alvo-min,44px);min-height:var(--alvo-min,44px);border-radius:12px;border:2px solid rgba(255,255,255,.75);background:rgba(13,17,32,.92);color:#fff;font-size:1.4em;font-weight:800;line-height:1;display:flex;align-items:center;justify-content:center;touch-action:none;-webkit-user-select:none;user-select:none;cursor:pointer}
|
|
610
810
|
.touch-btn:active{background:var(--accent);color:var(--accent-ink);border-color:var(--accent)}
|
|
611
811
|
.touch-jump{background:rgba(18,74,52,.94)}
|
|
612
|
-
/*
|
|
812
|
+
/* Action buttons in a DIAMOND (4 bubbles: 0 bottom, 1 right, 2 left, 3 top) + a START pill */
|
|
613
813
|
.touch-actions{align-items:center}
|
|
614
|
-
/*
|
|
615
|
-
(
|
|
814
|
+
/* PHYSICAL size (mm), not px: --pad-btn and --pad-diam are computed by `input/touch` from real millimetres
|
|
815
|
+
(reference: an iPhone 16 filling the screen). These are the fallbacks before the JS runs. */
|
|
616
816
|
.pad-diamond{position:relative;width:var(--pad-diam,182px);height:var(--pad-diam,182px);pointer-events:none}
|
|
617
817
|
.pad-b{position:absolute;width:var(--pad-btn,66px);height:var(--pad-btn,66px);border-radius:50%;font-size:calc(var(--pad-btn,66px)*.42);font-weight:800;pointer-events:auto;color:#fff;text-shadow:0 1px 2px rgba(0,0,0,.6);display:flex;align-items:center;justify-content:center}
|
|
618
818
|
.pad-top{top:0;left:50%;transform:translateX(-50%)}
|
|
619
819
|
.pad-bottom{bottom:0;left:50%;transform:translateX(-50%)}
|
|
620
820
|
.pad-left{left:0;top:50%;transform:translateY(-50%)}
|
|
621
821
|
.pad-right{right:0;top:50%;transform:translateY(-50%)}
|
|
622
|
-
|
|
822
|
+
/* `width:auto`: the pill is also a `.touch-btn`, whose fixed 56px cut the word — measured in the dist, «START» with 66px
|
|
823
|
+
of text in a 56px button at the cursive hand's 1.25 scale (ADR-0149). The pill grows with the word, and the floor is the target. */
|
|
824
|
+
/* The two system pills, SELECT and START, in a container at the centre (ADR-0155). Inside it they no longer place
|
|
825
|
+
themselves: the container puts them side by side, and each keeps the width of its text. */
|
|
826
|
+
/* 🔴 WITH A PANEL OPEN, THE PAD SITS ABOVE IT (ADR-0157): its directional is what moves in the panel. The panel's veil
|
|
827
|
+
(`#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
|
+
of the menu band, and that is the pad's role while a menu is open — a slot and not a new literal. */
|
|
829
|
+
#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}
|
|
831
|
+
.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}
|
|
623
833
|
.touch-start:active{background:var(--accent);color:var(--accent-ink);border-color:var(--accent)}
|
|
624
|
-
/* joystick
|
|
625
|
-
/*
|
|
834
|
+
/* digital joystick: base (larger circle) + knob (smaller circle) */
|
|
835
|
+
/* Directional (analogue/"lever"): base = surface + travel; knob = contact surface. Both in mm (JS). */
|
|
626
836
|
.touch-stick{position:relative;width:var(--stick-base,124px);height:var(--stick-base,124px);border-radius:50%;border:3px solid rgba(255,255,255,.7);background:rgba(13,17,32,.85);touch-action:none;pointer-events:auto;-webkit-user-select:none;user-select:none}
|
|
627
837
|
.touch-knob{position:absolute;left:50%;top:50%;width:var(--stick-knob,58px);height:var(--stick-knob,58px);margin:calc(var(--stick-knob,58px)/-2) 0 0 calc(var(--stick-knob,58px)/-2);border-radius:50%;background:rgba(255,255,255,.88);box-shadow:0 0 0 2px rgba(0,0,0,.45);transition:transform .04s linear;pointer-events:none}
|
|
628
|
-
/* D-pad
|
|
838
|
+
/* Cross D-pad (an alternative style): 4 arms + a core; the arm's size in mm (JS → --dpad-arm-l/w, --dpad-span) */
|
|
629
839
|
.touch-cross{position:relative;width:var(--dpad-span,120px);height:var(--dpad-span,120px);touch-action:none;pointer-events:auto;-webkit-user-select:none;user-select:none}
|
|
630
840
|
.touch-cross[hidden]{display:none}
|
|
631
841
|
.dpad-arm{position:absolute;display:flex;align-items:center;justify-content:center;background:rgba(13,17,32,.92);border:2px solid rgba(255,255,255,.75);color:rgba(255,255,255,.85);font-size:calc(var(--dpad-arm-w,34px)*.5);line-height:1;pointer-events:none}
|
|
@@ -641,4 +851,4 @@ select.vol:focus, .overlay__card select:focus{outline:3px solid var(--accent);ou
|
|
|
641
851
|
@media (prefers-reduced-motion: reduce){ .touch-knob{transition:none} }
|
|
642
852
|
@media (prefers-contrast: more){ .touch-btn{background:#000;border-color:#fff} .touch-btn:active{background:#fff;color:#000} .touch-stick{background:#000;border-color:#fff} .touch-knob{background:#fff} }
|
|
643
853
|
|
|
644
|
-
@media (max-width:560px){.title{font-size:1.
|
|
854
|
+
@media (max-width:560px){.title{font-size:1.1em}.hud{gap:1rem}}
|