diff --git a/sass/_variables.scss b/sass/_variables.scss index 2f2d788..ca98966 100644 --- a/sass/_variables.scss +++ b/sass/_variables.scss @@ -54,7 +54,7 @@ --border-subtle: #d9d1bd; --text: #1a2235; // deep navy — high AA on cream --text-dim: #44516a; - --text-faint: #6b7280; + --text-faint: #586273; // bumped from #6b7280 (4.4:1) to clear AA 4.5:1 on cream — sunlight-legibility fix --accent: #3a5fce; // darkened accent for AA on cream --accent-hover: #2747ad; --accent-glow: rgba(58, 95, 206, 0.10); diff --git a/static/cube.js b/static/cube.js index 1929cfe..06551ee 100644 --- a/static/cube.js +++ b/static/cube.js @@ -155,6 +155,15 @@ }); } + if (reduceMotion) { + // Honor prefers-reduced-motion: snap to target rotation, no zoom/rotate animations. + cube.style.transition = 'none'; + scene.style.transition = 'none'; + apply(); + if (detailPanel) detailPanel.classList.add('cube-detail--open'); + return; + } + // Animate: rotate the cube cube.style.transition = 'transform 0.6s cubic-bezier(0.25, 0.46, 0.45, 0.94)'; apply(); @@ -177,12 +186,23 @@ // Hide detail if (detailPanel) detailPanel.classList.remove('cube-detail--open'); - // Zoom back in - scene.style.transform = 'scale(1)'; - // Return to isometric rotX = -30; rotY = 35; + + if (reduceMotion) { + cube.style.transition = 'none'; + scene.style.transition = 'none'; + scene.style.transform = 'scale(1)'; + apply(); + autoSpin = true; + snaps.forEach(function (b) { b.classList.remove('face-btn--active'); }); + return; + } + + // Zoom back in + scene.style.transform = 'scale(1)'; + cube.style.transition = 'transform 0.6s cubic-bezier(0.25, 0.46, 0.45, 0.94)'; apply(); diff --git a/static/theme-toggle.js b/static/theme-toggle.js index 1b70fb8..0b84e38 100644 --- a/static/theme-toggle.js +++ b/static/theme-toggle.js @@ -27,9 +27,24 @@ return 'dark'; } + // Sync ARIA state to the rendered theme. aria-pressed="true" when light + // is active (the non-default state); aria-label describes what the click + // would *do*, which is what screen readers announce. + function syncAria() { + var theme = currentTheme(); + btn.setAttribute('aria-pressed', theme === 'light' ? 'true' : 'false'); + btn.setAttribute( + 'aria-label', + theme === 'light' ? 'Switch to dark theme' : 'Switch to light theme' + ); + } + + syncAria(); + btn.addEventListener('click', function () { var next = currentTheme() === 'dark' ? 'light' : 'dark'; document.documentElement.setAttribute('data-theme', next); try { localStorage.setItem(STORAGE_KEY, next); } catch (e) { /* private mode */ } + syncAria(); }); })(); diff --git a/templates/projects.html b/templates/projects.html index 76690a1..e823281 100644 --- a/templates/projects.html +++ b/templates/projects.html @@ -91,10 +91,6 @@