Files
2026-07-13 12:12:04 +08:00

125 lines
2.7 KiB
CSS

/* Base container */
.input-otp {
@apply relative flex items-center gap-2;
&[data-disabled="true"] {
@apply cursor-not-allowed opacity-50;
}
}
/* Group - slots separated with gap */
.input-otp__group {
@apply flex items-center gap-2;
}
/* Individual slot box - fully rounded, standalone */
.input-otp__slot {
@apply relative flex h-10 w-9.5 flex-1 items-center justify-center;
@apply border bg-field text-field-foreground shadow-field;
@apply rounded-field text-sm font-semibold outline-none;
border-width: var(--border-width-field);
border-color: var(--field-border);
/**
* Transitions
* CRITICAL: motion-reduce must be AFTER transition for correct override specificity
*/
transition:
background-color 150ms var(--ease-smooth),
border-color 150ms var(--ease-smooth),
box-shadow 150ms var(--ease-out);
@apply motion-reduce:transition-none;
/* Hover */
@media (hover: hover) {
&:hover,
&[data-hovered="true"] {
@apply bg-field-hover;
border-color: var(--field-border-hover);
}
}
/* Active/Focus */
&[data-active="true"] {
@apply z-10 bg-field-focus status-focused-field;
}
/* Filled */
&[data-filled="true"] {
@apply bg-field-focus;
}
/* Disabled */
&[data-disabled="true"] {
@apply status-disabled;
}
/* Invalid */
&[data-invalid="true"] {
@apply status-invalid-field;
background-color: var(--field-focus);
}
}
/* Slot value */
.input-otp__slot-value {
@apply text-lg leading-6 tracking-[-0.27px];
/**
* Animations
* CRITICAL: motion-reduce must be AFTER animation for correct override specificity
*/
animation: slot-value-in 250ms var(--ease-smooth) both;
transform-origin: bottom center;
@apply motion-reduce:animate-none;
}
/* Caret */
.input-otp__caret {
@apply absolute h-4 w-[2px] animate-caret-blink rounded-sm bg-field-placeholder;
}
/* Separator */
.input-otp__separator {
@apply h-[2px] w-[6px] shrink-0 rounded-sm bg-separator;
}
/* Variant property definitions */
.input-otp--primary {
/* Default styles */
}
.input-otp--secondary .input-otp__slot {
@apply shadow-none;
background-color: var(--input-otp-slot-bg);
--input-otp-slot-bg: var(--default);
--input-otp-slot-bg-hover: var(--default-hover);
--input-otp-slot-bg-focus: var(--default);
@media (hover: hover) {
&:hover,
&[data-hovered="true"] {
background-color: var(--input-otp-slot-bg-hover);
}
}
&[data-active="true"],
&[data-filled="true"] {
background-color: var(--input-otp-slot-bg-focus);
}
}
/* Animations */
@keyframes slot-value-in {
0% {
opacity: 0;
transform: translateY(8px) scale(0.8);
}
100% {
opacity: 1;
transform: translateY(0) scale(1);
}
}