/* CLS-safe wrapper for Typed.js hero animations. See purpose/js/typed-slot.js
   for the why. Every child of the grid cell occupies row 1 / column 1; the
   cell takes the max intrinsic width of all ghosts, so the live span can
   grow from 0 chars to the longest word without ever changing the parent's
   layout. */

.typed-slot {
    display: inline-grid;
    grid-template-columns: max-content;
    vertical-align: baseline;
}

.typed-slot > .typed-ghost,
.typed-slot > .typed-live {
    grid-column: 1;
    grid-row: 1;
}

.typed-slot > .typed-ghost {
    visibility: hidden;
    white-space: pre;
    pointer-events: none;
    user-select: none;
}

.typed-slot > .typed-live {
    justify-self: start;
    white-space: nowrap;
}

/* Typed.js inserts .typed-cursor as a sibling of the target; inside our grid
   cell it would render at the left edge, detached from the typed text. Hide
   it and render our own cursor inline-after the actual content so it tracks
   the last typed letter. */
.typed-slot > .typed-cursor {
    display: none;
}

.typed-slot > .typed-live::after {
    content: '|';
    display: inline-block;
    margin-left: 0.08em;
    font-weight: 400;
    color: currentColor;
    animation: typedSlotBlink 1s steps(2) infinite;
}

@keyframes typedSlotBlink {
    50% { opacity: 0; }
}
