/* 3D 礼物（第 138 章）：纯 CSS 立体造型 + 打赏特效
 *
 * 设计要点：
 *  1. 不用 Three.js / GLB 模型 —— 礼物是后台随时可加的运营项，不可能每次都传模型文件；
 *     WebGL 在低端安卓 WebView 上也容易掉帧。
 *  2. 立体感靠真 3D 变换：立方体六面 / 钻石双锥 / 圆环绕轴排片 / emoji 沿 Z 轴挤出。
 *     容器 perspective + 子层 translateZ 才是「转起来有厚度」的关键，
 *     text-shadow 堆叠在 rotateY 时会穿帮。
 *  3. 全部尺寸由 --s（px）驱动，同一套样式在 40px 小图标和 220px 全屏特效通用。
 *  4. 类名统一 g3- 前缀，后台预览可直接复用（后台也引这份 CSS）。
 */

/* ---------- 容器 ---------- */
.g3 { position: relative; display: inline-flex; align-items: center; justify-content: center;
  perspective: 640px; perspective-origin: 50% 45%; }
.g3-stage { position: relative; transform-style: preserve-3d; will-change: transform;
  transform: rotateX(-16deg) rotateY(-28deg); }
.g3-spin .g3-stage { animation: g3-spin var(--spin, 7s) linear infinite; }
.g3-bob .g3-stage { animation: g3-bob 3.2s ease-in-out infinite; }
@keyframes g3-spin {
  from { transform: rotateX(-12deg) rotateY(0deg); }
  to { transform: rotateX(-12deg) rotateY(360deg); }
}
@keyframes g3-bob {
  0%, 100% { transform: translateY(0) rotateX(-10deg) rotateY(-30deg); }
  50% { transform: translateY(-6%) rotateX(-6deg) rotateY(-8deg); }
}

/* 底座光斑：让立体物件「站」在光上，不是浮在空气里 */
.g3-shadow { position: absolute; left: 50%; bottom: -14%; width: 78%; height: 22%;
  transform: translateX(-50%) rotateX(72deg); border-radius: 50%;
  background: radial-gradient(ellipse at center, var(--g3-glow, #ff4d6d) 0%, transparent 70%);
  opacity: .45; filter: blur(3px); }

/* ---------- 立方体（礼盒 / 城堡）---------- */
.g3-cube { position: relative; width: var(--s); height: var(--s); transform-style: preserve-3d; }
.g3-cube .f { position: absolute; left: 0; top: 0; width: var(--s); height: var(--s);
  border-radius: calc(var(--s) * .08);
  display: flex; align-items: center; justify-content: center;
  font-size: calc(var(--s) * .46); line-height: 1;
  backface-visibility: visible;
  box-shadow: inset 0 0 calc(var(--s) * .16) rgba(255,255,255,.45); }
.g3-cube .f1 { transform: translateZ(calc(var(--s) / 2)); background: linear-gradient(150deg, var(--g3-c2), var(--g3-c1)); }
.g3-cube .f2 { transform: rotateY(180deg) translateZ(calc(var(--s) / 2)); background: linear-gradient(150deg, var(--g3-c1), var(--g3-c2)); }
.g3-cube .f3 { transform: rotateY(90deg) translateZ(calc(var(--s) / 2)); background: linear-gradient(150deg, var(--g3-c3), var(--g3-c2)); }
.g3-cube .f4 { transform: rotateY(-90deg) translateZ(calc(var(--s) / 2)); background: linear-gradient(150deg, var(--g3-c2), var(--g3-c3)); }
.g3-cube .f5 { transform: rotateX(90deg) translateZ(calc(var(--s) / 2)); background: linear-gradient(150deg, var(--g3-c3), #fff); opacity: .95; }
.g3-cube .f6 { transform: rotateX(-90deg) translateZ(calc(var(--s) / 2)); background: var(--g3-c3); opacity: .85; }
/* 缎带：横竖两条压在正面与侧面，礼盒才不像色块 */
.g3-cube .rib { position: absolute; left: 50%; top: 0; width: 14%; height: 100%;
  transform: translateX(-50%); background: linear-gradient(180deg, rgba(255,255,255,.85), rgba(255,255,255,.35)); opacity: .75; }
.g3-cube .f1 .rib, .g3-cube .f2 .rib { z-index: 2; }

/* ---------- 钻石（双锥体，四棱）---------- */
.g3-gem { position: relative; width: var(--s); height: var(--s); transform-style: preserve-3d; }
.g3-gem .gf-p { position: absolute; left: 0; top: calc(var(--s) * .26); width: var(--s); height: calc(var(--s) * .48);
  background: linear-gradient(180deg, var(--g3-c2), var(--g3-c1));
  box-shadow: inset 0 0 calc(var(--s) * .14) rgba(255,255,255,.6);
  backface-visibility: visible; }
.g3-gem .gf-p.p1 { transform: rotateY(0deg) translateZ(calc(var(--s) * .28)) rotateX(6deg); }
.g3-gem .gf-p.p2 { transform: rotateY(90deg) translateZ(calc(var(--s) * .28)) rotateX(6deg); }
.g3-gem .gf-p.p3 { transform: rotateY(180deg) translateZ(calc(var(--s) * .28)) rotateX(6deg); }
.g3-gem .gf-p.p4 { transform: rotateY(270deg) translateZ(calc(var(--s) * .28)) rotateX(6deg); }
.g3-gem .gt { position: absolute; left: 0; bottom: calc(var(--s) * .50); width: var(--s); height: calc(var(--s) * .34);
  clip-path: polygon(50% 0%, 100% 100%, 0% 100%);
  background: linear-gradient(180deg, #fff, var(--g3-c2));
  transform-origin: bottom center; opacity: .95; }
.g3-gem .gt.t1 { transform: rotateY(0deg) translateZ(calc(var(--s) * .14)) rotateX(-32deg); }
.g3-gem .gt.t2 { transform: rotateY(90deg) translateZ(calc(var(--s) * .14)) rotateX(-32deg); }
.g3-gem .gt.t3 { transform: rotateY(180deg) translateZ(calc(var(--s) * .14)) rotateX(-32deg); }
.g3-gem .gt.t4 { transform: rotateY(270deg) translateZ(calc(var(--s) * .14)) rotateX(-32deg); }
.g3-gem .gb { position: absolute; left: 0; top: calc(var(--s) * .70); width: var(--s); height: calc(var(--s) * .30);
  clip-path: polygon(0% 0%, 100% 0%, 50% 100%);
  background: linear-gradient(0deg, var(--g3-c3), var(--g3-c1));
  transform-origin: top center; opacity: .9; }
.g3-gem .gb.b1 { transform: rotateY(0deg) translateZ(calc(var(--s) * .14)) rotateX(28deg); }
.g3-gem .gb.b2 { transform: rotateY(90deg) translateZ(calc(var(--s) * .14)) rotateX(28deg); }
.g3-gem .gb.b3 { transform: rotateY(180deg) translateZ(calc(var(--s) * .14)) rotateX(28deg); }
.g3-gem .gb.b4 { transform: rotateY(270deg) translateZ(calc(var(--s) * .14)) rotateX(28deg); }

/* ---------- 圆环（戒指 / 光环）----------
 * 做法：16 片薄板绕 Y 轴排成「水平圆盘」，再把整个盘 rotateX(90deg) 立起来 ——
 * 这样正面看是一个中间有洞的环（直接竖直排片只会得到实心圆柱）。 */
.g3-ring { position: relative; width: var(--s); height: var(--s); transform-style: preserve-3d; }
.g3-ring .ringdeck { position: absolute; left: 0; top: 0; width: var(--s); height: var(--s);
  transform-style: preserve-3d; transform: rotateX(90deg); }
.g3-ring .seg { position: absolute; left: 50%; top: 50%;
  width: calc(var(--s) * .12); height: calc(var(--s) * .20);
  margin: calc(var(--s) * -.095) 0 0 calc(var(--s) * -.055);
  border-radius: calc(var(--s) * .04);
  background: linear-gradient(180deg, var(--g3-c2), var(--g3-c1) 45%, var(--g3-c3));
  box-shadow: inset 0 0 calc(var(--s) * .04) rgba(255,255,255,.6); }
/* 宝石嵌在环的正上方（环半径 0.34s，宝石半径 0.13s，所以顶部在 -0.47s），
 * 用五边 clip-path 切出钻石轮廓，圆形宝石看着像一颗蛋。 */
.g3-ring .crown-jewel { position: absolute; left: 50%; top: calc(var(--s) * -.09);
  width: calc(var(--s) * .26); height: calc(var(--s) * .24);
  margin-left: calc(var(--s) * -.13);
  clip-path: polygon(50% 0%, 96% 34%, 76% 100%, 24% 100%, 4% 34%);
  background: linear-gradient(160deg, #fff 0%, var(--g3-c2) 38%, var(--g3-c1) 76%, var(--g3-c3) 100%);
  filter: drop-shadow(0 0 calc(var(--s) * .12) var(--g3-glow));
  transform: translateZ(calc(var(--s) * .06)); }

/* ---------- 皇冠（棱柱 + 四个尖角）---------- */
.g3-crown { position: relative; width: var(--s); height: var(--s); transform-style: preserve-3d; }
.g3-crown .cw-b { position: absolute; left: 0; top: calc(var(--s) * .42); width: var(--s); height: calc(var(--s) * .42);
  background: linear-gradient(180deg, var(--g3-c2), var(--g3-c1));
  box-shadow: inset 0 0 calc(var(--s) * .1) rgba(255,255,255,.55); }
.g3-crown .cw-b.w1 { transform: rotateY(0deg) translateZ(calc(var(--s) * .3)); }
.g3-crown .cw-b.w2 { transform: rotateY(90deg) translateZ(calc(var(--s) * .3)); }
.g3-crown .cw-b.w3 { transform: rotateY(180deg) translateZ(calc(var(--s) * .3)); }
.g3-crown .cw-b.w4 { transform: rotateY(270deg) translateZ(calc(var(--s) * .3)); }
.g3-crown .cw-p { position: absolute; bottom: calc(var(--s) * .84); left: calc(var(--s) * .18); width: calc(var(--s) * .64); height: calc(var(--s) * .26);
  clip-path: polygon(50% 0%, 100% 100%, 0% 100%);
  background: linear-gradient(180deg, #fff7d6, var(--g3-c2)); transform-origin: bottom center; }
.g3-crown .cw-p.k1 { transform: rotateY(0deg) translateZ(calc(var(--s) * .14)) rotateX(-14deg); }
.g3-crown .cw-p.k2 { transform: rotateY(90deg) translateZ(calc(var(--s) * .14)) rotateX(-14deg); }
.g3-crown .cw-p.k3 { transform: rotateY(180deg) translateZ(calc(var(--s) * .14)) rotateX(-14deg); }
.g3-crown .cw-p.k4 { transform: rotateY(270deg) translateZ(calc(var(--s) * .14)) rotateX(-14deg); }
.g3-crown .cw-base { position: absolute; left: 0; top: calc(var(--s) * .80); width: var(--s); height: calc(var(--s) * .16);
  border-radius: calc(var(--s) * .05);
  background: linear-gradient(180deg, #fff3c4, var(--g3-c1)); box-shadow: 0 0 calc(var(--s) * .1) var(--g3-glow); }

/* ---------- emoji 挤出（通用立体图标）----------
 * 同一枚 emoji 复制 N 层沿 Z 轴排开，前层正常、后层压暗，转起来就是有厚度的立体字块。 */
.g3-plate { position: relative; width: var(--s); height: var(--s); transform-style: preserve-3d; }
.g3-plate .ly { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
  font-size: calc(var(--s) * .74); line-height: 1; backface-visibility: visible; }
/* 底层是剪影：彩色 emoji 叠十层会糊成色块，剪影只负责在侧转时露出厚度 */
.g3-plate .ly.behind { filter: brightness(0); opacity: .5; }
.g3-plate .ly.front { filter: drop-shadow(0 0 calc(var(--s) * .1) var(--g3-glow)); }

/* ---------- 光球（烟花 / 星球）---------- */
.g3-orb { position: relative; width: var(--s); height: var(--s); transform-style: preserve-3d; }
.g3-orb .ball { position: absolute; inset: 0; border-radius: 50%;
  background: radial-gradient(circle at 34% 28%, #fff 0%, var(--g3-c2) 26%, var(--g3-c1) 62%, var(--g3-c3) 100%);
  box-shadow: 0 0 calc(var(--s) * .3) var(--g3-glow), inset calc(var(--s) * -.06) calc(var(--s) * -.06) calc(var(--s) * .16) rgba(0,0,0,.25); }
.g3-orb .halo { position: absolute; left: -18%; top: 46%; width: 136%; height: 34%;
  border-radius: 50%; border: calc(var(--s) * .04) solid var(--g3-c2);
  transform: rotateX(74deg); box-shadow: 0 0 calc(var(--s) * .16) var(--g3-glow); opacity: .8; }
.g3-orb .spark { position: absolute; inset: -12%; border-radius: 50%;
  background: radial-gradient(circle, rgba(255,255,255,.5) 0%, transparent 62%);
  animation: g3-pulse 2.4s ease-in-out infinite; }
@keyframes g3-pulse { 0%, 100% { opacity: .35; transform: scale(.9); } 50% { opacity: .8; transform: scale(1.08); } }

/* emoji 兜底（未配 3D 造型的老礼物） */
.g3-emoji { display: inline-flex; align-items: center; justify-content: center;
  font-size: calc(var(--s) * .8); line-height: 1;
  filter: drop-shadow(0 calc(var(--s) * .05) calc(var(--s) * .1) rgba(0,0,0,.22)); }

/* =========================================================
   全屏打赏特效（抖音式）：从底部升起 → 旋转放大 → 光环扩散 → 粒子 → 连击
   ========================================================= */
.g3-fx { position: fixed; inset: 0; z-index: 9600; display: flex; align-items: center; justify-content: center;
  pointer-events: none; opacity: 0; transition: opacity .28s ease;
  background: radial-gradient(circle at 50% 46%, rgba(12,7,26,.84) 0%, rgba(7,4,16,.94) 55%, rgba(3,2,8,.97) 100%); }
.g3-fx.on { opacity: 1; }
.g3-fx.out { opacity: 0; }

/* 背景光束：四道斜向渐变，缓慢旋转 */
.g3-fx .rays { position: absolute; left: 50%; top: 46%; width: 160vmax; height: 160vmax;
  margin: -80vmax 0 0 -80vmax; opacity: .34;
  background: conic-gradient(from 0deg, transparent 0deg, var(--g3-glow) 12deg, transparent 26deg,
    transparent 84deg, var(--g3-glow) 96deg, transparent 110deg,
    transparent 168deg, var(--g3-glow) 180deg, transparent 194deg,
    transparent 252deg, var(--g3-glow) 264deg, transparent 278deg, transparent 360deg);
  filter: blur(26px); animation: g3-rays 9s linear infinite; }
@keyframes g3-rays { to { transform: rotate(360deg); } }

/* 地面光池 */
.g3-fx .pool { position: absolute; left: 50%; bottom: 8%; width: 84vmin; height: 26vmin; transform: translateX(-50%);
  background: radial-gradient(ellipse at center, var(--g3-glow) 0%, transparent 68%); opacity: .55; filter: blur(12px); }

/* 主体自转用「左右摇摆」而不是 360°：emoji 挤出这类扁平造型转到侧面会变成一条线，
 * 摇摆始终能看到正面，同时保留立体转动的观感。
 * 区间取 -44°~-12°（不经过 0°）——正对屏幕那一瞬侧脸、厚度全丢，看着就是张平面图。 */
.g3-fx .g3 .g3-stage { animation: g3-fxsway 3.4s ease-in-out infinite; }
@keyframes g3-fxsway {
  0%, 100% { transform: rotateX(-14deg) rotateY(-44deg); }
  50% { transform: rotateX(-7deg) rotateY(-12deg); }
}

/* 主舞台：从下往上飞入 */
.g3-fx .stage { position: relative; display: flex; align-items: center; justify-content: center;
  transform: translateY(38vh) scale(.5); opacity: 0; }
.g3-fx.rise .stage { animation: g3-rise 1s cubic-bezier(.2,.9,.25,1) forwards; }
@keyframes g3-rise {
  0% { transform: translateY(38vh) scale(.5) rotateY(-40deg); opacity: 0; }
  62% { transform: translateY(-2vh) scale(1.14) rotateY(14deg); opacity: 1; }
  100% { transform: translateY(0) scale(1) rotateY(0deg); opacity: 1; }
}

/* 扩散光环 */
.g3-fx .wave { position: absolute; left: 50%; top: 50%; width: 70vmin; height: 70vmin; margin: -35vmin 0 0 -35vmin;
  border-radius: 50%; border: 2px solid var(--g3-glow); opacity: 0; }
.g3-fx.rise .wave.w1 { animation: g3-wave 1.35s ease-out .1s 1 both; }
.g3-fx.rise .wave.w2 { animation: g3-wave 1.6s ease-out .3s 1 both; }
@keyframes g3-wave {
  0% { transform: scale(.18); opacity: .9; }
  100% { transform: scale(1.5); opacity: 0; }
}

/* 粒子：--x / --y 位移、--t 延迟由 JS 注入（不用 CSS 三角函数，老 WebView 不支持） */
.g3-fx .ps { position: absolute; left: 50%; top: 48%; width: 8px; height: 8px; margin: -4px 0 0 -4px;
  border-radius: 50%; background: var(--g3-glow); box-shadow: 0 0 10px var(--g3-glow); opacity: 0; }
.g3-fx.rise .ps { animation: g3-ps 1.5s ease-out var(--t) 1 both; }
@keyframes g3-ps {
  0% { transform: translate(0, 0) scale(.4); opacity: 0; }
  18% { opacity: 1; }
  100% { transform: translate(var(--x), var(--y)) scale(.1); opacity: 0; }
}

/* 文案 */
.g3-fx .cap { position: absolute; left: 0; right: 0; bottom: 16%; text-align: center; color: #fff;
  transform: translateY(16px); opacity: 0; }
.g3-fx.rise .cap { animation: g3-cap .5s ease-out .55s forwards; }
@keyframes g3-cap { to { transform: translateY(0); opacity: 1; } }
.g3-fx .cap .who { font-size: 14px; opacity: .82; letter-spacing: .5px; }
.g3-fx .cap .nm { margin-top: 6px; font-size: 22px; font-weight: 900;
  text-shadow: 0 2px 18px var(--g3-glow), 0 0 4px rgba(0,0,0,.5); }
.g3-fx .cap .nm i { font-style: normal; font-size: 16px; opacity: .9; margin-left: 6px; }
.g3-fx .cap .msg { margin: 8px auto 0; max-width: 76vw; font-size: 12.5px; line-height: 1.6; opacity: .78; }

/* 连击 */
.g3-fx .combo { position: absolute; right: 8%; top: 14%; color: #fff; text-align: right; opacity: 0;
  transform: scale(.4); transform-origin: right center; }
.g3-fx.rise .combo { animation: g3-combo .42s cubic-bezier(.2,1.5,.5,1) .2s forwards; }
@keyframes g3-combo { to { transform: scale(1); opacity: 1; } }
.g3-fx .combo b { display: block; font-size: 46px; font-weight: 900; line-height: 1;
  background: linear-gradient(180deg, #fff, var(--g3-glow)); -webkit-background-clip: text; background-clip: text; color: transparent;
  text-shadow: 0 0 24px var(--g3-glow); }
.g3-fx .combo span { font-size: 12px; opacity: .8; letter-spacing: 2px; }

/* 小程序 / 低性能设备：关掉高代价的模糊与光束 */
.g3-lite .g3-fx .rays, .g3-lite .g3-fx .pool { display: none; }
.g3-lite .g3-fx .ps { box-shadow: none; }

@media (prefers-reduced-motion: reduce) {
  .g3-spin .g3-stage, .g3-bob .g3-stage, .g3-fx .rays { animation: none; }
}
