Skill: openclawzhangchong/html-ppt-zc (version 1.0.0)

--- name: html_ppt_zc description: 自动生成 PPT（或 HTML 演示） 的技能，接受标题和正文，使用 python-pptx 库快速生成 .pptx 文件，可选导出为 HTML。 metadata: openclaw: emoji: 📊 requires: bins: [python] config: {} --- # Guizang PPT Skill ## 功能概述 - **生成 PPT**：依据提供的标题和文本内容，自动拆分成幻灯片，每段落生成一页，支持标题页、目录页和内容页。 - **可选导出 HTML**：使用内置模板将 PPT 转换为可在浏览器直接展示的 HTML 演示文稿。 - **自定义样式**：可通过可选参数指定配色、字体大小、页眉页脚等基础样式。 ## 环境依赖 - **Python**（系统已安装）。 - **python-pptx** 库：`pip install -U python-pptx`。 - **jinja2**（用于 HTML 导出，可选）：`pip install -U jinja2`。 确保上述库已安装，`python -c "import pptx"` 不会报错即表示可用。 ## 使用方法（Windows CMD / PowerShell） ### 1. 生成 PPT（默认） ```bash python "%USERPROFILE%\.openclaw\workspace\skills\guizang_ppt\generate_ppt.py" \ --title "<演示标题>" \ --text "<每行代表一段落的正文>" \ --output "C:\\Path\\to\\output.pptx" ``` - `--title`：演示标题（将生成封面页）。 - `--text`：多行文字，脚本会按换行拆分为幻灯片内容，每行生成一个要点列表；若段落之间留空行，会产生新幻灯片。 - `--output`：生成的 `.pptx` 文件路径。 ### 2. 导出 HTML 演示 ```bash python "%USERPROFILE%\.openclaw\workspace\skills\guizang_ppt\generate_ppt.py" \ --title "<演示标题>" \ --text "<正文>" \ --output "C:\\Path\\to\\output.html" \ --html ``` 添加 `--html` 参数将把 PPT 转为 HTML（使用简易模板），便于在浏览器直接查看。 ## 常见问题 - **缺少 python-pptx**：运行 `pip install -U python-pptx` 安装。 - **生成的 PPT 打不开**：确保 `--output` 路径所在的文件夹已存在且有写入权限。 - **文本过长**：脚本会自动换行，若单行文字超过幻灯片可容纳宽度，会自动换行为多个要点。 ## 注意事项 - 本技能仅用于个人学习、内部汇报等合法场景，生成的 PPT 如需对外发布，请自行确认内容版权。 - 若需要更高级的动画、模板或图表，请在生成的 PPT 基础上手动编辑。

path: generate_ppt.py
content: #!/usr/bin/env python3

import argparse, os, sys

try:
    from pptx import Presentation
    from pptx.util import Inches, Pt
except ImportError:
    sys.stderr.write('Missing python-pptx library. Install with: pip install -U python-pptx\n')
    sys.exit(1)

def create_ppt(title, paragraphs, output_path):
    prs = Presentation()
    # --- Title slide ---
    title_slide_layout = prs.slide_layouts[0]
    slide = prs.slides.add_slide(title_slide_layout)
    slide.shapes.title.text = title
    # subtitle optional
    if len(paragraphs) > 0:
        try:
            slide.placeholders[1].text = paragraphs[0]
        except Exception:
            pass
    # --- Content slides ---
    bullet_slide_layout = prs.slide_layouts[1]
    for para in paragraphs[1:]:
        if not para.strip():
            continue  # skip empty lines
        slide = prs.slides.add_slide(bullet_slide_layout)
        slide.shapes.title.text = title
        tf = slide.shapes.placeholders[1].text_frame
        for line in para.split('\n'):
            p = tf.add_paragraph()
            p.text = line.strip()
            p.level = 0
            p.font.size = Pt(18)
    prs.save(output_path)
    print(f'PPT saved to {output_path}')

def export_html(title, paragraphs, output_path):
    # simple HTML with each paragraph as a slide div
    html_parts = ["<html><head><meta charset='utf-8'><title>{}</title></head><body>".format(title)]
    for idx, para in enumerate(paragraphs):
        html_parts.append(f"<section style='margin:2em;'><h2>Slide {idx+1}</h2><pre>{para}</pre></section>")
    html_parts.append("</body></html>")
    with open(output_path, 'w', encoding='utf-8') as f:
        f.write('\n'.join(html_parts))
    print(f'HTML slide deck saved to {output_path}')

def main():
    parser = argparse.ArgumentParser(description='Generate PPT or HTML slide deck from plain text')
    parser.add_argument('--title', required=True, help='Presentation title')
    parser.add_argument('--text', required=True, help='Content text. Use "\\n" for line breaks or separate paragraphs with blank lines.')
    parser.add_argument('--output', required=True, help='Output file path (.pptx or .html)')
    parser.add_argument('--html', action='store_true', help='Export as simple HTML instead of PPTX')
    args = parser.parse_args()

    # Split into paragraphs using double line breaks
    paragraphs = [p.strip() for p in args.text.split('\n\n') if p.strip()]
    if args.html:
        export_html(args.title, paragraphs, args.output)
    else:
        # ensure output dir exists
        os.makedirs(os.path.dirname(args.output), exist_ok=True)
        create_ppt(args.title, paragraphs, args.output)

if __name__ == '__main__':
    main()


path: assets/motion.min.js
content: /**
 * Bundled by jsDelivr using Rollup v2.79.2 and Terser v5.39.0.
 * Original file: /npm/motion@11.11.17/dist/es/motion/lib/index.mjs
 *
 * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files
 */
function t(t,e){const n=t.indexOf(e);n>-1&&t.splice(n,1)}class e{constructor(){this.subscriptions=[]}add(e){var n,s;return n=this.subscriptions,s=e,-1===n.indexOf(s)&&n.push(s),()=>t(this.subscriptions,e)}notify(t,e,n){const s=this.subscriptions.length;if(s)if(1===s)this.subscriptions[0](t,e,n);else for(let i=0;i<s;i++){const s=this.subscriptions[i];s&&s(t,e,n)}}getSize(){return this.subscriptions.length}clear(){this.subscriptions.length=0}}function n(t,e){return e?t*(1e3/e):0}const s=!1,i=t=>t;const r=["read","resolveKeyframes","update","preRender","render","postRender"];const{schedule:o,cancel:a,state:l,steps:u}=function(t,e){let n=!1,s=!0;const i={delta:0,timestamp:0,isProcessing:!1},o=()=>n=!0,a=r.reduce(((t,e)=>(t[e]=function(t){let e=new Set,n=new Set,s=!1,i=!1;const r=new WeakSet;let o={delta:0,timestamp:0,isProcessing:!1};function a(e){r.has(e)&&(l.schedule(e),t()),e(o)}const l={schedule:(t,i=!1,o=!1)=>{const a=o&&s?e:n;return i&&r.add(t),a.has(t)||a.add(t),t},cancel:t=>{n.delete(t),r.delete(t)},process:t=>{o=t,s?i=!0:(s=!0,[e,n]=[n,e],n.clear(),e.forEach(a),s=!1,i&&(i=!1,l.process(t)))}};return l}(o),t)),{}),{read:l,resolveKeyframes:u,update:c,preRender:h,render:d,postRender:p}=a,f=()=>{const r=performance.now();n=!1,i.delta=s?1e3/60:Math.max(Math.min(r-i.timestamp,40),1),i.timestamp=r,i.isProcessing=!0,l.process(i),u.process(i),c.process(i),h.process(i),d.process(i),p.process(i),i.isProcessing=!1,n&&e&&(s=!1,t(f))};return{schedule:r.reduce(((e,r)=>{const o=a[r];return e[r]=(e,r=!1,a=!1)=>(n||(n=!0,s=!0,i.isProcessing||t(f)),o.schedule(e,r,a)),e}),{}),cancel:t=>{for(let e=0;e<r.length;e++)a[r[e]].cancel(t)},state:i,steps:a}}("undefined"!=typeof requestAnimationFrame?requestAnimationFrame:i,!0);let c;function h(){c=void 0}const d={now:()=>(void 0===c&&d.set(l.isProcessing||s?l.timestamp:performance.now()),c),set:t=>{c=t,queueMicrotask(h)}};class p{constructor(t,e={}){this.version="11.11.17",this.canTrackVelocity=null,this.events={},this.updateAndNotify=(t,e=!0)=>{const n=d.now();this.updatedAt!==n&&this.setPrevFrameValue(),this.prev=this.current,this.setCurrent(t),this.current!==this.prev&&this.events.change&&this.events.change.notify(this.current),e&&this.events.renderRequest&&this.events.renderRequest.notify(this.current)},this.hasAnimated=!1,this.setCurrent(t),this.owner=e.owner}setCurrent(t){var e;this.current=t,this.updatedAt=d.now(),null===this.canTrackVelocity&&void 0!==t&&(this.canTrackVelocity=(e=this.current,!isNaN(parseFloat(e))))}setPrevFrameValue(t=this.current){this.prevFrameValue=t,this.prevUpdatedAt=this.updatedAt}onChange(t){return this.on("change",t)}on(t,n){this.events[t]||(this.events[t]=new e);const s=this.events[t].add(n);return"change"===t?()=>{s(),o.read((()=>{this.events.change.getSize()||this.stop()}))}:s}clearListeners(){for(const t in this.events)this.events[t].clear()}attach(t,e){this.passiveEffect=t,this.stopPassiveEffect=e}set(t,e=!0){e&&this.passiveEffect?this.passiveEffect(t,this.updateAndNotify):this.updateAndNotify(t,e)}setWithVelocity(t,e,n){this.set(e),this.prev=void 0,this.prevFrameValue=t,this.prevUpdatedAt=this.updatedAt-n}jump(t,e=!0){this.updateAndNotify(t),this.prev=t,this.prevUpdatedAt=this.prevFrameValue=void 0,e&&this.stop(),this.stopPassiveEffect&&this.stopPassiveEffect()}get(){return this.current}getPrevious(){return this.prev}getVelocity(){const t=d.now();if(!this.canTrackVelocity||void 0===this.prevFrameValue||t-this.updatedAt>30)return 0;const e=Math.min(this.updatedAt-this.prevUpdatedAt,30);return n(parseFloat(this.current)-parseFloat(this.prevFrameValue),e)}start(t){return this.stop(),new Promise((e=>{this.hasAnimated=!0,this.animation=t(e),this.events.animationStart&&this.events.animationStart.notify()})).then((()=>{this.events.animationComplete&&this.events.animationComplete.notify(),this.clearAnimation()}))}stop(){this.animation&&(this.animation.stop(),this.events.animationCancel&&this.events.animationCancel.notify()),this.clearAnimation()}isAnimating(){return!!this.animation}clearAnimation(){delete this.animation}destroy(){this.clearListeners(),this.stop(),this.stopPassiveEffect&&this.stopPassiveEffect()}}function f(t,e){return new p(t,e)}function m(t){let e;return()=>(void 0===e&&(e=t()),e)}const g=m((()=>void 0!==window.ScrollTimeline));class y{constructor(t){this.stop=()=>this.runAll("stop"),this.animations=t.filter(Boolean)}then(t,e){return Promise.all(this.animations).then(t).catch(e)}getAll(t){return this.animations[0][t]}setAll(t,e){for(let n=0;n<this.animations.length;n++)this.animations[n][t]=e}attachTimeline(t,e){const n=this.animations.map((n=>g()&&n.attachTimeline?n.attachTimeline(t):e(n)));return()=>{n.forEach(((t,e)=>{t&&t(),this.animations[e].stop()}))}}get time(){return this.getAll("time")}set time(t){this.setAll("time",t)}get speed(){return this.getAll("speed")}set speed(t){this.setAll("speed",t)}get startTime(){return this.getAll("startTime")}get duration(){let t=0;for(let e=0;e<this.animations.length;e++)t=Math.max(t,this.animations[e].duration);return t}runAll(t){this.animations.forEach((e=>e[t]()))}flatten(){this.runAll("flatten")}play(){this.runAll("play")}pause(){this.runAll("pause")}cancel(){this.runAll("cancel")}complete(){this.runAll("complete")}}const v=t=>1e3*t,w=t=>t/1e3;function b(t,e,s){const i=Math.max(e-5,0);return n(s-t(i),e-i)}let T=i,x=i;const S=(t,e,n)=>n>e?e:n<t?t:n,V=.001;function A({duration:t=800,bounce:e=.25,velocity:n=0,mass:s=1}){let i,r,o=1-e;o=S(.05,1,o),t=S(.01,10,w(t)),o<1?(i=e=>{const s=e*o,i=s*t,r=s-n,a=P(e,o),l=Math.exp(-i);return V-r/a*l},r=e=>{const s=e*o*t,r=s*n+n,a=Math.pow(o,2)*Math.pow(e,2)*t,l=Math.exp(-s),u=P(Math.pow(e,2),o);return(-i(e)+V>0?-1:1)*((r-a)*l)/u}):(i=e=>Math.exp(-e*t)*((e-n)*t+1)-.001,r=e=>Math.exp(-e*t)*(t*t*(n-e)));const a=function(t,e,n){let s=n;for(let n=1;n<M;n++)s-=t(s)/e(s);return s}(i,r,5/t);if(t=v(t),isNaN(a))return{stiffness:100,damping:10,duration:t};{const e=Math.pow(a,2)*s;return{stiffness:e,damping:2*o*Math.sqrt(s*e),duration:t}}}const M=12;function P(t,e){return t*Math.sqrt(1-e*e)}const k=["duration","bounce"],F=["stiffness","damping","mass"];function C(t,e){return e.some((e=>void 0!==t[e]))}function E({keyframes:t,restDelta:e,restSpeed:n,...s}){const i=t[0],r=t[t.length-1],o={done:!1,value:i},{stiffness:a,damping:l,mass:u,duration:c,velocity:h,isResolvedFromDuration:d}=function(t){let e={velocity:0,stiffness:100,damping:10,mass:1,isResolvedFromDuration:!1,...t};if(!C(t,F)&&C(t,k)){const n=A(t);e={...e,...n,mass:1},e.isResolvedFromDuration=!0}return e}({...s,velocity:-w(s.velocity||0)}),p=h||0,f=l/(2*Math.sqrt(a*u)),m=r-i,g=w(Math.sqrt(a/u)),y=Math.abs(m)<5;let T;if(n||(n=y?.01:2),e||(e=y?.005:.5),f<1){const t=P(g,f);T=e=>{const n=Math.exp(-f*g*e);return r-n*((p+f*g*m)/t*Math.sin(t*e)+m*Math.cos(t*e))}}else if(1===f)T=t=>r-Math.exp(-g*t)*(m+(p+g*m)*t);else{const t=g*Math.sqrt(f*f-1);T=e=>{const n=Math.exp(-f*g*e),s=Math.min(t*e,300);return r-n*((p+f*g*m)*Math.sinh(s)+t*m*Math.cosh(s))/t}}return{calculatedDuration:d&&c||null,next:t=>{const s=T(t);if(d)o.done=t>=c;else{let i=0;f<1&&(i=0===t?v(p):b(T,t,s));const a=Math.abs(i)<=n,l=Math.abs(r-s)<=e;o.done=a&&l}return o.value=o.done?r:s,o}}}const O=2e4;function R(t){let e=0;let n=t.next(e);for(;!n.done&&e<O;)e+=50,n=t.next(e);return e>=O?1/0:e}function B(t,e=100,n){const s=n({...t,keyframes:[0,e]}),i=Math.min(R(s),O);return{type:"keyframes",ease:t=>s.next(i*t).value/e,duration:w(i)}}const I=(t,e,n)=>t+(e-t)*n,L=(t,e,n)=>{const s=e-t;return 0===s?1:(n-t)/s};function W(t,e){const n=t[t.length-1];for(let s=1;s<=e;s++){const i=L(0,e,s);t.push(I(n,1,i))}}function D(t){const e=[0];return W(e,t.length-1),e}const N=t=>Boolean(t&&t.getVelocity);function K(t,e,n){var s;if("string"==typeof t){let i=document;e&&(x(Boolean(e.current)),i=e.current),n?(null!==(s=n[t])&&void 0!==s||(n[t]=i.querySelectorAll(t)),t=n[t]):t=i.querySelectorAll(t)}else t instanceof Element&&(t=[t]);return Array.from(t||[])}function $(t){return"object"==typeof t&&!Array.isArray(t)}function j(t,e,n,s){return"string"==typeof t&&$(e)?K(t,n,s):t instanceof NodeList?Array.from(t):Array.isArray(t)?t:[t]}function z(t){return"function"==typeof t}function H(t,e,n,s){var i;return"number"==typeof e?e:e.startsWith("-")||e.startsWith("+")?Math.max(0,t+parseFloat(e)):"<"===e?n:null!==(i=s.get(e))&&void 0!==i?i:t}const U=(t,e,n)=>{const s=e-t;return((n-t)%s+s)%s+t},Y=t=>Array.isArray(t)&&"number"!=typeof t[0];function q(t,e){return Y(t)?t[U(0,t.length,e)]:t}function X(e,n,s,i,r,o){!function(e,n,s){for(let i=0;i<e.length;i++){const r=e[i];r.at>n&&r.at<s&&(t(e,r),i--)}}(e,r,o);for(let t=0;t<n.length;t++)e.push({value:n[t],at:I(r,o,i[t]),easing:q(s,t)})}function G(t,e){return t.at===e.at?null===t.value?1:null===e.value?-1:0:t.at-e.at}function Z(t,e){return!e.has(t)&&e.set(t,{}),e.get(t)}function _(t,e){return e[t]||(e[t]=[]),e[t]}function J(t){return Array.isArray(t)?t:[t]}function Q(t,e){return t&&t[e]?{...t,...t[e]}:{...t}}const tt=t=>"number"==typeof t,et=t=>t.every(tt),nt=new WeakMap,st=["transformPerspective","x","y","z","translateX","translateY","translateZ","scale","scaleX","scaleY","rotate","rotateX","rotateY","rotateZ","skew","skewX","skewY"],it=new Set(st),rt={type:"spring",stiffness:500,damping:25,restSpeed:10},ot={type:"keyframes",duration:.8},at={type:"keyframes",ease:[.25,.1,.35,1],duration:.3},lt=(t,{keyframes:e})=>e.length>2?ot:it.has(t)?t.startsWith("scale")?{type:"spring",stiffness:550,damping:0===e[1]?2*Math.sqrt(550):30,restSpeed:10}:rt:at;function ut(t,e){return t?t[e]||t.default||t:void 0}const ct=t=>null!==t;function ht(t,{repeat:e,repeatType:n="loop"},s){const i=t.filter(ct),r=e&&"loop"!==n&&e%2==1?0:i.length-1;return r&&void 0!==s?s:i[r]}const dt=(t,e,n)=>(((1-3*n+3*e)*t+(3*n-6*e))*t+3*e)*t;function pt(t,e,n,s){if(t===e&&n===s)return i;const r=e=>function(t,e,n,s,i){let r,o,a=0;do{o=e+(n-e)/2,r=dt(o,s,i)-t,r>0?n=o:e=o}while(Math.abs(r)>1e-7&&++a<12);return o}(e,0,1,t,n);return t=>0===t||1===t?t:dt(r(t),e,s)}const ft=t=>e=>e<=.5?t(2*e)/2:(2-t(2*(1-e)))/2,mt=t=>e=>1-t(1-e),gt=pt(.33,1.53,.69,.99),yt=mt(gt),vt=ft(yt),wt=t=>(t*=2)<1?.5*yt(t):.5*(2-Math.pow(2,-10*(t-1))),bt=t=>1-Math.sin(Math.acos(t)),Tt=mt(bt),xt=ft(bt),St=t=>/^0[^.\s]+$/u.test(t);const Vt=t=>/^-?(?:\d+(?:\.\d+)?|\.\d+)$/u.test(t),At=t=>e=>"string"==typeof e&&e.startsWith(t),Mt=At("--"),Pt=At("var(--"),kt=t=>!!Pt(t)&&Ft.test(t.split("/*")[0].trim()),Ft=/var\(--(?:[\w-]+\s*|[\w-]+\s*,(?:\s*[^)(\s]|\s*\((?:[^)(]|\([^)(]*\))*\))+\s*)\)$/iu,Ct=/^var\(--(?:([\w-]+)|([\w-]+), ?([a-zA-Z\d ()%#.,-]+))\)/u;function Et(t,e,n=1){const[s,i]=function(t){const e=Ct.exec(t);if(!e)return[,];const[,n,s,i]=e;return[`--${null!=n?n:s}`,i]}(t);if(!s)return;const r=window.getComputedStyle(e).getPropertyValue(s);if(r){const t=r.trim();return Vt(t)?parseFloat(t):t}return kt(i)?Et(i,e,n+1):i}const Ot={test:t=>"number"==typeof t,parse:parseFloat,transform:t=>t},Rt={...Ot,transform:t=>S(0,1,t)},Bt={...Ot,default:1},It=t=>({test:e=>"string"==typeof e&&e.endsWith(t)&&1===e.split(" ").length,parse:parseFloat,transform:e=>`${e}${t}`}),Lt=It("deg"),Wt=It("%"),Dt=It("px"),Nt=It("vh"),Kt=It("vw"),$t={...Wt,parse:t=>Wt.parse(t)/100,transform:t=>Wt.transform(100*t)},jt=new Set(["width","height","top","left","right","bottom","x","y","translateX","translateY"]),zt=t=>t===Ot||t===Dt,Ht=(t,e)=>parseFloat(t.split(", ")[e]),Ut=(t,e)=>(n,{transform:s})=>{if("none"===s||!s)return 0;const i=s.match(/^matrix3d\((.+)\)$/u);if(i)return Ht(i[1],e);{const e=s.match(/^matrix\((.+)\)$/u);return e?Ht(e[1],t):0}},Yt=new Set(["x","y","z"]),qt=st.filter((t=>!Yt.has(t)));const Xt={width:({x:t},{paddingLeft:e="0",paddingRight:n="0"})=>t.max-t.min-parseFloat(e)-parseFloat(n),height:({y:t},{paddingTop:e="0",paddingBottom:n="0"})=>t.max-t.min-parseFloat(e)-parseFloat(n),top:(t,{top:e})=>parseFloat(e),left:(t,{left:e})=>parseFloat(e),bottom:({y:t},{top:e})=>parseFloat(e)+(t.max-t.min),right:({x:t},{left:e})=>parseFloat(e)+(t.max-t.min),x:Ut(4,13),y:Ut(5,14)};Xt.translateX=Xt.x,Xt.translateY=Xt.y;const Gt=t=>e=>e.test(t),Zt=[Ot,Dt,Wt,Lt,Kt,Nt,{test:t=>"auto"===t,parse:t=>t}],_t=t=>Zt.find(Gt(t)),Jt=new Set;let Qt=!1,te=!1;function ee(){if(te){const t=Array.from(Jt).filter((t=>t.needsMeasurement)),e=new Set(t.map((t=>t.element))),n=new Map;e.forEach((t=>{const e=function(t){const e=[];return qt.forEach((n=>{const s=t.getValue(n);void 0!==s&&(e.push([n,s.get()]),s.set(n.startsWith("scale")?1:0))})),e}(t);e.length&&(n.set(t,e),t.render())})),t.forEach((t=>t.measureInitialState())),e.forEach((t=>{t.render();const e=n.get(t);e&&e.forEach((([e,n])=>{var s;null===(s=t.getValue(e))||void 0===s||s.set(n)}))})),t.forEach((t=>t.measureEndState())),t.forEach((t=>{void 0!==t.suspendedScrollY&&window.scrollTo(0,t.suspendedScrollY)}))}te=!1,Qt=!1,Jt.forEach((t=>t.complete())),Jt.clear()}function ne(){Jt.forEach((t=>{t.readKeyframes(),t.needsMeasurement&&(te=!0)}))}class se{constructor(t,e,n,s,i,r=!1){this.isComplete=!1,this.isAsync=!1,this.needsMeasurement=!1,this.isScheduled=!1,this.unresolvedKeyframes=[...t],this.onComplete=e,this.name=n,this.motionValue=s,this.element=i,this.isAsync=r}scheduleResolve(){this.isScheduled=!0,this.isAsync?(Jt.add(this),Qt||(Qt=!0,o.read(ne),o.resolveKeyframes(ee))):(this.readKeyframes(),this.complete())}readKeyframes(){const{unresolvedKeyframes:t,name:e,element:n,motionValue:s}=this;for(let i=0;i<t.length;i++)if(null===t[i])if(0===i){const i=null==s?void 0:s.get(),r=t[t.length-1];if(void 0!==i)t[0]=i;else if(n&&e){const s=n.readValue(e,r);null!=s&&(t[0]=s)}void 0===t[0]&&(t[0]=r),s&&void 0===i&&s.set(t[0])}else t[i]=t[i-1]}setFinalKeyframe(){}measureInitialState(){}renderEndStyles(){}measureEndState(){}complete(){this.isComplete=!0,this.onComplete(this.unresolvedKeyframes,this.finalKeyframe),Jt.delete(this)}cancel(){this.isComplete||(this.isScheduled=!1,Jt.delete(this))}resume(){this.isComplete||this.scheduleResolve()}}const ie=t=>Math.round(1e5*t)/1e5,re=/-?(?:\d+(?:\.\d+)?|\.\d+)/gu;const oe=/^(?:#[\da-f]{3,8}|(?:rgb|hsl)a?\((?:-?[\d.]+%?[,\s]+){2}-?[\d.]+%?\s*(?:[,/]\s*)?(?:\b\d+(?:\.\d+)?|\.\d+)?%?\))$/iu,ae=(t,e)=>n=>Boolean("string"==typeof n&&oe.test(n)&&n.startsWith(t)||e&&!function(t){return null==t}(n)&&Object.prototype.hasOwnProperty.call(n,e)),le=(t,e,n)=>s=>{if("string"!=typeof s)return s;const[i,r,o,a]=s.match(re);return{[t]:parseFloat(i),[e]:parseFloat(r),[n]:parseFloat(o),alpha:void 0!==a?parseFloat(a):1}},ue={...Ot,transform:t=>Math.round((t=>S(0,255,t))(t))},ce={test:ae("rgb","red"),parse:le("red","green","blue"),transform:({red:t,green:e,blue:n,alpha:s=1})=>"rgba("+ue.transform(t)+", "+ue.transform(e)+", "+ue.transform(n)+", "+ie(Rt.transform(s))+")"};const he={test:ae("#"),parse:function(t){let e="",n="",s="",i="";return t.length>5?(e=t.substring(1,3),n=t.substring(3,5),s=t.substring(5,7),i=t.substring(7,9)):(e=t.substring(1,2),n=t.substring(2,3),s=t.substring(3,4),i=t.substring(4,5),e+=e,n+=n,s+=s,i+=i),{red:parseInt(e,16),green:parseInt(n,16),blue:parseInt(s,16),alpha:i?parseInt(i,16)/255:1}},transform:ce.transform},de={test:ae("hsl","hue"),parse:le("hue","saturation","lightness"),transform:({hue:t,saturation:e,lightness:n,alpha:s=1})=>"hsla("+Math.round(t)+", "+Wt.transform(ie(e))+", "+Wt.transform(ie(n))+", "+ie(Rt.transform(s))+")"},pe={test:t=>ce.test(t)||he.test(t)||de.test(t),parse:t=>ce.test(t)?ce.parse(t):de.test(t)?de.parse(t):he.parse(t),transform:t=>"string"==typeof t?t:t.hasOwnProperty("red")?ce.transform(t):de.transform(t)},fe=/(?:#[\da-f]{3,8}|(?:rgb|hsl)a?\((?:-?[\d.]+%?[,\s]+){2}-?[\d.]+%?\s*(?:[,/]\s*)?(?:\b\d+(?:\.\d+)?|\.\d+)?%?\))/giu;const me="number",ge="color",ye=/var\s*\(\s*--(?:[\w-]+\s*|[\w-]+\s*,(?:\s*[^)(\s]|\s*\((?:[^)(]|\([^)(]*\))*\))+\s*)\)|#[\da-f]{3,8}|(?:rgb|hsl)a?\((?:-?[\d.]+%?[,\s]+){2}-?[\d.]+%?\s*(?:[,/]\s*)?(?:\b\d+(?:\.\d+)?|\.\d+)?%?\)|-?(?:\d+(?:\.\d+)?|\.\d+)/giu;function ve(t){const e=t.toString(),n=[],s={color:[],number:[],var:[]},i=[];let r=0;const o=e.replace(ye,(t=>(pe.test(t)?(s.color.push(r),i.push(ge),n.push(pe.parse(t))):t.startsWith("var(")?(s.var.push(r),i.push("var"),n.push(t)):(s.number.push(r),i.push(me),n.push(parseFloat(t))),++r,"${}"))).split("${}");return{values:n,split:o,indexes:s,types:i}}function we(t){return ve(t).values}function be(t){const{split:e,types:n}=ve(t),s=e.length;return t=>{let i="";for(let r=0;r<s;r++)if(i+=e[r],void 0!==t[r]){const e=n[r];i+=e===me?ie(t[r]):e===ge?pe.transform(t[r]):t[r]}return i}}const Te=t=>"number"==typeof t?0:t;const xe={test:function(t){var e,n;return isNaN(t)&&"string"==typeof t&&((null===(e=t.match(re))||void 0===e?void 0:e.length)||0)+((null===(n=t.match(fe))||void 0===n?void 0:n.length)||0)>0},parse:we,createTransformer:be,getAnimatableNone:function(t){const e=we(t);return be(t)(e.map(Te))}},Se=new Set(["brightness","contrast","saturate","opacity"]);function Ve(t){const[e,n]=t.slice(0,-1).split("(");if("drop-shadow"===e)return t;const[s]=n.match(re)||[];if(!s)return t;const i=n.replace(s,"");let r=Se.has(e)?1:0;return s!==n&&(r*=100),e+"("+r+i+")"}const Ae=/\b([a-z-]*)\(.*?\)/gu,Me={...xe,getAnimatableNone:t=>{const e=t.match(Ae);return e?e.map(Ve).join(" "):t}},Pe={borderWidth:Dt,borderTopWidth:Dt,borderRightWidth:Dt,borderBottomWidth:Dt,borderLeftWidth:Dt,borderRadius:Dt,radius:Dt,borderTopLeftRadius:Dt,borderTopRightRadius:Dt,borderBottomRightRadius:Dt,borderBottomLeftRadius:Dt,width:Dt,maxWidth:Dt,height:Dt,maxHeight:Dt,top:Dt,right:Dt,bottom:Dt,left:Dt,padding:Dt,paddingTop:Dt,paddingRight:Dt,paddingBottom:Dt,paddingLeft:Dt,margin:Dt,marginTop:Dt,marginRight:Dt,marginBottom:Dt,marginLeft:Dt,backgroundPositionX:Dt,backgroundPositionY:Dt},ke={rotate:Lt,rotateX:Lt,rotateY:Lt,rotateZ:Lt,scale:Bt,scaleX:Bt,scaleY:Bt,scaleZ:Bt,skew:Lt,skewX:Lt,skewY:Lt,distance:Dt,translateX:Dt,translateY:Dt,translateZ:Dt,x:Dt,y:Dt,z:Dt,perspective:Dt,transformPerspective:Dt,opacity:Rt,originX:$t,originY:$t,originZ:Dt},Fe={...Ot,transform:Math.round},Ce={...Pe,...ke,zIndex:Fe,size:Dt,fillOpacity:Rt,strokeOpacity:Rt,numOctaves:Fe},Ee={...Ce,color:pe,backgroundColor:pe,outlineColor:pe,fill:pe,stroke:pe,borderColor:pe,borderTopColor:pe,borderRightColor:pe,borderBottomColor:pe,borderLeftColor:pe,filter:Me,WebkitFilter:Me},Oe=t=>Ee[t];function Re(t,e){let n=Oe(t);return n!==Me&&(n=xe),n.getAnimatableNone?n.getAnimatableNone(e):void 0}const Be=new Set(["auto","none","0"]);class Ie extends se{constructor(t,e,n,s,i){super(t,e,n,s,i,!0)}readKeyframes(){const{unresolvedKeyframes:t,element:e,name:n}=this;if(!e||!e.current)return;super.readKeyframes();for(let n=0;n<t.length;n++){let s=t[n];if("string"==typeof s&&(s=s.trim(),kt(s))){const i=Et(s,e.current);void 0!==i&&(t[n]=i),n===t.length-1&&(this.finalKeyframe=s)}}if(this.resolveNoneKeyframes(),!jt.has(n)||2!==t.length)return;const[s,i]=t,r=_t(s),o=_t(i);if(r!==o)if(zt(r)&&zt(o))for(let e=0;e<t.length;e++){const n=t[e];"string"==typeof n&&(t[e]=parseFloat(n))}else this.needsMeasurement=!0}resolveNoneKeyframes(){const{unresolvedKeyframes:t,name:e}=this,n=[];for(let e=0;e<t.length;e++)("number"==typeof(s=t[e])?0===s:null===s||"none"===s||"0"===s||St(s))&&n.push(e);var s;n.length&&function(t,e,n){let s,i=0;for(;i<t.length&&!s;){const e=t[i];"string"==typeof e&&!Be.has(e)&&ve(e).values.length&&(s=t[i]),i++}if(s&&n)for(const i of e)t[i]=Re(n,s)}(t,n,e)}measureInitialState(){const{element:t,unresolvedKeyframes:e,name:n}=this;if(!t||!t.current)return;"height"===n&&(this.suspendedScrollY=window.pageYOffset),this.measuredOrigin=Xt[n](t.measureViewportBox(),window.getComputedStyle(t.current)),e[0]=this.measuredOrigin;const s=e[e.length-1];void 0!==s&&t.getValue(n,s).jump(s,!1)}measureEndState(){var t;const{element:e,name:n,unresolvedKeyframes:s}=this;if(!e||!e.current)return;const i=e.getValue(n);i&&i.jump(this.measuredOrigin,!1);const r=s.length-1,o=s[r];s[r]=Xt[n](e.measureViewportBox(),window.getComputedStyle(e.current)),null!==o&&void 0===this.finalKeyframe&&(this.finalKeyframe=o),(null===(t=this.removedTransforms)||void 0===t?void 0:t.length)&&this.removedTransforms.forEach((([t,n])=>{e.getValue(t).set(n)})),this.resolveNoneKeyframes()}}const Le=(t,e)=>"zIndex"!==e&&(!("number"!=typeof t&&!Array.isArray(t))||!("string"!=typeof t||!xe.test(t)&&"0"!==t||t.startsWith("url(")));function We(t,e,n,s){const i=t[0];if(null===i)return!1;if("display"===e||"visibility"===e)return!0;const r=t[t.length-1],o=Le(i,e),a=Le(r,e);return!(!o||!a)&&(function(t){const e=t[0];if(1===t.length)return!0;for(let n=0;n<t.length;n++)if(t[n]!==e)return!0}(t)||("spring"===n||z(n))&&s)}class De{constructor({autoplay:t=!0,delay:e=0,type:n="keyframes",repeat:s=0,repeatDelay:i=0,repeatType:r="loop",...o}){this.isStopped=!1,this.hasAttemptedResolve=!1,this.createdAt=d.now(),this.options={autoplay:t,delay:e,type:n,repeat:s,repeatDelay:i,repeatType:r,...o},this.updateFinishedPromise()}calcStartTime(){return this.resolvedAt&&this.resolvedAt-this.createdAt>40?this.resolvedAt:this.createdAt}get resolved(){return this._resolved||this.hasAttemptedResolve||(ne(),ee()),this._resolved}onKeyframesResolved(t,e){this.resolvedAt=d.now(),this.hasAttemptedResolve=!0;const{name:n,type:s,velocity:i,delay:r,onComplete:o,onUpdate:a,isGenerator:l}=this.options;if(!l&&!We(t,n,s,i)){if(!r)return null==a||a(ht(t,this.options,e)),null==o||o(),void this.resolveFinishedPromise();this.options.duration=0}const u=this.initPlayback(t,e);!1!==u&&(this._resolved={keyframes:t,finalKeyframe:e,...u},this.onPostResolved())}onPostResolved(){}then(t,e){return this.currentFinishedPromise.then(t,e)}flatten(){this.options.type="keyframes",this.options.ease="linear"}updateFinishedPromise(){this.currentFinishedPromise=new Promise((t=>{this.resolveFinishedPromise=t}))}}function Ne({keyframes:t,velocity:e=0,power:n=.8,timeConstant:s=325,bounceDamping:i=10,bounceStiffness:r=500,modifyTarget:o,min:a,max:l,restDelta:u=.5,restSpeed:c}){const h=t[0],d={done:!1,value:h},p=t=>void 0===a?l:void 0===l||Math.abs(a-t)<Math.abs(l-t)?a:l;let f=n*e;const m=h+f,g=void 0===o?m:o(m);g!==m&&(f=g-h);const y=t=>-f*Math.exp(-t/s),v=t=>g+y(t),w=t=>{const e=y(t),n=v(t);d.done=Math.abs(e)<=u,d.value=d.done?g:n};let T,x;const S=t=>{var e;(e=d.value,void 0!==a&&e<a||void 0!==l&&e>l)&&(T=t,x=E({keyframes:[d.value,p(d.value)],velocity:b(v,t,d.value),damping:i,stiffness:r,restDelta:u,restSpeed:c}))};return S(0),{calculatedDuration:null,next:t=>{let e=!1;return x||void 0!==T||(e=!0,w(t),S(t)),void 0!==T&&t>=T?x.next(t-T):(!e&&w(t),d)}}}const Ke=pt(.42,0,1,1),$e=pt(0,0,.58,1),je=pt(.42,0,.58,1),ze=t=>Array.isArray(t)&&"number"==typeof t[0],He={linear:i,easeIn:Ke,easeInOut:je,easeOut:$e,circIn:bt,circInOut:xt,circOut:Tt,backIn:yt,backInOut:vt,backOut:gt,anticipate:wt},Ue=t=>{if(ze(t)){x(4===t.length);const[e,n,s,i]=t;return pt(e,n,s,i)}return"string"==typeof t?He[t]:t},Ye=(t,e)=>n=>e(t(n)),qe=(...t)=>t.reduce(Ye);function Xe(t,e,n){return n<0&&(n+=1),n>1&&(n-=1),n<1/6?t+6*(e-t)*n:n<.5?e:n<2/3?t+(e-t)*(2/3-n)*6:t}function Ge(t,e){return n=>n>0?e:t}const Ze=(t,e,n)=>{const s=t*t,i=n*(e*e-s)+s;return i<0?0:Math.sqrt(i)},_e=[he,ce,de];function Je(t){const e=(n=t,_e.find((t=>t.test(n))));var n;if(!Boolean(e))return!1;let s=e.parse(t);return e===de&&(s=function({hue:t,saturation:e,lightness:n,alpha:s}){t/=360,n/=100;let i=0,r=0,o=0;if(e/=100){const s=n<.5?n*(1+e):n+e-n*e,a=2*n-s;i=Xe(a,s,t+1/3),r=Xe(a,s,t),o=Xe(a,s,t-1/3)}else i=r=o=n;return{red:Math.round(255*i),green:Math.round(255*r),blue:Math.round(255*o),alpha:s}}(s)),s}const Qe=(t,e)=>{const n=Je(t),s=Je(e);if(!n||!s)return Ge(t,e);const i={...n};return t=>(i.red=Ze(n.red,s.red,t),i.green=Ze(n.green,s.green,t),i.blue=Ze(n.blue,s.blue,t),i.alpha=I(n.alpha,s.alpha,t),ce.transform(i))},tn=new Set(["none","hidden"]);function en(t,e){return n=>I(t,e,n)}function nn(t){return"number"==typeof t?en:"string"==typeof t?kt(t)?Ge:pe.test(t)?Qe:on:Array.isArray(t)?sn:"object"==typeof t?pe.test(t)?Qe:rn:Ge}function sn(t,e){const n=[...t],s=n.length,i=t.map(((t,n)=>nn(t)(t,e[n])));return t=>{for(let e=0;e<s;e++)n[e]=i[e](t);return n}}function rn(t,e){const n={...t,...e},s={};for(const i in n)void 0!==t[i]&&void 0!==e[i]&&(s[i]=nn(t[i])(t[i],e[i]));return t=>{for(const e in s)n[e]=s[e](t);return n}}const on=(t,e)=>{const n=xe.createTransformer(e),s=ve(t),i=ve(e);return s.indexes.var.length===i.indexes.var.length&&s.indexes.color.length===i.indexes.color.length&&s.indexes.number.length>=i.indexes.number.length?tn.has(t)&&!i.values.length||tn.has(e)&&!s.values.length?function(t,e){return tn.has(t)?n=>n<=0?t:e:n=>n>=1?e:t}(t,e):qe(sn(function(t,e){var n;const s=[],i={color:0,var:0,number:0};for(let r=0;r<e.values.length;r++){const o=e.types[r],a=t.indexes[o][i[o]],l=null!==(n=t.values[a])&&void 0!==n?n:0;s[r]=l,i[o]++}return s}(s,i),i.values),n):Ge(t,e)};function an(t,e,n){if("number"==typeof t&&"number"==typeof e&&"number"==typeof n)return I(t,e,n);return nn(t)(t,e)}function ln(t,e,{clamp:n=!0,ease:s,mixer:r}={}){const o=t.length;if(x(o===e.length),1===o)return()=>e[0];if(2===o&&t[0]===t[1])return()=>e[1];t[0]>t[o-1]&&(t=[...t].reverse(),e=[...e].reverse());const a=function(t,e,n){const s=[],r=n||an,o=t.length-1;for(let n=0;n<o;n++){let o=r(t[n],t[n+1]);if(e){const t=Array.isArray(e)?e[n]||i:e;o=qe(t,o)}s.push(o)}return s}(e,s,r),l=a.length,u=e=>{let n=0;if(l>1)for(;n<t.length-2&&!(e<t[n+1]);n++);const s=L(t[n],t[n+1],e);return a[n](s)};return n?e=>u(S(t[0],t[o-1],e)):u}function un({duration:t=300,keyframes:e,times:n,ease:s="easeInOut"}){const i=Y(s)?s.map(Ue):Ue(s),r={done:!1,value:e[0]},o=function(t,e){return t.map((t=>t*e))}(n&&n.length===e.length?n:D(e),t),a=ln(o,e,{ease:Array.isArray(i)?i:(l=e,u=i,l.map((()=>u||je)).splice(0,l.length-1))});var l,u;return{calculatedDuration:t,next:e=>(r.value=a(e),r.done=e>=t,r)}}const cn=t=>{const e=({timestamp:e})=>t(e);return{start:()=>o.update(e,!0),stop:()=>a(e),now:()=>l.isProcessing?l.timestamp:d.now()}},hn={decay:Ne,inertia:Ne,tween:un,keyframes:un,spring:E},dn=t=>t/100;class pn extends De{constructor(t){super(t),this.holdTime=null,this.cancelTime=null,this.currentTime=0,this.playbackSpeed=1,this.pendingPlayState="running",this.startTime=null,this.state="idle",this.stop=()=>{if(this.resolver.cancel(),this.isStopped=!0,"idle"===this.state)return;this.teardown();const{onStop:t}=this.options;t&&t()};const{name:e,motionValue:n,element:s,keyframes:i}=this.options,r=(null==s?void 0:s.KeyframeResolver)||se;this.resolver=new r(i,((t,e)=>this.onKeyframesResolved(t,e)),e,n,s),this.resolver.scheduleResolve()}flatten(){super.flatten(),this._resolved&&Object.assign(this._resolved,this.initPlayback(this._resolved.keyframes))}initPlayback(t){const{type:e="keyframes",repeat:n=0,repeatDelay:s=0,repeatType:i,velocity:r=0}=this.options,o=z(e)?e:hn[e]||un;let a,l;o!==un&&"number"!=typeof t[0]&&(a=qe(dn,an(t[0],t[1])),t=[0,100]);const u=o({...this.options,keyframes:t});"mirror"===i&&(l=o({...this.options,keyframes:[...t].reverse(),velocity:-r})),null===u.calculatedDuration&&(u.calculatedDuration=R(u));const{calculatedDuration:c}=u,h=c+s;return{generator:u,mirroredGenerator:l,mapPercentToKeyframes:a,calculatedDuration:c,resolvedDuration:h,totalDuration:h*(n+1)-s}}onPostResolved(){const{autoplay:t=!0}=this.options;this.play(),"paused"!==this.pendingPlayState&&t?this.state=this.pendingPlayState:this.pause()}tick(t,e=!1){const{resolved:n}=this;if(!n){const{keyframes:t}=this.options;return{done:!0,value:t[t.length-1]}}const{finalKeyframe:s,generator:i,mirroredGenerator:r,mapPercentToKeyframes:o,keyframes:a,calculatedDuration:l,totalDuration:u,resolvedDuration:c}=n;if(null===this.startTime)return i.next(0);const{delay:h,repeat:d,repeatType:p,repeatDelay:f,onUpdate:m}=this.options;this.speed>0?this.startTime=Math.min(this.startTime,t):this.speed<0&&(this.startTime=Math.min(t-u/this.speed,this.startTime)),e?this.currentTime=t:null!==this.holdTime?this.currentTime=this.holdTime:this.currentTime=Math.round(t-this.startTime)*this.speed;const g=this.currentTime-h*(this.speed>=0?1:-1),y=this.speed>=0?g<0:g>u;this.currentTime=Math.max(g,0),"finished"===this.state&&null===this.holdTime&&(this.currentTime=u);let v=this.currentTime,w=i;if(d){const t=Math.min(this.currentTime,u)/c;let e=Math.floor(t),n=t%1;!n&&t>=1&&(n=1),1===n&&e--,e=Math.min(e,d+1);Boolean(e%2)&&("reverse"===p?(n=1-n,f&&(n-=f/c)):"mirror"===p&&(w=r)),v=S(0,1,n)*c}const b=y?{done:!1,value:a[0]}:w.next(v);o&&(b.value=o(b.value));let{done:T}=b;y||null===l||(T=this.speed>=0?this.currentTime>=u:this.currentTime<=0);const x=null===this.holdTime&&("finished"===this.state||"running"===this.state&&T);return x&&void 0!==s&&(b.value=ht(a,this.options,s)),m&&m(b.value),x&&this.finish(),b}get duration(){const{resolved:t}=this;return t?w(t.calculatedDuration):0}get time(){return w(this.currentTime)}set time(t){t=v(t),this.currentTime=t,null!==this.holdTime||0===this.speed?this.holdTime=t:this.driver&&(this.startTime=this.driver.now()-t/this.speed)}get speed(){return this.playbackSpeed}set speed(t){const e=this.playbackSpeed!==t;this.playbackSpeed=t,e&&(this.time=w(this.currentTime))}play(){if(this.resolver.isScheduled||this.resolver.resume(),!this._resolved)return void(this.pendingPlayState="running");if(this.isStopped)return;const{driver:t=cn,onPlay:e,startTime:n}=this.options;this.driver||(this.driver=t((t=>this.tick(t)))),e&&e();const s=this.driver.now();null!==this.holdTime?this.startTime=s-this.holdTime:this.startTime?"finished"===this.state&&(this.startTime=s):this.startTime=null!=n?n:this.calcStartTime(),"finished"===this.state&&this.updateFinishedPromise(),this.cancelTime=this.startTime,this.holdTime=null,this.state="running",this.driver.start()}pause(){var t;this._resolved?(this.state="paused",this.holdTime=null!==(t=this.currentTime)&&void 0!==t?t:0):this.pendingPlayState="paused"}complete(){"running"!==this.state&&this.play(),this.pendingPlayState=this.state="finished",this.holdTime=null}finish(){this.teardown(),this.state="finished";const{onComplete:t}=this.options;t&&t()}cancel(){null!==this.cancelTime&&this.tick(this.cancelTime),this.teardown(),this.updateFinishedPromise()}teardown(){this.state="idle",this.stopDriver(),this.resolveFinishedPromise(),this.updateFinishedPromise(),this.startTime=this.cancelTime=null,this.resolver.cancel()}stopDriver(){this.driver&&(this.driver.stop(),this.driver=void 0)}sample(t){return this.startTime=0,this.tick(t,!0)}}const fn=new Set(["opacity","clipPath","filter","transform"]),mn={linearEasing:void 0};function gn(t,e){const n=m(t);return()=>{var t;return null!==(t=mn[e])&&void 0!==t?t:n()}}const yn=gn((()=>{try{document.createElement("div").animate({opacity:0},{easing:"linear(0, 1)"})}catch(t){return!1}return!0}),"linearEasing");function vn(t){return Boolean("function"==typeof t&&yn()||!t||"string"==typeof t&&(t in bn||yn())||ze(t)||Array.isArray(t)&&t.every(vn))}const wn=([t,e,n,s])=>`cubic-bezier(${t}, ${e}, ${n}, ${s})`,bn={linear:"linear",ease:"ease",easeIn:"ease-in",easeOut:"ease-out",easeInOut:"ease-in-out",circIn:wn([0,.65,.55,1]),circOut:wn([.55,0,1,.45]),backIn:wn([.31,.01,.66,-.59]),backOut:wn([.33,1.53,.69,.99])};function Tn(t,e){return t?"function"==typeof t&&yn()?((t,e)=>{let n="";const s=Math.max(Math.round(e/10),2);for(let e=0;e<s;e++)n+=t(L(0,s-1,e))+", ";return`linear(${n.substring(0,n.length-2)})`})(t,e):ze(t)?wn(t):Array.isArray(t)?t.map((t=>Tn(t,e)||bn.easeOut)):bn[t]:void 0}function xn(t,e,n,{delay:s=0,duration:i=300,repeat:r=0,repeatType:o="loop",ease:a="easeInOut",times:l}={}){const u={[e]:n};l&&(u.offset=l);const c=Tn(a,i);return Array.isArray(c)&&(u.easing=c),t.animate(u,{delay:s,duration:i,easing:Array.isArray(c)?"linear":c,fill:"both",iterations:r+1,direction:"reverse"===o?"alternate":"normal"})}function Sn(t,e){t.timeline=e,t.onfinish=null}const Vn=m((()=>Object.hasOwnProperty.call(Element.prototype,"animate")));const An={anticipate:wt,backInOut:vt,circInOut:xt};class Mn extends De{constructor(t){super(t);const{name:e,motionValue:n,element:s,keyframes:i}=this.options;this.resolver=new Ie(i,((t,e)=>this.onKeyframesResolved(t,e)),e,n,s),this.resolver.scheduleResolve()}initPlayback(t,e){var n;let{duration:s=300,times:i,ease:r,type:o,motionValue:a,name:l,startTime:u}=this.options;if(!(null===(n=a.owner)||void 0===n?void 0:n.current))return!1;var c;if("string"==typeof r&&yn()&&r in An&&(r=An[r]),z((c=this.options).type)||"spring"===c.type||!vn(c.ease)){const{onComplete:e,onUpdate:n,motionValue:a,element:l,...u}=this.options,c=function(t,e){const n=new pn({...e,keyframes:t,repeat:0,delay:0,isGenerator:!0});let s={done:!1,value:t[0]};const i=[];let r=0;for(;!s.done&&r<2e4;)s=n.sample(r),i.push(s.value),r+=10;return{times:void 0,keyframes:i,duration:r-10,ease:"linear"}}(t,u);1===(t=c.keyframes).length&&(t[1]=t[0]),s=c.duration,i=c.times,r=c.ease,o="keyframes"}const h=xn(a.owner.current,l,t,{...this.options,duration:s,times:i,ease:r});return h.startTime=null!=u?u:this.calcStartTime(),this.pendingTimeline?(Sn(h,this.pendingTimeline),this.pendingTimeline=void 0):h.onfinish=()=>{const{onComplete:n}=this.options;a.set(ht(t,this.options,e)),n&&n(),this.cancel(),this.resolveFinishedPromise()},{animation:h,duration:s,times:i,type:o,ease:r,keyframes:t}}get duration(){const{resolved:t}=this;if(!t)return 0;const{duration:e}=t;return w(e)}get time(){const{resolved:t}=this;if(!t)return 0;const{animation:e}=t;return w(e.currentTime||0)}set time(t){const{resolved:e}=this;if(!e)return;const{animation:n}=e;n.currentTime=v(t)}get speed(){const{resolved:t}=this;if(!t)return 1;const{animation:e}=t;return e.playbackRate}set speed(t){const{resolved:e}=this;if(!e)return;const{animation:n}=e;n.playbackRate=t}get state(){const{resolved:t}=this;if(!t)return"idle";const{animation:e}=t;return e.playState}get startTime(){const{resolved:t}=this;if(!t)return null;const{animation:e}=t;return e.startTime}attachTimeline(t){if(this._resolved){const{resolved:e}=this;if(!e)return i;const{animation:n}=e;Sn(n,t)}else this.pendingTimeline=t;return i}play(){if(this.isStopped)return;const{resolved:t}=this;if(!t)return;const{animation:e}=t;"finished"===e.playState&&this.updateFinishedPromise(),e.play()}pause(){const{resolved:t}=this;if(!t)return;const{animation:e}=t;e.pause()}stop(){if(this.resolver.cancel(),this.isStopped=!0,"idle"===this.state)return;this.resolveFinishedPromise(),this.updateFinishedPromise();const{resolved:t}=this;if(!t)return;const{animation:e,keyframes:n,duration:s,type:i,ease:r,times:o}=t;if("idle"===e.playState||"finished"===e.playState)return;if(this.time){const{motionValue:t,onUpdate:e,onComplete:a,element:l,...u}=this.options,c=new pn({...u,keyframes:n,duration:s,type:i,ease:r,times:o,isGenerator:!0}),h=v(this.time);t.setWithVelocity(c.sample(h-10).value,c.sample(h).value,10)}const{onStop:a}=this.options;a&&a(),this.cancel()}complete(){const{resolved:t}=this;t&&t.animation.finish()}cancel(){const{resolved:t}=this;t&&t.animation.cancel()}static supports(t){const{motionValue:e,name:n,repeatDelay:s,repeatType:i,damping:r,type:o}=t;return Vn()&&n&&fn.has(n)&&e&&e.owner&&e.owner.current instanceof HTMLElement&&!e.owner.getProps().onUpdate&&!s&&"mirror"!==i&&0!==r&&"inertia"!==o}}const Pn=(t,e,n,s={},i,r)=>a=>{const l=ut(s,t)||{},u=l.delay||s.delay||0;let{elapsed:c=0}=s;c-=v(u);let h={keyframes:Array.isArray(n)?n:[null,n],ease:"easeOut",velocity:e.getVelocity(),...l,delay:-c,onUpdate:t=>{e.set(t),l.onUpdate&&l.onUpdate(t)},onComplete:()=>{a(),l.onComplete&&l.onComplete()},name:t,motionValue:e,element:r?void 0:i};(function({when:t,delay:e,delayChildren:n,staggerChildren:s,staggerDirection:i,repeat:r,repeatType:o,repeatDelay:a,from:l,elapsed:u,...c}){return!!Object.keys(c).length})(l)||(h={...h,...lt(t,h)}),h.duration&&(h.duration=v(h.duration)),h.repeatDelay&&(h.repeatDelay=v(h.repeatDelay)),void 0!==h.from&&(h.keyframes[0]=h.from);let d=!1;if((!1===h.type||0===h.duration&&!h.repeatDelay)&&(h.duration=0,0===h.delay&&(d=!0)),d&&!r&&void 0!==e.get()){const t=ht(h.keyframes,l);if(void 0!==t)return o.update((()=>{h.onUpdate(t),h.onComplete()})),new y([])}return!r&&Mn.supports(h)?new Mn(h):new pn(h)},kn=t=>(t=>Array.isArray(t))(t)?t[t.length-1]||0:t;function Fn(t){const e=[{},{}];return null==t||t.values.forEach(((t,n)=>{e[0][n]=t.get(),e[1][n]=t.getVelocity()})),e}function Cn(t,e,n,s){if("function"==typeof e){const[i,r]=Fn(s);e=e(void 0!==n?n:t.custom,i,r)}if("string"==typeof e&&(e=t.variants&&t.variants[e]),"function"==typeof e){const[i,r]=Fn(s);e=e(void 0!==n?n:t.custom,i,r)}return e}function En(t,e,n){t.hasValue(e)?t.getValue(e).set(n):t.addValue(e,f(n))}function On(t,e){const n=function(t,e,n){const s=t.getProps();return Cn(s,e,void 0!==n?n:s.custom,t)}(t,e);let{transitionEnd:s={},transition:i={},...r}=n||{};r={...r,...s};for(const e in r){En(t,e,kn(r[e]))}}const Rn=t=>t.replace(/([a-z])([A-Z])/gu,"$1-$2").toLowerCase(),Bn="data-"+Rn("framerAppearId");function In(t){return t.props[Bn]}function Ln(t,e){const n=t.getValue("willChange");if(s=n,Boolean(N(s)&&s.add))return n.add(e);var s}function Wn({protectedKeys:t,needsAnimating:e},n){const s=t.hasOwnProperty(n)&&!0!==e[n];return e[n]=!1,s}function Dn(t,e,{delay:n=0,transitionOverride:s,type:i}={}){var r;let{transition:a=t.getDefaultTransition(),transitionEnd:l,...u}=e;s&&(a=s);const c=[],h=i&&t.animationState&&t.animationState.getState()[i];for(const e in u){const s=t.getValue(e,null!==(r=t.latestValues[e])&&void 0!==r?r:null),i=u[e];if(void 0===i||h&&Wn(h,e))continue;const l={delay:n,...ut(a||{},e)};let d=!1;if(window.MotionHandoffAnimation){const n=In(t);if(n){const t=window.MotionHandoffAnimation(n,e,o);null!==t&&(l.startTime=t,d=!0)}}Ln(t,e),s.start(Pn(e,s,i,t.shouldReduceMotion&&it.has(e)?{type:!1}:l,t,d));const p=s.animation;p&&c.push(p)}return l&&Promise.all(c).then((()=>{o.update((()=>{l&&On(t,l)}))})),c}const Nn={};function Kn(t,{layout:e,layoutId:n}){return it.has(t)||t.startsWith("origin")||(e||void 0!==n)&&(!!Nn[t]||"opacity"===t)}function $n(t,e,n){var s;const{style:i}=t,r={};for(const o in i)(N(i[o])||e.style&&N(e.style[o])||Kn(o,t)||void 0!==(null===(s=null==n?void 0:n.getValue(o))||void 0===s?void 0:s.liveStyle))&&(r[o]=i[o]);return r}const jn="undefined"!=typeof window,zn={current:null},Hn={current:!1};const Un=["initial","animate","whileInView","whileFocus","whileHover","whileTap","whileDrag","exit"];function Yn(t){return null!==(e=t.animate)&&"object"==typeof e&&"function"==typeof e.start||Un.some((e=>function(t){return"string"==typeof t||Array.isArray(t)}(t[e])));var e}const qn={animation:["animate","variants","whileHover","whileTap","exit","whileInView","whileFocus","whileDrag"],exit:["exit"],drag:["drag","dragControls"],focus:["whileFocus"],hover:["whileHover","onHoverStart","onHoverEnd"],tap:["whileTap","onTap","onTapStart","onTapCancel"],pan:["onPan","onPanStart","onPanSessionStart","onPanEnd"],inView:["whileInView","onViewportEnter","onViewportLeave"],layout:["layout","layoutId"]},Xn={};for(const t in qn)Xn[t]={isEnabled:e=>qn[t].some((t=>!!e[t]))};const Gn=[...Zt,pe,xe],Zn=()=>({x:{min:0,max:0},y:{min:0,max:0}}),_n=["AnimationStart","AnimationComplete","Update","BeforeLayoutMeasure","LayoutMeasure","LayoutAnimationStart","LayoutAnimationComplete"];class Jn{scrapeMotionValuesFromProps(t,e,n){return{}}constructor({parent:t,props:e,presenceContext:n,reducedMotionConfig:s,blockInitialAnimation:i,visualState:r},a={}){this.current=null,this.children=new Set,this.isVariantNode=!1,this.isControllingVariants=!1,this.shouldReduceMotion=null,this.values=new Map,this.KeyframeResolver=se,this.features={},this.valueSubscriptions=new Map,this.prevMotionValues={},this.events={},this.propEventSubscriptions={},this.notifyUpdate=()=>this.notify("Update",this.latestValues),this.render=()=>{this.current&&(this.triggerBuild(),this.renderInstance(this.current,this.renderState,this.props.style,this.projection))},this.renderScheduledAt=0,this.scheduleRender=()=>{const t=d.now();this.renderScheduledAt<t&&(this.renderScheduledAt=t,o.render(this.render,!1,!0))};const{latestValues:l,renderState:u}=r;this.latestValues=l,this.baseTarget={...l},this.initialValues=e.initial?{...l}:{},this.renderState=u,this.parent=t,this.props=e,this.presenceContext=n,this.depth=t?t.depth+1:0,this.reducedMotionConfig=s,this.options=a,this.blockInitialAnimation=Boolean(i),this.isControllingVariants=Yn(e),this.isVariantNode=function(t){return Boolean(Yn(t)||t.variants)}(e),this.isVariantNode&&(this.variantChildren=new Set),this.manuallyAnimateOnMount=Boolean(t&&t.current);const{willChange:c,...h}=this.scrapeMotionValuesFromProps(e,{},this);for(const t in h){const e=h[t];void 0!==l[t]&&N(e)&&e.set(l[t],!1)}}mount(t){this.current=t,nt.set(t,this),this.projection&&!this.projection.instance&&this.projection.mount(t),this.parent&&this.isVariantNode&&!this.isControllingVariants&&(this.removeFromVariantTree=this.parent.addVariantChild(this)),this.values.forEach(((t,e)=>this.bindToMotionValue(e,t))),Hn.current||function(){if(Hn.current=!0,jn)if(window.matchMedia){const t=window.matchMedia("(prefers-reduced-motion)"),e=()=>zn.current=t.matches;t.addListener(e),e()}else zn.current=!1}(),this.shouldReduceMotion="never"!==this.reducedMotionConfig&&("always"===this.reducedMotionConfig||zn.current),this.parent&&this.parent.children.add(this),this.update(this.props,this.presenceContext)}unmount(){nt.delete(this.current),this.projection&&this.projection.unmount(),a(this.notifyUpdate),a(this.render),this.valueSubscriptions.forEach((t=>t())),this.valueSubscriptions.clear(),this.removeFromVariantTree&&this.removeFromVariantTree(),this.parent&&this.parent.children.delete(this);for(const t in this.events)this.events[t].clear();for(const t in this.features){const e=this.features[t];e&&(e.unmount(),e.isMounted=!1)}this.current=null}bindToMotionValue(t,e){this.valueSubscriptions.has(t)&&this.valueSubscriptions.get(t)();const n=it.has(t),s=e.on("change",(e=>{this.latestValues[t]=e,this.props.onUpdate&&o.preRender(this.notifyUpdate),n&&this.projection&&(this.projection.isTransformDirty=!0)})),i=e.on("renderRequest",this.scheduleRender);let r;window.MotionCheckAppearSync&&(r=window.MotionCheckAppearSync(this,t,e)),this.valueSubscriptions.set(t,(()=>{s(),i(),r&&r(),e.owner&&e.stop()}))}sortNodePosition(t){return this.current&&this.sortInstanceNodePosition&&this.type===t.type?this.sortInstanceNodePosition(this.current,t.current):0}updateFeatures(){let t="animation";for(t in Xn){const e=Xn[t];if(!e)continue;const{isEnabled:n,Feature:s}=e;if(!this.features[t]&&s&&n(this.props)&&(this.features[t]=new s(this)),this.features[t]){const e=this.features[t];e.isMounted?e.update():(e.mount(),e.isMounted=!0)}}}triggerBuild(){this.build(this.renderState,this.latestValues,this.props)}measureViewportBox(){return this.current?this.measureInstanceViewportBox(this.current,this.props):{x:{min:0,max:0},y:{min:0,max:0}}}getStaticValue(t){return this.latestValues[t]}setStaticValue(t,e){this.latestValues[t]=e}update(t,e){(t.transformTemplate||this.props.transformTemplate)&&this.scheduleRender(),this.prevProps=this.props,this.props=t,this.prevPresenceContext=this.presenceContext,this.presenceContext=e;for(let e=0;e<_n.length;e++){const n=_n[e];this.propEventSubscriptions[n]&&(this.propEventSubscriptions[n](),delete this.propEventSubscriptions[n]);const s=t["on"+n];s&&(this.propEventSubscriptions[n]=this.on(n,s))}this.prevMotionValues=function(t,e,n){for(const s in e){const i=e[s],r=n[s];if(N(i))t.addValue(s,i);else if(N(r))t.addValue(s,f(i,{owner:t}));else if(r!==i)if(t.hasValue(s)){const e=t.getValue(s);!0===e.liveStyle?e.jump(i):e.hasAnimated||e.set(i)}else{const e=t.getStaticValue(s);t.addValue(s,f(void 0!==e?e:i,{owner:t}))}}for(const s in n)void 0===e[s]&&t.removeValue(s);return e}(this,this.scrapeMotionValuesFromProps(t,this.prevProps,this),this.prevMotionValues),this.handleChildMotionValue&&this.handleChildMotionValue()}getProps(){return this.props}getVariant(t){return this.props.variants?this.props.variants[t]:void 0}getDefaultTransition(){return this.props.transition}getTransformPagePoint(){return this.props.transformPagePoint}getClosestVariantNode(){return this.isVariantNode?this:this.parent?this.parent.getClosestVariantNode():void 0}addVariantChild(t){const e=this.getClosestVariantNode();if(e)return e.variantChildren&&e.variantChildren.add(t),()=>e.variantChildren.delete(t)}addValue(t,e){const n=this.values.get(t);e!==n&&(n&&this.removeValue(t),this.bindToMotionValue(t,e),this.values.set(t,e),this.latestValues[t]=e.get())}removeValue(t){this.values.delete(t);const e=this.valueSubscriptions.get(t);e&&(e(),this.valueSubscriptions.delete(t)),delete this.latestValues[t],this.removeValueFromRenderState(t,this.renderState)}hasValue(t){return this.values.has(t)}getValue(t,e){if(this.props.values&&this.props.values[t])return this.props.values[t];let n=this.values.get(t);return void 0===n&&void 0!==e&&(n=f(null===e?void 0:e,{owner:this}),this.addValue(t,n)),n}readValue(t,e){var n;let s=void 0===this.latestValues[t]&&this.current?null!==(n=this.getBaseTargetFromProps(this.props,t))&&void 0!==n?n:this.readValueFromInstance(this.current,t,this.options):this.latestValues[t];var i;return null!=s&&("string"==typeof s&&(Vt(s)||St(s))?s=parseFloat(s):(i=s,!Gn.find(Gt(i))&&xe.test(e)&&(s=Re(t,e))),this.setBaseTarget(t,N(s)?s.get():s)),N(s)?s.get():s}setBaseTarget(t,e){this.baseTarget[t]=e}getBaseTarget(t){var e;const{initial:n}=this.props;let s;if("string"==typeof n||"object"==typeof n){const i=Cn(this.props,n,null===(e=this.presenceContext)||void 0===e?void 0:e.custom);i&&(s=i[t])}if(n&&void 0!==s)return s;const i=this.getBaseTargetFromProps(this.props,t);return void 0===i||N(i)?void 0!==this.initialValues[t]&&void 0===s?void 0:this.baseTarget[t]:i}on(t,n){return this.events[t]||(this.events[t]=new e),this.events[t].add(n)}notify(t,...e){this.events[t]&&this.events[t].notify(...e)}}class Qn extends Jn{constructor(){super(...arguments),this.KeyframeResolver=Ie}sortInstanceNodePosition(t,e){return 2&t.compareDocumentPosition(e)?1:-1}getBaseTargetFromProps(t,e){return t.style?t.style[e]:void 0}removeValueFromRenderState(t,{vars:e,style:n}){delete e[t],delete n[t]}}const ts=(t,e)=>e&&"number"==typeof t?e.transform(t):t,es={x:"translateX",y:"translateY",z:"translateZ",transformPerspective:"perspective"},ns=st.length;function ss(t,e,n){const{style:s,vars:i,transformOrigin:r}=t;let o=!1,a=!1;for(const t in e){const n=e[t];if(it.has(t))o=!0;else if(Mt(t))i[t]=n;else{const e=ts(n,Ce[t]);t.startsWith("origin")?(a=!0,r[t]=e):s[t]=e}}if(e.transform||(o||n?s.transform=function(t,e,n){let s="",i=!0;for(let r=0;r<ns;r++){const o=st[r],a=t[o];if(void 0===a)continue;let l=!0;if(l="number"==typeof a?a===(o.startsWith("scale")?1:0):0===parseFloat(a),!l||n){const t=ts(a,Ce[o]);l||(i=!1,s+=`${es[o]||o}(${t}) `),n&&(e[o]=t)}}return s=s.trim(),n?s=n(e,i?"":s):i&&(s="none"),s}(e,t.transform,n):s.transform&&(s.transform="none")),a){const{originX:t="50%",originY:e="50%",originZ:n=0}=r;s.transformOrigin=`${t} ${e} ${n}`}}function is(t,e,n){return"string"==typeof t?t:Dt.transform(e+n*t)}const rs={offset:"stroke-dashoffset",array:"stroke-dasharray"},os={offset:"strokeDashoffset",array:"strokeDasharray"};function as(t,{attrX:e,attrY:n,attrScale:s,originX:i,originY:r,pathLength:o,pathSpacing:a=1,pathOffset:l=0,...u},c,h){if(ss(t,u,h),c)return void(t.style.viewBox&&(t.attrs.viewBox=t.style.viewBox));t.attrs=t.style,t.style={};const{attrs:d,style:p,dimensions:f}=t;d.transform&&(f&&(p.transform=d.transform),delete d.transform),f&&(void 0!==i||void 0!==r||p.transform)&&(p.transformOrigin=function(t,e,n){return`${is(e,t.x,t.width)} ${is(n,t.y,t.height)}`}(f,void 0!==i?i:.5,void 0!==r?r:.5)),void 0!==e&&(d.x=e),void 0!==n&&(d.y=n),void 0!==s&&(d.scale=s),void 0!==o&&function(t,e,n=1,s=0,i=!0){t.pathLength=1;const r=i?rs:os;t[r.offset]=Dt.transform(-s);const o=Dt.transform(e),a=Dt.transform(n);t[r.array]=`${o} ${a}`}(d,o,a,l,!1)}const ls=new Set(["baseFrequency","diffuseConstant","kernelMatrix","kernelUnitLength","keySplines","keyTimes","limitingConeAngle","markerHeight","markerWidth","numOctaves","targetX","targetY","surfaceScale","specularConstant","specularExponent","stdDeviation","tableValues","viewBox","gradientTransform","pathLength","startOffset","textLength","lengthAdjust"]);function us(t,{style:e,vars:n},s,i){Object.assign(t.style,e,i&&i.getProjectionStyles(s));for(const e in n)t.style.setProperty(e,n[e])}class cs extends Qn{constructor(){super(...arguments),this.type="svg",this.isSVGTag=!1,this.measureInstanceViewportBox=Zn}getBaseTargetFromProps(t,e){return t[e]}readValueFromInstance(t,e){if(it.has(e)){const t=Oe(e);return t&&t.default||0}return e=ls.has(e)?e:Rn(e),t.getAttribute(e)}scrapeMotionValuesFromProps(t,e,n){return function(t,e,n){const s=$n(t,e,n);for(const n in t)(N(t[n])||N(e[n]))&&(s[-1!==st.indexOf(n)?"attr"+n.charAt(0).toUpperCase()+n.substring(1):n]=t[n]);return s}(t,e,n)}build(t,e,n){as(t,e,this.isSVGTag,n.transformTemplate)}renderInstance(t,e,n,s){!function(t,e,n,s){us(t,e,void 0,s);for(const n in e.attrs)t.setAttribute(ls.has(n)?n:Rn(n),e.attrs[n])}(t,e,0,s)}mount(t){var e;this.isSVGTag="string"==typeof(e=t.tagName)&&"svg"===e.toLowerCase(),super.mount(t)}}class hs extends Qn{constructor(){super(...arguments),this.type="html",this.renderInstance=us}readValueFromInstance(t,e){if(it.has(e)){const t=Oe(e);return t&&t.default||0}{const s=(n=t,window.getComputedStyle(n)),i=(Mt(e)?s.getPropertyValue(e):s[e])||0;return"string"==typeof i?i.trim():i}var n}measureInstanceViewportBox(t,{transformPagePoint:e}){return function(t,e){return function({top:t,left:e,right:n,bottom:s}){return{x:{min:e,max:n},y:{min:t,max:s}}}(function(t,e){if(!e)return t;const n=e({x:t.left,y:t.top}),s=e({x:t.right,y:t.bottom});return{top:n.y,left:n.x,bottom:s.y,right:s.x}}(t.getBoundingClientRect(),e))}(t,e)}build(t,e,n){ss(t,e,n.transformTemplate)}scrapeMotionValuesFromProps(t,e,n){return $n(t,e,n)}handleChildMotionValue(){this.childSubscription&&(this.childSubscription(),delete this.childSubscription);const{children:t}=this.props;N(t)&&(this.childSubscription=t.on("change",(t=>{this.current&&(this.current.textContent=`${t}`)})))}}class ds extends Jn{constructor(){super(...arguments),this.type="object"}readValueFromInstance(t,e){if(function(t,e){return t in e}(e,t)){const n=t[e];if("string"==typeof n||"number"==typeof n)return n}}getBaseTargetFromProps(){}removeValueFromRenderState(t,e){delete e.output[t]}measureInstanceViewportBox(){return{x:{min:0,max:0},y:{min:0,max:0}}}build(t,e){Object.assign(t.output,e)}renderInstance(t,{output:e}){Object.assign(t,e)}sortInstanceNodePosition(){return 0}}function ps(t){const e={presenceContext:null,props:{},visualState:{renderState:{transform:{},transformOrigin:{},style:{},vars:{},attrs:{}},latestValues:{}}},n=function(t){return t instanceof SVGElement&&"svg"!==t.tagName}(t)?new cs(e):new hs(e);n.mount(t),nt.set(t,n)}function fs(t){const e=new ds({presenceContext:null,props:{},visualState:{renderState:{output:{}},latestValues:{}}});e.mount(t),nt.set(t,e)}function ms(t,e,n,s){const i=[];if(function(t,e){return N(t)||"number"==typeof t||"string"==typeof t&&!$(e)}(t,e))i.push(function(t,e,n){const s=N(t)?t:f(t);return s.start(Pn("",s,e,n)),s.animation}(t,$(e)&&e.default||e,n&&n.default||n));else{const r=j(t,e,s),o=r.length;for(let t=0;t<o;t++){const s=r[t],a=s instanceof Element?ps:fs;nt.has(s)||a(s);const l=nt.get(s),u={...n};"delay"in u&&"function"==typeof u.delay&&(u.delay=u.delay(t,o)),i.push(...Dn(l,{...e,transition:u},{}))}}return i}function gs(t,e,n){const s=[],i=function(t,{defaultTransition:e={},...n}={},s,i){const r=e.duration||.3,o=new Map,a=new Map,l={},u=new Map;let c=0,h=0,d=0;for(let n=0;n<t.length;n++){const o=t[n];if("string"==typeof o){u.set(o,h);continue}if(!Array.isArray(o)){u.set(o.name,H(h,o.at,c,u));continue}let[p,f,m={}]=o;void 0!==m.at&&(h=H(h,m.at,c,u));let g=0;const y=(t,n,s,o=0,a=0)=>{const l=J(t),{delay:u=0,times:c=D(l),type:p="keyframes",...f}=n;let{ease:m=e.ease||"easeOut",duration:y}=n;const w="function"==typeof u?u(o,a):u,b=l.length,T=z(p)?p:null==i?void 0:i[p];if(b<=2&&T){let t=100;if(2===b&&et(l)){const e=l[1]-l[0];t=Math.abs(e)}const e={...f};void 0!==y&&(e.duration=v(y));const n=B(e,t,T);m=n.ease,y=n.duration}null!=y||(y=r);const x=h+w,S=x+y;1===c.length&&0===c[0]&&(c[1]=1);const V=c.length-l.length;V>0&&W(c,V),1===l.length&&l.unshift(null),X(s,l,m,c,x,S),g=Math.max(w+y,g),d=Math.max(S,d)};if(N(p))y(f,m,_("default",Z(p,a)));else{const t=j(p,f,s,l),e=t.length;for(let n=0;n<e;n++){const s=Z(t[n],a);for(const t in f)y(f[t],Q(m,t),_(t,s),n,e)}}c=h,h+=g}return a.forEach(((t,s)=>{for(const i in t){const r=t[i];r.sort(G);const a=[],l=[],u=[];for(let t=0;t<r.length;t++){const{at:e,value:n,easing:s}=r[t];a.push(n),l.push(L(0,d,e)),u.push(s||"easeOut")}0!==l[0]&&(l.unshift(0),a.unshift(a[0]),u.unshift("easeInOut")),1!==l[l.length-1]&&(l.push(1),a.push(null)),o.has(s)||o.set(s,{keyframes:{},transition:{}});const c=o.get(s);c.keyframes[i]=a,c.transition[i]={...e,duration:d,ease:u,times:l,...n}}})),o}(t,e,n,{spring:E});return i.forEach((({keyframes:t,transition:e},n)=>{s.push(...ms(n,t,e))})),s}function ys(t){return function(e,n,s){let i=[];var r;r=e,i=Array.isArray(r)&&Array.isArray(r[0])?gs(e,n,t):ms(e,n,s,t);const o=new y(i);return t&&t.animations.push(o),o}}const vs=ys();function ws(t,e,n){t.style.setProperty(`--${e}`,n)}function bs(t,e,n){t.style[e]=n}const Ts=m((()=>{try{document.createElement("div").animate({opacity:[1]})}catch(t){return!1}return!0})),xs=new WeakMap;const Ss="easeOut";function Vs(t){const e=xs.get(t)||new Map;return xs.set(t,e),xs.get(t)}class As{constructor(t,e,n,s){const i=e.startsWith("--");this.setValue=i?ws:bs,this.options=s,this.updateFinishedPromise(),x("string"!=typeof s.type);const r=Vs(t).get(e);r&&r.stop();if(Array.isArray(n)||(n=[n]),function(t,e,n){for(let s=0;s<e.length;s++)null===e[s]&&(e[s]=0===s?n():e[s-1]),"number"==typeof e[s]&&Pe[t]&&(e[s]=Pe[t].transform(e[s]));!Ts()&&e.length<2&&e.unshift(n())}(e,n,(()=>e.startsWith("--")?t.style.getPropertyValue(e):window.getComputedStyle(t)[e])),z(s.type)){const t=B(s,100,s.type);s.ease=yn()?t.ease:Ss,s.duration=v(t.duration),s.type="keyframes"}else s.ease=s.ease||Ss;this.removeAnimation=()=>{var n;return null===(n=xs.get(t))||void 0===n?void 0:n.delete(e)};const o=()=>{this.setValue(t,e,ht(n,this.options)),this.cancel(),this.resolveFinishedPromise()};Vn()?(this.animation=xn(t,e,n,s),!1===s.autoplay&&this.animation.pause(),this.animation.onfinish=o,this.pendingTimeline&&Sn(this.animation,this.pendingTimeline),Vs(t).set(e,this)):o()}get duration(){return w(this.options.duration||300)}get time(){var t;return this.animation?w((null===(t=this.animation)||void 0===t?void 0:t.currentTime)||0):0}set time(t){this.animation&&(this.animation.currentTime=v(t))}get speed(){return this.animation?this.animation.playbackRate:1}set speed(t){this.animation&&(this.animation.playbackRate=t)}get state(){return this.animation?this.animation.playState:"finished"}get startTime(){return this.animation?this.animation.startTime:null}flatten(){var t;this.animation&&(null===(t=this.animation.effect)||void 0===t||t.updateTiming({easing:"linear"}))}play(){"finished"===this.state&&this.updateFinishedPromise(),this.animation&&this.animation.play()}pause(){this.animation&&this.animation.pause()}stop(){this.animation&&"idle"!==this.state&&"finished"!==this.state&&(this.animation.commitStyles&&this.animation.commitStyles(),this.cancel())}complete(){this.animation&&this.animation.finish()}cancel(){this.removeAnimation();try{this.animation&&this.animation.cancel()}catch(t){}}then(t,e){return this.currentFinishedPromise.then(t,e)}updateFinishedPromise(){this.currentFinishedPromise=new Promise((t=>{this.resolveFinishedPromise=t}))}attachTimeline(t){return this.animation?Sn(this.animation,t):this.pendingTimeline=t,i}}const Ms=t=>function(e,n,s){return new y(function(t,e,n,s){const i=K(t,s),r=i.length,o=[];for(let t=0;t<r;t++){const s=i[t],a={...n};"function"==typeof a.delay&&(a.delay=a.delay(t,r));for(const t in e){const n=e[t],i={...ut(a,t)};i.duration=i.duration?v(i.duration):i.duration,i.delay=v(i.delay||0),o.push(new As(s,t,n,i))}}return o}(e,n,s,t))},Ps=Ms(),ks=new WeakMap;let Fs;function Cs({target:t,contentRect:e,borderBoxSize:n}){var s;null===(s=ks.get(t))||void 0===s||s.forEach((s=>{s({target:t,contentSize:e,get size(){return function(t,e){if(e){const{inlineSize:t,blockSize:n}=e[0];return{width:t,height:n}}return t instanceof SVGElement&&"getBBox"in t?t.getBBox():{width:t.offsetWidth,height:t.offsetHeight}}(t,n)}})}))}function Es(t){t.forEach(Cs)}function Os(t,e){Fs||"undefined"!=typeof ResizeObserver&&(Fs=new ResizeObserver(Es));const n=K(t);return n.forEach((t=>{let n=ks.get(t);n||(n=new Set,ks.set(t,n)),n.add(e),null==Fs||Fs.observe(t)})),()=>{n.forEach((t=>{const n=ks.get(t);null==n||n.delete(e),(null==n?void 0:n.size)||null==Fs||Fs.unobserve(t)}))}}const Rs=new Set;let Bs;function Is(t){return Rs.add(t),Bs||(Bs=()=>{const t={width:window.innerWidth,height:window.innerHeight},e={target:window,size:t,contentSize:t};Rs.forEach((t=>t(e)))},window.addEventListener("resize",Bs)),()=>{Rs.delete(t),!Rs.size&&Bs&&(Bs=void 0)}}const Ls={x:{length:"Width",position:"Left"},y:{length:"Height",position:"Top"}};function Ws(t,e,s,i){const r=s[e],{length:o,position:a}=Ls[e],l=r.current,u=s.time;r.current=t[`scroll${a}`],r.scrollLength=t[`scroll${o}`]-t[`client${o}`],r.offset.length=0,r.offset[0]=0,r.offset[1]=r.scrollLength,r.progress=L(0,r.scrollLength,r.current);const c=i-u;r.velocity=c>50?0:n(r.current-l,c)}const Ds={Enter:[[0,1],[1,1]],Exit:[[0,0],[1,0]],Any:[[1,0],[0,1]],All:[[0,0],[1,1]]},Ns={start:0,center:.5,end:1};function Ks(t,e,n=0){let s=0;if(t in Ns&&(t=Ns[t]),"string"==typeof t){const e=parseFloat(t);t.endsWith("px")?s=e:t.endsWith("%")?t=e/100:t.endsWith("vw")?s=e/100*document.documentElement.clientWidth:t.endsWith("vh")?s=e/100*document.documentElement.clientHeight:t=e}return"number"==typeof t&&(s=e*t),n+s}const $s=[0,0];function js(t,e,n,s){let i=Array.isArray(t)?t:$s,r=0,o=0;return"number"==typeof t?i=[t,t]:"string"==typeof t&&(i=(t=t.trim()).includes(" ")?t.split(" "):[t,Ns[t]?t:"0"]),r=Ks(i[0],n,s),o=Ks(i[1],e),r-o}const zs={x:0,y:0};function Hs(t,e,n){const{offset:s=Ds.All}=n,{target:i=t,axis:r="y"}=n,o="y"===r?"height":"width",a=i!==t?function(t,e){const n={x:0,y:0};let s=t;for(;s&&s!==e;)if(s instanceof HTMLElement)n.x+=s.offsetLeft,n.y+=s.offsetTop,s=s.offsetParent;else if("svg"===s.tagName){const t=s.getBoundingClientRect();s=s.parentElement;const e=s.getBoundingClientRect();n.x+=t.left-e.left,n.y+=t.top-e.top}else{if(!(s instanceof SVGGraphicsElement))break;{const{x:t,y:e}=s.getBBox();n.x+=t,n.y+=e;let i=null,r=s.parentNode;for(;!i;)"svg"===r.tagName&&(i=r),r=s.parentNode;s=i}}return n}(i,t):zs,l=i===t?{width:t.scrollWidth,height:t.scrollHeight}:function(t){return"getBBox"in t&&"svg"!==t.tagName?t.getBBox():{width:t.clientWidth,height:t.clientHeight}}(i),u={width:t.clientWidth,height:t.clientHeight};e[r].offset.length=0;let c=!e[r].interpolate;const h=s.length;for(let t=0;t<h;t++){const n=js(s[t],u[o],l[o],a[r]);c||n===e[r].interpolatorOffsets[t]||(c=!0),e[r].offset[t]=n}c&&(e[r].interpolate=ln(e[r].offset,D(s)),e[r].interpolatorOffsets=[...e[r].offset]),e[r].progress=e[r].interpolate(e[r].current)}function Us(t,e,n,s={}){return{measure:()=>function(t,e=t,n){if(n.x.targetOffset=0,n.y.targetOffset=0,e!==t){let s=e;for(;s&&s!==t;)n.x.targetOffset+=s.offsetLeft,n.y.targetOffset+=s.offsetTop,s=s.offsetParent}n.x.targetLength=e===t?e.scrollWidth:e.clientWidth,n.y.targetLength=e===t?e.scrollHeight:e.clientHeight,n.x.containerLength=t.clientWidth,n.y.containerLength=t.clientHeight}(t,s.target,n),update:e=>{!function(t,e,n){Ws(t,"x",e,n),Ws(t,"y",e,n),e.time=n}(t,n,e),(s.offset||s.target)&&Hs(t,n,s)},notify:()=>e(n)}}const Ys=new WeakMap,qs=new WeakMap,Xs=new WeakMap,Gs=t=>t===document.documentElement?window:t;function Zs(t,{container:e=document.documentElement,...n}={}){let s=Xs.get(e);s||(s=new Set,Xs.set(e,s));const i=Us(e,t,{time:0,x:{current:0,offset:[],progress:0,scrollLength:0,targetOffset:0,targetLength:0,containerLength:0,velocity:0},y:{current:0,offset:[],progress:0,scrollLength:0,targetOffset:0,targetLength:0,containerLength:0,velocity:0}},n);if(s.add(i),!Ys.has(e)){const t=()=>{for(const t of s)t.measure()},n=()=>{for(const t of s)t.update(l.timestamp)},i=()=>{for(const t of s)t.notify()},a=()=>{o.read(t,!1,!0),o.read(n,!1,!0),o.update(i,!1,!0)};Ys.set(e,a);const c=Gs(e);window.addEventListener("resize",a,{passive:!0}),e!==document.documentElement&&qs.set(e,(u=a,"function"==typeof(r=e)?Is(r):Os(r,u))),c.addEventListener("scroll",a,{passive:!0})}var r,u;const c=Ys.get(e);return o.read(c,!1,!0),()=>{var t;a(c);const n=Xs.get(e);if(!n)return;if(n.delete(i),n.size)return;const s=Ys.get(e);Ys.delete(e),s&&(Gs(e).removeEventListener("scroll",s),null===(t=qs.get(e))||void 0===t||t(),window.removeEventListener("resize",s))}}function _s(t,e){let n;const s=()=>{const{currentTime:s}=e,i=(null===s?0:s.value)/100;n!==i&&t(i),n=i};return o.update(s,!0),()=>a(s)}const Js=new Map;function Qs({source:t,container:e=document.documentElement,axis:n="y"}={}){t&&(e=t),Js.has(e)||Js.set(e,{});const s=Js.get(e);return s[n]||(s[n]=g()?new ScrollTimeline({source:e,axis:n}):function({source:t,container:e,axis:n="y"}){t&&(e=t);const s={value:0},i=Zs((t=>{s.value=100*t[n].progress}),{container:e,axis:n});return{currentTime:s,cancel:i}}({source:e,axis:n})),s[n]}function ti(t){return t&&(t.target||t.offset)}function ei(t,{axis:e="y",...n}={}){const s={axis:e,...n};return"function"==typeof t?function(t,e){return function(t){return 2===t.length}(t)||ti(e)?Zs((n=>{t(n[e.axis].progress,n)}),e):_s(t,Qs(e))}(t,s):function(t,e){if(t.flatten(),ti(e))return t.pause(),Zs((n=>{t.time=t.duration*n[e.axis].progress}),e);{const n=Qs(e);return t.attachTimeline?t.attachTimeline(n,(t=>(t.pause(),_s((e=>{t.time=t.duration*e}),n)))):i}}(t,s)}const ni={some:0,all:1};function si(t,e,{root:n,margin:s,amount:i="some"}={}){const r=K(t),o=new WeakMap,a=new IntersectionObserver((t=>{t.forEach((t=>{const n=o.get(t.target);if(t.isIntersecting!==Boolean(n))if(t.isIntersecting){const n=e(t);"function"==typeof n?o.set(t.target,n):a.unobserve(t.target)}else n&&(n(t),o.delete(t.target))}))}),{root:n,rootMargin:s,threshold:"number"==typeof i?i:ni[i]});return r.forEach((t=>a.observe(t))),()=>a.disconnect()}function ii(t,e="end"){return n=>{const s=(n="end"===e?Math.min(n,.999):Math.max(n,.001))*t,i="end"===e?Math.floor(s):Math.ceil(s);return S(0,1,i/t)}}function ri(t=.1,{startDelay:e=0,from:n=0,ease:s}={}){return(i,r)=>{const o="number"==typeof n?n:function(t,e){if("first"===t)return 0;{const n=e-1;return"last"===t?n:n/2}}(n,r),a=Math.abs(o-i);let l=t*a;if(s){const e=r*t;l=Ue(s)(l/e)*e}return e+l}}function oi(...t){const e=!Array.isArray(t[0]),n=e?0:-1,s=t[0+n],i=t[1+n],r=t[2+n],o=t[3+n],a=ln(i,r,{mixer:(l=r[0],(t=>t&&"object"==typeof t&&t.mix)(l)?l.mix:void 0),...o});var l;return e?a(s):a}function ai(t,e){return function(t,e){const n=d.now(),s=({timestamp:i})=>{const r=i-n;r>=e&&(a(s),t(r-e))};return o.read(s,!0),()=>a(s)}(t,v(e))}const li=(t,e)=>Math.abs(t-e);function ui(t,e){const n=li(t.x,e.x),s=li(t.y,e.y);return Math.sqrt(n**2+s**2)}const ci=o,hi=r.reduce(((t,e)=>(t[e]=t=>a(t),t)),{});export{p as MotionValue,vs as animate,Ps as animateMini,wt as anticipate,yt as backIn,vt as backInOut,gt as backOut,a as cancelFrame,hi as cancelSync,bt as circIn,xt as circInOut,Tt as circOut,S as clamp,ys as createScopedAnimate,pt as cubicBezier,ai as delay,li as distance,ui as distance2D,Ke as easeIn,je as easeInOut,$e as easeOut,o as frame,l as frameData,u as frameSteps,si as inView,Ne as inertia,ln as interpolate,x as invariant,un as keyframes,ft as mirrorEasing,an as mix,f as motionValue,qe as pipe,L as progress,mt as reverseEasing,ei as scroll,Zs as scrollInfo,E as spring,ri as stagger,ii as steps,ci as sync,oi as transform,T as warning,U as wrap};export default null;
//# sourceMappingURL=/sm/d5d4bfa5a3f292edc74ce2b856e25f03ebbfa4c4c22aa37e3f75ca1dabe374b0.map

path: assets/template.html
content: <!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>[必填] 替换为 PPT 标题 · Deck Title</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Playfair+Display:ital,wght@0,400;0,500;0,600;0,700;0,800;0,900;1,400;1,700&family=Source+Serif+4:ital,opsz,wght@0,8..60,300;0,8..60,400;0,8..60,500;0,8..60,600;1,8..60,400&family=IBM+Plex+Mono:wght@300;400;500;600&family=Noto+Serif+SC:wght@300;400;500;600;700;900&family=Noto+Sans+SC:wght@300;400;500;700;900&display=swap" rel="stylesheet">
<style>
  :root{
    /* ============ 主题色(默认:🖋 墨水经典) ============
       切换主题:从 references/themes.md 复制对应的 :root 块
       整体替换这几行(--ink / --ink-rgb / --paper / --paper-rgb)
       其他地方散落的 rgba() 都走 var(--ink-rgb) / var(--paper-rgb),无需逐处改 */
    --ink:#0a0a0b;
    --ink-rgb:10,10,11;
    --paper:#f1efea;
    --paper-rgb:241,239,234;
    --paper-tint:#e8e5de;
    --ink-tint:#18181a;

    /* ============ 字体(跨主题固定) ============ */
    --mono:"IBM Plex Mono",ui-monospace,monospace;
    --serif-en:"Playfair Display","Source Serif 4",Georgia,serif;
    --serif-body-en:"Source Serif 4",Georgia,serif;
    --serif-zh:"Noto Serif SC",source-han-serif-sc,serif;
    --sans-zh:"Noto Sans SC",source-han-sans-sc,sans-serif;
  }
  *{box-sizing:border-box;margin:0;padding:0}
  html,body{width:100%;height:100%;overflow:hidden;background:var(--ink);color:var(--paper);font-family:var(--sans-zh);-webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility}

  /* ============ WebGL 双背景 ============ */
  canvas.bg{position:fixed;inset:0;width:100vw;height:100vh;z-index:0;display:block;transition:opacity 1.2s ease}
  canvas#bg-light{opacity:0}
  canvas#bg-dark{opacity:1}
  body.light-bg canvas#bg-light{opacity:1}
  body.light-bg canvas#bg-dark{opacity:0}

  /* ============ Deck 容器 + 翻页 ============ */
  /* width: NSLIDES * 100vw，会在 JS 里动态矫正 */
  #deck{position:fixed;inset:0;width:10000vw;height:100vh;display:flex;flex-wrap:nowrap;transition:transform .9s cubic-bezier(.77,0,.175,1);z-index:10;will-change:transform}
  .slide{width:100vw;height:100vh;flex:0 0 100vw;position:relative;padding:6vh 6vw 10vh 6vw;display:flex;flex-direction:column;overflow:hidden}
  .slide.light{color:var(--ink)}
  .slide.dark{color:var(--paper)}

  /* 默认页：遮罩较厚，保证文字可读 */
  .slide::before{content:"";position:absolute;inset:0;z-index:-1;pointer-events:none;transition:background .7s ease}
  .slide.light::before{background:rgba(var(--paper-rgb),.78);backdrop-filter:blur(3px)}
  .slide.dark::before{background:rgba(var(--ink-rgb),.78);backdrop-filter:blur(3px)}
  /* Hero 页：遮罩大幅降低，让 WebGL 背景明显透出 */
  .slide.hero.light::before{background:rgba(var(--paper-rgb),.16);backdrop-filter:none}
  .slide.hero.dark::before{background:rgba(var(--ink-rgb),.12);backdrop-filter:none}
  /* Hero 页顶底微弱渐隐，保证 chrome/foot 区域可读 */
  .slide.hero::after{content:"";position:absolute;inset:0;z-index:-1;pointer-events:none}
  .slide.hero.light::after{background:linear-gradient(180deg,rgba(var(--paper-rgb),.28) 0%,rgba(var(--paper-rgb),0) 14%,rgba(var(--paper-rgb),0) 86%,rgba(var(--paper-rgb),.28) 100%)}
  .slide.hero.dark::after{background:linear-gradient(180deg,rgba(var(--ink-rgb),.32) 0%,rgba(var(--ink-rgb),0) 14%,rgba(var(--ink-rgb),0) 86%,rgba(var(--ink-rgb),.32) 100%)}

  /* ============ Magazine chrome：顶部 meta + 底部 foot ============ */
  .chrome{display:flex;justify-content:space-between;align-items:flex-start;font-family:var(--mono);font-size:12px;letter-spacing:.18em;text-transform:uppercase;opacity:.7}
  .chrome .left,.chrome .right{display:flex;gap:2.4em;align-items:center}
  .chrome .sep{width:40px;height:1px;background:currentColor;opacity:.4}
  .foot{margin-top:auto;display:flex;justify-content:space-between;align-items:flex-end;font-family:var(--mono);font-size:12px;letter-spacing:.14em;text-transform:uppercase;opacity:.55}
  .foot .title{font-family:var(--serif-zh);font-weight:400;letter-spacing:.05em;text-transform:none;opacity:.75;font-size:13px}

  .tag{display:inline-block;font-family:var(--mono);font-size:11px;letter-spacing:.24em;text-transform:uppercase;padding:6px 14px;border:1px solid currentColor;opacity:.85}
  .rule{width:100%;height:1px;background:currentColor;opacity:.25;margin:3vh 0}
  .rule.v{width:1px;height:100%;margin:0}

  /* ============ 字体规则 ============
     · 衬线（Noto Serif SC / Playfair）：大标题、重点金句、数字
     · 非衬线（Noto Sans SC）：正文描述、body、补充说明
     · 等宽（IBM Plex Mono）：kicker、meta 小标签、foot 右侧
  */
  .kicker{font-family:var(--mono);font-size:12px;letter-spacing:.3em;text-transform:uppercase;opacity:.6;margin-bottom:2.6vh}
  .display{font-family:var(--serif-en);font-weight:700;font-size:11vw;line-height:.92;letter-spacing:-.025em}
  .display-zh{font-family:var(--serif-zh);font-weight:700;font-size:7.8vw;line-height:1.04;letter-spacing:-.005em}
  .h1-zh{font-family:var(--serif-zh);font-weight:700;font-size:4.6vw;line-height:1.12;letter-spacing:-.005em}
  .h2-zh{font-family:var(--serif-zh);font-weight:600;font-size:3.2vw;line-height:1.2;letter-spacing:0}
  .h3-zh{font-family:var(--serif-zh);font-weight:500;font-size:1.9vw;line-height:1.35}
  .body-zh{font-family:var(--sans-zh);font-weight:400;font-size:max(15px,1.22vw);line-height:1.75;opacity:.82;letter-spacing:.01em}
  .body-serif{font-family:var(--serif-zh);font-weight:400;font-size:max(15px,1.3vw);line-height:1.65;opacity:.88}
  .lead{font-family:var(--serif-zh);font-weight:400;font-size:1.9vw;line-height:1.4;opacity:.85}
  .meta{font-family:var(--mono);font-size:max(11px,.88vw);letter-spacing:.16em;text-transform:uppercase;opacity:.6}
  .big-num{font-family:var(--serif-en);font-weight:800;font-size:10vw;line-height:.85;letter-spacing:-.03em;font-feature-settings:"tnum"}
  .mid-num{font-family:var(--serif-en);font-weight:700;font-size:5.5vw;line-height:.88;letter-spacing:-.02em;font-feature-settings:"tnum"}
  .ghost{font-family:var(--serif-en);font-weight:900;font-size:34vw;line-height:.8;opacity:.06;letter-spacing:-.04em;position:absolute;font-feature-settings:"tnum"}
  em{font-style:italic;font-family:var(--serif-en)}
  .en{font-family:var(--serif-en);font-style:italic;font-weight:500}

  /* ============ 布局工具 ============ */
  .col{display:flex;flex-direction:column;gap:2.4vh}
  .row{display:flex;align-items:center;gap:3vw}
  .grid-6{display:grid;grid-template-columns:repeat(3,1fr);grid-template-rows:repeat(2,1fr);gap:4vw 6vw;flex:1;align-content:center;padding:2vh 0}
  .grid-9{display:grid;grid-template-columns:repeat(3,1fr);grid-template-rows:repeat(3,1fr);gap:3vh 4vw;flex:1;align-content:center}
  .grid-4{display:grid;grid-template-columns:repeat(2,1fr);grid-template-rows:repeat(2,1fr);gap:4vh 6vw;flex:1;align-content:center}
  .grid-3{display:grid;grid-template-columns:repeat(3,1fr);gap:4vw;flex:1;align-content:center}
  .split{display:grid;grid-template-columns:1fr 1fr;gap:4vw;flex:1;align-items:center}
  .split-55{display:grid;grid-template-columns:55fr 45fr;gap:5vw;flex:1;align-items:stretch}
  .fill{flex:1}
  .center{align-items:center;justify-content:center;text-align:center}
  .bottom-left{position:absolute;left:6vw;bottom:9vh;max-width:50vw}
  .bottom-right{position:absolute;right:6vw;bottom:9vh;max-width:50vw;text-align:right}
  .top-right{position:absolute;right:6vw;top:6vh;text-align:right}

  /* ============ Stat（数字矩阵） ============ */
  .stat{display:flex;flex-direction:column;gap:1vh;align-items:flex-start}
  .stat .n{font-family:var(--serif-en);font-weight:800;font-size:8vw;line-height:.88;letter-spacing:-.03em;font-feature-settings:"tnum"}
  .stat .l{font-family:var(--sans-zh);font-size:max(13px,1.05vw);opacity:.7;margin-top:1vh;font-weight:400;line-height:1.5}
  .stat .m{font-family:var(--mono);font-size:10px;letter-spacing:.22em;text-transform:uppercase;opacity:.5;margin-bottom:.2vh}

  /* ============ Callout（引用框） ============ */
  .callout{padding:3vh 2.4vw;border-left:3px solid currentColor;position:relative;font-family:var(--serif-zh);font-size:max(15px,1.2vw);line-height:1.55;opacity:.92}
  .slide.light .callout{background:rgba(var(--ink-rgb),.05)}
  .slide.dark .callout{background:rgba(var(--paper-rgb),.06)}
  .callout .cite{display:block;margin-top:1.6vh;font-family:var(--mono);font-size:11px;letter-spacing:.2em;text-transform:uppercase;opacity:.6}
  .callout .q-big{font-family:var(--serif-zh);font-weight:600;font-size:max(17px,1.6vw);line-height:1.42}

  /* ============ Platform（平台卡） ============ */
  .plat{display:flex;flex-direction:column;justify-content:flex-end;padding:2vh 0;border-top:1px solid currentColor;border-color:rgba(127,127,127,.35)}
  .plat .name{font-family:var(--serif-zh);font-weight:700;font-size:1.8vw;margin-bottom:.6vh}
  .plat .nb{font-family:var(--serif-en);font-weight:700;font-size:3.2vw;letter-spacing:-.02em;line-height:1;font-feature-settings:"tnum"}
  .plat .sub{font-family:var(--mono);font-size:10px;letter-spacing:.18em;text-transform:uppercase;opacity:.55;margin-top:.6vh}
  .plat .fill{font-family:var(--sans-zh);font-weight:300;font-size:2.4vw;opacity:.28;letter-spacing:-.01em;line-height:1}

  /* ============ Rowline（表格行） ============ */
  .rowline{display:grid;grid-template-columns:1fr 2fr 1fr;gap:2vw;padding:2.2vh 0;border-top:1px solid currentColor;align-items:center;border-color:rgba(127,127,127,.25)}
  .rowline:last-child{border-bottom:1px solid currentColor;border-color:rgba(127,127,127,.25)}
  .rowline .k{font-family:var(--serif-zh);font-weight:700;font-size:1.7vw}
  .rowline .v{font-family:var(--sans-zh);font-weight:400;font-size:max(14px,1.2vw);opacity:.85;line-height:1.55}
  .rowline .m{font-family:var(--mono);font-size:11px;letter-spacing:.2em;text-transform:uppercase;opacity:.6;justify-self:end}

  /* ============ Pillar（支柱卡片） ============ */
  .pillar{display:flex;flex-direction:column;gap:1.8vh}
  .pillar .ic{font-family:var(--serif-en);font-style:italic;font-size:2.6vw;opacity:.45;font-weight:400}
  .pillar .ic svg{width:2.8vw;height:2.8vw;stroke-width:1.2;opacity:.7}
  .pillar .t{font-family:var(--serif-zh);font-weight:700;font-size:2.4vw;line-height:1.1}
  .pillar .d{font-family:var(--sans-zh);font-weight:400;font-size:max(14px,1.1vw);opacity:.76;line-height:1.6}

  /* ============ Signature / Highlight ============ */
  .sign{font-family:var(--serif-en);font-style:italic;font-weight:500;font-size:2vw;opacity:.7}
  .hi{position:relative;display:inline}
  .slide.dark .hi::after{content:"";position:absolute;left:-.1em;right:-.1em;bottom:-.05em;height:.28em;background:rgba(var(--paper-rgb),.15);z-index:-1}
  .slide.light .hi::after{content:"";position:absolute;left:-.1em;right:-.1em;bottom:-.05em;height:.28em;background:rgba(var(--ink-rgb),.08);z-index:-1}

  /* ============ Icons（Lucide via CDN） ============ */
  .ico{width:1em;height:1em;display:inline-block;vertical-align:-.12em;stroke:currentColor;fill:none;stroke-width:1.4;stroke-linecap:round;stroke-linejoin:round;flex-shrink:0}
  .ico-lg,.ico-md,.ico-sm{fill:none;stroke:currentColor;stroke-linecap:round;stroke-linejoin:round}
  .ico-lg{width:2.6vw;height:2.6vw;stroke-width:1.2;display:inline-block}
  .ico-md{width:1.8vw;height:1.8vw;stroke-width:1.3;display:inline-block;vertical-align:-.4em}
  .ico-sm{width:1.1vw;height:1.1vw;stroke-width:1.4;display:inline-block;vertical-align:-.15em;opacity:.7}

  /* ============ 图片占位（虚线框，提示设计师位置） ============ */
  .img-slot{border:1.5px dashed rgba(127,127,127,.4);display:flex;align-items:center;justify-content:center;flex-direction:column;gap:1vh;padding:2vh 2vw;font-family:var(--mono);font-size:10px;letter-spacing:.28em;text-transform:uppercase;opacity:.55;position:relative;aspect-ratio:16/9;width:100%;max-height:56vh;margin-inline:auto;box-sizing:border-box}
  .img-slot::before{content:"";position:absolute;inset:8px;border:1px solid currentColor;opacity:.2}
  .img-slot .plus{font-size:2vw;font-weight:300;opacity:.5;letter-spacing:0}
  .img-slot .label{position:relative;z-index:2;text-align:center}
  .img-slot.r-4x3{aspect-ratio:4/3}
  .img-slot.r-3x2{aspect-ratio:3/2}
  .img-slot.r-1x1{aspect-ratio:1/1}

  /* ============ 图片实填框（关键：固定高度 + 只裁底部） ============
     重要约束：高度用内联 height:Nvh 精确控制，不要用 aspect-ratio（会撑破布局）
     object-position:top center 保证严禁裁剪顶部和左右，只裁剪底部
  */
  .frame-img{overflow:hidden;position:relative;background:rgba(0,0,0,.04);box-sizing:border-box;width:100%;border-radius:4px}
  .slide.dark .frame-img{background:rgba(255,255,255,.04);border-color:rgba(255,255,255,.12)}
  .frame-img > img{width:100%;height:100%;object-fit:cover;object-position:top center;display:block}
  .frame-cap{display:flex;justify-content:space-between;align-items:baseline;gap:1vw;margin-top:.8vh;font-family:var(--mono);font-size:10px;letter-spacing:.22em;text-transform:uppercase;opacity:.72}
  .frame-cap .pf{font-family:var(--serif-zh);font-weight:600;font-size:max(13px,1vw);letter-spacing:.04em;text-transform:none;opacity:.94}
  .frame-cap .nb{font-family:var(--serif-en);font-style:italic;font-size:max(15px,1.2vw);letter-spacing:.02em;text-transform:none;opacity:.88}
  .frame-cap .idx{font-family:var(--mono);opacity:.5}
  figure.tile{display:flex;flex-direction:column;margin:0;min-width:0}
  figure.tile > .frame-img{flex:0 0 auto}

  /* ============ 导航 ============ */
  #nav{position:fixed;left:50%;bottom:2.6vh;transform:translateX(-50%);z-index:30;display:flex;gap:10px;padding:8px 14px;border-radius:999px;background:rgba(0,0,0,.18);backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px)}
  #nav .dot{width:8px;height:8px;border-radius:50%;background:rgba(255,255,255,.3);cursor:pointer;transition:all .3s ease;border:0;padding:0}
  #nav .dot:hover{background:rgba(255,255,255,.5);transform:scale(1.15)}
  #nav .dot.active{background:rgba(255,255,255,.95);width:22px;border-radius:999px}
  body.light-bg #nav{background:rgba(255,255,255,.25)}
  body.light-bg #nav .dot{background:rgba(var(--ink-rgb),.25)}
  body.light-bg #nav .dot.active{background:rgba(var(--ink-rgb),.9)}
  #hint{position:fixed;bottom:3vh;right:3vw;z-index:30;font-family:var(--mono);font-size:10px;letter-spacing:.2em;text-transform:uppercase;opacity:.4;mix-blend-mode:difference;color:#aaa}

  /* ============================================================
     ============ LAYOUTS API · 面向 agent 的类（v2）============
     所有 layouts.md 中的骨架都基于下面这套命名。
     如果你在 layouts.md 里看到某个类，它必须在下面有定义。
     ============================================================ */

  /* ---------- .frame：每页主内容容器 ---------- */
  .frame{flex:1;display:flex;flex-direction:column;min-height:0;overflow:hidden}
  /* 当 .frame 同时加了 grid 类时，grid 的 display:grid 覆盖 flex */
  .frame.grid-2-7-5,
  .frame.grid-2-6-6,
  .frame.grid-2-8-4,
  .frame.grid-3-3,
  .frame.grid-6{display:grid}

  /* ---------- 标题层级（API 名称，衬线为主） ---------- */
  .h-hero{
    font-family:var(--serif-zh);
    font-weight:900;
    font-size:10vw;
    line-height:.96;
    letter-spacing:-.02em;
  }
  .h-xl{
    font-family:var(--serif-zh);
    font-weight:700;
    font-size:6.2vw;
    line-height:1.08;
    letter-spacing:-.01em;
  }
  .h-sub{
    font-family:var(--serif-zh);
    font-weight:500;
    font-size:3.1vw;
    line-height:1.25;
    letter-spacing:0;
    opacity:.7;
  }
  .h-md{
    font-family:var(--serif-zh);
    font-weight:600;
    font-size:2.3vw;
    line-height:1.3;
  }
  /* 英文标题专用（Playfair 衬线） */
  .h-hero-en,.h-xl-en{font-family:var(--serif-en);letter-spacing:-.025em}

  /* ---------- lead 引语 ---------- */
  .lead{
    font-family:var(--serif-zh);
    font-weight:400;
    font-size:1.75vw;
    line-height:1.5;
    opacity:.86;
  }

  /* ---------- meta-row 底部元数据 ---------- */
  .meta-row{
    display:flex;
    gap:1.2em;
    align-items:baseline;
    flex-wrap:wrap;
    font-family:var(--mono);
    font-size:max(12px,.92vw);
    letter-spacing:.16em;
    text-transform:uppercase;
    opacity:.6;
  }

  /* ---------- stat-card（数据大字报用） ---------- */
  .stat-card{
    display:flex;
    flex-direction:column;
    gap:.8vh;
    align-items:flex-start;
    padding-top:1.6vh;
    border-top:1px solid currentColor;
    border-color:rgba(127,127,127,.3);
  }
  .stat-card .stat-label{
    font-family:var(--mono);
    font-size:max(10px,.78vw);
    letter-spacing:.24em;
    text-transform:uppercase;
    opacity:.55;
  }
  .stat-card .stat-nb{
    font-family:var(--serif-en);
    font-weight:800;
    font-size:5.8vw;
    line-height:.9;
    letter-spacing:-.03em;
    font-feature-settings:"tnum";
    margin-top:.4vh;
  }
  .stat-card .stat-nb .stat-unit{
    font-family:var(--serif-zh);
    font-weight:500;
    font-size:.38em;
    letter-spacing:0;
    opacity:.72;
    margin-left:.14em;
  }
  .stat-card .stat-note{
    font-family:var(--sans-zh);
    font-weight:400;
    font-size:max(13px,1.05vw);
    line-height:1.5;
    opacity:.72;
    margin-top:.6vh;
  }
  /* 当 stat-card 用于 grid-4（2x2），数字适度放大；若页面有标题+引文在上方，可内联 style 覆盖为更小值 */
  .grid-4 .stat-card .stat-nb{font-size:5vw}
  /* 当只有 3 个，字也可以稍大 */
  .grid-3 .stat-card .stat-nb{font-size:6.8vw}

  /* ---------- pipeline（流水线） ---------- */
  .pipeline-section{
    margin-top:4.4vh;
    padding-top:2.8vh;
    border-top:1px dashed rgba(127,127,127,.32);
  }
  .pipeline-section:first-of-type{
    border-top:0;
    padding-top:0;
    margin-top:3vh;
  }
  .pipeline-label{
    font-family:var(--mono);
    font-size:max(11px,.85vw);
    letter-spacing:.24em;
    text-transform:uppercase;
    opacity:.62;
    margin-bottom:2.2vh;
  }
  .pipeline{
    display:grid;
    grid-template-columns:repeat(5,1fr);
    gap:1.2vw;
  }
  .pipeline[data-cols="3"]{grid-template-columns:repeat(3,1fr)}
  .pipeline[data-cols="4"]{grid-template-columns:repeat(4,1fr)}
  .pipeline[data-cols="6"]{grid-template-columns:repeat(6,1fr)}
  .step{
    display:flex;
    flex-direction:column;
    gap:.8vh;
    padding-top:1.4vh;
    border-top:1px solid currentColor;
    border-color:rgba(127,127,127,.35);
  }
  .step-nb{
    font-family:var(--serif-en);
    font-style:italic;
    font-weight:500;
    font-size:1.15vw;
    opacity:.45;
  }
  .step-title{
    font-family:var(--sans-zh);
    font-weight:700;
    font-size:1.55vw;
    letter-spacing:.01em;
    line-height:1.2;
  }
  .step-desc{
    font-family:var(--sans-zh);
    font-weight:400;
    font-size:max(12px,.95vw);
    line-height:1.45;
    opacity:.72;
  }

  /* ---------- 网格（layouts.md 所用） ---------- */
  /* 这些类独立挂到任何容器上都能生效，不依赖 .frame 复合选择器 */
  .grid-2-7-5{display:grid;grid-template-columns:7fr 5fr;gap:3vw 4vh;align-items:start}
  .grid-2-6-6{display:grid;grid-template-columns:1fr 1fr;gap:3vw 4vh;align-items:start}
  .grid-2-8-4{display:grid;grid-template-columns:8fr 4fr;gap:3vw 4vh;align-items:start}
  .grid-3-3{
    display:grid;
    grid-template-columns:repeat(3,1fr);
    grid-auto-rows:minmax(0,1fr);
    gap:2.4vh 2vw;
  }
  /* grid-6 已在旧样式里定义为 3x2，这里仅补 align */

  /* ---------- 图片 frame-img（layouts.md 主命名） ---------- */
  /* 在旧样式里已定义，这里补 img-cap 命名别名与增强 */
  figure.frame-img{margin:0;display:flex;flex-direction:column;min-width:0}
  .img-cap{
    display:block;
    margin-top:.8vh;
    font-family:var(--mono);
    font-size:max(10px,.8vw);
    letter-spacing:.22em;
    text-transform:uppercase;
    opacity:.6;
  }
  /* callout src 命名别名 */
  .callout-src{
    display:block;
    margin-top:1.6vh;
    font-family:var(--mono);
    font-size:11px;
    letter-spacing:.2em;
    text-transform:uppercase;
    opacity:.6;
  }

  /* ---------- chrome & foot 补位（layouts.md 简单写法） ---------- */
  .chrome{font-family:var(--mono);font-size:max(11px,.78vw);letter-spacing:.2em;text-transform:uppercase;opacity:.62}
  .foot{font-family:var(--mono);font-size:max(11px,.78vw);letter-spacing:.18em;text-transform:uppercase;opacity:.5}

  /* ============ 动效系统(Motion One 驱动) ============
     所有 [data-anim] 元素默认隐藏,进入页面时由 JS 逐个揭示。
     - cascade(默认):按 DOM 顺序 stagger 120ms 淡入 + y:16→0
     - hero(hero 页自动):慢一点的 stagger 180ms
     - quote(含 [data-anim="line"]):逐行 600ms 淡入
     - directional(含 [data-anim="left|right"]):左→分隔线→右
     - pipeline(data-animate="pipeline"):Space/→ 手动推进
     Motion One 没加载成功时(CDN 断 + 本地丢),所有 [data-anim] 会兜底显示。
  */
  [data-anim]{opacity:0}
  [data-anim="left"]{transform:translateX(-24px)}
  [data-anim="right"]{transform:translateX(24px)}
  [data-anim="line"]{opacity:0;transform:translateY(10px)}
  [data-animate="pipeline"] [data-anim]{opacity:.15}

  /* ---------- 响应式降级 ---------- */
  @media (max-width:900px){
    .display{font-size:16vw}
    .display-zh{font-size:12vw}
    .h1-zh{font-size:7vw}
    .h-hero{font-size:14vw}
    .h-xl{font-size:9vw}
    .pipeline{grid-template-columns:repeat(2,1fr)}
    .grid-2-7-5,.grid-2-6-6,.grid-2-8-4{grid-template-columns:1fr}
  }
</style>
</head>
<body>

<canvas id="bg-dark" class="bg"></canvas>
<canvas id="bg-light" class="bg"></canvas>
<div id="hint">← → 翻页 · ESC 索引</div>

<div id="deck">

<!-- ============================================================
     SLIDES 插入区 · 在此处填充所有 <section class="slide ..."> 页面
     每页模板参考 references/page-patterns.md
     页面组件参考 references/components.md
     ============================================================ -->

<!-- SLIDES_HERE -->

</div>

<div id="nav"></div>

<script>
/* =============== WebGL 双背景 ===============
   深色页：Holographic Dispersion（全息色散 · 钛金暗流）—— 彩虹微扰、鼠标径向涟漪
   浅色页：Spiral Vortex（旋转涡流 · 银色珍珠）—— domain-warp 流动、无中心
   修改风格请参考 references/webgl-backgrounds.md
*/
const VS = `attribute vec2 position;void main(){gl_Position=vec4(position,0.0,1.0);}`;

const FS_DARK = `precision highp float;
uniform vec2 u_resolution;uniform float u_time;uniform vec2 u_mouse;
vec3 palette(float t,vec3 a,vec3 b,vec3 c,vec3 d){return a+b*cos(6.28318*(c*t+d));}
void main(){
  vec2 uv=gl_FragCoord.xy/u_resolution.xy;
  vec2 p=uv*2.0-1.0;p.x*=u_resolution.x/u_resolution.y;
  vec2 m=u_mouse*2.0-1.0;m.x*=u_resolution.x/u_resolution.y;
  float md=length(p-m);
  float mr=sin(md*15.0-u_time*4.0)*exp(-md*3.0);p+=mr*0.08;
  vec2 p0=p;
  for(float i=1.0;i<4.0;i++){
    p.x+=0.1/i*sin(i*3.0*p.y+u_time*0.4)+0.05;
    p.y+=0.1/i*cos(i*2.0*p.x+u_time*0.3)-0.05;
  }
  float r=length(p);float ang=atan(p.y,p.x);
  vec3 a=vec3(0.12,0.12,0.13);
  vec3 b=vec3(0.03,0.04,0.05);
  vec3 c=vec3(1.0,1.0,1.0);
  vec3 d=vec3(0.1,0.2,0.4);
  vec3 col=palette(r*1.5+p0.x*0.5+u_time*0.1,a,b,c,d);
  float disp=sin(r*25.0-u_time*1.5+ang*2.0)*0.5+0.5;
  col+=vec3(disp*0.015,disp*0.01,disp*0.02);
  float hi=pow(sin(p.x*4.0+p.y*3.0+u_time)*0.5+0.5,8.0);
  col+=hi*0.08;
  vec3 base=vec3(0.05,0.05,0.06);
  col=mix(base,col,0.85);
  gl_FragColor=vec4(col,1.0);
}`;

const FS_LIGHT = `precision highp float;
uniform vec2 u_resolution;uniform float u_time;uniform vec2 u_mouse;
float hash(vec2 p){return fract(sin(dot(p,vec2(127.1,311.7)))*43758.5453);}
float noise(vec2 p){
  vec2 i=floor(p),f=fract(p);
  float a=hash(i),b=hash(i+vec2(1,0));
  float c=hash(i+vec2(0,1)),d=hash(i+vec2(1,1));
  vec2 u=f*f*(3.0-2.0*f);
  return mix(a,b,u.x)+(c-a)*u.y*(1.0-u.x)+(d-b)*u.x*u.y;
}
float fbm(vec2 p){
  float v=0.0,a=0.5;
  mat2 m=mat2(0.80,0.60,-0.60,0.80);
  for(int i=0;i<5;i++){v+=a*noise(p);p=m*p*2.02;a*=0.5;}
  return v;
}
void main(){
  vec2 uv=gl_FragCoord.xy/u_resolution.xy;
  vec2 p=uv;p.x*=u_resolution.x/u_resolution.y;
  vec2 m=u_mouse;m.x*=u_resolution.x/u_resolution.y;
  vec2 md=p-m;float dl=length(md);
  p+=normalize(md+vec2(0.0001))*exp(-dl*5.0)*0.03;
  vec2 q=vec2(fbm(p*1.8+u_time*0.07),fbm(p*1.8+vec2(5.2,1.3)+u_time*0.06));
  vec2 r=vec2(fbm(p*2.0+q*1.3+vec2(1.7,9.2)+u_time*0.05),
              fbm(p*2.0+q*1.3+vec2(8.3,2.8)+u_time*0.04));
  float f=fbm(p*2.2+r*1.5);
  vec3 silverDark=vec3(0.86,0.85,0.84);
  vec3 paper=vec3(0.955,0.945,0.925);
  vec3 col=mix(silverDark,paper,f);
  float ph=r.x*2.2+u_time*0.35;
  col+=vec3(0.78,0.62,0.92)*sin(ph)*0.055;
  col+=vec3(0.55,0.72,0.95)*sin(ph*0.8+2.0)*0.05;
  float hl=smoothstep(0.48,0.92,f);
  col+=hl*0.06;
  gl_FragColor=vec4(col,1.0);
}`;

const mouse={x:0.5,y:0.5};
addEventListener('mousemove',e=>{mouse.x=e.clientX/innerWidth;mouse.y=e.clientY/innerHeight});

function bootGL(canvasId, fsSrc){
  const canvas=document.getElementById(canvasId);
  const gl=canvas.getContext('webgl',{alpha:false,antialias:true});
  if(!gl) return ()=>false;
  const mk=(t,s)=>{const sh=gl.createShader(t);gl.shaderSource(sh,s);gl.compileShader(sh);return sh};
  const prog=gl.createProgram();
  gl.attachShader(prog,mk(gl.VERTEX_SHADER,VS));
  gl.attachShader(prog,mk(gl.FRAGMENT_SHADER,fsSrc));
  gl.linkProgram(prog);gl.useProgram(prog);
  const buf=gl.createBuffer();
  gl.bindBuffer(gl.ARRAY_BUFFER,buf);
  gl.bufferData(gl.ARRAY_BUFFER,new Float32Array([-1,-1,1,-1,-1,1,-1,1,1,-1,1,1]),gl.STATIC_DRAW);
  const pos=gl.getAttribLocation(prog,'position');
  gl.enableVertexAttribArray(pos);gl.vertexAttribPointer(pos,2,gl.FLOAT,false,0,0);
  const lRes=gl.getUniformLocation(prog,'u_resolution');
  const lT=gl.getUniformLocation(prog,'u_time');
  const lM=gl.getUniformLocation(prog,'u_mouse');
  const resize=()=>{
    const d=Math.min(window.devicePixelRatio||1,2);
    canvas.width=innerWidth*d;canvas.height=innerHeight*d;
    gl.viewport(0,0,canvas.width,canvas.height);
  };
  addEventListener('resize',resize);resize();
  return (tSec)=>{
    gl.uniform2f(lRes,canvas.width,canvas.height);
    gl.uniform1f(lT,tSec);
    gl.uniform2f(lM,mouse.x,1-mouse.y);
    gl.drawArrays(gl.TRIANGLES,0,6);
    return true;
  };
}
const drawDark=bootGL('bg-dark',FS_DARK);
const drawLight=bootGL('bg-light',FS_LIGHT);
const t0=Date.now();
(function loop(){
  const t=(Date.now()-t0)/1000;
  drawDark(t);drawLight(t);
  requestAnimationFrame(loop);
})();

// =============== 导航（翻页 / 圆点 / 键盘 / 滚轮 / 触屏） ===============
const deck=document.getElementById('deck');
const slides=deck.querySelectorAll('.slide');
const nav=document.getElementById('nav');
let idx=0,total=slides.length,lock=false;

// 关键：矫正 deck 宽度为 total * 100vw，否则翻页会错位
deck.style.width=(total*100)+'vw';

slides.forEach((s,i)=>{
  const b=document.createElement('button');
  b.className='dot';b.dataset.i=i;b.setAttribute('aria-label','Page '+(i+1));
  b.onclick=()=>go(i);
  nav.appendChild(b);
});

function go(n){
  if(lock)return;
  idx=Math.max(0,Math.min(total-1,n));
  deck.style.transform=`translateX(${-idx*100}vw)`;
  nav.querySelectorAll('.dot').forEach((d,i)=>d.classList.toggle('active',i===idx));
  /* 主题切换：优先读 data-theme，其次从 class（light/dark）推断 */
  const el=slides[idx];
  const th=el.dataset.theme || (el.classList.contains('light')?'light':(el.classList.contains('dark')?'dark':'dark'));
  document.body.classList.toggle('light-bg',th==='light');
  /* 动效：翻页过渡中段触发当前页的入场动画（由 motion-boot 注册） */
  if(window.__playSlide) setTimeout(()=>window.__playSlide(idx), 450);
  lock=true;setTimeout(()=>lock=false,700);
}

/* =============== ESC 索引视图 =============== */
let overviewOn=false;
const ov=document.createElement('div');
ov.id='overview';
ov.style.cssText='position:fixed;inset:0;z-index:100;background:rgba(var(--ink-rgb),.92);backdrop-filter:blur(12px);display:none;overflow-y:auto;padding:4vh 4vw';
document.body.appendChild(ov);

function buildOverview(){
  ov.innerHTML='';
  const grid=document.createElement('div');
  grid.style.cssText='display:grid;grid-template-columns:repeat(4,1fr);gap:2vh 1.6vw;max-width:90vw;margin:0 auto';
  slides.forEach((s,i)=>{
    const card=document.createElement('div');
    card.style.cssText='cursor:pointer;border-radius:6px;overflow:hidden;border:2px solid '+(i===idx?'rgba(var(--paper-rgb),.8)':'rgba(var(--paper-rgb),.15)')+';transition:border-color .2s';
    card.onmouseenter=()=>card.style.borderColor='rgba(var(--paper-rgb),.6)';
    card.onmouseleave=()=>card.style.borderColor=i===idx?'rgba(var(--paper-rgb),.8)':'rgba(var(--paper-rgb),.15)';
    const wrap=document.createElement('div');
    wrap.style.cssText='width:100%;aspect-ratio:16/9;overflow:hidden;position:relative;pointer-events:none;background:'+(s.classList.contains('light')?'var(--paper)':'var(--ink)');
    const clone=s.cloneNode(true);
    clone.style.cssText='width:100vw;height:100vh;transform:scale('+(1/4.5)+');transform-origin:top left;position:absolute;top:0;left:0;pointer-events:none';
    wrap.appendChild(clone);
    const label=document.createElement('div');
    label.style.cssText='padding:6px 10px;font-family:var(--mono);font-size:11px;letter-spacing:.18em;text-transform:uppercase;color:var(--paper);opacity:.7';
    label.textContent=(i+1)+' / '+total;
    card.appendChild(wrap);
    card.appendChild(label);
    card.onclick=()=>{toggleOverview();go(i)};
    grid.appendChild(card);
  });
  ov.appendChild(grid);
}

function toggleOverview(){
  overviewOn=!overviewOn;
  if(overviewOn){buildOverview();ov.style.display='block';}
  else{ov.style.display='none';}
}

addEventListener('keydown',e=>{
  if(e.key==='Escape'){e.preventDefault();toggleOverview();return;}
  if(overviewOn)return;
  if(e.key==='ArrowRight'||e.key==='PageDown'||e.key===' '||e.key==='ArrowDown'){
    if(window.__pipeAdvance && window.__pipeAdvance()) return;
    go(idx+1);
    return;
  }
  if(e.key==='ArrowLeft'||e.key==='PageUp'||e.key==='ArrowUp')go(idx-1);
  if(e.key==='Home')go(0);
  if(e.key==='End')go(total-1);
});

let wheelTO=null,wheelAcc=0;
addEventListener('wheel',e=>{
  wheelAcc+=e.deltaY+e.deltaX;
  if(Math.abs(wheelAcc)>50){
    if(wheelAcc>0 && window.__pipeAdvance && window.__pipeAdvance()){
      wheelAcc=0;
    }else{
      go(idx+(wheelAcc>0?1:-1));wheelAcc=0;
    }
  }
  clearTimeout(wheelTO);wheelTO=setTimeout(()=>wheelAcc=0,150);
},{passive:true});

let tx=0,ty=0;
addEventListener('touchstart',e=>{tx=e.touches[0].clientX;ty=e.touches[0].clientY},{passive:true});
addEventListener('touchend',e=>{
  const dx=(e.changedTouches[0].clientX-tx);
  const dy=(e.changedTouches[0].clientY-ty);
  if(Math.abs(dx)>50&&Math.abs(dx)>Math.abs(dy)){
    if(dx<0 && window.__pipeAdvance && window.__pipeAdvance()) return;
    go(idx+(dx<0?1:-1));
  }
},{passive:true});

go(0);
</script>
<script src="https://unpkg.com/lucide@latest/dist/umd/lucide.min.js"></script>
<script>lucide.createIcons();</script>

<!-- ============ Motion One 动效引擎（本地优先,CDN 兜底） ============
     加载策略:先 ./assets/motion.min.js(本地,离线可用),失败 fallback 到 jsDelivr CDN
     加载完成后挂 window.__playSlide / window.__pipeAdvance,
     导航脚本会在翻页中段调用 __playSlide(idx),键盘/滚轮/触屏会在翻页前调用 __pipeAdvance()
     双双失败时会兜底把所有 [data-anim] 设为可见,不让动效破坏阅读
-->
<script type="module">
let motion;
try {
  motion = await import('./assets/motion.min.js');
} catch(e1) {
  try {
    motion = await import('https://cdn.jsdelivr.net/npm/motion@11.11.17/+esm');
  } catch(e2) {
    console.warn('[motion] local + CDN both failed, disabling animations', e1, e2);
    document.querySelectorAll('[data-anim]').forEach(el=>{el.style.opacity='1';el.style.transform='none'});
    document.querySelectorAll('[data-animate="pipeline"] [data-anim]').forEach(el=>el.style.opacity='1');
  }
}

if(motion){
  const { animate, stagger } = motion;
  const EASE = [.22, 1, .36, 1];
  const slides = [...document.querySelectorAll('.slide')];
  let pipeStep = -1;
  let lastIdx = -1;

  function resetAnims(slide){
    slide.querySelectorAll('[data-anim]').forEach(el=>{
      el.style.opacity='';
      el.style.transform='';
    });
  }

  function playSlide(i){
    const slide = slides[i];
    if(!slide) return;
    lastIdx = i;
    const recipe = slide.dataset.animate || (slide.classList.contains('hero') ? 'hero' : 'cascade');

    if(recipe === 'pipeline'){
      pipeStep = -1;
      slide.querySelectorAll('[data-anim]').forEach(el=>{
        el.style.opacity='0.15';
        el.style.transform='none';
      });
      return;
    }

    resetAnims(slide);
    const all = [...slide.querySelectorAll('[data-anim]')];
    if(!all.length) return;

    if(recipe === 'directional'){
      const lefts  = all.filter(el=>el.dataset.anim==='left');
      const divs   = all.filter(el=>el.dataset.anim==='divider');
      const rights = all.filter(el=>el.dataset.anim==='right');
      const others = all.filter(el=>!['left','right','divider'].includes(el.dataset.anim));
      if(others.length) animate(others, {opacity:[0,1], y:[12,0]}, {duration:.6, delay:stagger(.1, {start:.15}), easing:EASE});
      if(lefts.length)  animate(lefts,  {opacity:[0,1], x:[-24,0]}, {duration:.8, delay:.35, easing:EASE});
      if(divs.length)   animate(divs,   {opacity:[0,.25]},          {duration:.5, delay:.9});
      if(rights.length) animate(rights, {opacity:[0,1], x:[24,0]},  {duration:.8, delay:1.0, easing:EASE});
      return;
    }

    if(recipe === 'quote'){
      const lines = all.filter(el=>el.dataset.anim==='line');
      const others = all.filter(el=>el.dataset.anim!=='line');
      if(others.length) animate(others, {opacity:[0,1], y:[8,0]},    {duration:.6, delay:stagger(.12, {start:.2}), easing:EASE});
      if(lines.length)  animate(lines,  {opacity:[.35,1], y:[10,0]}, {duration:.8, delay:stagger(.55, {start:.5}), easing:EASE});
      return;
    }

    if(recipe === 'hero'){
      animate(all, {opacity:[0,1], y:[14,0]}, {duration:.9, delay:stagger(.16, {start:.2}), easing:EASE});
      return;
    }

    // default: cascade
    animate(all, {opacity:[0,1], y:[16,0]}, {duration:.75, delay:stagger(.1, {start:.15}), easing:EASE});
  }

  function pipeAdvance(){
    const slide = slides[lastIdx];
    if(!slide || slide.dataset.animate !== 'pipeline') return false;
    const steps  = [...slide.querySelectorAll('[data-anim="step"]')];
    const arrows = [...slide.querySelectorAll('[data-anim="arrow"]')];
    if(pipeStep >= steps.length - 1) return false;
    pipeStep++;
    animate(steps[pipeStep], {opacity:[0.15,1], y:[8,0]}, {duration:.5, easing:EASE});
    if(pipeStep > 0 && arrows[pipeStep-1]){
      animate(arrows[pipeStep-1], {opacity:[0.15,.7]}, {duration:.3, delay:.15});
    }
    return true;
  }

  window.__playSlide = playSlide;
  window.__pipeAdvance = pipeAdvance;

  // 首屏:go(0) 已跑过(同步),没来得及触发动效 → 这里补一下
  playSlide(0);
}
</script>
</body>
</html>


Security scan verdicts — ClawScan: clean | static analysis: clean | VirusTotal: clean | SkillSpector: suspicious (MEDIUM)