/* Deadpan 2010s-utility look: black on white, monospace, no chrome. */

:root {
  /* Height of a single reel row. Both the CSS and script.js depend on this
     value (ROWH in script.js) staying in sync. */
  --rowh: 1.5em;
}

/* Edge opacity of a reel's faded neighbour rows. Registered so it can be
   transitioned (plain custom properties can't interpolate). 0.35 while
   spinning, animated to 0 on lock so the neighbours fade out. */
@property --edge {
  syntax: "<number>";
  inherits: false;
  initial-value: 0.2;
}

* { box-sizing: border-box; }

html, body { height: 100%; }

body {
  margin: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1.6rem;
  background: #ffffff;
  color: #111111;
  font-family: ui-monospace, "SF Mono", "Menlo", "Consolas", monospace;
}

/* ---- The UUID spinner ---------------------------------------------------- */

.uuid {
  display: flex;
  align-items: center;
  justify-content: center;
  /* Scales the whole 36-char string to fit a phone without wrapping. */
  font-size: clamp(0.85rem, 4.3vw, 2.1rem);
  line-height: var(--rowh); /* match the reel rows so the collapse-to-text is seamless */
  /* Keep a stable height while reels collapse from 3-row to 1-row on lock. */
  min-height: calc(3 * var(--rowh));
  /* Not selectable until the spin is done. */
  user-select: none;
  -webkit-user-select: none;
}

.uuid.done {
  user-select: text;
  -webkit-user-select: text;
}

/* A single reel while spinning: a 3-row window onto a vertical strip, with
   the top and bottom rows faded so the centre value reads as the "payline"
   and the spin feels like a drum. */
.reel {
  --edge: 0.2;
  display: inline-block;
  overflow: hidden;
  height: calc(3 * var(--rowh));
  line-height: var(--rowh);
  text-align: center;
  white-space: nowrap;
  /* Faint flat neighbours, full-dark centre band (the payline). */
  -webkit-mask-image: linear-gradient(to bottom,
      rgba(0, 0, 0, var(--edge)) 0%, rgba(0, 0, 0, var(--edge)) 33%,
      #000 35%, #000 65%,
      rgba(0, 0, 0, var(--edge)) 67%, rgba(0, 0, 0, var(--edge)) 100%);
          mask-image: linear-gradient(to bottom,
      rgba(0, 0, 0, var(--edge)) 0%, rgba(0, 0, 0, var(--edge)) 33%,
      #000 35%, #000 65%,
      rgba(0, 0, 0, var(--edge)) 67%, rgba(0, 0, 0, var(--edge)) 100%);
  transition: --edge 1s ease;
}

.reel-strip {
  display: block;
  will-change: transform;
}

.reel-row {
  display: block; /* without this, inline spans ignore height and collapse to one line */
  height: var(--rowh);
  line-height: var(--rowh);
}

/* Only the final, centred row of a locked reel is selectable/copyable; the
   faded garbage rows must never end up in a copied selection. */
.uuid .reel-row {
  user-select: none;
  -webkit-user-select: none;
}

.uuid.done .reel-row.is-final {
  user-select: text;
  -webkit-user-select: text;
}

/* Once everything has settled, all wheels fade their neighbours out together
   (it's one result fading, not a left-to-right cascade). */
.uuid.settled .reel {
  --edge: 0;
}

/* A plain reel (placeholder / reduced-motion): just one centred value, no
   wheel, no mask. */
.reel.plain {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  -webkit-mask-image: none;
          mask-image: none;
}

.sep {
  /* No padding: keeps the spinning layout width-identical to the plain-text
     UUID we collapse to, so the swap doesn't shift. */
  padding: 0;
}

/* ---- Controls ------------------------------------------------------------ */

.controls {
  display: flex;
  justify-content: center;
  gap: 0.6rem;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.55s ease;
}

.controls.show {
  opacity: 1;
  pointer-events: auto;
}

button {
  font: inherit;
  font-size: 0.95rem;
  padding: 0.4em 1em;
  border: 1px solid #111;
  border-radius: 2px;
  background: #fff;
  color: #111;
  cursor: pointer;
}

button:hover { background: #111; color: #fff; }
button:active { transform: translateY(1px); }
button:focus-visible { outline: 2px solid #111; outline-offset: 2px; }

/* ---- A11y ---------------------------------------------------------------- */

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  border: 0;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  overflow: hidden;
  white-space: nowrap;
}

@media (prefers-reduced-motion: reduce) {
  .controls { transition: none; }
}
