mirror of
https://github.com/got-feedBack/feedBack.git
synced 2026-08-13 12:20:09 +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
@@ -58,7 +58,7 @@
|
||||
const handle = opts.draggable
|
||||
? '<span class="cursor-grab text-fb-textDim/60 px-1" title="Drag to reorder">⠿</span>' : '';
|
||||
const tuning = s.tuning_name
|
||||
? '<span class="ml-2 text-[10px] bg-fb-mid text-black font-bold px-1.5 py-0.5 rounded-sm">' + esc(s.tuning_name) + '</span>' : '';
|
||||
? '<span class="ml-2 text-[0.625rem] bg-fb-mid text-black font-bold px-1.5 py-0.5 rounded-sm">' + esc(s.tuning_name) + '</span>' : '';
|
||||
// ── Curated-album slot extras (P6) — mixes/saved emit none of this ──
|
||||
// A slot plays its RESOLVED chart (data-play-fn: the pinned file, or
|
||||
// the work's current keeper when the pinned file is gone) with its
|
||||
@@ -76,9 +76,9 @@
|
||||
? '<span class="text-xs font-bold shrink-0 ' + (opts.acc >= 0.9 ? 'text-fb-good' : opts.acc >= 0.5 ? 'text-fb-mid' : 'text-fb-low') + '">' + Math.round(opts.acc * 100) + '%</span>'
|
||||
: '';
|
||||
const pin = (isAlbum && s.arrangement)
|
||||
? '<span class="ml-2 text-[10px] bg-fb-primary/20 text-fb-primary font-bold px-1.5 py-0.5 rounded-sm" title="Pinned arrangement">' + esc(s.arrangement) + '</span>' : '';
|
||||
? '<span class="ml-2 text-[0.625rem] bg-fb-primary/20 text-fb-primary font-bold px-1.5 py-0.5 rounded-sm" title="Pinned arrangement">' + esc(s.arrangement) + '</span>' : '';
|
||||
const orphan = (isAlbum && s.resolved_from_orphan)
|
||||
? '<span class="ml-2 text-[10px] text-fb-textDim" title="The pinned chart is gone — playing this song\'s current keeper instead">(auto)</span>' : '';
|
||||
? '<span class="ml-2 text-[0.625rem] text-fb-textDim" title="The pinned chart is gone — playing this song\'s current keeper instead">(auto)</span>' : '';
|
||||
const slotBtn = (isAlbum && !missing)
|
||||
? '<button data-slot aria-label="Choose chart / arrangement" title="Choose chart / arrangement" class="opacity-0 group-hover:opacity-100 text-fb-textDim hover:text-fb-text text-sm px-2">▾</button>' : '';
|
||||
return '<li data-fn="' + esc(s.filename) + '"' + playAttrs + (opts.draggable ? ' draggable="true"' : '') +
|
||||
@@ -313,7 +313,7 @@
|
||||
'<label class="flex items-start gap-2 px-2 py-1.5 rounded hover:bg-fb-card/60 cursor-pointer">' +
|
||||
'<input type="radio" name="' + name + '" value="' + esc(value) + '"' + (checked ? ' checked' : '') + ' class="accent-fb-primary mt-0.5">' +
|
||||
'<span class="min-w-0 flex-1"><span class="block text-sm text-fb-text truncate">' + label + '</span>' +
|
||||
(sub ? '<span class="block text-[10px] text-fb-textDim truncate">' + sub + '</span>' : '') +
|
||||
(sub ? '<span class="block text-[0.625rem] text-fb-textDim truncate">' + sub + '</span>' : '') +
|
||||
'</span></label>';
|
||||
// Checked = the stored pin; an orphaned slot (stored file gone from the
|
||||
// list) pre-checks the chart it currently resolves to, so Apply re-pins
|
||||
@@ -322,9 +322,9 @@
|
||||
const chartRows = chartList.map((c) => radio(
|
||||
'slot-chart', c.filename,
|
||||
c.filename === slot.filename || (!slotInList && c.filename === curFn),
|
||||
esc(c.title) + (c.is_representative ? ' <span class="text-[10px] text-fb-primary">● preferred</span>' : ''),
|
||||
esc(c.title) + (c.is_representative ? ' <span class="text-[0.625rem] text-fb-primary">● preferred</span>' : ''),
|
||||
esc((c.tuning_name ? c.tuning_name + ' · ' : '') + c.filename))).join('');
|
||||
const arrRows = [radio('slot-arr', '', !slot.arrangement, 'Full song <span class="text-[10px] text-fb-textDim">(default)</span>', '')]
|
||||
const arrRows = [radio('slot-arr', '', !slot.arrangement, 'Full song <span class="text-[0.625rem] text-fb-textDim">(default)</span>', '')]
|
||||
.concat((slot.arrangements || []).map((a) => {
|
||||
const name = (a && (a.smart_name || a.name)) || '';
|
||||
if (!name) return '';
|
||||
|
||||
Reference in New Issue
Block a user