From 0f08c93a67e85a11c23c567312a80c7bcd98b18a Mon Sep 17 00:00:00 2001 From: AliceDarkest Date: Mon, 13 Jul 2026 21:32:17 +0200 Subject: [PATCH] Skin accessibility controls for games --- src/main/resources/static/css/accessibility-placement.css | 7 +++++++ src/main/resources/static/js/accessibility.js | 3 ++- src/main/resources/static/js/theme.js | 4 ++-- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/main/resources/static/css/accessibility-placement.css b/src/main/resources/static/css/accessibility-placement.css index a0c83ef..4d57f70 100644 --- a/src/main/resources/static/css/accessibility-placement.css +++ b/src/main/resources/static/css/accessibility-placement.css @@ -4,4 +4,11 @@ body{padding-left:0!important;padding-bottom:0!important} .mf-a11y-panel{inset:76px 16px auto auto!important;width:min(450px,calc(100vw - 32px));max-height:calc(100dvh - 92px)} .mf-a11y-utility{position:sticky;top:0;z-index:1700;min-height:60px;display:flex;align-items:center;justify-content:flex-end;padding:.5rem 1rem;background:var(--panel);border-bottom:1px solid var(--border)} .mf-theme-float{display:flex;align-items:center;gap:.55rem} +body.mf-a11y-skin-codeescape{--mf-a11y-accent:var(--esc-accent);--mf-a11y-glow:var(--esc-glow);--mf-a11y-ink:#1c1100} +body.mf-a11y-skin-bughunter{--mf-a11y-accent:var(--bh-accent);--mf-a11y-glow:var(--bh-glow);--mf-a11y-ink:#210c12} +body[class*="mf-a11y-skin-"] .mf-a11y-trigger{border-color:color-mix(in srgb,var(--mf-a11y-accent) 65%,var(--border));background:linear-gradient(135deg,var(--mf-a11y-accent),color-mix(in srgb,var(--mf-a11y-accent) 72%,#fff));color:var(--mf-a11y-ink);box-shadow:0 0 16px var(--mf-a11y-glow)} +body[class*="mf-a11y-skin-"] .mf-a11y-panel{border-color:color-mix(in srgb,var(--mf-a11y-accent) 56%,var(--border));box-shadow:0 12px 45px rgba(0,0,0,.55),0 0 22px var(--mf-a11y-glow)} +body[class*="mf-a11y-skin-"] .mf-a11y-head{background:color-mix(in srgb,var(--mf-a11y-accent) 28%,#07121f)} +body[class*="mf-a11y-skin-"] .mf-a11y-close{background:var(--mf-a11y-accent);color:var(--mf-a11y-ink)} +body[class*="mf-a11y-skin-"] .mf-a11y-option[aria-pressed="true"]{border-color:var(--mf-a11y-accent);background:color-mix(in srgb,var(--mf-a11y-accent) 18%,var(--surface));box-shadow:inset 0 0 0 2px var(--mf-a11y-accent)} @media(max-width:700px){.mf-a11y-panel{inset:70px 6px auto 6px!important;width:auto;max-height:calc(100dvh - 82px)}} diff --git a/src/main/resources/static/js/accessibility.js b/src/main/resources/static/js/accessibility.js index 070cad1..daad1ad 100644 --- a/src/main/resources/static/js/accessibility.js +++ b/src/main/resources/static/js/accessibility.js @@ -2,10 +2,11 @@ function load(){try{return Object.assign({},defaults,JSON.parse(localStorage.getItem(KEY)||'{}'));}catch(e){return Object.assign({},defaults);}}var state=load(); function apply(){var h=document.documentElement;h.setAttribute('data-mf-font',String(state.font));h.setAttribute('data-mf-readable',state.readable);h.setAttribute('data-mf-contrast',state.contrast);h.setAttribute('data-mf-color',state.color?'safe':'standard');h.setAttribute('data-mf-mono',state.mono);h.setAttribute('data-mf-links',state.links);h.setAttribute('data-mf-motion',state.motion);h.setAttribute('data-mf-cursor',state.cursor);try{localStorage.setItem(KEY,JSON.stringify(state));}catch(e){}} apply(); +function applySkin(){var root=document.querySelector('[data-a11y-skin]'),skin=root&&root.getAttribute('data-a11y-skin');if(!skin&&document.querySelector('.esc-app'))skin='codeescape';if(!skin&&document.querySelector('.bh-app'))skin='bughunter';if(skin)document.body.classList.add('mf-a11y-skin-'+skin);} function button(id,icon,label,detail){return '';} function init(){if(document.querySelector('.mf-a11y-trigger'))return;var trigger=document.createElement('button');trigger.type='button';trigger.className='mf-a11y-trigger';trigger.setAttribute('aria-label','Barrierefreiheit öffnen');trigger.setAttribute('aria-expanded','false');trigger.setAttribute('aria-controls','mf-a11y-panel');trigger.innerHTML=''; var panel=document.createElement('section');panel.id='mf-a11y-panel';panel.className='mf-a11y-panel';panel.hidden=true;panel.setAttribute('role','dialog');panel.setAttribute('aria-modal','false');panel.setAttribute('aria-labelledby','mf-a11y-title');panel.innerHTML='

Barrierefreiheit

'+button('font','T⁺','Text vergrößern','100 %')+button('contrast','◐','Hochkontrast')+button('color','◉','Farbenblind-Modus')+button('mono','◒','Monochrom')+button('readable','Aa','Lesemodus (Dyslexie)','Verdana + Abstände')+button('links','🔗','Links unterstreichen')+button('motion','Ⅱ','Animationen stoppen')+button('cursor','➤','Großer Cursor')+button('reset','↺','Alles zurücksetzen')+'
'; document.body.appendChild(trigger);document.body.appendChild(panel);var close=panel.querySelector('.mf-a11y-close');function paint(){panel.querySelectorAll('[data-a11y]').forEach(function(b){var id=b.dataset.a11y,on=id==='font'?state.font>100:id==='motion'?!state.motion:id==='reset'?false:!!state[id];b.setAttribute('aria-pressed',on);if(id==='font')b.querySelector('small').textContent=state.font+' %';});} var host=document.querySelector('.mf-a11y-host,.mf-tools,.tt-header-tools,.mm-header-tools,.ss-header-tools,.dlg-header-tools,.mf-theme-float');if(host){host.insertBefore(trigger,host.firstChild);}else{var utility=document.createElement('div');utility.className='mf-a11y-utility';utility.setAttribute('aria-label','Globale Werkzeuge');utility.appendChild(trigger);document.body.insertBefore(utility,document.body.firstChild);} function hide(){panel.hidden=true;trigger.setAttribute('aria-expanded','false');trigger.focus();}function show(){panel.hidden=false;trigger.setAttribute('aria-expanded','true');paint();close.focus();}trigger.addEventListener('click',function(){panel.hidden?show():hide();});close.addEventListener('click',hide);window.addEventListener('keydown',function(e){if(e.key==='Escape'&&!panel.hidden)hide();});panel.addEventListener('click',function(e){var b=e.target.closest('[data-a11y]');if(!b)return;var id=b.dataset.a11y;if(id==='reset')state=Object.assign({},defaults);else if(id==='font')state.font=levels[(levels.indexOf(state.font)+1)%levels.length];else if(id==='motion')state.motion=!state.motion;else state[id]=!state[id];apply();paint();});paint();} -if(document.readyState==='loading')document.addEventListener('DOMContentLoaded',init);else init();})(); +function start(){applySkin();init();}if(document.readyState==='loading')document.addEventListener('DOMContentLoaded',start);else start();})(); diff --git a/src/main/resources/static/js/theme.js b/src/main/resources/static/js/theme.js index c0d984b..e531d5d 100644 --- a/src/main/resources/static/js/theme.js +++ b/src/main/resources/static/js/theme.js @@ -32,13 +32,13 @@ document.head.appendChild(accessibilityCss); var accessibilityPlacementCss = document.createElement('link'); accessibilityPlacementCss.rel = 'stylesheet'; - accessibilityPlacementCss.href = '/css/accessibility-placement.css?v=2'; + accessibilityPlacementCss.href = '/css/accessibility-placement.css?v=3'; accessibilityPlacementCss.setAttribute('data-accessibility', ''); document.head.appendChild(accessibilityPlacementCss); } if (!document.querySelector('script[data-accessibility]')) { var accessibilityScript = document.createElement('script'); - accessibilityScript.src = '/js/accessibility.js?v=4'; + accessibilityScript.src = '/js/accessibility.js?v=5'; accessibilityScript.defer = true; accessibilityScript.setAttribute('data-accessibility', ''); document.head.appendChild(accessibilityScript);