Make the armed reset a centred, unwinding ring in the button flash colour

The old confirmation ring was a scaling, fading border. It sat off-centre —
the ::before had no top/left, so it landed on its static position in the
grid rather than over the icon — and it read as a shrinking circle rather
than time running out.

It's now an SVG ring animated on stroke-dashoffset (0 to 113.1, the
circumference at r=18) and rotated -90deg to start at 12 o'clock, so it
unwinds like a progress ring in reverse over the same 2s as the timeout.
Explicitly centred on the button.

The stroke is currentColor against #reset.armed{color:var(--icon-hot)},
so it uses the pale flash every button already shows on :active instead of
the theme accent, and no longer changes with the colour setting.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-11 11:31:06 +02:00
co-authored by Claude Opus 5
parent 559b6cd335
commit 0b96eb824b
2 changed files with 23 additions and 11 deletions
+1 -1
View File
@@ -35,7 +35,7 @@ except installation and the service worker.
- The bar under the big time is the delay draining. When it empties you get a - The bar under the big time is the delay draining. When it empties you get a
soft tick and your reserve starts moving. That's the moment worth hearing. soft tick and your reserve starts moving. That's the moment worth hearing.
- **Reset** returns to the starting position. It takes two taps: the first arms - **Reset** returns to the starting position. It takes two taps: the first arms
the button — it turns your accent colour and a ring drains — and a second tap the button — it lights up and a ring unwinds around it — and a second tap
within those two seconds does it. One stray thumb can't wipe a live game. within those two seconds does it. One stray thumb can't wipe a live game.
- **Pause** freezes mid-turn and resumes exactly where it stopped, delay - **Pause** freezes mid-turn and resumes exactly where it stopped, delay
included. Opening settings pauses automatically, and leaves it paused so the included. Opening settings pauses automatically, and leaves it paused so the
+22 -10
View File
@@ -149,18 +149,29 @@
.btn svg[hidden]{display:none} .btn svg[hidden]{display:none}
.btn:focus-visible{outline:2px solid var(--icon-hot);outline-offset:-6px;border-radius:8px} .btn:focus-visible{outline:2px solid var(--icon-hot);outline-offset:-6px;border-radius:8px}
/* reset armed for a second tap — the ring drains over the same 2s as the timeout */ /* reset armed for a second tap — the ring unwinds over the same 2s as the timeout */
#reset{position:relative} #reset{position:relative}
#reset.armed{color:var(--accent)} #reset.armed{color:var(--icon-hot)}
#reset.armed::before{ #reset .ring{
content:"";position:absolute; position:absolute;
width:clamp(36px,9vw,48px);aspect-ratio:1; top:50%;left:50%;
border-radius:50%;border:2px solid var(--accent); width:clamp(36px,9.6vw,48px);height:clamp(36px,9.6vw,48px);
animation:drain 2s linear forwards; transform:translate(-50%,-50%) rotate(-90deg); /* start the arc at 12 o'clock */
display:none;
pointer-events:none;
} }
@keyframes drain{ #reset.armed .ring{display:block}
from{opacity:1;transform:scale(1)} #reset .ring circle{
to{opacity:0;transform:scale(.72)} fill:none;
stroke:currentColor; /* the same flash the buttons use */
stroke-width:2.6;
stroke-linecap:round;
stroke-dasharray:113.1; /* 2πr, r=18 */
animation:unwind 2s linear forwards;
}
@keyframes unwind{
from{stroke-dashoffset:0}
to{stroke-dashoffset:113.1}
} }
/* ---------- settings sheet ---------- */ /* ---------- settings sheet ---------- */
@@ -292,6 +303,7 @@
<div class="bar"> <div class="bar">
<button class="btn" id="reset" aria-label="Reset clock"> <button class="btn" id="reset" aria-label="Reset clock">
<svg class="ring" viewBox="0 0 40 40" aria-hidden="true"><circle cx="20" cy="20" r="18"/></svg>
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"> <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round">
<path d="M20 5v6h-6"/><path d="M20 11a8 8 0 1 0-2.3 5.3"/> <path d="M20 5v6h-6"/><path d="M20 11a8 8 0 1 0-2.3 5.3"/>
</svg> </svg>