:root {
  --bg: #FAF9F5;
  --surface: #F0EEE6;
  --text: #1F1E1D;
  --muted: #6B6A63;
  --border: #E5E3DA;
  --accent: #D97757;
  --accent-strong: #B8552F;
  --accent-tint: rgba(217, 119, 87, 0.10);
  --shadow: 0 1px 3px rgba(31, 30, 29, 0.04);
}
[data-theme="dark"] {
  --bg: #262624;
  --surface: #30302E;
  --text: #ECEAE2;
  --muted: #A6A39A;
  --border: #3E3D39;
  --accent: #D97757;
  --accent-strong: #E08B6D;
  --accent-tint: rgba(217, 119, 87, 0.16);
  --shadow: none;
}
* { box-sizing: border-box; }
body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: "Source Serif 4", Georgia, "Noto Serif SC", serif;
  font-size: 17px;
  line-height: 1.75;
  transition: background 0.25s ease, color 0.25s ease;
  -webkit-font-smoothing: antialiased;
}
::selection { background: var(--accent); color: #FAF9F5; }
a { color: var(--accent-strong); text-decoration: none; border-bottom: 1px solid transparent; transition: border-color .15s ease, color .15s ease; }
a:hover { border-bottom-color: var(--accent-strong); }
.wrap { max-width: 44rem; margin: 0 auto; padding: 4.5rem 1.5rem 3rem; }

/* theme toggle */
.theme-toggle {
  position: fixed; top: 1.1rem; right: 1.1rem; z-index: 10;
  width: 38px; height: 38px; border-radius: 50%;
  border: 1px solid var(--border); background: var(--surface); color: var(--muted);
  font-size: 17px; line-height: 1; cursor: pointer; display: flex; align-items: center; justify-content: center;
  transition: color .2s ease, border-color .2s ease, transform .3s cubic-bezier(.22,.61,.36,1);
}
.theme-toggle:hover { color: var(--accent); border-color: var(--accent); transform: rotate(-20deg); }
[data-theme="light"] .icon-sun { display: none; }
[data-theme="dark"] .icon-moon { display: none; }

/* 主题切换的圆形擦除（支持 View Transitions 的浏览器） */
::view-transition-old(root), ::view-transition-new(root) { animation: none; mix-blend-mode: normal; }

/* hero */
.hero { text-align: center; margin-bottom: 1rem; position: relative; }
.hero::before {
  content: ""; position: absolute; left: 50%; top: -90px;
  width: 460px; height: 340px; max-width: 120vw;
  transform: translateX(-50%); pointer-events: none; z-index: -1;
  background: radial-gradient(ellipse at center, var(--accent-tint) 0%, transparent 68%);
}
.avatar {
  width: 104px; height: 104px; border-radius: 50%; object-fit: cover;
  border: 3px solid var(--surface); box-shadow: 0 0 0 1px var(--border), var(--shadow);
  transition: transform .4s cubic-bezier(.22,.61,.36,1);
}
.avatar:hover { transform: scale(1.05); }
h1.name { font-size: 2.45rem; font-weight: 600; letter-spacing: -0.015em; margin: 1.1rem 0 0.2rem; }
.tagline { font-family: Inter, "Noto Sans SC", sans-serif; font-size: 0.95rem; color: var(--muted); margin: 0; }
.tagline a { color: var(--muted); border-bottom: 1px dotted var(--border); }
.tagline a:hover { color: var(--accent-strong); border-bottom-color: var(--accent-strong); }
.email { font-family: Inter, sans-serif; font-size: 0.88rem; color: var(--muted); margin-top: 0.35rem; }
.links { margin-top: 1.15rem; display: flex; flex-wrap: wrap; gap: 0.5rem; justify-content: center; }
.pill {
  font-family: Inter, sans-serif; font-size: 0.82rem; font-weight: 500;
  padding: 0.38rem 0.95rem; border-radius: 999px;
  border: 1px solid var(--border); color: var(--text); background: transparent;
  transition: border-color .18s ease, color .18s ease, background .18s ease, transform .18s ease;
}
.pill:hover { border-color: var(--accent); color: var(--accent-strong); background: var(--accent-tint); transform: translateY(-2px); }

/* sections: 每个 h2 开启一节 */
.content h2 {
  position: relative;
  font-size: 1.4rem; font-weight: 600; letter-spacing: -0.01em;
  margin: 3rem 0 1.1rem; padding-top: 2.4rem;
}
.content h2::before {
  content: "✳"; color: var(--accent); margin-right: 0.45rem; font-weight: 400;
  display: inline-block; transition: transform .5s cubic-bezier(.22,.61,.36,1);
}
.content h2:hover::before { transform: rotate(180deg); }
/* 分节线：随滚动从左向右划开 */
.content h2::after {
  content: ""; position: absolute; left: 0; right: 0; top: 0; height: 1px;
  background: var(--border); transform-origin: left;
  transition: transform .8s cubic-bezier(.22,.61,.36,1);
}
.js .content h2::after { transform: scaleX(0); }
.js .content h2.in::after { transform: scaleX(1); }
.content > p { margin: 0.6rem 0; }

/* 滚动渐现 */
.js .reveal { opacity: 0; transform: translateY(12px); }
.js .reveal.in {
  opacity: 1; transform: none;
  transition: opacity .55s ease, transform .55s cubic-bezier(.22,.61,.36,1);
}

/* research interests */
.ri-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 0.9rem; }
.ri-card {
  background: var(--surface); border: 1px solid var(--border); border-radius: 14px; padding: 1.05rem 1.25rem;
  transition: transform .25s cubic-bezier(.22,.61,.36,1), border-color .25s ease;
}
.ri-card:hover { transform: translateY(-3px); border-color: var(--accent); }
.ri-card h3 { font-size: 1.02rem; font-weight: 600; margin: 0 0 0.4rem; }
.ri-card ul { margin: 0; padding-left: 1.1rem; font-size: 0.93rem; color: var(--muted); }
.ri-card li { margin: 0.15rem 0; }
@media (max-width: 560px) { .ri-grid { grid-template-columns: 1fr; } }

/* news：时间轴 */
.news { list-style: none; margin: 0; padding: 0 0 0 1.5rem; position: relative; }
.news::before {
  content: ""; position: absolute; left: 4px; top: 0.9rem; bottom: 0.9rem;
  width: 1px; background: var(--border);
}
.news li { position: relative; display: flex; gap: 1.1rem; padding: 0.42rem 0; font-size: 0.97rem; }
.news li::before {
  content: ""; position: absolute; left: -1.5rem; top: 0.78rem;
  width: 7px; height: 7px; border-radius: 50%;
  background: var(--border); border: 1px solid var(--bg); box-sizing: content-box;
  transition: background .25s ease, transform .25s ease;
}
.news li:hover::before { background: var(--accent); transform: scale(1.25); }
.news li:first-child::before { background: var(--accent); }
.news li:first-child::after {
  content: ""; position: absolute; left: -1.5rem; top: 0.78rem;
  width: 7px; height: 7px; border-radius: 50%; border: 1px solid var(--accent);
  box-sizing: content-box; animation: ping 2.8s cubic-bezier(0, 0, 0.2, 1) infinite;
  pointer-events: none;
}
@keyframes ping {
  0% { transform: scale(1); opacity: 0.65; }
  70%, 100% { transform: scale(2.4); opacity: 0; }
}
.news .date {
  font-family: Inter, sans-serif; font-size: 0.78rem; font-weight: 600; color: var(--accent-strong);
  flex: 0 0 4.6rem; text-transform: uppercase; letter-spacing: 0.04em; padding-top: 0.28rem;
}
.news .what { flex: 1; }

/* publications */
.pub {
  display: flex; gap: 1.15rem; padding: 1.15rem 0.9rem; margin: 0 -0.9rem;
  border-bottom: 1px dashed var(--border); border-radius: 12px;
  transition: background .25s ease;
}
.pub:last-child { border-bottom: none; }
.pub:hover { background: var(--surface); }
.pub .thumb {
  flex: 0 0 112px; width: 112px; height: 80px;
  border-radius: 10px; border: 1px solid var(--border);
  background: #FFFFFF; display: flex; align-items: center; justify-content: center;
  overflow: hidden; padding: 5px;
}
.pub .thumb img {
  max-width: 100%; max-height: 100%; width: auto; height: auto; display: block;
  transition: transform .35s cubic-bezier(.22,.61,.36,1);
}
.pub:hover .thumb img { transform: scale(1.06); }
.pub .title { font-size: 1.03rem; font-weight: 600; line-height: 1.45; }
.pub .title a { color: var(--text); }
.pub .title a:hover { color: var(--accent-strong); border-bottom-color: var(--accent-strong); }
.pub .authors { font-size: 0.88rem; color: var(--muted); margin-top: 0.2rem; line-height: 1.55; }
.pub .authors strong, .pub .authors b { color: var(--text); font-weight: 600; }
.pub .meta { margin-top: 0.45rem; display: flex; flex-wrap: wrap; align-items: center; gap: 0.45rem; }
.badge {
  font-family: Inter, sans-serif; font-size: 0.7rem; font-weight: 600; letter-spacing: 0.05em; text-transform: uppercase;
  color: var(--accent-strong); background: var(--accent-tint); border-radius: 999px; padding: 0.18rem 0.6rem;
}
.plink { font-family: Inter, sans-serif; font-size: 0.78rem; font-weight: 500; color: var(--muted); border-bottom: 1px solid var(--border); }
.plink:hover { color: var(--accent-strong); border-bottom-color: var(--accent-strong); }
@media (max-width: 560px) { .pub .thumb { display: none; } }

/* services */
.services-list h3 { font-size: 1rem; font-weight: 600; margin: 0 0 0.5rem; }
.services-list ul { margin: 0; padding-left: 1.15rem; font-size: 0.95rem; }
.services-list li { margin: 0.25rem 0; }

footer {
  border-top: 1px solid var(--border); margin-top: 3.5rem; padding: 1.6rem 0 0;
  font-family: Inter, sans-serif; font-size: 0.78rem; color: var(--muted); text-align: center;
}
footer a { color: var(--muted); }
footer a:hover { color: var(--accent-strong); }

@media (prefers-reduced-motion: no-preference) {
  html { scroll-behavior: smooth; }
}
/* 尊重系统的"减少动态效果"设置 */
@media (prefers-reduced-motion: reduce) {
  .js .reveal, .js .reveal.in { opacity: 1; transform: none; transition: none; }
  .js .content h2::after, .js .content h2.in::after { transform: scaleX(1); transition: none; }
  .news li:first-child::after { animation: none; opacity: 0; }
  .avatar, .pill, .ri-card, .pub .thumb img, .theme-toggle, .content h2::before { transition: none; }
  .avatar:hover, .pill:hover, .ri-card:hover, .pub:hover .thumb img, .theme-toggle:hover, .content h2:hover::before { transform: none; }
}


/* ===== 论文悬停动画场景 (悬停时配图切换为剧场) ===== */
.pub .thumb { position: relative; }
.pub .thumb img { position: relative; }
.pub .thumb .scene {
  position: absolute; inset: 0; width: 100%; height: 100%;
  opacity: 0; background: var(--bg); color: var(--text);
  transition: opacity .35s ease; pointer-events: none;
}
.pub:hover .thumb img { opacity: 0; }
.pub:hover .thumb .scene { opacity: 1; }

/* 场景绘图零件 */
.scene .ln { fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }
.scene .ln-m { fill: none; stroke: var(--muted); stroke-width: 1.4; stroke-linecap: round; }
.scene .ac { fill: var(--accent); }
.scene .ac-s { fill: none; stroke: var(--accent); stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }
.scene .fillbg { fill: var(--bg); }
.scene .fillsurf { fill: var(--surface); }
.scene .tiny { font-family: Inter, sans-serif; font-size: 5.5px; fill: var(--muted); }
.s-ufeval .ray { stroke-dasharray: 34; stroke-dashoffset: 0; }
.s-instructor .loop { stroke-dasharray: 90; }

/* 场景 keyframes */
@keyframes float{0%,100%{transform:translateY(0)}50%{transform:translateY(-2px)}}
@keyframes blink{0%,92%,100%{transform:scaleY(1)}96%{transform:scaleY(.08)}}
@keyframes travelR{0%{opacity:0;transform:translateX(-10px) scale(.5)}10%{opacity:1;transform:translateX(-10px) scale(1)}40%{opacity:1;transform:translateX(14px) scale(1)}48%{opacity:0;transform:translateX(18px) scale(.7)}100%{opacity:0}}
@keyframes travelL{0%,46%{opacity:0;transform:translateX(10px) scale(.5)}56%{opacity:1;transform:translateX(10px) scale(1)}80%{opacity:1;transform:translateX(-14px) scale(1)}88%{opacity:0;transform:translateX(-18px) scale(.7)}100%{opacity:0}}
@keyframes think{0%,32%{opacity:0}40%{opacity:1}52%{opacity:0}100%{opacity:0}}
@keyframes stamp{0%,84%{opacity:0;transform:scale(2) rotate(-14deg)}91%{opacity:1;transform:scale(.92) rotate(0)}95%{transform:scale(1.06)}100%{opacity:1;transform:scale(1)}}
@keyframes sweep{0%{transform:translateX(0)}45%{transform:translateX(60px)}55%{transform:translateX(60px)}100%{transform:translateX(0)}}
@keyframes popIn{0%,18%{opacity:0;transform:scale(.3)}26%{opacity:1;transform:scale(1.25)}32%,100%{opacity:1;transform:scale(1)}}
@keyframes barGrow{0%,12%{transform:scaleX(0)}55%,100%{transform:scaleX(1)}}
@keyframes drawRay{0%,8%{stroke-dashoffset:34}45%,100%{stroke-dashoffset:0}}
@keyframes orbit{0%{stroke-dashoffset:90}100%{stroke-dashoffset:0}}
@keyframes markOff{0%,42%{opacity:1;transform:scale(1)}50%,100%{opacity:0;transform:scale(.5)}}
@keyframes markOn{0%,48%{opacity:0;transform:scale(.5)}58%{opacity:1;transform:scale(1.2)}64%,100%{opacity:1;transform:scale(1)}}
@keyframes mui-probe{
  0%,10%   {opacity:0;transform:translate(0,0)}
  16%,22%  {opacity:1;transform:translate(0,0)}
  32%,40%  {opacity:1;transform:translate(42px,3px)}
  48%,56%  {opacity:1;transform:translate(69px,-8px)}
  64%,92%  {opacity:1;transform:translate(78px,14px)}
  100%     {opacity:0;transform:translate(78px,14px)}
}
@keyframes mui-p1{0%,30%{opacity:0}38%,92%{opacity:1}100%{opacity:0}}
@keyframes mui-p2{0%,46%{opacity:0}54%,92%{opacity:1}100%{opacity:0}}
@keyframes mui-p3{0%,62%{opacity:0}70%,92%{opacity:1}100%{opacity:0}}
@keyframes mui-bar1{0%{stroke-dashoffset:36}16%,92%{stroke-dashoffset:0}100%{stroke-dashoffset:36}}
@keyframes mui-bar2{0%,72%{stroke-dashoffset:11}84%,92%{stroke-dashoffset:0}100%{stroke-dashoffset:11}}
@keyframes dual-stem{0%,4%{stroke-dashoffset:100;opacity:1}12%,94%{stroke-dashoffset:0;opacity:1}100%{stroke-dashoffset:0;opacity:0}}
@keyframes dual-fork{0%,19%{stroke-dashoffset:100;opacity:1}33%,94%{stroke-dashoffset:0;opacity:1}100%{stroke-dashoffset:0;opacity:0}}
@keyframes dual-ax{0%,31%{stroke-dashoffset:100;opacity:1}43%,94%{stroke-dashoffset:0;opacity:1}100%{stroke-dashoffset:0;opacity:0}}
@keyframes dual-seed{0%,11%{transform:scale(0);opacity:0}17%{transform:scale(1.35);opacity:1}22%,94%{transform:scale(1);opacity:1}100%{transform:scale(1);opacity:0}}
@keyframes dual-lab{0%,32%{opacity:0}44%,94%{opacity:1}100%{opacity:0}}
@keyframes dual-q1{0%,39%{opacity:0;stroke:var(--muted)}46%{opacity:1;stroke:var(--accent)}58%,94%{opacity:1;stroke:var(--muted)}100%{opacity:0;stroke:var(--muted)}}
@keyframes dual-q2{0%,46%{opacity:0;stroke:var(--muted)}53%{opacity:1;stroke:var(--accent)}65%,94%{opacity:1;stroke:var(--muted)}100%{opacity:0;stroke:var(--muted)}}
@keyframes dual-q3{0%,53%{opacity:0;stroke:var(--muted)}60%{opacity:1;stroke:var(--accent)}72%,94%{opacity:1;stroke:var(--muted)}100%{opacity:0;stroke:var(--muted)}}
@keyframes dual-q4{0%,60%{opacity:0;stroke:var(--muted)}68%,94%{opacity:1;stroke:var(--accent)}100%{opacity:0;stroke:var(--accent)}}
@keyframes dual-m1{0%,44%{opacity:0}50%,94%{opacity:1}100%{opacity:0}}
@keyframes dual-m2{0%,51%{opacity:0}57%,94%{opacity:1}100%{opacity:0}}
@keyframes dual-m3{0%,58%{opacity:0}64%,94%{opacity:1}100%{opacity:0}}
@keyframes dual-m4{0%,66%{opacity:0}73%,94%{opacity:1}100%{opacity:0}}
@keyframes update-old{0%,14%{opacity:1}30%,88%{opacity:.24}100%{opacity:1}}
@keyframes update-x{0%,16%{opacity:0;transform:scale(2.3) rotate(-14deg)}28%,84%{opacity:1;transform:scale(1) rotate(0)}93%,100%{opacity:0;transform:scale(1) rotate(0)}}
@keyframes update-arc{0%,32%{stroke-dashoffset:90;opacity:1}60%,84%{stroke-dashoffset:0;opacity:1}92%,100%{stroke-dashoffset:0;opacity:0}}
@keyframes update-new{0%,56%{opacity:0;transform:scale(.55)}70%{opacity:1;transform:scale(1.06)}78%,84%{opacity:1;transform:scale(1)}92%,100%{opacity:0;transform:scale(1)}}
@keyframes update-check{0%,70%{stroke-dashoffset:12}82%,100%{stroke-dashoffset:0}}
@keyframes conflict-sway{0%,14%{transform:translateX(-4.5px) rotate(-6deg)}50%,64%{transform:translateX(4.5px) rotate(6deg)}100%{transform:translateX(-4.5px) rotate(-6deg)}}
@keyframes conflict-mem{0%,6%{transform:scale(1.06);opacity:1}20%,64%{transform:scale(.93);opacity:.28}78%,100%{transform:scale(1.06);opacity:1}}
@keyframes conflict-pmt{0%,6%{transform:scale(.93);opacity:.28}20%,64%{transform:scale(1.06);opacity:1}78%,100%{transform:scale(.93);opacity:.28}}
@keyframes conflict-pl{0%,6%{opacity:1}20%,64%{opacity:.12}78%,100%{opacity:1}}
@keyframes conflict-pr{0%,6%{opacity:.12}20%,64%{opacity:1}78%,100%{opacity:.12}}
@keyframes ab-doc{0%{transform:translateX(0);opacity:0}8%{transform:translateX(2px);opacity:1}40%{transform:translateX(50px);opacity:1}47%,100%{transform:translateX(50px);opacity:0}}
@keyframes ab-draw{0%,48%{stroke-dashoffset:90;opacity:1}72%{stroke-dashoffset:0}94%{stroke-dashoffset:0;opacity:1}100%{stroke-dashoffset:0;opacity:0}}
@keyframes ab-pop{0%,72%{transform:scale(0);opacity:0}80%{transform:scale(1.3);opacity:1}84%,94%{transform:scale(1);opacity:1}100%{transform:scale(1);opacity:0}}
@keyframes ab-tag{0%,76%{opacity:0}82%,94%{opacity:1}100%{opacity:0}}

/* 悬停触发的场景动画 */
.pub:hover .bot{animation:float 3.2s ease-in-out infinite}
.pub:hover .bot .eye{animation:blink 4.4s infinite;transform-origin:center;transform-box:fill-box}
.pub:hover .b2 .bot{animation-delay:-1.6s}
.pub:hover .s-examiner .qbub{animation:travelR 4.6s ease-in-out infinite}
.pub:hover .s-examiner .abub{animation:travelL 4.6s ease-in-out infinite}
.pub:hover .s-examiner .dots{animation:think 4.6s infinite}
.pub:hover .s-examiner .score{animation:stamp 4.6s ease-out infinite}
.pub:hover .s-skill .glass{animation:sweep 5s ease-in-out infinite}
.pub:hover .s-skill .m1{animation:popIn 5s infinite}
.pub:hover .s-skill .m2{animation:popIn 5s infinite;animation-delay:.9s}
.pub:hover .s-skill .m3{animation:popIn 5s infinite;animation-delay:1.8s}
.pub:hover .s-ufeval .ray{animation:drawRay 4.2s ease-out infinite}
.pub:hover .s-ufeval .r2{animation-delay:.12s}
.pub:hover .s-ufeval .r3{animation-delay:.24s}
.pub:hover .s-ufeval .r4{animation-delay:.36s}
.pub:hover .s-ufeval .bar{animation:barGrow 4.2s ease-out infinite}
.pub:hover .s-ufeval .g2 .bar{animation-delay:.12s}
.pub:hover .s-ufeval .g3 .bar{animation-delay:.24s}
.pub:hover .s-ufeval .g4 .bar{animation-delay:.36s}
.pub:hover .s-instructor .loop{animation:orbit 4s linear infinite}
.pub:hover .s-instructor .cross{animation:markOff 4s infinite}
.pub:hover .s-instructor .tick{animation:markOn 4s infinite}
.pub:hover .mui-lens{animation:mui-probe 4.6s ease-in-out infinite}
.pub:hover .mui-n1{animation:mui-p1 4.6s ease-in-out infinite}
.pub:hover .mui-n2{animation:mui-p2 4.6s ease-in-out infinite}
.pub:hover .mui-n3{animation:mui-p3 4.6s ease-in-out infinite}
.pub:hover .mui-b1{animation:mui-bar1 4.6s linear infinite}
.pub:hover .mui-b2{animation:mui-bar2 4.6s linear infinite}
.pub:hover .dual-stem{stroke-dasharray:100 110;animation:dual-stem 4.5s linear infinite}
.pub:hover .dual-fork{stroke-dasharray:100 110;animation:dual-fork 4.5s ease-out infinite}
.pub:hover .dual-ax{stroke-dasharray:100 110;animation:dual-ax 4.5s linear infinite}
.pub:hover .dual-seed{animation:dual-seed 4.5s ease-in-out infinite}
.pub:hover .dual-lab{animation:dual-lab 4.5s ease-in-out infinite}
.pub:hover .dual-q1{animation:dual-q1 4.5s ease-in-out infinite}
.pub:hover .dual-q2{animation:dual-q2 4.5s ease-in-out infinite}
.pub:hover .dual-q3{animation:dual-q3 4.5s ease-in-out infinite}
.pub:hover .dual-q4{animation:dual-q4 4.5s ease-in-out infinite}
.pub:hover .dual-m1{animation:dual-m1 4.5s ease-in-out infinite}
.pub:hover .dual-m2{animation:dual-m2 4.5s ease-in-out infinite}
.pub:hover .dual-m3{animation:dual-m3 4.5s ease-in-out infinite}
.pub:hover .dual-m4{animation:dual-m4 4.5s ease-in-out infinite}
.pub:hover .update-old{animation:update-old 4.6s ease-in-out infinite}
.pub:hover .update-x{stroke-width:2;animation:update-x 4.6s ease-in-out infinite}
.pub:hover .update-arc{stroke-dasharray:90;animation:update-arc 4.6s ease-in-out infinite}
.pub:hover .update-new{animation:update-new 4.6s ease-in-out infinite}
.pub:hover .update-check{stroke-dasharray:12;animation:update-check 4.6s ease-in-out infinite}
.pub:hover .conflict-sway{animation:conflict-sway 4.6s ease-in-out infinite}
.pub:hover .conflict-mem{animation:conflict-mem 4.6s ease-in-out infinite}
.pub:hover .conflict-pmt{animation:conflict-pmt 4.6s ease-in-out infinite}
.pub:hover .conflict-pl{animation:conflict-pl 4.6s ease-in-out infinite}
.pub:hover .conflict-pr{animation:conflict-pr 4.6s ease-in-out infinite}
.pub:hover .ab-doc{animation:ab-doc 4.5s ease-in-out infinite}
.pub:hover .ab-draw{stroke-dasharray:90;animation:ab-draw 4.5s linear infinite}
.pub:hover .ab-pop{animation:ab-pop 4.5s ease-in-out infinite}
.pub:hover .ab-tag{fill:var(--accent-strong);animation:ab-tag 4.5s ease-in-out infinite}

/* 悬停旁白: 与动画同步展开的一句话解说 */
.pub .story {
  font-style: italic; font-size: 0.85rem; line-height: 1.5;
  color: var(--accent-strong);
  max-height: 0; opacity: 0; overflow: hidden;
  margin-top: 0; transform: translateY(4px);
  transition: max-height .45s cubic-bezier(.22,.61,.36,1),
              opacity .35s ease .1s, transform .35s ease .1s, margin-top .45s cubic-bezier(.22,.61,.36,1);
}
.pub .story::before { content: "✳ "; font-style: normal; color: var(--accent); }
.pub:hover .story { max-height: 3.4rem; opacity: 1; transform: none; margin-top: 0.5rem; }

/* 减少动态效果: 场景停用保持配图, 旁白常显不再依赖悬停 */
@media (prefers-reduced-motion: reduce) {
  .pub:hover .thumb img { opacity: 1; }
  .pub:hover .thumb .scene { opacity: 0; }
  .scene, .scene * { animation: none !important; }
  .pub .story { max-height: none; opacity: 1; transform: none; margin-top: 0.5rem; transition: none; }
}

