:root {
  color-scheme: light;
  --page: #f9f9f7;
  --surface: #fcfcfb;
  --ink: #0b0b0b;
  --ink-2: #52514e;
  --line: #c3c2b7;
  --error: #d03b3b;
  --font: system-ui, -apple-system, "Segoe UI", sans-serif;
}
@media (prefers-color-scheme: dark) {
  :root {
    color-scheme: dark;
    --page: #0d0d0d;
    --surface: #1a1a19;
    --ink: #ffffff;
    --ink-2: #c3c2b7;
    --line: #52514e;
    --error: #e66767;
  }
}

* { box-sizing: border-box; }
html, body { margin: 0; height: 100%; }
body {
  background: var(--page);
  color: var(--ink);
  font: 15px/1.45 var(--font);
  -webkit-font-smoothing: antialiased;
  -webkit-tap-highlight-color: transparent;
}

.gate {
  min-height: 100%;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  padding: 24px 16px 18vh;
}

.pin { position: relative; width: min(100%, 420px); }
.cells {
  display: grid;
  grid-template-columns: repeat(4, 1fr) 10px repeat(4, 1fr);
  gap: 8px;
}
.cells span {
  aspect-ratio: 4 / 5;
  display: grid; place-items: center;
  border: 1.5px solid var(--line);
  border-radius: 12px;
  background: var(--surface);
  transition: border-color .12s, transform .12s;
}
/* The gap between the two groups of four. */
.cells span:nth-child(5) { grid-column: 6; }
.cells span::after {
  content: "";
  width: 12px; height: 12px; border-radius: 50%;
  background: var(--ink);
  transform: scale(0);
  transition: transform .12s;
}
.cells span.filled::after { transform: scale(1); }
.pin:focus-within .cells span.next { border-color: var(--ink); }

/* The real input sits on top of the cells, invisible, so a tap anywhere on them opens the keypad. */
.pin input {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  opacity: 0;
  font-size: 16px; /* stops iOS from zooming in */
  border: 0; padding: 0; margin: 0;
  cursor: text;
}

.pin.busy .cells span { border-color: var(--line); }
.pin.busy .cells span.filled::after { animation: pulse .9s ease-in-out infinite; }
.pin.wrong .cells span { border-color: var(--error); }
.pin.wrong .cells { animation: shake .4s; }
.pin.locked .cells { opacity: .45; }

.msg {
  min-height: 1.45em;
  margin: 18px 0 0;
  color: var(--ink-2);
  font-size: 14px;
  text-align: center;
  font-variant-numeric: tabular-nums;
}
.msg.error { color: var(--error); }

@keyframes shake {
  0%, 100% { transform: translateX(0); }
  20% { transform: translateX(-8px); }
  40% { transform: translateX(7px); }
  60% { transform: translateX(-5px); }
  80% { transform: translateX(3px); }
}
@keyframes pulse { 50% { opacity: .35; } }

@media (prefers-reduced-motion: reduce) {
  .pin.wrong .cells, .pin.busy .cells span.filled::after { animation: none; }
  .cells span, .cells span::after { transition: none; }
}
