/* curlo — Animations (framework-agnostic). Requires tokens.css. */

/* ---- Signature: blinking terminal cursor ---- */
.curlo-cursor {
    display: inline-block;
    width: 0.5em;
    height: 1.05em;
    margin-left: 0.22em;
    background: var(--curlo-accent);
    border-radius: 3px;
    transform: translateY(0.12em);
    animation: curlo-blink 1.1s steps(1) infinite;
}
.curlo-cursor.green { background: var(--curlo-primary); }
@keyframes curlo-blink { 50% { opacity: 0; } }

/* ---- Entrance (the two used by curlo.js popovers/results) ---- */
.curlo-fade-in  { opacity: 0; animation: curlo-fadeIn 0.4s ease-out forwards; }
.curlo-scale-in { opacity: 0; transform: scale(0.85); animation: curlo-scaleIn 0.4s ease-out forwards; }

@keyframes curlo-fadeIn { from { opacity: 0; } to { opacity: 1; } }
@keyframes curlo-scaleIn { from { transform: scale(0.85); opacity: 0; } to { transform: scale(1); opacity: 1; } }

/* ---- Signature loader: ">curl" fills up with o's until ">curloooooo" ----
 * The o's are REAL font glyphs (plain text), so they share "curl"'s exact font,
 * size, height, baseline and colour — no overlay to drift or misalign. They sit
 * dimmed, then a currentColor fill sweeps across them left-to-right, snapping one
 * whole o at a time. background-clip:text paints the fill only onto the glyphs,
 * and currentColor means the o's are dark on light surfaces and white in the
 * terminal — always matching the "curl" next to them. The only knob is the
 * o-count (--curlo-curl-o); the per-o speed (0.25s) and end-hold (2 beats) are
 * fixed, so every instance shares the same rhythm.
 *   <span class="curlo-curl" role="status" aria-label="Loading">
 *     <span class="curlo-curl__chev">&gt;</span>curl<span class="curlo-curl__o">oooooo</span>
 *   </span>
 */
.curlo-curl {
    --curlo-curl-o: 6;               /* how many o's to print & fill (the only knob) */
    /* inline-flex + baseline so the word aligns to adjacent mono text of the same
     * size with no consumer translateY hacks; vertical-align keeps the whole box
     * on the surrounding text's baseline when used inline in a row. */
    display: inline-flex;
    align-items: baseline;
    vertical-align: baseline;
    font-family: var(--curlo-font-mono);
    font-weight: 700;
    letter-spacing: -0.01em;
    white-space: nowrap;
    line-height: 1;
}
.curlo-curl__chev { color: var(--curlo-primary); }
.curlo-curl__o {
    letter-spacing: 0;               /* exact N-ch slot so each step reveals one whole o */
    /* Unfilled o's: the glyph in a dimmed currentColor (also the reduced-motion
     * fallback). The fill — a solid currentColor gradient clipped to the glyphs —
     * grows over them in N steps; a slow breathe keeps the pending o's alive. */
    -webkit-text-fill-color: color-mix(in srgb, currentColor 26%, transparent);
    background-image: linear-gradient(currentColor, currentColor);
    background-repeat: no-repeat;
    background-size: 0% 100%;
    -webkit-background-clip: text;
            background-clip: text;
    /* Loop runs over (o + 2 hold) steps, one o per step at 0.25s each. The fill
     * overshoots to >100% so the last 2 steps stay fully covered — the completed
     * word lingers a beat before the reset, reading as "done → again" not a hard
     * snap. Count stays parametric, so it's crisp at any --curlo-curl-o. */
    animation: curlo-curl-fill
                   calc((var(--curlo-curl-o, 6) + 2) * 0.25s)
                   steps(calc(var(--curlo-curl-o, 6) + 2), start) infinite,
               curlo-curl-breathe 1.8s ease-in-out infinite;
}
.curlo-curl--sm { font-size: 0.85rem; }
.curlo-curl--lg { font-size: 1.6rem; letter-spacing: -0.03em; }
/* Freeze the fill on a frame (handy for inspecting the progress). */
.curlo-curl.is-paused .curlo-curl__o { animation-play-state: paused; }
@keyframes curlo-curl-fill {
    from { background-size: 0% 100%; }
    to   { background-size: calc(100% * (var(--curlo-curl-o, 6) + 2) / var(--curlo-curl-o, 6)) 100%; }
}
/* Pending o's gently pulse; filled ones sit on the solid background, so this only
 * reads on the dim track — a subtle heartbeat instead of a dead placeholder. */
@keyframes curlo-curl-breathe {
    0%, 100% { -webkit-text-fill-color: color-mix(in srgb, currentColor 24%, transparent); }
    50%      { -webkit-text-fill-color: color-mix(in srgb, currentColor 46%, transparent); }
}

@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: 0.001ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.001ms !important;
    }
    /* Settle the loader on the finished ">curloooooo", not an empty track. */
    .curlo-curl__o { background-size: 100% 100% !important; }
}
