mirror of
https://github.com/got-feedBack/feedBack.git
synced 2026-08-12 03:41:40 +00:00
feat(a11y): app-wide "Interface size" setting (Accessibility) (#664)
* feat(a11y): app-wide "Interface size" setting (Accessibility) Adds a dedicated Accessibility -> Interface size control so users on large, low-DPI displays can enlarge the app's menus, buttons and text (reported: eye strain on a 32" 1440p panel with no OS scaling). Mechanism: a host-owned scale capability (window.feedBack.scale) applies a RELATIVE root font-size (a % of the user-agent base, never a px literal, so a raised browser/OS base font is respected) and publishes an always-present --fb-scale token. The rem-based v3 chrome scales together; the gameplay highway canvas (device-pixel sized) is deliberately untouched, so playback resolution and FPS are unchanged. Medium (100%) clears the override, so default rendering is byte-identical to before -- zero blast radius. - Settings -> new Accessibility tab: Small/Medium/Large/Extra-Large presets (0.90/1.00/1.15/1.30) + a fine-tune slider (to 150%). - Applied pre-paint from an inline <head> script (mirrors the ss-follower pattern) so there is no flash-of-reflow on load. - window.feedBack.scale read-API (get/set + scale:changed, fires once on load) so canvas/WebGL surfaces that cannot inherit rem can follow the size. Shape mirrors the working-tuning read-API; persists as a durable preference. - Cosmetic px->rem sweep so text scales cleanly at the larger stops (2 v3.css font-sizes + 20 text-[Npx] utilities across 8 v3 files; tailwind.min.css rebuilt byte-stable via the pinned toolchain). - One-time first-run nudge for the large/low-DPI display profile that deep-links to the control (never fires once the setting is touched, or on other displays). v3-only. Verified headless: core apply/persist/reset/reload/UI-sync + nudge gating, with no console errors. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QbexxfTt8q2tAn436MqGWF * fix(v3): regenerate tailwind.min.css to satisfy tailwind-fresh CI (PR #664 review) Regenerate static/tailwind.min.css via scripts/build-tailwind.sh (tailwindcss@3.4.19) so a fresh build matches the committed artifact and the tailwind-fresh CI job's `git diff --quiet` passes. Two consecutive regenerations are byte-identical. Also (Fix 2) switch the fine-tune interface-size slider to the documented transient-preview path: oninput now calls scale.set(v, { persist:false }) so dragging previews without writing localStorage/emitting a commit each tick, and a new onchange commits with persistence on release. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> Co-authored-by: byrongamatos <xasiklas@gmail.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
byrongamatos
parent
15fabb62aa
commit
727b8c8f24
@@ -60,6 +60,24 @@
|
||||
} catch (_) { /* file:// or sandboxed iframe */ }
|
||||
})();
|
||||
</script>
|
||||
<!-- Interface size (Accessibility): apply the saved UI scale to the root
|
||||
font-size BEFORE any stylesheet paints, so there is no flash-of-reflow
|
||||
on load. Mirrors capabilities/interface-scale.js, which is the
|
||||
authoritative owner and re-applies once it parses. Relative % (never a
|
||||
px literal) so a raised browser/OS base font size is respected. -->
|
||||
<script>
|
||||
(function () {
|
||||
try {
|
||||
var raw = localStorage.getItem('v3-interface-scale');
|
||||
if (raw == null) return;
|
||||
var v = Math.min(1.5, Math.max(0.85, parseFloat(raw)));
|
||||
if (!isFinite(v) || Math.abs(v - 1) < 0.001) return;
|
||||
var el = document.documentElement;
|
||||
el.style.setProperty('--fb-scale', String(v));
|
||||
el.style.fontSize = (v * 100).toFixed(2) + '%';
|
||||
} catch (_) { /* file:// or private mode */ }
|
||||
})();
|
||||
</script>
|
||||
<!-- fee[dB]ack mark (the [dB] motif). SVG primary, PNG fallback. -->
|
||||
<link rel="icon" type="image/svg+xml" href="/static/v3/brand/favicon.svg">
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="/static/v3/brand/favicon-32.png">
|
||||
@@ -96,6 +114,7 @@
|
||||
<script src="/static/capabilities/visualization.js"></script>
|
||||
<script src="/static/capabilities/note-detection.js"></script>
|
||||
<script src="/static/capabilities/midi-input.js"></script>
|
||||
<script src="/static/capabilities/interface-scale.js"></script>
|
||||
</head>
|
||||
<body class="h-screen flex overflow-hidden bg-fb-sidebar text-fb-text font-display">
|
||||
|
||||
@@ -359,6 +378,7 @@
|
||||
panels (manifest settings.category routes the others). -->
|
||||
<div class="fb-tabbar" id="settings-tabbar">
|
||||
<button type="button" class="fb-tab" data-tab="gameplay">Gameplay</button>
|
||||
<button type="button" class="fb-tab" data-tab="accessibility">Accessibility</button>
|
||||
<button type="button" class="fb-tab" data-tab="audio">Audio</button>
|
||||
<button type="button" class="fb-tab" data-tab="graphics">Graphics</button>
|
||||
<button type="button" class="fb-tab" data-tab="keybinds">Keybinds</button>
|
||||
@@ -540,6 +560,40 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ══ ACCESSIBILITY ═══════════════════════════════════════════ -->
|
||||
<div class="fb-tabpanel" data-tab="accessibility">
|
||||
<div class="fb-tabpanel-head"><h3>Accessibility</h3></div>
|
||||
<div class="fb-srows">
|
||||
<!-- Interface size -->
|
||||
<div class="fb-srow fb-srow-stack">
|
||||
<div style="display:flex; align-items:center; gap:1rem;">
|
||||
<span class="fb-srow-icon"><svg fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 7V5a1 1 0 011-1h14a1 1 0 011 1v2M9 20h6M12 4v16"/></svg></span>
|
||||
<div class="fb-srow-main">
|
||||
<div class="fb-srow-title">Interface size</div>
|
||||
<div class="fb-srow-desc">Make the app’s menus, buttons and text larger or smaller. This changes the <strong>app interface</strong> — not the notes on the note highway (set those under <strong>Graphics</strong>). On desktop you can also press <strong>Ctrl +</strong> / <strong>Ctrl −</strong> to zoom the whole window.</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="fb-seg" id="setting-interface-size" role="group" aria-label="Interface size">
|
||||
<button type="button" class="fb-seg-btn" data-scale="0.90" aria-pressed="false" onclick="window.feedBack.scale.set(0.90)">Small</button>
|
||||
<button type="button" class="fb-seg-btn" data-scale="1.00" aria-pressed="false" onclick="window.feedBack.scale.set(1.00)">Medium</button>
|
||||
<button type="button" class="fb-seg-btn" data-scale="1.15" aria-pressed="false" onclick="window.feedBack.scale.set(1.15)">Large</button>
|
||||
<button type="button" class="fb-seg-btn" data-scale="1.30" aria-pressed="false" onclick="window.feedBack.scale.set(1.30)">Extra Large</button>
|
||||
</div>
|
||||
<p class="fb-srow-desc" style="margin-top:.55rem;">Larger sizes are recommended for large or high-resolution displays.</p>
|
||||
<details class="fb-finetune">
|
||||
<summary>Fine-tune size</summary>
|
||||
<div class="fb-finetune-body">
|
||||
<input type="range" id="setting-interface-size-slider" min="85" max="150" step="5" value="100"
|
||||
oninput="window.feedBack.scale.set(this.value / 100, { persist: false })"
|
||||
onchange="window.feedBack.scale.set(this.value / 100)" class="fb-srow-wide slider-input"
|
||||
aria-label="Interface size percent">
|
||||
<span class="fb-seg-val"><span id="setting-interface-size-val">100</span>%</span>
|
||||
</div>
|
||||
</details>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ══ AUDIO ═══════════════════════════════════════════════════ -->
|
||||
<div class="fb-tabpanel" data-tab="audio">
|
||||
<div class="fb-tabpanel-head"><h3>Audio Settings</h3></div>
|
||||
@@ -1147,10 +1201,12 @@
|
||||
<script src="/static/v3/lessons.js"></script>
|
||||
<script src="/static/v3/dashboard.js"></script>
|
||||
<script src="/static/v3/settings.js"></script>
|
||||
<script src="/static/v3/interface-size-ui.js"></script>
|
||||
<!-- First-run home tour: spotlights the home cards via the shared tour
|
||||
engine (tour-engine.js, loaded above). Auto-runs once after onboarding
|
||||
(triggered from profile.js finish()); replayable from the "?" menu. -->
|
||||
<script src="/static/v3/onboarding-tour.js"></script>
|
||||
<script src="/static/v3/interface-size-nudge.js"></script>
|
||||
<script src="/static/v3/feedbarcade.js"></script>
|
||||
<script src="/static/v3/player-chrome.js"></script>
|
||||
<script>
|
||||
|
||||
Reference in New Issue
Block a user