/**
 * 高级动画与交互 —— 前台动画样式
 *
 * 进入动画：元素带 [data-animate]，初始隐藏（仅当 html.yk-anim 存在时，
 * 即 JS 已成功加载——JS 加载失败则元素正常显示，不产生 FOUC/永久隐藏）。
 * 进入视口后 JS 添加 .yk-in 触发 @keyframes；时长/延迟/缓动来自 CSS 变量
 * （由 JS 从 data-animate-duration / data-animate-delay-ms / data-animate-easing 读取）。
 *
 * 悬停效果：纯 CSS 属性选择器 + CSS 变量（--yk-hover-*），变量由 JS 从
 * data-hover-* 读取并设置。进入动画结束（fill-mode:both → transform:none）
 * 后，悬停 transform 正常生效。
 */

/* 仅当 JS 可用时才预先隐藏，避免无 JS 时内容不可见 */
html.yk-anim [data-animate] {
    opacity: 0;
}

/* 防闪烁：未触发前归一静态 transform，统一由 @keyframes 决定动画起点。
   旧 tailwind 规则给 [data-animate] 预设了 40px 位移 / scale(.9)，
   与动画 from 状态（30px / scale(.6)）不一致，触发瞬间会产生位移跳变
   （元素先跳到动画起点再播放），视觉上即"闪一下"。触发后（.yk-in）
   由动画与 fill-mode 接管，悬停 transform 不受影响。 */
html.yk-anim [data-animate]:not(.yk-in) {
    transform: none;
}

/* 触发动画：时长/延迟/缓动来自 CSS 变量 */
[data-animate].yk-in {
    animation-fill-mode: both;
    animation-duration: var(--yk-dur, 600ms);
    animation-delay: var(--yk-del, 0ms);
    animation-timing-function: var(--yk-ease, ease);
}

/* 各动画类型的 @keyframes */
[data-animate="fade"].yk-in { animation-name: ykFade; }
[data-animate="fade-up"].yk-in { animation-name: ykFadeUp; }
[data-animate="fade-down"].yk-in { animation-name: ykFadeDown; }
[data-animate="fade-left"].yk-in { animation-name: ykFadeLeft; }
[data-animate="fade-right"].yk-in { animation-name: ykFadeRight; }
[data-animate="zoom-in"].yk-in { animation-name: ykZoomIn; }
[data-animate="rotate"].yk-in { animation-name: ykRotate; }

@keyframes ykFade {
    from { opacity: 0; }
    to   { opacity: 1; }
}
@keyframes ykFadeUp {
    from { opacity: 0; transform: translateY(30px); }
    to   { opacity: 1; transform: none; }
}
@keyframes ykFadeDown {
    from { opacity: 0; transform: translateY(-30px); }
    to   { opacity: 1; transform: none; }
}
@keyframes ykFadeLeft {
    from { opacity: 0; transform: translateX(-30px); }
    to   { opacity: 1; transform: none; }
}
@keyframes ykFadeRight {
    from { opacity: 0; transform: translateX(30px); }
    to   { opacity: 1; transform: none; }
}
@keyframes ykZoomIn {
    from { opacity: 0; transform: scale(0.6); }
    to   { opacity: 1; transform: none; }
}
@keyframes ykRotate {
    from { opacity: 0; transform: rotate(-12deg) scale(0.9); }
    to   { opacity: 1; transform: none; }
}

/* —— 悬停效果 —— */
[data-hover-scale],
[data-hover-lift],
[data-hover-color],
[data-hover-shadow] {
    transition: transform 0.25s ease, color 0.25s ease, box-shadow 0.25s ease;
}

[data-hover-scale]:hover {
    transform: scale(var(--yk-hover-scale, 1.05));
}
[data-hover-lift]:hover {
    transform: translateY(calc(-1 * var(--yk-hover-lift, 0px)));
}
[data-hover-scale][data-hover-lift]:hover {
    transform: scale(var(--yk-hover-scale, 1)) translateY(calc(-1 * var(--yk-hover-lift, 0px)));
}
[data-hover-color]:hover {
    color: var(--yk-hover-color, inherit) !important;
}
[data-hover-shadow]:hover {
    box-shadow: 0 8px 30px rgba(0, 0, 0, 0.16) !important;
}

/* ---- Flicker guard ----
   Keep elements visible after the entrance animation ends.
   animation-fill-mode: both already holds the final state; this static
   rule is an extra guard so elements can never fall back to opacity:0
   even if the animation state is cleared in edge cases. */
html.yk-anim [data-animate].yk-in {
    opacity: 1;
}