From 0d19b259f944a9c857b0d3a8d10c32f480da108a Mon Sep 17 00:00:00 2001 From: Jonathan Miller Date: Tue, 21 Jul 2026 14:14:44 -0500 Subject: [PATCH 1/3] a11y(#75): add skip-to-content link + fix broken .skip-link:focus selector Main template had no skip link (only offline.php did) and the focus rule had a stray space ('.skip-l ink:focus') that disabled the on-focus reveal. Add a 'Skip to content' anchor as the first focusable element targeting #maincontent and fix the focus style. WCAG 2.4.1 Bypass Blocks. --- CHANGELOG.md | 3 +++ source/index.php | 1 + source/media/css/template.css | 6 +++++- 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 45b1c58..bf63c03 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,9 @@ # Changelog — MokoOnyx (VERSION: 02.33.04) ## [Unreleased] +### Fixed +- Skip-to-content link (WCAG 2.4.1 Bypass Blocks): the main template had no skip link (only the offline page did), and the `.skip-link:focus` rule had a typo (`.skip-l ink`) that broke the on-focus reveal. Added a "Skip to content" anchor as the first focusable element (targets `#maincontent`) and corrected the focus style. (#75) + ## [02.33.00] --- 2026-07-20 ### Fixed diff --git a/source/index.php b/source/index.php index fab89b4..b237dbb 100644 --- a/source/index.php +++ b/source/index.php @@ -344,6 +344,7 @@ $wa->useScript('user.js'); // js/user.js . $hasClass . ($this->direction == 'rtl' ? ' rtl' : ''); ?>"> + guest ? 'guest' : 'logged_in'; diff --git a/source/media/css/template.css b/source/media/css/template.css index 44648b2..3bd85a2 100644 --- a/source/media/css/template.css +++ b/source/media/css/template.css @@ -17477,11 +17477,15 @@ body.site.error-page { overflow: hidden; } -.skip-l ink:focus { +.skip-link:focus { position: static; width: auto; height: auto; padding: .5rem 1rem; + z-index: 2000; + background: var(--color-primary, #112855); + color: #fff; + border-radius: 0 0 .25rem 0; } .btn { -- 2.52.0 From 8240e8ea93c19d6ebaf18808605a4d0626a81149 Mon Sep 17 00:00:00 2001 From: Jonathan Miller Date: Tue, 21 Jul 2026 14:29:14 -0500 Subject: [PATCH 2/3] feat(#178): relocate theme FAB into login card (MokoAI parity) MokoOnyx already matched MokoAI's vendored widget (inline a11y toggle, floating panel, tap-outside close, theme-aware toggle colors #1565c0/#42a5f5). The one refinement MokoAI added beyond the vendored JS was moving the FAB into the login card as a flush bottom bar. Port it, adapted to Joomla's com_users login view: relocateFabToLoginCard() moves #mokoThemeFab into the login container on body.view-login (MutationObserver for late render) + .in-card CSS. --- CHANGELOG.md | 3 +++ source/media/css/template.css | 18 ++++++++++++++++++ source/media/js/template.js | 34 ++++++++++++++++++++++++++++++++++ 3 files changed, 55 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index bf63c03..dda93e3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,9 @@ # Changelog — MokoOnyx (VERSION: 02.33.04) ## [Unreleased] +### Added +- Login view: the theme FAB (with its accessibility toggle) now relocates into the login card as a flush bottom bar with a theme-aware separator, matching the MokoAI widget behavior. Uses a `MutationObserver` so it works even if the login form renders late. (#178) + ### Fixed - Skip-to-content link (WCAG 2.4.1 Bypass Blocks): the main template had no skip link (only the offline page did), and the `.skip-link:focus` rule had a typo (`.skip-l ink`) that broke the on-focus reveal. Added a "Skip to content" anchor as the first focusable element (targets `#maincontent`) and corrected the focus style. (#75) diff --git a/source/media/css/template.css b/source/media/css/template.css index 3bd85a2..1aca6ab 100644 --- a/source/media/css/template.css +++ b/source/media/css/template.css @@ -17230,6 +17230,24 @@ body.has-gtranslate #mokoThemeFab.pos-bl { top: 1rem; } +/* Login view: FAB relocated into the login card as a flush bottom bar (parity with + MokoAI). Stretches to the card edges (assumes ~1rem card padding), drops its float + positioning, and uses a theme-aware separator instead of a shadow. */ +#mokoThemeFab.in-card { + position: static; + transform: none; + inset: auto; + width: auto; + margin: 1.25rem -1rem -1rem; + padding: .875rem; + border: 0; + border-top: 1px solid var(--border-color, #dfe3e7); + border-radius: 0; + box-shadow: none; + background: transparent; + justify-content: center; +} + /* Sun/Moon theme toggle button */ .theme-icon-btn { display: flex; diff --git a/source/media/js/template.js b/source/media/js/template.js index 205c5f4..851d4f9 100644 --- a/source/media/js/template.js +++ b/source/media/js/template.js @@ -477,6 +477,37 @@ } } + /** + * Relocate the theme FAB into the login card as a flush bottom bar (parity with + * MokoAI). Only on the com_users login view. The FAB (with its a11y toggle) becomes + * part of the card via the `in-card` class. Uses a MutationObserver in case the + * login form renders late; Joomla's login container is `.com-users-login`, with + * fallbacks in case a template override changes the wrapper. + */ + function relocateFabToLoginCard() { + if (!doc.body.classList.contains("view-login")) return; + + function move() { + var fab = doc.getElementById("mokoThemeFab"); + if (!fab) return false; + var card = doc.querySelector(".com-users-login, .login .card, main#maincontent .card, .login-max"); + if (!card) return false; + fab.classList.add("in-card"); + card.appendChild(fab); + return true; + } + + if (move()) return; + + if (typeof win.MutationObserver === "function") { + var obs = new win.MutationObserver(function () { + if (move()) obs.disconnect(); + }); + obs.observe(doc.body, { childList: true, subtree: true }); + win.setTimeout(function () { obs.disconnect(); move(); }, 3000); + } + } + // ======================================================================== // TEMPLATE UTILITIES // ======================================================================== @@ -940,6 +971,9 @@ buildA11yToolbar(); } + // On the login view, relocate the FAB into the login card as a flush bottom bar + relocateFabToLoginCard(); + // Sticky header behavior handleScroll(); win.addEventListener("scroll", handleScroll); -- 2.52.0 From 55b421362585e4ed6ed217d09c31aecce52d0ed6 Mon Sep 17 00:00:00 2001 From: Jonathan Miller Date: Tue, 21 Jul 2026 14:34:05 -0500 Subject: [PATCH 3/3] feat(#83): add Reading mode toggle to accessibility toolbar New a11y toolbar switch that strips sidebars/TOC, narrows content to ~72ch, and relaxes line-height/letter/word spacing for cognitive-accessibility / dyslexia. Follows the existing a11y-option pattern: a11y_reading_mode param + data-a11y-reading body attr + applyReadingMode() (html.a11y-reading-mode class) + localStorage pref + language strings (en-GB/en-US). --- CHANGELOG.md | 1 + source/index.php | 2 ++ source/language/en-GB/tpl_mokoonyx.ini | 2 ++ source/language/en-US/tpl_mokoonyx.ini | 2 ++ source/media/css/template.css | 22 ++++++++++++++++++++++ source/media/js/template.js | 9 ++++++++- source/templateDetails.xml | 7 +++++++ 7 files changed, 44 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index dda93e3..b2d7fac 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ ## [Unreleased] ### Added +- Accessibility toolbar: **Reading mode** toggle — hides sidebars/TOC, narrows the content to a comfortable measure, and relaxes line-height/letter/word spacing for easier reading (cognitive-accessibility / dyslexia aid). Persisted in `localStorage`; toggled via new `a11y_reading_mode` template param. (#83) - Login view: the theme FAB (with its accessibility toggle) now relocates into the login card as a flush bottom bar with a theme-aware separator, matching the MokoAI widget behavior. Uses a `MutationObserver` so it works even if the login form renders late. (#178) ### Fixed diff --git a/source/index.php b/source/index.php index b237dbb..665eaba 100644 --- a/source/index.php +++ b/source/index.php @@ -57,6 +57,7 @@ $params_a11y_contrast = $this->params->get('a11y_high_contrast', 1); $params_a11y_links = $this->params->get('a11y_highlight_links', 1); $params_a11y_font = $this->params->get('a11y_readable_font', 1); $params_a11y_animations = $this->params->get('a11y_pause_animations', 1); +$params_a11y_reading = $this->params->get('a11y_reading_mode', 1); $params_a11y_pos = 'br'; // Detecting Active Variables @@ -333,6 +334,7 @@ $wa->useScript('user.js'); // js/user.js data-a11y-links="" data-a11y-font="" data-a11y-animations="" + data-a11y-reading="" data-a11y-pos="" class="site JNO + + + +