.timer {
  display: flex;
  flex-direction: column;
  gap: var(--space-6);
  align-items: center;
}

/* The box the digits are fitted to in fullscreen. Inert on the page itself,
   where the display sizes itself from the viewport. */
.timer-fit {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
}

.timer-display {
  font-variant-numeric: tabular-nums;
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1;
  /* Sized to be read from the back of a room. In fullscreen the toy measures
     the glyphs and overrides this, so the number fills the screen. */
  font-size: clamp(4rem, 22vw, 16rem);
  color: var(--c-ink);
}

.is-running .timer-display {
  color: var(--hue, var(--c-amber));
}

/* Time is up: three jumps, one a second, then it settles. Long enough to catch
   a room that was not watching, short enough that nobody has to turn it off.
   The distance is a share of the element's own height, so the jump keeps its
   proportions whether the digits are on a phone or filling a projector. */
.is-done .timer-display {
  color: var(--c-abort);
  animation: timer-jump 1s linear 3;
}

/* Shaped like something actually bouncing: three hops of decaying height, each
   one landing and setting off again, then a beat of stillness before the next
   second. The curves do the smoothing — every rise decelerates into its apex
   and every fall accelerates out of it, the way gravity would, which is why
   the timing function is set per keyframe and the shorthand above is linear.
   A flat ease-in-out across the whole second reads as floating, not bouncing.
   Heights fall to roughly a third each hop and the hops shorten with them,
   since the time in the air goes with the square root of the height. */
@keyframes timer-jump {
  0% {
    transform: translateY(0);
    animation-timing-function: cubic-bezier(0.5, 1, 0.89, 1);
  }

  26% {
    transform: translateY(-20%);
    animation-timing-function: cubic-bezier(0.11, 0, 0.5, 0);
  }

  50% {
    transform: translateY(0);
    animation-timing-function: cubic-bezier(0.5, 1, 0.89, 1);
  }

  64% {
    transform: translateY(-7%);
    animation-timing-function: cubic-bezier(0.11, 0, 0.5, 0);
  }

  78% {
    transform: translateY(0);
    animation-timing-function: cubic-bezier(0.5, 1, 0.89, 1);
  }

  86% {
    transform: translateY(-2%);
    animation-timing-function: cubic-bezier(0.11, 0, 0.5, 0);
  }

  92%,
  100% {
    transform: translateY(0);
  }
}

@media (prefers-reduced-motion: reduce) {
  .is-done .timer-display {
    animation: none;
  }
}

.timer-bar {
  width: 100%;
  height: 8px;
  border-radius: 999px;
  background: var(--hue-tint, var(--c-amber-tint));
  overflow: hidden;
}

.timer-bar-fill {
  height: 100%;
  background: var(--hue, var(--c-amber));
  transform-origin: left center;
  transition: transform 250ms linear;
}

.is-done .timer-bar-fill {
  background: var(--c-abort);
}

.timer-setup {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-4) var(--space-6);
  align-items: flex-end;
  justify-content: center;
}

.presets {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}

.timer-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  justify-content: center;
}

/* In fullscreen the setup controls are noise: the room should see the number. */
.toy.is-fullscreen .timer {
  justify-content: center;
  height: 100%;
  width: 100%;
}

/* All the room the other rows do not need goes to the digits, and that is the
   box the toy measures against. min-height:0 so a flex item that big can still
   be told to shrink. */
.toy.is-fullscreen .timer-fit {
  flex: 1;
  min-height: 0;
}

.toy.is-fullscreen .timer-setup {
  opacity: 0;
  transition: opacity 200ms ease;
}

.toy.is-fullscreen .timer-setup:focus-within,
.toy.is-fullscreen:hover .timer-setup {
  opacity: 1;
}
