.otp-input {
  --otp-error-bg: color-mix(in srgb, var(--color-red) 12%, transparent);
  --otp-underline-color: color-mix(in srgb, var(--color-navy) 35%, transparent);

  --otp-digit-font-size: 28px;
  --otp-digits: 6;
  --otp-letter-spacing: 2ch;
  --otp-gap-ratio: 1.25;

  box-sizing: border-box;
  display: flex;
  justify-content: center;
  align-items: center;
  width: fit-content;
  max-width: 100%;
  margin-left: auto;
  margin-right: auto;
  padding: 4px 0;
  border-radius: var(--radius-sm);
  background-color: transparent;
  transition: box-shadow var(--hover-speed-fast, 120ms) ease;
}

.otp-input__field {
  --_otp-cell: calc(var(--otp-letter-spacing) + 1ch);

  all: unset;
  box-sizing: content-box;
  flex: 0 0 auto;

  font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum";
  font-weight: 500;
  font-size: var(--otp-digit-font-size);
  color: var(--color-navy);
  caret-color: var(--color-navy);

  inline-size: calc(var(--otp-digits) * var(--_otp-cell));
  letter-spacing: var(--otp-letter-spacing);

  padding-inline-start: calc(((var(--otp-letter-spacing) - 1ch) / 2) * var(--otp-gap-ratio));
  padding-block: 0.25em;

  /* clip-path hides the trailing letter-spacing area so the phantom caret after
     digit 6 is not visible; matching negative margin collapses the layout box
     so the fit-content wrapper shrink-wraps to the visible width (keeps slots
     symmetric inside wrapper padding). */
  clip-path: inset(0% calc(var(--otp-letter-spacing) / 2) 0% 0%);
  margin-inline-end: calc(-1 * var(--otp-letter-spacing) / 2);

  --otp-underline-thickness: 2px;

  background: linear-gradient(
    90deg,
    var(--otp-underline-color) calc(var(--otp-gap-ratio) * var(--otp-letter-spacing)),
    transparent 0
  ) 0 100% / var(--_otp-cell) var(--otp-underline-thickness) repeat-x;
}

.otp-input:focus-within .otp-input__field,
.otp-input--error .otp-input__field,
.otp-input__field.is-invalid {
  --otp-underline-thickness: 3px;
}

/* background-image isn't animatable; transitioning the custom property is. */
@property --otp-underline-color {
  syntax: "<color>";
  inherits: true;
  initial-value: transparent;
}

.otp-input__field {
  transition: --otp-underline-color var(--hover-speed-fast, 120ms) ease;
}

.otp-input:focus-within .otp-input__field {
  --otp-underline-color: var(--color-green);
}

.otp-input--error {
  background-color: var(--otp-error-bg);
}

.otp-input--error .otp-input__field,
.otp-input__field.is-invalid {
  --otp-underline-color: var(--color-red);
}

.otp-input--error:focus-within .otp-input__field {
  --otp-underline-color: var(--color-red);
}

.otp-input__field:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.otp-input__error-message {
  display: block;
  margin-top: 8px;
  color: var(--color-red);
  font-size: var(--text-sm);
  text-align: center;
}

.otp-input--big {
  --otp-digit-font-size: 36px;
}

/* Styleguide-only: renders a static focused preview. Not production API. */
.otp-input.is-focused .otp-input__field {
  --otp-underline-color: var(--color-green);
}

@media (max-width: 576px) {
  .otp-input {
    --otp-digit-font-size: 22px;
    padding: 4px 0;
  }

  .otp-input__field {
    min-height: 44px;
  }

  .otp-input--big {
    --otp-digit-font-size: 26px;
  }
}

/* Background gradients are suppressed in print and forced-colors; fall back to
   a single continuous border-bottom (six slots collapse to one line). */
@media print {
  .otp-input {
    background-color: transparent;
    padding: 0;
  }
  .otp-input__field {
    background: none;
    border-bottom: 2px solid var(--color-navy);
    clip-path: none;
  }
}

@media (forced-colors: active) {
  .otp-input {
    background-color: transparent;
  }
  .otp-input__field {
    background: none;
    border-bottom: 2px solid CanvasText;
    clip-path: none;
  }
  .otp-input:focus-within .otp-input__field {
    border-bottom-color: Highlight;
  }
  .otp-input--error .otp-input__field {
    border-bottom-color: Mark;
  }
}
