/*!
 * Joe 主题 · 背景动效（模板设置 → 外观设置 →「背景动效」）
 * 一个固定层 .joe-bgfx，压在 body::before（背景图/底色/纹理）之上、页面内容之下。
 * · 颜色统一走变量 --fx / --fx2，浅色底用深一点的颜色、夜间自动换成浅色
 * · 只用 transform / opacity 动画（走合成层，基本不吃 CPU）
 * · 粒子类（粒子/落雪/气泡）的 <i> 由 header.php 随机生成
 */

.joe-bgfx {
    position: fixed;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    z-index: -450;
    overflow: hidden;
    pointer-events: none;
    --fx: rgba(60, 10, 30, .26);
    --fx2: rgba(0, 111, 255, .38);
}

html[data-night='night'] .joe-bgfx {
    --fx: rgba(255, 255, 255, .55);
    --fx2: rgba(120, 190, 255, .5);
}

/* 「漂浮类」动效要浮在页面内容之上才看得见（卡片是不透明的，放下面基本白搭）；
   大面积的氛围类（极光/网格流动/光带扫过）仍然只铺在背景层，避免糊住正文。 */
.joe-bgfx--particles,
.joe-bgfx--snow,
.joe-bgfx--bubbles,
.joe-bgfx--mouse,
.joe-bgfx--fireflies {
    z-index: 900;
    --fx: rgba(70, 84, 110, .45);
}

html[data-night='night'] .joe-bgfx--particles,
html[data-night='night'] .joe-bgfx--snow,
html[data-night='night'] .joe-bgfx--bubbles {
    --fx: rgba(255, 255, 255, .7);
}

/* ---------- 粒子 / 落雪 / 气泡（共用一套动画） ---------- */
.joe-bgfx i {
    position: absolute;
    left: calc(var(--x, .5) * 100%);
    width: var(--s, 3px);
    height: var(--s, 3px);
    border-radius: 50%;
    background: var(--fx);
    opacity: 0;
    will-change: transform, opacity;
}

.joe-bgfx--particles i,
.joe-bgfx--bubbles i {
    bottom: -8vh;
    animation: joe-bgfx-up var(--d, 18s) linear var(--t, 0s) infinite;
}

.joe-bgfx--snow i {
    top: -8vh;
    animation: joe-bgfx-down var(--d, 14s) linear var(--t, 0s) infinite;
}

.joe-bgfx--bubbles i {
    background: transparent;
    border: 1px solid var(--fx);
}

@keyframes joe-bgfx-up {
    0% {
        transform: translate3d(0, 0, 0);
        opacity: 0;
    }

    12% {
        opacity: var(--o, .5);
    }

    88% {
        opacity: var(--o, .5);
    }

    100% {
        transform: translate3d(var(--dx, 0px), -120vh, 0);
        opacity: 0;
    }
}

@keyframes joe-bgfx-down {
    0% {
        transform: translate3d(0, 0, 0);
        opacity: 0;
    }

    12% {
        opacity: var(--o, .5);
    }

    88% {
        opacity: var(--o, .5);
    }

    100% {
        transform: translate3d(var(--dx, 0px), 120vh, 0);
        opacity: 0;
    }
}

/* ---------- 极光：两团柔光缓慢漂移 ---------- */
.joe-bgfx--aurora::before,
.joe-bgfx--aurora::after {
    content: '';
    position: absolute;
    top: -30%;
    right: -30%;
    bottom: -30%;
    left: -30%;
}

.joe-bgfx--aurora::before {
    background-image:
        radial-gradient(closest-side, rgba(64, 158, 255, .44), rgba(64, 158, 255, 0)),
        radial-gradient(closest-side, rgba(150, 120, 220, .38), rgba(150, 120, 220, 0));
    background-size: 62% 62%, 54% 54%;
    background-position: 4% 10%, 80% 20%;
    background-repeat: no-repeat;
    animation: joe-bgfx-drift 28s ease-in-out infinite alternate;
}

.joe-bgfx--aurora::after {
    background-image:
        radial-gradient(closest-side, rgba(103, 194, 58, .30), rgba(103, 194, 58, 0)),
        radial-gradient(closest-side, rgba(230, 162, 60, .32), rgba(230, 162, 60, 0));
    background-size: 60% 60%, 48% 48%;
    background-position: 52% 96%, 18% 76%;
    background-repeat: no-repeat;
    animation: joe-bgfx-drift 38s ease-in-out infinite alternate-reverse;
}

@keyframes joe-bgfx-drift {
    0% {
        transform: translate3d(-4%, -3%, 0) scale(1);
    }

    50% {
        transform: translate3d(3%, 3%, 0) scale(1.14);
    }

    100% {
        transform: translate3d(5%, -2%, 0) scale(1.02);
    }
}

/* ---------- 网格流动：把网格整体斜向推一格，正好无缝循环 ---------- */
.joe-bgfx--grid-flow {
    --fx: rgba(60, 10, 30, .16);
}

html[data-night='night'] .joe-bgfx--grid-flow {
    --fx: rgba(255, 255, 255, .13);
}

.joe-bgfx--grid-flow::before {
    content: '';
    position: absolute;
    top: -20px;
    right: -20px;
    bottom: -20px;
    left: -20px;
    background-image:
        linear-gradient(90deg, var(--fx) 1px, transparent 1px),
        linear-gradient(0deg, var(--fx) 1px, transparent 1px);
    background-size: 20px 20px;
    animation: joe-bgfx-grid 26s linear infinite;
}

@keyframes joe-bgfx-grid {
    from {
        transform: translate3d(0, 0, 0);
    }

    to {
        transform: translate3d(20px, 20px, 0);
    }
}

/* ---------- 光带扫过：一道柔光斜着来回扫 ---------- */
.joe-bgfx--sweep::before {
    content: '';
    position: absolute;
    top: -40%;
    right: -40%;
    bottom: -40%;
    left: -40%;
    background-image: linear-gradient(105deg, rgba(0, 111, 255, 0) 42%, var(--fx2) 50%, rgba(0, 111, 255, 0) 58%);
    opacity: .7;
    animation: joe-bgfx-sweep 13s ease-in-out infinite alternate;
}

@keyframes joe-bgfx-sweep {
    from {
        transform: translate3d(-26%, 0, 0);
    }

    to {
        transform: translate3d(26%, 0, 0);
    }
}

/* ---------- 鼠标光晕：一团柔光跟着鼠标（脚本在 header.php 里） ---------- */
.joe-bgfx--mouse::before {
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    width: 620px;
    height: 620px;
    margin: -310px 0 0 -310px;
    border-radius: 50%;
    background-image: radial-gradient(closest-side, var(--fx2), rgba(0, 111, 255, 0));
    opacity: .75;
    transform: translate3d(var(--mx, 50vw), var(--my, 38vh), 0);
    transition: transform .55s cubic-bezier(.22, .61, .36, 1);
    will-change: transform;
}

/* ---------- 尊重系统的「减少动效」设置 ---------- */
@media (prefers-reduced-motion: reduce) {

    .joe-bgfx,
    .joe-bgfx::before,
    .joe-bgfx::after,
    .joe-bgfx i {
        animation: none !important;
        transition: none !important;
    }
}

/* ==================== 追加：呼吸光 / 雨丝 / 流星 / 花瓣 / 光斑 ==================== */

/* 漂浮类同样要浮在内容之上 */
.joe-bgfx--rain,
.joe-bgfx--meteor,
.joe-bgfx--petal,
.joe-bgfx--bokeh {
    z-index: 900;
    --fx: rgba(70, 84, 110, .45);
}

html[data-night='night'] .joe-bgfx--rain,
html[data-night='night'] .joe-bgfx--meteor,
html[data-night='night'] .joe-bgfx--petal {
    --fx: rgba(255, 255, 255, .7);
}

html[data-night='night'] .joe-bgfx--bokeh {
    --fx2: rgba(120, 190, 255, .45);
}

/* ---------- 呼吸光：一团柔光缓慢明暗（背景层） ---------- */
.joe-bgfx--breathe::before {
    content: '';
    position: absolute;
    top: -25%;
    right: -25%;
    bottom: -25%;
    left: -25%;
    background-image: radial-gradient(closest-side, var(--fx2), rgba(0, 111, 255, 0));
    background-size: 70% 70%;
    background-position: 50% 45%;
    background-repeat: no-repeat;
    animation: joe-bgfx-breathe 12s ease-in-out infinite alternate;
}

@keyframes joe-bgfx-breathe {
    from {
        transform: scale(.88);
        opacity: .4;
    }

    to {
        transform: scale(1.14);
        opacity: 1;
    }
}

/* ---------- 雨丝：细长的斜线快速下落 ---------- */
.joe-bgfx--rain i {
    top: -10vh;
    width: 1px;
    height: var(--s, 20px);
    border-radius: 1px;
    background-image: linear-gradient(to bottom, rgba(0, 111, 255, 0), var(--fx));
    animation: joe-bgfx-rain var(--d, 1.6s) linear var(--t, 0s) infinite;
}

@keyframes joe-bgfx-rain {
    0% {
        transform: translate3d(0, 0, 0) rotate(14deg);
        opacity: 0;
    }

    10% {
        opacity: var(--o, .45);
    }

    85% {
        opacity: var(--o, .45);
    }

    100% {
        transform: translate3d(var(--dx, 0px), 118vh, 0) rotate(14deg);
        opacity: 0;
    }
}

/* ---------- 流星：带光晕的细长光尾，偶尔斜着划过（2026-10-08 优化） ----------
   原来：2px 纯色直线 + 固定 26° 斜角 → 看起来像划痕。
   现在：更细更长 + 头亮尾淡的三段渐变 + 外发光 + 每个子元素角度不同（nth-child 给 --rot）。 */
.joe-bgfx--meteor i {
    top: -8vh;
    width: var(--s, 150px);
    height: 1.5px;
    border-radius: 2px;
    background-image: linear-gradient(90deg, rgba(0, 111, 255, 0), var(--fx) 68%, #fff);
    box-shadow: 0 0 9px 1px var(--fx);
    animation: joe-bgfx-meteor var(--d, 10s) linear var(--t, 0s) infinite;
}

.joe-bgfx--meteor i:nth-child(3n+1) {
    --rot: 21deg;
}

.joe-bgfx--meteor i:nth-child(3n+2) {
    --rot: 29deg;
}

.joe-bgfx--meteor i:nth-child(3n+3) {
    --rot: 14deg;
}

@keyframes joe-bgfx-meteor {

    0%,
    76% {
        transform: translate3d(0, 0, 0) rotate(var(--rot, 26deg));
        opacity: 0;
    }

    83% {
        opacity: var(--o, .8);
    }

    99% {
        opacity: calc(var(--o, .8) * .45);
    }

    100% {
        transform: translate3d(-48vw, 116vh, 0) rotate(var(--rot, 26deg));
        opacity: 0;
    }
}

/* ---------- 花瓣：翻着跟头飘落（2026-10-08 优化） ----------
   原来：扁平纯色椭圆 + 匀速直线下落 + 单纯 rotate → 像彩色纸屑。
   现在：① `rotate3d` 做出"翻面"的立体感 ② 中途加一段反向横移 = 左右摇摆
        ③ 半透明渐变填充 + 极淡投影 ④ 三种色调（nth-child）避免单调 */
.joe-bgfx--petal i {
    top: -10vh;
    width: var(--s, 10px);
    height: calc(var(--s, 10px) * .68);
    border-radius: 62% 12% 62% 12%;
    background-image: linear-gradient(135deg, rgba(255, 255, 255, .55), var(--fx) 58%);
    box-shadow: 0 1px 2px rgba(0, 0, 0, .1);
    animation: joe-bgfx-petal var(--d, 16s) linear var(--t, 0s) infinite;
}

.joe-bgfx--petal i:nth-child(3n+1) {
    background-image: linear-gradient(135deg, rgba(255, 255, 255, .55), #ffb9cd 58%);
}

.joe-bgfx--petal i:nth-child(3n+2) {
    background-image: linear-gradient(135deg, rgba(255, 255, 255, .55), #ffd4b4 58%);
}

.joe-bgfx--petal i:nth-child(3n+3) {
    background-image: linear-gradient(135deg, rgba(255, 255, 255, .55), #fff1f4 58%);
}

@keyframes joe-bgfx-petal {

    0% {
        transform: translate3d(0, 0, 0) rotate3d(1, .35, 0, 0deg);
        opacity: 0;
    }

    12% {
        opacity: var(--o, .5);
    }

    50% {
        transform: translate3d(calc(var(--dx, 0px) * -1), 55vh, 0) rotate3d(1, .35, 0, 340deg);
        opacity: calc(var(--o, .5) * .78);
    }

    88% {
        opacity: var(--o, .5);
    }

    100% {
        transform: translate3d(var(--dx, 0px), 118vh, 0) rotate3d(1, .35, 0, 720deg);
        opacity: 0;
    }
}

/* ---------- 光斑：大而柔的圆缓缓上浮 ---------- */
.joe-bgfx--bokeh i {
    bottom: -14vh;
    border-radius: 50%;
    background-image: radial-gradient(closest-side, var(--fx2), rgba(0, 111, 255, 0));
    animation: joe-bgfx-bokeh var(--d, 28s) ease-in-out var(--t, 0s) infinite alternate;
}

@keyframes joe-bgfx-bokeh {
    0% {
        transform: translate3d(0, 0, 0) scale(.8);
        opacity: 0;
    }

    22% {
        opacity: var(--o, .35);
    }

    78% {
        opacity: var(--o, .35);
    }

    100% {
        transform: translate3d(var(--dx, 0px), -95vh, 0) scale(1.15);
        opacity: 0;
    }
}

/* ==========================================================================
   2026-10-08 追加：① 背景图 + 背景动效同时启用时的适配
   ② 新增：萤火虫 / 波浪（已去掉 光柱 / 涟漪 / 星野）
   ========================================================================== */

/* ---------- ① 有背景图时（body.joe-bgfx-over）：动效要"浮"在照片上才看得见 ----------
   原来那套配色是给纯色底设计的（深色半透明），压到照片上基本消失。
   分两类处理：
   · 光晕类（极光/光带/呼吸/星野/光柱/鼠标光晕）→ 改 `mix-blend-mode: screen`，
     无论照片是明是暗都能提亮，等于免费加了一层"发光"。
   · 漂浮类（浮在内容之上，粒子是实心小点）→ 改亮色 + 一圈极淡投影，任何壁纸都读得出。 */
body.joe-bgfx-over .joe-bgfx--aurora,
body.joe-bgfx-over .joe-bgfx--sweep,
body.joe-bgfx-over .joe-bgfx--breathe,
body.joe-bgfx-over .joe-bgfx--mouse,
body.joe-bgfx-over .joe-bgfx--fireflies,
body.joe-bgfx-over .joe-bgfx--comet {
    mix-blend-mode: screen;
}

body.joe-bgfx-over .joe-bgfx--particles,
body.joe-bgfx-over .joe-bgfx--snow,
body.joe-bgfx-over .joe-bgfx--bubbles,
body.joe-bgfx-over .joe-bgfx--petal,
body.joe-bgfx-over .joe-bgfx--rain,
body.joe-bgfx-over .joe-bgfx--meteor,
body.joe-bgfx-over .joe-bgfx--bokeh,

body.joe-bgfx-over .joe-bgfx--particles i,
body.joe-bgfx-over .joe-bgfx--snow i,
body.joe-bgfx-over .joe-bgfx--bubbles i,
body.joe-bgfx-over .joe-bgfx--petal i,
body.joe-bgfx-over .joe-bgfx--rain i,
body.joe-bgfx-over .joe-bgfx--bokeh i,
body.joe-bgfx-over .joe-bgfx--comet i {
    filter: drop-shadow(0 1px 2px rgba(0, 0, 0, .45));
}

/* ---------- ② 萤火虫：暖黄小点缓慢上浮 + 明灭 ---------- */
.joe-bgfx--fireflies {
    z-index: 900;
    --fx: rgba(255, 214, 102, .95);
}

html[data-night='night'] .joe-bgfx--fireflies {
    --fx: rgba(255, 226, 130, .95);
}

.joe-bgfx--fireflies i {
    bottom: -10vh;
    background: var(--fx);
    box-shadow: 0 0 9px 2px rgba(255, 206, 84, .55);
    animation: joe-bgfx-firefly var(--d, 20s) linear var(--t, 0s) infinite;
}

@keyframes joe-bgfx-firefly {
    0% {
        transform: translate3d(0, 0, 0);
        opacity: 0;
    }

    14% {
        opacity: var(--o, .7);
    }

    50% {
        transform: translate3d(var(--dx, 0px), -55vh, 0);
        opacity: calc(var(--o, .7) * .3);
    }

    86% {
        opacity: var(--o, .7);
    }

    100% {
        transform: translate3d(calc(var(--dx, 0px) * -.6), -112vh, 0);
        opacity: 0;
    }
}

/* ---------- 波浪：底部两层 SVG 波面缓慢反向流动（背景层） ---------- */
.joe-bgfx--waves::before,
.joe-bgfx--waves::after {
    position: absolute;
    right: 0;
    bottom: 0;
    left: 0;
    height: 34vh;
    min-height: 190px;
    content: '';
    background-repeat: repeat-x;
    background-position: 0 bottom;
}

.joe-bgfx--waves::before {
    opacity: .5;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1440' height='220' viewBox='0 0 1440 220' preserveAspectRatio='none'%3E%3Cpath d='M0,132 C220,196 340,72 700,124 C1060,176 1220,64 1440,110 L1440,220 L0,220 Z' fill='%23ffffff' fill-opacity='0.2'/%3E%3C/svg%3E");
    background-size: 1440px 100%;
    animation: joe-bgfx-wave 30s linear infinite;
}

.joe-bgfx--waves::after {
    opacity: .34;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1440' height='220' viewBox='0 0 1440 220' preserveAspectRatio='none'%3E%3Cpath d='M0,150 C260,86 420,182 760,132 C1100,82 1260,168 1440,124 L1440,220 L0,220 Z' fill='%23ffffff' fill-opacity='0.26'/%3E%3C/svg%3E");
    background-size: 1440px 100%;
    animation: joe-bgfx-wave 44s linear infinite reverse;
}

@keyframes joe-bgfx-wave {
    from {
        background-position: 0 bottom;
    }

    to {
        background-position: 1440px bottom;
    }
}

/* ==========================================================================
   2026-10-08 第二批：去掉 光柱 / 涟漪 / 星野之后补上的 4 种
   浮尘 / 彗星 / 微光 / 光雾
   ========================================================================== */

/* ---------- 浮尘：极慢斜向飘过的细小光点（背景层，比"微光粒子"更细更慢） ---------- */
.joe-bgfx--dust {
    --fx: rgba(255, 255, 255, .5);
}

html[data-night='night'] .joe-bgfx--dust {
    --fx: rgba(255, 255, 255, .55);
}

html:not([data-night='night']) .joe-bgfx--dust {
    --fx: rgba(60, 10, 30, .2);
}

.joe-bgfx--dust i {
    top: -6vh;
    width: calc(var(--s, 2px) * .7);
    height: calc(var(--s, 2px) * .7);
    animation: joe-bgfx-dust var(--d, 46s) linear var(--t, 0s) infinite;
}

@keyframes joe-bgfx-dust {

    0% {
        transform: translate3d(0, 0, 0);
        opacity: 0;
    }

    15% {
        opacity: var(--o, .35);
    }

    85% {
        opacity: var(--o, .35);
    }

    100% {
        transform: translate3d(-14vw, 116vh, 0);
        opacity: 0;
    }
}

/* ---------- 彗星：带长尾的大颗流星，间隔更长更显眼（背景层） ---------- */
.joe-bgfx--comet i {
    top: -10vh;
    width: var(--s, 220px);
    height: 2px;
    border-radius: 2px;
    background-image: linear-gradient(90deg, rgba(0, 111, 255, 0), var(--fx) 42%, #fff 100%);
    box-shadow: 0 0 12px 2px var(--fx);
    animation: joe-bgfx-comet var(--d, 16s) linear var(--t, 0s) infinite;
}

.joe-bgfx--comet i:nth-child(2n+1) {
    --rot: 24deg;
}

.joe-bgfx--comet i:nth-child(2n+2) {
    --rot: 34deg;
}

@keyframes joe-bgfx-comet {

    0%,
    70% {
        transform: translate3d(0, 0, 0) rotate(var(--rot, 26deg));
        opacity: 0;
    }

    78% {
        opacity: var(--o, .85);
    }

    99% {
        opacity: calc(var(--o, .85) * .4);
    }

    100% {
        transform: translate3d(62vw, 104vh, 0) rotate(var(--rot, 26deg));
        opacity: 0;
    }
}

/* ---------- 微光：细密的横向光条缓慢流动，像水面反光（背景层） ---------- */
.joe-bgfx--shimmer {
    --fx: rgba(255, 255, 255, .5);
}

html:not([data-night='night']) .joe-bgfx--shimmer {
    --fx: rgba(60, 10, 30, .16);
}

.joe-bgfx--shimmer::before {
    position: absolute;
    top: -30%;
    right: -10%;
    bottom: -30%;
    left: -10%;
    content: '';
    background-image: repeating-linear-gradient(78deg, rgba(255, 255, 255, 0) 0 14px, var(--fx) 14px 15px, rgba(255, 255, 255, 0) 15px 40px);
    -webkit-mask-image: linear-gradient(180deg, transparent, #000 26%, #000 74%, transparent);
    mask-image: linear-gradient(180deg, transparent, #000 26%, #000 74%, transparent);
    animation: joe-bgfx-shimmer 22s linear infinite;
}

.joe-bgfx--shimmer::after {
    display: none;
}

@keyframes joe-bgfx-shimmer {
    from {
        transform: translate3d(0, 0, 0);
    }

    to {
        transform: translate3d(-40px, 18px, 0);
    }
}

/* ---------- 光雾：三团超大柔光缓慢漂移 + 呼吸（背景层，像清晨的雾） ---------- */
.joe-bgfx--haze::before,
.joe-bgfx--haze::after {
    position: absolute;
    top: -35%;
    right: -25%;
    bottom: -35%;
    left: -25%;
    content: '';
}

.joe-bgfx--haze::before {
    background-image:
        radial-gradient(closest-side, rgba(255, 255, 255, .30), rgba(255, 255, 255, 0)),
        radial-gradient(closest-side, rgba(190, 215, 255, .26), rgba(190, 215, 255, 0));
    background-size: 68% 58%, 54% 46%;
    background-position: 12% 26%, 78% 68%;
    background-repeat: no-repeat;
    animation: joe-bgfx-haze 40s ease-in-out infinite alternate;
}

.joe-bgfx--haze::after {
    background-image: radial-gradient(closest-side, rgba(255, 240, 220, .24), rgba(255, 240, 220, 0));
    background-size: 62% 52%;
    background-position: 52% 88%;
    background-repeat: no-repeat;
    animation: joe-bgfx-haze 54s ease-in-out infinite alternate-reverse;
}

@keyframes joe-bgfx-haze {

    0% {
        transform: translate3d(-3%, -2%, 0) scale(1);
        opacity: .75;
    }

    100% {
        transform: translate3d(4%, 3%, 0) scale(1.18);
        opacity: 1;
    }
}
