diff --git a/timer.c b/timer.c
index 7c031a6..fe30ad2 100644
--- a/timer.c
+++ b/timer.c
@@ -4,8 +4,10 @@
 #include <helianthus.h>
 
 
+unsigned long long prevMonotonicMs;
+
 int hours, minutes, seconds;
-double subSeconds;
+int mills;
 
 int started;
 int alarm;
@@ -19,13 +21,17 @@ void init() {
 
 
 void draw() {
+  unsigned long long monotonicMs = windowGetMonotonicMilliseconds();
+  int timeMs = (int)(monotonicMs - prevMonotonicMs);
+  prevMonotonicMs = monotonicMs;
+
   if (started) {
     if (alarm) {
-      subSeconds += windowGetFrameTime();
-      while(subSeconds >= 1) subSeconds -= 1;
+      mills += timeMs;
+      while(mills >= 1000) mills -= 1000;
     } else {
-      subSeconds += windowGetFrameTime();
-      while(subSeconds >= 1) { subSeconds -= 1; --seconds; }
+      mills += timeMs;
+      while(mills >= 1000) { mills -= 1000; --seconds; }
       while(seconds < 0) { --minutes; seconds += 60; }
       while(minutes < 0) { --hours; minutes += 60; }
       if (hours < 0 || (hours == 0 && minutes == 0 && seconds == 0)) {
@@ -51,7 +57,7 @@ void draw() {
     saveState();
     translate( (i-1)*size, 0 );
     textSize(64);
-    if (alarm) stroke(colorByRGBA(0, 0, 0, subSeconds));
+    if (alarm) stroke(colorByRGBA(0, 0, 0, mills*0.001));
 
     double mx = mouseTransformedX();
     double my = mouseTransformedY();
@@ -77,7 +83,7 @@ void draw() {
   if (started) {
     saveState();
     strokeWidth(0.1*size);
-    if (alarm) stroke(colorByRGBA(0, 0, 0, subSeconds)); else rotate(-60*subSeconds);
+    if (alarm) stroke(colorByRGBA(0, 0, 0, mills*0.001)); else rotate(-60*0.001*mills);
     for(int i = 0; i < 12; ++i) {
       point(2*size, 0);
       rotate(-30);
@@ -105,7 +111,7 @@ void draw() {
       }
     } else {
       text(0, 0, "start");
-      if (click) { subSeconds = 0; started = TRUE; }
+      if (click) { mills = 0; started = TRUE; }
     }
 
     translate(buttonWidth, 0);