fuzzyworld

nordic-skating / commit

refactor(ui): tilt is turned on by its button alone, not in Settings as well

df03cd8b973bb52867e650faced2eee85125a23d · Pavel Safronov · 2026-10-09 22:58:06 -0700 · parents fe6b506c1f59

Claude Code usage: this commit ~5.4K out / ~2.6M cached · cost unknown (no per-model trailer) · session 1 tally 970 in / 813.7K out / 114.4M cached · usage by commit and session

refactor(ui): tilt is turned on by its button alone, not in Settings as well

The button at the bottom left made the setting a second way to do the
same thing. With the setting gone, a browser's refusal to allow tilt is
said where the hint is, for ten seconds, with where to allow it.

Screenshots retaken, and the README and the plan brought up to date:
tilt, the rotation lock and full screen in a tab are confirmed working
on a phone.

Usage: 970 in / 813.7K out / 114.4M cached (session tally)
rtk:   1.7M saved, 25.3% over 2679 cmds (global/lifetime)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
 PLAN.md                           |   5 +++--
 README.md                         |   8 ++++----
 docs/screenshots/about.png        | Bin 220741 -> 223387 bytes
 docs/screenshots/aurora-phone.png | Bin 257058 -> 256152 bytes
 docs/screenshots/aurora.png       | Bin 308826 -> 308040 bytes
 docs/screenshots/autopilot.png    | Bin 224400 -> 226224 bytes
 docs/screenshots/dusk.png         | Bin 256346 -> 256885 bytes
 docs/screenshots/far.png          | Bin 263103 -> 264297 bytes
 docs/screenshots/fork.png         | Bin 339255 -> 338327 bytes
 docs/screenshots/islets-dusk.png  | Bin 199445 -> 199662 bytes
 docs/screenshots/islets.png       | Bin 300858 -> 300899 bytes
 docs/screenshots/landscape.png    | Bin 280324 -> 280727 bytes
 docs/screenshots/night.png        | Bin 262214 -> 259964 bytes
 docs/screenshots/pass.png         | Bin 223768 -> 223547 bytes
 docs/screenshots/sea.png          | Bin 232429 -> 231845 bytes
 docs/screenshots/settings.png     | Bin 218822 -> 218026 bytes
 docs/screenshots/steering.png     | Bin 178461 -> 179001 bytes
 docs/screenshots/thin-ice.png     | Bin 284279 -> 284179 bytes
 index.html                        |   6 ------
 src/main.ts                       |  21 ++++++++-------------
 20 files changed, 15 insertions(+), 25 deletions(-)

diff --git a/PLAN.md b/PLAN.md
index 93d4845..dcc043e 100644
--- a/PLAN.md
+++ b/PLAN.md
@@ -175,8 +175,9 @@ tablets: lean the phone like a wheel to steer, level to let the skater skate its
 Dragging still works with it on.
 
 Tried by Pavel on a phone, 2026-10-10: it works. Turning it on in Settings was
-cumbersome, so there is now a Tilt button at the bottom left of the screen as well,
-hidden like the setting where there is nothing to tilt.
+cumbersome, so there is now a Tilt button at the bottom left of the screen, hidden
+where there is nothing to tilt, and the setting is gone. Tilt, the rotation lock and
+full screen in a browser tab all confirmed working by Pavel on a phone.
 
 Also asked for: the screen should not turn with the phone while tilt is on. Built with
 the browser's own rotation lock, which Android gives to an installed app or a page in
diff --git a/README.md b/README.md
index a9b8807..9cbde2d 100644
--- a/README.md
+++ b/README.md
@@ -79,7 +79,6 @@ Each takes effect as it is touched, behind the box, and is remembered for next t
 | Setting | Choices | To begin with |
 |---|---|---|
 | Time of day | Surprise me, Day, Dusk, Night, Aurora | Surprise me: whichever the lake comes with |
-| Tilt to steer (phones and tablets only) | on or off | off |
 | Impossible ice | on or off | off |
 | Lake | Another lake (the same as Randomize); a link back to this one | a different lake every visit |
 
@@ -87,8 +86,8 @@ Each takes effect as it is touched, behind the box, and is remembered for next t
 
 ### Tilt to steer
 
-On a phone or tablet there is a **Tilt** button at the bottom left, and the same choice
-in Settings; anywhere else, neither is shown. Turned on, the phone is leaned
+On a phone or tablet there is a **Tilt** button at the bottom left; anywhere else it is
+not shown. Turned on, which is remembered, the phone is leaned
 left or right like a wheel, about the line the skater looks along: more lean, tighter
 turn, full steering at 28°. Within 4° of level counts as level, since nobody holds a
 phone dead level, and held level the skater skates itself. It works held upright or on
@@ -102,7 +101,8 @@ iPhone will do neither for a web page, so there the phone's own rotation lock, i
 Control Centre, is the way.
 
 An iPhone asks leave for this, each visit, at the first touch. If it has been refused
-it is not asked again: Settings, Safari, Motion & Orientation Access turns it back on.
+it is not asked again, and the app says so where its hint is: Settings, Safari, Motion &
+Orientation Access turns it back on.
 Browsers give a page the phone's tilt only over HTTPS, which the live site is and
 `npm run dev` on a phone is not, so it cannot be tried on a phone from the dev server.
 
diff --git a/docs/screenshots/about.png b/docs/screenshots/about.png
index e9cbaea..c684294 100644
Binary files a/docs/screenshots/about.png and b/docs/screenshots/about.png differ
diff --git a/docs/screenshots/aurora-phone.png b/docs/screenshots/aurora-phone.png
index 1fa491a..14dd639 100644
Binary files a/docs/screenshots/aurora-phone.png and b/docs/screenshots/aurora-phone.png differ
diff --git a/docs/screenshots/aurora.png b/docs/screenshots/aurora.png
index 79db5b4..f5cbb0c 100644
Binary files a/docs/screenshots/aurora.png and b/docs/screenshots/aurora.png differ
diff --git a/docs/screenshots/autopilot.png b/docs/screenshots/autopilot.png
index 1d6ef0f..4be3eef 100644
Binary files a/docs/screenshots/autopilot.png and b/docs/screenshots/autopilot.png differ
diff --git a/docs/screenshots/dusk.png b/docs/screenshots/dusk.png
index 7e693f3..8961610 100644
Binary files a/docs/screenshots/dusk.png and b/docs/screenshots/dusk.png differ
diff --git a/docs/screenshots/far.png b/docs/screenshots/far.png
index f7bae61..2d0b531 100644
Binary files a/docs/screenshots/far.png and b/docs/screenshots/far.png differ
diff --git a/docs/screenshots/fork.png b/docs/screenshots/fork.png
index bdab069..f1438b8 100644
Binary files a/docs/screenshots/fork.png and b/docs/screenshots/fork.png differ
diff --git a/docs/screenshots/islets-dusk.png b/docs/screenshots/islets-dusk.png
index 79aa6f3..943ab2d 100644
Binary files a/docs/screenshots/islets-dusk.png and b/docs/screenshots/islets-dusk.png differ
diff --git a/docs/screenshots/islets.png b/docs/screenshots/islets.png
index fc10a32..e38e926 100644
Binary files a/docs/screenshots/islets.png and b/docs/screenshots/islets.png differ
diff --git a/docs/screenshots/landscape.png b/docs/screenshots/landscape.png
index b77e627..097cd56 100644
Binary files a/docs/screenshots/landscape.png and b/docs/screenshots/landscape.png differ
diff --git a/docs/screenshots/night.png b/docs/screenshots/night.png
index d9f889b..4f034b9 100644
Binary files a/docs/screenshots/night.png and b/docs/screenshots/night.png differ
diff --git a/docs/screenshots/pass.png b/docs/screenshots/pass.png
index ec45f7a..28222a9 100644
Binary files a/docs/screenshots/pass.png and b/docs/screenshots/pass.png differ
diff --git a/docs/screenshots/sea.png b/docs/screenshots/sea.png
index 03c47a9..bf8fcd3 100644
Binary files a/docs/screenshots/sea.png and b/docs/screenshots/sea.png differ
diff --git a/docs/screenshots/settings.png b/docs/screenshots/settings.png
index 5dde400..a13248e 100644
Binary files a/docs/screenshots/settings.png and b/docs/screenshots/settings.png differ
diff --git a/docs/screenshots/steering.png b/docs/screenshots/steering.png
index 4ffadf9..5923e50 100644
Binary files a/docs/screenshots/steering.png and b/docs/screenshots/steering.png differ
diff --git a/docs/screenshots/thin-ice.png b/docs/screenshots/thin-ice.png
index af2adce..b881552 100644
Binary files a/docs/screenshots/thin-ice.png and b/docs/screenshots/thin-ice.png differ
diff --git a/index.html b/index.html
index 09cbfba..3db032b 100644
--- a/index.html
+++ b/index.html
@@ -81,12 +81,6 @@
     <label><input type="radio" name="time" value="aurora" /> Aurora <small>the northern lights</small></label>
   </fieldset>
 
-  <fieldset id="steering" hidden>
-    <legend>Steering</legend>
-    <label><input type="checkbox" id="tilt" /> Tilt to steer <small>lean the phone left or right, like a wheel; held level, the skater skates itself</small></label>
-    <p id="tilt-refused" hidden><small>The browser would not allow it. On an iPhone: Settings, Safari, Motion &amp; Orientation Access.</small></p>
-  </fieldset>
-
   <fieldset>
     <legend>Ice</legend>
     <label><input type="checkbox" id="impossible" /> Impossible ice <small>patches thinner than any ice could be: a very high note, a green glow, no cracks</small></label>
diff --git a/src/main.ts b/src/main.ts
index e4d000f..b0600f8 100644
--- a/src/main.ts
+++ b/src/main.ts
@@ -180,12 +180,9 @@ for (const [button, box] of [[aboutButton, about], [settingsButton, settingsBox]
 
 // The settings box: each thing in it takes effect as it is touched, and is remembered.
 const impossible = settingsBox.querySelector<HTMLInputElement>('#impossible')!
-const tilt = settingsBox.querySelector<HTMLInputElement>('#tilt')!
-const tiltRefused = settingsBox.querySelector<HTMLElement>('#tilt-refused')!
 const tiltButton = document.querySelector<HTMLButtonElement>('#tilt-button')!
-// Steering by tilt is offered only on what can be tilted: in the settings, and by a
-// button of its own at the foot of the screen, which is the quick way to it.
-settingsBox.querySelector<HTMLElement>('#steering')!.hidden = !Input.canTilt
+// Steering by tilt is offered only on what can be tilted, by a button of its own at the
+// foot of the screen.
 tiltButton.hidden = !Input.canTilt
 // A touch of the button is the touch an iPhone wants before it will give its leave.
 tiltButton.addEventListener('click', () => void setTilt(!settings.tilt))
@@ -229,12 +226,15 @@ async function holdRotation(hold: boolean): Promise<void> {
 async function setTilt(on: boolean): Promise<void> {
   const given = on && (await input.tiltOn())
   if (!given) input.tiltOff()
-  tiltRefused.hidden = !on || given
-  // Refused from the button, there is nowhere to say so but the settings: open them there.
-  if (on && !given && !settingsBox.open) settingsButton.click()
   settings.tilt = given
   saveSettings(settings)
   showSettings()
+  // Refused: said where the hint is, for long enough to read, with where to allow it.
+  if (on && !given) {
+    hint.textContent = 'The browser would not allow tilt. On an iPhone: Settings, Safari, Motion & Orientation Access.'
+    hint.classList.remove('gone')
+    setTimeout(() => hint.classList.add('gone'), 10_000)
+  }
   void holdRotation(given)
 }
 // Remembered from last time. An iPhone gives its leave afresh each visit and only at a
@@ -252,7 +252,6 @@ function showSettings(): void {
     radio.checked = radio.value === settings.time
   }
   impossible.checked = settings.impossibleIce
-  tilt.checked = settings.tilt
   tiltButton.textContent = settings.tilt ? '📱 Tilt on' : '📱 Tilt off'
   tiltButton.setAttribute('aria-pressed', String(settings.tilt))
   tiltButton.classList.toggle('on', settings.tilt)
@@ -266,10 +265,6 @@ settingsBox.addEventListener('change', (e) => {
   if (changed.name === 'time') {
     settings.time = changed.value as typeof settings.time
     showTime(timeNow())
-  } else if (changed === tilt) {
-    // This is the touch an iPhone wants before it will give its leave.
-    void setTilt(tilt.checked)
-    return
   } else if (changed === impossible) {
     settings.impossibleIce = lakeOptions.impossibleIce = impossible.checked
     ice.redraw()