/* ── The instrument cluster ───────────────────────────────────────────────
   One component, built twice: a 0–260 km/h speedometer that holds the date
   lock, and a 0–8k tachometer that holds the ignition. Everything inside is
   sized in `em` against a font-size derived from the cluster width, so the
   whole gauge scales as a single object at any viewport. */

.cluster {
  --size: min(88vw, 520px);
  position: relative;
  width: var(--size);
  height: var(--size);
  margin-inline: auto;
  font-size: calc(var(--size) / 100);
  flex: none;
  user-select: none;
  -webkit-user-select: none;
}

/* the tach shares its screen with a heading and the start button, so it is
   capped against viewport height too — short laptops would push START off */
.cluster[data-size="tach"] { --size: min(80vw, 420px, 36vh); }

.cluster__housing {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background: var(--void);
  box-shadow:
    0 0 0 1px rgba(0, 0, 0, 0.9),
    0 4em 9em -2.5em rgba(0, 0, 0, 0.95),
    0 0 14em -4em rgba(190, 226, 208, 0.12);
}

/* Knurled chrome bezel: the wide conic ramp is light wrapping the ring, the
   fine repeating conic on top is the machined ridging. */
.cluster__bezel {
  position: absolute;
  inset: 1.6%;
  border-radius: 50%;
  background: conic-gradient(from 212deg,
    #7c8288 0deg, #e6e9eb 46deg, #a8aeb3 96deg,
    #4c5157 150deg, #c9ced2 214deg, #868c92 268deg,
    #dfe3e5 312deg, #5a6066 350deg, #7c8288 360deg);
}

.cluster__bezel::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background: repeating-conic-gradient(from 0deg,
    rgba(255, 255, 255, 0.16) 0deg 0.22deg,
    rgba(0, 0, 0, 0.20) 0.22deg 0.44deg);
  opacity: 0.55;
}

.cluster__bezel::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 50%;
  box-shadow:
    inset 0 0.14em 0.3em rgba(255, 255, 255, 0.45),
    inset 0 -0.14em 0.36em rgba(0, 0, 0, 0.6),
    inset 0 0 0 0.06em rgba(255, 255, 255, 0.10);
}

.cluster__dial {
  position: absolute;
  inset: 5.4%;
  border-radius: 50%;
  background: radial-gradient(circle at 50% 26%, #15181d 0%, #0c0f13 52%, #06070a 100%);
  box-shadow:
    inset 0 0 0 0.14em #000,
    inset 0 0.6em 1.8em rgba(0, 0, 0, 0.9);
  overflow: hidden;
}

.cluster__face {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}

/* dial graphics (viewBox units, 400 × 400) */
.tick-major { stroke: #eef1f3; stroke-width: 2.8; }
.tick-minor { stroke: #767d83; stroke-width: 1.3; }
.tick-red   { stroke: #ff4b5c; }

.dial-num {
  fill: #f3f6f8;
  font-family: var(--face-display);
  font-size: 17.5px;
  font-weight: 600;
  font-variation-settings: 'wdth' 86;
  text-anchor: middle;
  dominant-baseline: central;
}
.dial-num--red { fill: #ff5a68; }

.dial-unit {
  fill: #8d9399;
  font-family: var(--face-display);
  font-size: 13px;
  font-weight: 600;
  font-variation-settings: 'wdth' 86;
  letter-spacing: 0.08em;
  text-anchor: middle;
  dominant-baseline: central;
}

.redline-arc { stroke: #d81328; stroke-width: 5; fill: none; }

/* the needle */
.needle {
  transform-box: view-box;
  transform-origin: 200px 200px;
  transform: rotate(var(--angle, -120deg));
  transition: transform 800ms var(--ease-out);
}
.needle.is-live { transition: none; }
.needle__blade { fill: #d81328; }

/* glass */
.cluster__glass {
  position: absolute;
  inset: 5.4%;
  border-radius: 50%;
  pointer-events: none;
  background:
    linear-gradient(148deg,
      rgba(255, 255, 255, 0.10) 0%,
      rgba(255, 255, 255, 0.035) 24%,
      rgba(255, 255, 255, 0) 44%),
    radial-gradient(120% 90% at 50% 120%, rgba(255, 255, 255, 0.05), transparent 62%);
}


/* ── inner display pod ──────────────────────────────────────────────────── */

.cluster__inner {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 55%;
  height: 55%;
  transform: translate(-50%, -50%);
  border-radius: 50%;
  background: radial-gradient(circle at 50% 38%, #0c110f 0%, #070a09 68%, #030504 100%);
  box-shadow:
    0 0 0 0.25em #05070a,
    0 0 0 0.62em #8f959b,
    0 0 0 0.95em #d3d8dc,
    0 0 0 1.25em #3d4249,
    0 0 0 1.6em #0b0d10,
    inset 0 0 2.4em rgba(0, 0, 0, 0.96);
}

.lcd {
  position: absolute;
  inset: 9%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1.1em;
  font-family: var(--face-lcd);
  color: var(--lcd);
  text-shadow: 0 0 0.5em var(--lcd-glow);
  line-height: 1;
  text-align: center;
}

.lcd__row {
  display: flex;
  align-items: center;
  justify-content: center;
}

/* the tiny unit caption that sits under the trip figure on the real cluster */
.lcd__caption {
  margin: -0.5em 0 0;
  font-size: 2.2em;
  font-weight: 400;
  letter-spacing: 0.26em;
  text-indent: 0.26em;
  text-transform: uppercase;
  color: var(--lcd-dim);
}

.lcd__status {
  margin: 0;
  font-size: 2.9em;
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--lcd-mid);
  white-space: nowrap;
  transition: color var(--d-fast) linear;
}
.lcd__status.is-alarm { color: var(--alarm); text-shadow: 0 0 0.5em rgba(255, 46, 63, 0.55); }
.lcd__status.is-ok    { color: var(--ok);    text-shadow: 0 0 0.5em rgba(79, 224, 138, 0.55); }

.lcd__meta {
  width: 100%;
  justify-content: space-between;
  font-size: 2.4em;
  font-weight: 400;
  color: var(--lcd-mid);
  padding-inline: 0.4em;
  font-variant-numeric: tabular-nums;
}

/* P R N S — S is lit, because he does not drive this like a normal person */
.lcd__gear {
  font-size: 3.4em;
  font-weight: 600;
  color: var(--lcd-mid);
  gap: 0.6em;
}
.lcd__gear span { transition: color var(--d-fast) linear; }
.lcd__gear .is-lit {
  color: var(--sport);
  text-shadow: 0 0 0.55em rgba(255, 106, 44, 0.6);
}
.lcd__gear .gear-c {
  margin-left: 0.2em;
  padding: 0.06em 0.2em;
  border: 0.085em solid currentColor;
  border-radius: 0.1em;
  font-size: 0.84em;
}

/* Doto's glyphs sit at roughly half the em box, so this runs large on purpose. */
.lcd__big {
  margin: 0;
  font-size: 15em;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.02em;
}


/* ── odometer date rollers ──────────────────────────────────────────────── */

.rollers {
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 5.8em;
  font-weight: 600;
}

/* Doto draws a period as a cross, so the separator is a drawn pixel instead. */
.rollers__dot {
  width: 0.15em;
  height: 0.15em;
  margin: 0 0.09em;
  transform: translateY(0.3em);
  background: currentColor;
  color: var(--lcd-mid);
  border-radius: 0.02em;
}

.roller {
  position: relative;
  cursor: ns-resize;
  border-radius: 0.08em;
  padding-inline: 0.05em;
  touch-action: none;
}

.roller__window {
  position: relative;
  height: 1.1em;
  overflow: hidden;
  -webkit-mask-image: linear-gradient(180deg, transparent 0%, #000 14%, #000 86%, transparent 100%);
          mask-image: linear-gradient(180deg, transparent 0%, #000 14%, #000 86%, transparent 100%);
}

.roller__drum {
  display: flex;
  flex-direction: column;
  transform: translateY(var(--offset, 0px));
  transition: transform 280ms var(--ease-mech);
  will-change: transform;
}
.roller__drum.is-dragging { transition: none; }

.roller__cell {
  height: 1.1em;
  display: flex;
  align-items: center;
  justify-content: center;
  font-variant-numeric: tabular-nums;
}

.roller__nudge {
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
  width: 1.6em;
  height: 0.62em;
  display: grid;
  place-items: center;
  padding: 0;
  border: 0;
  background: none;
  color: var(--lcd-mid);
  font-size: 0.34em;
  line-height: 1;
  cursor: pointer;
  opacity: 0;
  transition: opacity var(--d-fast) linear;
}
.roller__nudge--up   { bottom: calc(100% - 0.1em); }
.roller__nudge--down { top: calc(100% - 0.1em); }

.roller:hover .roller__nudge,
.roller:focus-visible .roller__nudge,
.roller.is-active .roller__nudge { opacity: 0.9; }

@media (hover: none) {
  .roller__nudge { opacity: 0.55; }
}

.roller:focus-visible {
  outline: none;
  background: rgba(211, 227, 218, 0.12);
  box-shadow: 0 0 0 0.035em rgba(211, 227, 218, 0.5);
}

/* wrong date */
.cluster.is-rejecting .cluster__dial { animation: cluster-shake 440ms var(--ease-out); }
@keyframes cluster-shake {
  0%, 100% { transform: translateX(0); }
  16% { transform: translateX(-1%); }
  36% { transform: translateX(0.9%); }
  58% { transform: translateX(-0.55%); }
  80% { transform: translateX(0.3%); }
}

@media (prefers-reduced-motion: reduce) {
  .cluster.is-rejecting .cluster__dial { animation: none; }
  .roller__drum, .needle { transition-duration: 1ms; }
}
