.allCodes {
  white-space: pre-wrap;
}

.with-floating-button {
  position: relative;
}

.with-floating-button .textarea {
  padding-right: 3rem;
}

.with-floating-button .code-block {
  display: block;
  width: 100%;
  padding: 0.5rem 3rem 0.5rem 0.75rem;
  box-sizing: border-box;
  word-break: break-all;
  white-space: pre-wrap;
  min-height: 3.5rem;
}

.floating-button {
  position: absolute;
  top: 0.5rem;
  right: 0.5rem;
  z-index: 2;
}

/* Bulma sets `display` on components like .tag (inline-flex), which has the
   same specificity as the UA `[hidden]` rule but is declared later, so it
   wins. This puts the `hidden` HTML attribute back in charge everywhere. */
[hidden] {
  display: none !important;
}

/* An <a> without href doesn't get the pointer cursor by default. */
#resultRevert {
  cursor: pointer;
}

/* <details><summary> doesn't pick up cursor: pointer in all browsers (Firefox
   does, Safari is inconsistent). Bulma's .is-clickable does this — kept here
   in case the class is removed by a linter. */
summary.is-clickable {
  cursor: pointer;
}

/* One-row chip for each collected code: small delete on the left, truncated
   code on the right. Sits in a vertical stack inside #codesList. */
.code-row {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin-bottom: 0.25rem;
}

.code-row__value {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  padding: 0.15rem 0.5rem;
}

/* Two-tap delete confirmation hint. Hidden unless the row is armed; sits at
   the right end of the row beside the truncated code value. */
.code-row__confirm {
  color: var(--bulma-danger, #f14668);
  font-size: 0.85em;
  white-space: nowrap;
  margin-left: 0.5rem;
}
.code-row:not(.code-row--confirming) .code-row__confirm {
  display: none;
}

/* The decrypted PIN uses .title for size/weight, but .title forces a dark
   color via Bulma's title-color variable — inside a green .is-success
   notification that's almost unreadable. Pin it to Bulma's normal <code>
   color so it pops the same way an inline `code` does in body text. */
#resultCode {
  color: var(--bulma-code);
}

@media (prefers-reduced-motion: no-preference) {
  /* New-code row: brief slide-in + info-tinted background that fades to
     transparent. JS adds .code-row--new on freshly-added codes only. */
  @keyframes codeRowAppear {
    from {
      opacity: 0;
      transform: translateY(-4px);
      background-color: var(--bulma-info-95, #ebf6fc);
    }
    to {
      opacity: 1;
      transform: translateY(0);
      background-color: transparent;
    }
  }
  .code-row--new {
    animation: codeRowAppear 280ms ease-out;
  }

  /* <progress> value transitions: webkit (Chrome/Safari) animates the
     ::-webkit-progress-value width, Firefox animates ::-moz-progress-bar.
     Browsers that don't honor these snap instantly — acceptable fallback. */
  progress::-webkit-progress-value {
    transition: width 280ms ease-out;
  }
  progress::-moz-progress-bar {
    transition: width 280ms ease-out;
  }

  /* Decrypted PIN reveal: opacity + scale pop. JS re-toggles .reveal-anim
     to re-fire keyframes on each Decrypt click. */
  @keyframes resultReveal {
    from {
      opacity: 0;
      transform: scale(0.94);
    }
    to {
      opacity: 1;
      transform: scale(1);
    }
  }
  .reveal-anim {
    animation: resultReveal 220ms ease-out;
  }

  /* "Out of date" tag fade-in. JS adds .fade-in-anim on the hidden→visible
     edge only, so live typing doesn't repeatedly retrigger it. */
  @keyframes fadeIn {
    from {
      opacity: 0;
    }
    to {
      opacity: 1;
    }
  }
  .fade-in-anim {
    animation: fadeIn 200ms ease-out;
  }

  /* Result textarea pulse: expanding info-colored ring when fresh shares
     are written. JS re-toggles .pulse-anim to re-fire on each generation. */
  @keyframes resultPulse {
    0% {
      box-shadow: 0 0 0 0 var(--bulma-info, #3e8ed0);
    }
    100% {
      box-shadow: 0 0 0 6px rgba(62, 142, 208, 0);
    }
  }
  .pulse-anim {
    animation: resultPulse 600ms ease-out;
  }

  /* Armed-delete pulse: gentle expanding danger ring on the × of a row
     waiting for its second tap, so users notice the state change. */
  @keyframes deleteConfirmPulse {
    0%,
    100% {
      box-shadow: 0 0 0 0 var(--bulma-danger, #f14668);
    }
    50% {
      box-shadow: 0 0 0 5px rgba(241, 70, 104, 0);
    }
  }
  .code-row--confirming .delete {
    animation: deleteConfirmPulse 1.2s ease-in-out infinite;
  }

  /* Deletion "crumble to dust" exit: row drifts toward the top-right while
     rotating, shrinking, blurring, and fading. Pure transform/filter — CSS
     can't actually fragment a DOM node, but this reads as a puff of dust.
     JS adds .code-row--exiting and waits the same duration before removing
     the code from storage and re-rendering. */
  @keyframes codeRowDust {
    0% {
      opacity: 1;
      transform: translate(0, 0) scale(1) rotate(0deg);
      filter: blur(0);
    }
    100% {
      opacity: 0;
      transform: translate(160px, -120px) scale(0.5) rotate(12deg);
      filter: blur(5px);
    }
  }
  .code-row--exiting {
    animation: codeRowDust 600ms cubic-bezier(0.55, 0, 0.85, 0.3) forwards;
    pointer-events: none;
  }
}
