/* 版本控制动画 —— 模块样式(主页 feature 行 / anim4-demo 页共用) 无边框无底色,融于星空;无 glow。token(--text-1 等)由宿主页面提供。 类名一律 anim4- 前缀,避免与 01~03 模块冲突。 */ .anim4-window { position: relative; width: 100%; height: 100%; overflow: hidden; } /* 舞台:固定 540×380 逻辑尺寸,JS 按容器等比缩放居中(transform: translate+scale) */ .anim4-stage { position: absolute; left: 50%; top: 50%; width: 540px; height: 380px; overflow: hidden; user-select: none; -webkit-user-select: none; } /* ───────── 用户指令气泡(右上角堆叠) ───────── */ /* 新气泡从下面浮现,旧的上移跑出可视区(不销毁,倒带时随堆叠回落); 容器高度 = 2.5 个气泡 + 间距,顶部渐隐遮罩 = 边缘虚化。 进出场全由 JS tween 驱动 margin/transform(rAF 可见时间),不用 CSS transition、不 tween height。 */ .anim4-bubbles { position: absolute; right: 8px; top: 2px; width: 248px; height: 84px; display: flex; flex-direction: column; justify-content: flex-end; overflow: hidden; z-index: 30; -webkit-mask-image: linear-gradient(to bottom, transparent 0, #000 26px); mask-image: linear-gradient(to bottom, transparent 0, #000 26px); pointer-events: none; } /* 单条气泡:风格同 01 的用户气泡(accent 底深字、右下小尾巴),不变色 */ .anim4-bubble { flex: none; align-self: flex-end; max-width: 236px; /* 兜底最长指令「我让你整理工作区,不是让你全删了!」17 字单行放下 */ margin-top: 6px; padding: 6px 11px; background: var(--accent); color: var(--bg-0); font-size: 12px; line-height: 1.35; border-radius: 10px 10px 3px 10px; } /* 湮灭碎片:回卷时被时间抹掉的指令字符(逐字 span,JS 物理驱动) */ .anim4-shard { position: absolute; left: 0; top: 0; color: var(--accent); font-size: 12px; line-height: 1.35; white-space: nowrap; z-index: 40; pointer-events: none; will-change: transform, opacity; } /* ───────── 纸(3D 斜铺的工作台) / 终端 ───────── */ .anim4-paper { position: absolute; left: 268px; top: 190px; width: 192px; height: 122px; transform: perspective(760px) rotateX(42deg) rotateZ(-7deg); /* 尺寸/倾斜与 03 一致;位置比 03 低 60px(避让右上气泡区) */ z-index: 15; will-change: transform; } .anim4-paper-sheet { width: 100%; height: 100%; background: var(--bg-panel); border: 1px solid var(--line); border-radius: 6px; padding: 18px 16px; display: flex; flex-direction: column; gap: 14px; /* 与 03 纸页行距一致 */ transition: background 0.3s ease; } .anim4-paper.is-term .anim4-paper-sheet { background: var(--bg-1); } /* 内容行(行宽由 JS 逐帧驱动,不用 transition) */ .anim4-pl { position: relative; width: 0; /* 初始是空纸:宽度由 JS 逐帧写入;不写死 100% 会默认撑满 */ height: 4px; border-radius: 2px; background: var(--text-3); opacity: 0.75; transition: opacity 0.25s ease; } .anim4-paper.is-term .anim4-pl { opacity: 0; } .anim4-pl-end { position: absolute; right: 0; top: 50%; width: 0; height: 0; } /* 终端层:叠在纸面上,morph 时淡入 */ .anim4-term { position: absolute; inset: 0; padding: 16px 16px; font-family: var(--font-mono); font-size: 12px; line-height: 1.75; color: var(--text-2); opacity: 0; overflow: hidden; /* 抢救段行多上滚时,裁掉滚出纸面的行 */ transition: opacity 0.3s ease; } /* 内容上滚动画在 body 内层做:term 自身 transform 会连同裁剪区一起跑 */ .anim4-term-body { transition: transform 0.25s ease; } .anim4-paper.is-term .anim4-term { opacity: 1; } .anim4-term-line { display: flex; align-items: baseline; white-space: nowrap; } .anim4-term-p { color: var(--accent); margin-right: 6px; } .anim4-term-c { color: var(--text-1); } .anim4-term-out { color: var(--text-3); visibility: hidden; } .anim4-term-out.is-on { visibility: visible; } .anim4-term-new { visibility: hidden; } .anim4-term-new.is-on { visibility: visible; } .anim4-term-caret { display: inline-block; width: 7px; height: 13px; margin-left: 1px; vertical-align: -2px; background: var(--accent); animation: anim4-caret 0.85s steps(1) infinite; } @keyframes anim4-caret { 50% { opacity: 0; } } /* ───────── 智能体(全部动作由 JS 逐帧驱动,无 CSS 过渡,防 fill 冲突) ───────── */ .anim4-agent { position: absolute; left: 0; top: 0; width: 70px; height: 70px; z-index: 35; will-change: transform; pointer-events: none; } .anim4-agent-avatar { display: block; width: 70px; height: 70px; color: var(--text-1); } .anim4-agent-avatar .astrion-avatar { width: 100%; height: 100%; } /* 本动画里智能体在纸/终端/亭前活动:六边形填底色遮住后方元素(组件默认 fill:none 是状态栏规格,此处局部覆盖) */ .anim4-agent-avatar .aa-frame { fill: var(--bg-0); } /* ───────── 笔(结构同 03:外层定位 + 内层绕笔尖摇摆) ───────── */ .anim4-pen-pos { position: absolute; left: 0; top: 0; z-index: 40; width: 40px; height: 40px; color: var(--accent); will-change: transform; transition: transform 0.45s cubic-bezier(.4, 0, .2, 1); /* 普通飞行用过渡 */ } .anim4-pen-pos.is-live { transition: none; } /* 逐帧驱动时关闭过渡 */ .anim4-pen { width: 40px; height: 40px; transform-origin: 11% 87.6%; /* 笔尖触点(同 03) */ } /* 写字摇晃由 JS 逐帧驱动(振幅包络起止收敛到 0°,见 writeLine),不用 CSS 动画 */ /* 甩飞:绕中心翻滚 */ .anim4-pen.is-free { transform-origin: 50% 50%; animation: none; } /* 捡笔回正:过渡平滑转正,期间 origin 保持中心(结束移除后 rotate=0 不受 origin 影响) */ .anim4-pen.is-returning { transition: transform 0.38s ease; transform-origin: 50% 50%; animation: none; } .anim4-pen-ref { visibility: hidden; fill: none; stroke: none; pointer-events: none; } /* ───────── 时光机(整机 2D 矢量化:所有面 JS 手算透视投影、屏幕空间 SVG 绘制) ───────── wrapper 承担 2D 整体运动(下落/浮空/微倾);面的投影由 drawBooth() 每帧按偏航 24°+sway 计算。 三层:后层 svg z1(左外墙 + clip 到门洞的内景)< 智能体 z2 < 前层 svg z3(关门即挡住他)。 体:96×96×142 正方形柱;正面左右梃各 18 + 门洞 60(双开门);屋顶四棱锥底 108×108 高 28。 智能体进出不做消失动画:走进深处被左梃自然遮挡。 */ .anim4-booth { position: absolute; left: 0; top: 0; width: 150px; height: 220px; z-index: 20; opacity: 0; will-change: transform; pointer-events: none; } /* 智能体挂载层:与门洞投影对齐的透明层(投影公式标定),夹在前后两层 svg 之间。 无背景无裁剪:室内由内景多边形提供;超出门口的部分被前层双梃/门板自然遮住。 */ .anim4-booth-inner { position: absolute; z-index: 2; pointer-events: none; } /* 矢量化覆盖层:屏幕空间绘制(原生 AA 永远锐利,根治 3D 纹理重采样锯齿); 填色/描边语言延续线稿(bg-1 面 + text-1 棱;内景 bg-0、地板 bg-panel) */ .anim4-booth-wire { position: absolute; inset: 0; overflow: visible; pointer-events: none; } .anim4-booth-wire-back { z-index: 1; } #boothWireFront { z-index: 3; } .anim4-booth-wire polygon { fill: var(--bg-1); stroke: var(--text-1); stroke-width: 1.6; stroke-linejoin: round; } #bwInBack, #bwInSideR, #bwInCeil { fill: var(--bg-0); } #bwInFloor { fill: var(--bg-panel); } .bw-door-stripe { stroke: var(--text-1); stroke-width: 1.6; } .bw-door-knob { fill: var(--text-1); stroke: none; } #bwRod { stroke: var(--text-1); stroke-width: 2; stroke-linecap: round; } #bwKnob { fill: var(--bg-1); stroke: var(--text-1); stroke-width: 1.6; } /* ───────── 地面接触阴影(中性灰,非发光) ───────── */ .anim4-shadow { position: absolute; height: 10px; border-radius: 50%; background: rgba(0, 0, 0, 0.35); z-index: 5; pointer-events: none; } .anim4-shadow-booth { width: 116px; opacity: 0; } .anim4-shadow-agent { width: 56px; opacity: 0; }