/*
 * Persistent watchlist rail - every move it makes, each with its
 * reduced-motion opt-out, in one place. Motion here always MEANS something:
 *   - a NEW list deals its rows in and their sparklines draw themselves
 *     (first load, a tab switch, the rail opening - never a refresh of the
 *     same list; watchlist_rail_rows.js decides) - the reading card first,
 *     an empty list's invitation fading up behind it;
 *   - the tab ink slides to the chosen tab (watchlist_rail.js places it);
 *   - the quick look's sections rise in as it opens, its horizon tiles one
 *     after another (their scores count up in JS, via score_countup.js);
 *   - a quick-added row lights up where it landed;
 *   - a follow that lands while the rail is tucked away bumps its count;
 *   - the collapsed tab steps aside while you read down a narrow page,
 *     and is back the moment it's wanted (watchlist_rail_tuck.js);
 *   - ghost rows shimmer while the first list is on its way.
 * Rows carry their index as --i (capped at 12 by the template), so the
 * longest cascade stays short.
 */
@keyframes rail-rise {
    from {
        opacity: 0;
        transform: translateY(var(--rise, 6px));
    }
}
@keyframes rail-fade-in {
    from {
        opacity: 0;
    }
}
@keyframes rail-spark-draw {
    from {
        stroke-dashoffset: 1;
    }
}

/* ---- the deal ------------------------------------------------------------- */
#watchlist-rail-content.is-dealing .rail-row,
#watchlist-rail-content.is-dealing .rail-reading {
    animation: rail-rise 0.34s cubic-bezier(0.2, 0.8, 0.2, 1) both;
    animation-delay: calc(var(--i, 0) * 28ms);
}
#watchlist-rail-content.is-dealing .rail-empty {
    animation: rail-fade-in 0.45s ease-out 0.08s both;
}
#watchlist-rail-content.is-dealing .rail-row-spark-line {
    stroke-dasharray: 1; /* the path's pathLength is 1: one dash, drawn by its offset */
    animation: rail-spark-draw 0.7s ease-out both;
    animation-delay: calc(var(--i, 0) * 28ms + 0.12s);
}
#watchlist-rail-content.is-dealing .rail-row-spark-area {
    animation: rail-fade-in 0.6s ease-out both;
    animation-delay: calc(var(--i, 0) * 28ms + 0.25s);
}

/* ---- a quick-added row lights up where it landed --------------------------- */
@keyframes rail-row-arrive {
    from {
        background-color: color-mix(in srgb, var(--color-accent) 22%, transparent);
        box-shadow: inset 3px 0 0 var(--color-accent);
    }
}
.rail-row-arrive {
    animation: rail-row-arrive 1.4s ease-out;
}
/* Landing in a list that's being dealt: both moves, or the deal's more
   specific rule would silently cancel the light. */
#watchlist-rail-content.is-dealing .rail-row.rail-row-arrive {
    animation: rail-rise 0.34s cubic-bezier(0.2, 0.8, 0.2, 1) both, rail-row-arrive 1.4s ease-out;
    animation-delay: calc(var(--i, 0) * 28ms);
}

/* ---- the tab ink ---------------------------------------------------------- */
.watchlist-rail-tabs.has-ink {
    position: relative;
}
.watchlist-rail-tabs.has-ink .watchlist-rail-tab.is-active {
    border-bottom-color: transparent; /* the ink draws it now */
}
.watchlist-rail-tab-ink {
    position: absolute;
    left: 0;
    bottom: 0;
    width: 0;
    height: 2px;
    border-radius: 2px 2px 0 0;
    background: var(--color-accent);
    box-shadow: 0 0 10px color-mix(in srgb, var(--color-accent) 55%, transparent);
    pointer-events: none;
}
.watchlist-rail-tabs.ink-ready .watchlist-rail-tab-ink {
    transition: transform 0.28s cubic-bezier(0.2, 0.8, 0.2, 1), width 0.28s cubic-bezier(0.2, 0.8, 0.2, 1);
}

/* ---- the quick look arrives ------------------------------------------------- */
.rail-look > * {
    --rise: 8px;
    animation: rail-rise 0.32s cubic-bezier(0.2, 0.8, 0.2, 1) both;
}
.rail-look > :nth-child(2) { animation-delay: 40ms; }
.rail-look > :nth-child(3) { animation-delay: 80ms; }
.rail-look > :nth-child(4) { animation-delay: 120ms; }
.rail-look > :nth-child(n + 5) { animation-delay: 160ms; }
.rail-look > .rail-look-horizons {
    animation: none; /* its tiles rise on their own, one after another */
}
.rail-look-tile {
    --rise: 10px;
    animation: rail-rise 0.36s cubic-bezier(0.2, 0.8, 0.2, 1) both;
}
.rail-look-tile:nth-child(1) { animation-delay: 110ms; }
.rail-look-tile:nth-child(2) { animation-delay: 170ms; }
.rail-look-tile:nth-child(3) { animation-delay: 230ms; }

/* ---- a follow lands while the rail is tucked away -------------------------- */
@keyframes rail-count-bump {
    40% {
        transform: scale(1.35);
        box-shadow: 0 0 0 4px color-mix(in srgb, var(--color-accent) 30%, transparent);
    }
}
.watchlist-rail-toggle-count.is-bumped {
    animation: rail-count-bump 0.5s cubic-bezier(0.3, 1.6, 0.5, 1);
}

/* ---- the collapsed tab steps aside while you read ---------------------------
   Below 1280px it floats over the page's right edge, so reading down tucks
   it just past the screen edge (style.css's transform transition slides
   it). Keyboard focus always wins: a focused tab is never out of view
   (WCAG 2.4.11), even before watchlist_rail_tuck.js reacts. */
@media (max-width: 1279.98px) {
    .watchlist-rail.is-collapsed.is-tucked .watchlist-rail-toggle:not(:focus-visible) {
        transform: translateX(calc(100% + 2px));
    }
}

/* ---- waiting: the ghost rows shimmer, left to right ------------------------------ */
@keyframes rail-ghost-shimmer {
    from {
        background-position: 100% 0;
    }
    to {
        background-position: -100% 0;
    }
}
.rail-ghost span {
    animation: rail-ghost-shimmer 1.6s ease-in-out infinite;
}

/* ---- reduced motion: every move above, stilled -------------------------------- */
@media (prefers-reduced-motion: reduce) {
    #watchlist-rail-content.is-dealing .rail-row,
    #watchlist-rail-content.is-dealing .rail-reading,
    #watchlist-rail-content.is-dealing .rail-empty,
    .rail-ghost span,
    #watchlist-rail-content.is-dealing .rail-row-spark-line,
    #watchlist-rail-content.is-dealing .rail-row-spark-area,
    .rail-look > *,
    .rail-look-tile,
    .watchlist-rail-toggle-count.is-bumped {
        animation: none;
    }
    .rail-row-arrive,
    #watchlist-rail-content.is-dealing .rail-row.rail-row-arrive {
        animation: none;
        outline: 1px solid color-mix(in srgb, var(--color-accent) 60%, transparent); /* still says "here" */
        outline-offset: -1px;
    }
    .watchlist-rail-tabs.ink-ready .watchlist-rail-tab-ink {
        transition: none;
    }
    .watchlist-rail-toggle {
        transition: background-color 0.15s ease; /* tucks and returns in place - no slide */
    }
}
