/* 图示与循环短视频（2026-10 起，全站共用，主会话维护）。
   约定：
   - 图是解释机制的，不作装饰；去掉图，正文也能读通。
   - 纸色底、墨色线；朱色每张图只用在一处重点上。
   - 宽图 .fig-wide 用于桌面；需要竖排的，另画 .fig-tall，并给 figure 加 .fig-has-tall，700px 以下自动换成竖排。
     两张都写 role="img"：宽图带 <title>/<desc>，竖图用 aria-labelledby 引用宽图的这两个 id（隐藏元素也能被引用），读屏软件在手机上也读得到。
   - 一次性动画的「重播」按钮在图框右下角；768px 及以下挪到左下角，免得被右下角悬浮的「动效」开关盖住（视频的「暂停 / 播放」同样）。
     图的底部要留出约 40px 空白，左右两个角都不要放字，免得按钮压住图里的字。
   - 动画只在「动效 · 开」且图进入视口后播放（html.motion-active + .fig.in-view）；
     动效关闭、系统要求减少动态效果、脚本没加载时，元素直接显示最终状态。
   - 循环动画用 .on-screen 控制，离开视口就暂停。
   - 每张图自己的样式写在图里的 <style>，选择器一律以图的 id 开头，例如 #fig-ai-os .ring{…}。 */
/* 插图的色（--fig-paper、--fig-ink……）在 ui.css 第 1 段，昼夜两套（10-26 质感版：原来这里另有一份 :root，盖掉了 ui.css 昼的值，去掉） */
.fig{margin:2.4em 0 2.6em;padding:0}
.fig-frame{position:relative;background:var(--fig-paper);border:1px solid var(--fig-hair);border-radius:var(--r-lg);padding:clamp(14px,2.6vw,30px);overflow:hidden}
.fig-frame.is-bare{background:transparent;border:0;padding:0}
.fig svg{display:block;width:100%;height:auto;overflow:visible}
.fig .fig-wide{display:block}
.fig .fig-tall{display:none}
@media(max-width:700px){.fig.fig-has-tall .fig-wide{display:none}.fig.fig-has-tall .fig-tall{display:block;max-width:440px;margin:0 auto}}
.fig figcaption{margin-top:12px;font-family:var(--sans);font-size:13.5px;line-height:1.8;color:var(--muted);text-wrap:pretty}
.fig figcaption b{font-family:var(--head);font-weight:400;color:var(--fig-ink);margin-right:.7em}
.fig figcaption .fig-note{display:block;margin-top:2px;font-size:12.5px;color:var(--muted)}

/* SVG 里的文字和线条，用 class 取色取字，不在 SVG 里写死颜色 */
.fig .t-title{font-family:var(--head);font-size:24px;fill:var(--fig-ink)}
.fig .t-label{font-family:var(--head);font-size:19px;fill:var(--fig-ink)}
.fig .t-body{font-family:var(--sans);font-size:15px;fill:var(--fig-ink-2)}
.fig .t-note{font-family:var(--sans);font-size:13.5px;fill:var(--fig-ink-2);fill:color-mix(in srgb,var(--fig-muted) 78%,var(--fig-ink))}   /* 注释压在浅褐的框里，--fig-muted 只有 4.0–4.4:1，往墨里收两成（10-26 W2）；不认 color-mix 的用 --fig-ink-2 */
.fig .t-small{font-family:var(--sans);font-size:12px;fill:var(--fig-muted);letter-spacing:.02em}
.fig .t-num{font-family:var(--mono);font-size:15px;fill:var(--fig-muted)}
.fig .t-accent{fill:var(--fig-accent)}
.fig .t-paper{fill:var(--fig-paper)}
.fig .s-ink{stroke:var(--fig-ink);stroke-width:1.6;fill:none;stroke-linecap:round;stroke-linejoin:round}
.fig .s-line{stroke:var(--fig-line);stroke-width:1.2;fill:none;stroke-linecap:round;stroke-linejoin:round}
.fig .s-hair{stroke:var(--fig-hair);stroke-width:1;fill:none}
.fig .s-dash{stroke:var(--fig-line);stroke-width:1.2;fill:none;stroke-dasharray:4 5}
.fig .s-accent{stroke:var(--fig-accent);stroke-width:2;fill:none;stroke-linecap:round;stroke-linejoin:round}
.fig .f-paper{fill:var(--fig-paper)}
.fig .f-paper2{fill:var(--fig-paper-2)}
.fig .f-paper3{fill:var(--fig-paper-3)}
.fig .f-ink{fill:var(--fig-ink)}
.fig .f-accent{fill:var(--fig-accent)}
.fig .f-accent-soft{fill:var(--fig-accent-soft)}

/* 动画开关：元素加 data-anim，按需写 style="--d:400ms" 作为延迟 */
.motion-active .fig-anim:not(.in-view) [data-anim]{opacity:0}
.motion-active .fig-anim.in-view [data-anim="fade"]{animation:fig-fade .7s var(--ease,ease) both;animation-delay:var(--d,0ms)}
.motion-active .fig-anim.in-view [data-anim="rise"]{animation:fig-rise .7s var(--ease,ease) both;animation-delay:var(--d,0ms)}
.motion-active .fig-anim.in-view [data-anim="draw"]{stroke-dasharray:var(--len,600);animation:fig-draw 1.1s var(--ease,ease) both;animation-delay:var(--d,0ms)}
.motion-active .fig-anim.in-view [data-anim="pop"]{transform-box:fill-box;transform-origin:center;animation:fig-pop .55s var(--ease,ease) both;animation-delay:var(--d,0ms)}
@keyframes fig-fade{from{opacity:0}to{opacity:1}}
@keyframes fig-rise{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:none}}
@keyframes fig-draw{from{stroke-dashoffset:var(--len,600);opacity:1}to{stroke-dashoffset:0;opacity:1}}
@keyframes fig-pop{0%{opacity:0;transform:scale(.86)}70%{opacity:1;transform:scale(1.03)}100%{opacity:1;transform:none}}
.fig-anim:not(.on-screen) .is-loop,.fig-anim:not(.on-screen) .is-loop *{animation-play-state:paused!important}
.fig-replay{position:absolute;right:10px;bottom:10px;display:none;align-items:center;gap:6px;padding:4px 10px;border:1px solid var(--fig-hair);border-radius:var(--r-pill);background:rgb(var(--paper-rgb) / .92);font-size:12px;color:var(--muted);cursor:pointer}
.motion-active .fig-anim.in-view .fig-replay{display:inline-flex}
.fig-replay:hover,.fig-replay:focus-visible{color:var(--fig-ink);border-color:var(--fig-line)}

/* 循环短视频：静音、循环、懒加载；动效关闭时只显示封面 */
.fig-video .fig-frame{padding:0;background:var(--fig-paper-2)}
.fig-video video{display:block;width:100%;height:auto;aspect-ratio:var(--ratio,16/9);object-fit:cover;background:var(--fig-paper-2)}
.video-toggle{position:absolute;right:10px;bottom:10px;display:inline-flex;align-items:center;gap:6px;padding:4px 10px;border:1px solid var(--fig-hair);border-radius:var(--r-pill);background:rgb(var(--paper-rgb) / .92);font-size:12px;color:var(--muted);cursor:pointer}
.video-toggle:hover,.video-toggle:focus-visible{color:var(--fig-ink);border-color:var(--fig-line)}
@media(prefers-reduced-motion:reduce){.video-toggle{display:none}}
/* 768px 及以下：「重播」和视频的「暂停 / 播放」放在图框左下角，右下角会被悬浮的「动效」开关盖住 */
@media(max-width:768px){.fig-replay,.video-toggle{right:auto;left:10px}}

/* 放进 .prose / .article-body 等窄栏时，图可以比正文略宽 */
.article-body .fig,.prose .fig{margin-left:0;margin-right:0}
@media(min-width:1100px){.article-body .fig.is-wide{margin-left:-60px;margin-right:-60px}}
@media(prefers-reduced-motion:reduce){.motion-active .fig-anim:not(.in-view) [data-anim]{opacity:1}.fig-replay{display:none!important}}
