{
  "slug": "neon-frame-forerun",
  "title": "Neon frame forerun",
  "tagline": "A steep-perspective neon frame draws itself in from both ends, the page brightens from dark inside it, components land from above with matching soft shadows, and background neon tubes dim out at the end.",
  "description": "A steep-perspective neon frame draws itself in from both ends, the page brightens from dark inside it, components land from above with matching soft shadows, ",
  "category": "ui-entrance",
  "tags": [
    "shotcraft",
    "remotion",
    "ui-entrance",
    "effects"
  ],
  "tier": "free",
  "license": "Apache-2.0",
  "spec": {
    "width": 1920,
    "height": 1080,
    "fps": 30,
    "duration": 4.46,
    "aspect": "16:9"
  },
  "kind": "remotion",
  "params_schema": {
    "type": "object",
    "properties": {}
  },
  "default_params": {},
  "preview": {
    "poster": "https://gimgs.net/motion/media/neon-frame-forerun/poster-3b88ec1d6cbe.jpg",
    "video": "https://gimgs.net/motion/media/neon-frame-forerun/video-196d40740900.mp4"
  },
  "variants": [
    {
      "key": "neon-frame-forerun",
      "label": "neon-frame-forerun · Neon frame forerun",
      "description": "A steep-perspective neon frame draws itself in from both ends, the page brightens from dark inside it, components land from above with matching soft shadows, and background neon tubes dim out at the end.",
      "use": "",
      "video": "https://gimgs.net/motion/media/neon-frame-forerun/video-196d40740900.mp4",
      "poster": "https://gimgs.net/motion/media/neon-frame-forerun/poster-3b88ec1d6cbe.jpg"
    }
  ],
  "credits": {
    "author": "video-shotcraft (Vincent Wei)",
    "url": "https://github.com/Vincentwei1021/video-shotcraft"
  },
  "page_url": "https://gimgs.net/motion/neon-frame-forerun.html",
  "json_url": "https://gimgs.net/motion/neon-frame-forerun.json",
  "template_url": "https://gimgs.net/motion/neon-frame-forerun/template.html",
  "play_url": null,
  "markdown_url": "https://gimgs.net/motion/neon-frame-forerun.md",
  "updated_at": "2026-09-24T07:40:08.229Z",
  "prompt": "## When to use\n\nA \"grand entrance\" ritual for a UI panel in a dark brand film (the frame arrives first, content lands after); a feature area's first appearance; the opening of a neon/cyberpunk-toned segment.\n\n## Intention\n\nFrame first, then fill it in: the neon wireframe draws itself in from both ends like runway lights, announcing \"something is about to appear here\"; as the page brightens from dark inside the frame, components land from above with a trailing shadow — the audience watches the interface being \"placed\" into the frame. The three layers of motion (frame drawing / page lighting up / component landing) must **lock together in sync**: the landing progresses in step with the lighting-up, finishing slightly after, and the frame's light eventually merges into the panel's glow. The background neon tubes dim out at the end, handing all the brightness to the lead subject to close the shot.\n\n## Duration & energy\n\n- Duration: Frame drawing ~0.6s + lighting-up and landing ~2s + background dim-out ~0.8s; whole segment 4–4.5s\n- Energy: Medium-high (three layers of action stacked, all serving the same entrance)\n\n## Shot recipe (original Chinese — timing, easing, parameter table, known pitfalls)\n\n## 意图\n先立框后填肉：霓虹线框像跑道灯一样两头奔画圈出位置，宣告\n\"这里要出现东西\"；页面在框内由暗转亮的同时，组件从空中带影\n贴落——观众看见界面被\"安放\"进框里。三层动作（框奔画/页面点亮/\n组件贴落）必须**同步咬合**：贴落进程与点亮进程同步推进、稍滞后\n收尾，框光最终并入面板辉光。背景霓虹管群终段熄灭，把亮度让给\n主角完成收束。\n\n## 动效核心\n- 霓虹框：强透视直角框（梯形），自左缘中点两头同时奔画（描边\n  动画），带辉光亮头；成型后框光渐并入面板辉光\n- 页面点亮：框内面板由暗灰到亮的显影推进（lit 窗口 ~54f）\n- 组件贴落：框内全部元素套 FloatWrap（graze-face-tour 同款模式）：\n  初始抬高 100–150px、easeFall 加速贴落、同形软影随高度收敛、\n  侧栏自上而下/主区自上而下错峰落位；贴落窗口与点亮窗口同步\n  推进、稍滞后 ~20f 收尾\n- 背景：大霓虹管群先亮衬气氛，终段中亮尾熄（先中间后两端熄灭）\n\n## 参数表\n| 参数 | 典型值 | 调节手感 |\n|------|--------|----------|\n| 框奔画 | ~18f 两头对奔 | 单头描画读作画图；>30f 观众等不及内容 |\n| 悬浮高度 | 100–150px、影随高度收敛 | 判例：高度过小+启动过早=影子不可感（v3 第 1 轮返工加大 1.7x 并延后） |\n| 贴落窗口 | 与点亮窗口同步、滞后 ~20f 收尾 | 贴落先于点亮完＝黑屋子里落家具；滞后太多读作两段戏 |\n| 错峰 | 错开起点、下落重叠并行 | 串行等待被裁（掉落节奏通用判例） |\n| 背景熄灭 | 终段中亮尾熄 ~22f | 不熄灭主角不突出；同帧全熄读作断电 |\n| 贴落粒度 | 行/卡级（原片为逐 UI 卡片级，更细） | 粒度越细越贵；行级已验证可读 |\n\n## 已知坑\n- demo 在灰阶/占位素材上调校通过——参数是调校起点非实战定稿，\n  首次实战须以真实素材回验\n- 悬空贴落=clickup 语言核心签名（已验证的口味信号），本卡\n  与 graze-face-tour 共用 FloatWrap 模式——影子不可感等于没做\n- 与 brand-frame-snap 分工：那张是品牌框咔哒定位的\n  节拍戏；本卡是框先行+内容贴落的登场仪式，框只是序幕\n- 衍生方向备忘：视角旋转变体（镜头左→右弧线旋转+同时贴落）\n  曾被裁\"改改再看\"（要求所有组件同时贴落），已收敛进 neon-frame-orbit-drop 卡\n\n## 参考实现\ndemos/ui-entrance/neon-frame-forerun/\n（NeonFrameForerun.tsx）\n原片出处：clickup-30.mp4\n\n## Reference implementation (Remotion)\n\n- demos/ui-entrance/neon-frame-forerun/NeonFrameForerun.tsx — https://raw.githubusercontent.com/Vincentwei1021/video-shotcraft/main/demos/ui-entrance/neon-frame-forerun/NeonFrameForerun.tsx\n\nThe component imports shared fixtures from `demos/_fixtures` and helpers from `assets/lib` in the repo; SKILL.md there documents the render workflow.\n",
  "flow": [
    {
      "step": "Read the recipe",
      "note": "Prompt = when to use, intention, parameter table with typical values and how each one feels, known pitfalls. Treat values as calibrated starting points."
    },
    {
      "step": "Get the code",
      "tool": "git",
      "cmd": "git clone https://github.com/Vincentwei1021/video-shotcraft && cd video-shotcraft && npm install"
    },
    {
      "step": "Register + render",
      "tool": "remotion",
      "cmd": "npx remotion render <CompositionId> out.mp4   # component: demos/ui-entrance/neon-frame-forerun/NeonFrameForerun.tsx"
    },
    {
      "step": "Or re-implement",
      "note": "Port the timing/easing from the recipe to HTML + WAAPI (gimgs motion contract) or any engine; keep the same segment windows and easing."
    }
  ],
  "files": [
    {
      "path": "demos/ui-entrance/neon-frame-forerun/NeonFrameForerun.tsx",
      "url": "https://raw.githubusercontent.com/Vincentwei1021/video-shotcraft/main/demos/ui-entrance/neon-frame-forerun/NeonFrameForerun.tsx"
    }
  ],
  "contract": "React/Remotion composition (TSX) from the open-source video-shotcraft library (Apache-2.0). It is not a browser-playable template: clone the repo, register the component in a Remotion project and render with `npx remotion render`. The recipe (prompt) describes timing, easing and parameters so you can also re-implement the shot in any engine.",
  "render": {
    "engine": "remotion",
    "frames": 134,
    "repo": "https://github.com/Vincentwei1021/video-shotcraft",
    "files": [
      "https://raw.githubusercontent.com/Vincentwei1021/video-shotcraft/main/demos/ui-entrance/neon-frame-forerun/NeonFrameForerun.tsx"
    ],
    "note": "Clone https://github.com/Vincentwei1021/video-shotcraft (npm install). The component lives under demos/{category}/{name}/ and imports shared fixtures from demos/_fixtures and helpers from assets/lib. Copy it (with those imports) into a Remotion project, register a <Composition> with the template's width/height/fps/duration in Root.tsx, then `npx remotion render <CompositionId> out.mp4`. SKILL.md in the repo documents the full Claude Code / Codex workflow. The prompt below is the shot recipe (timing, easing, parameter table, pitfalls) — enough to re-implement the shot in HTML/WAAPI or another engine if you prefer."
  },
  "source": "// ===== demos/ui-entrance/neon-frame-forerun/NeonFrameForerun.tsx =====\n// neon-frame-forerun v3 —— v2 基础上按用户意见新增（clickup04 五张）：\n// 框内各组件/文字初始悬空在页面上空（3D 抬起），悬空时在面板上映射\n// 同形软影，随页面点亮进程同步先后贴合（FloatWrap 模式，对标截图③：\n// tab/组件悬空带错位影 → ④全部贴合）。v2 已有：强透视直角框左缘中点\n// 两头奔画、面板原地由暗转亮、背景霓虹管框群中亮尾熄。\nimport React, { useId } from 'react';\nimport { AbsoluteFill, useCurrentFrame, interpolate, Easing } from 'remotion';\n\nconst easeFall = Easing.bezier(0.5, 0.05, 0.6, 1); // 加速下落、末端软着陆\n\n/* 悬浮 + 同形软影：h=悬浮高度(px)。本体向左上抬起，原位留模糊压暗同形影，\n * h→0 时重合、影子消失（对标批次11 GrazeFaceTour FloatWrap） */\nconst FloatWrap: React.FC<{ h: number; children: React.ReactNode }> = ({ h, children }) => (\n  <div style={{ position: 'relative' }}>\n    {h > 1 && (\n      <div style={{\n        position: 'absolute', inset: 0,\n        transform: `translate(${h * 0.26}px, ${h * 0.48}px) scale(${1 + h * 0.0012})`,\n        filter: `blur(${2.5 + h * 0.09}px) brightness(0.32) saturate(0.4)`,\n        opacity: Math.min(0.4, 0.16 + h * 0.005),\n        pointerEvents: 'none',\n      }}>{children}</div>\n    )}\n    <div style={{ transform: `translate(${-h * 0.36}px, ${-h * 0.82}px)` }}>{children}</div>\n  </div>\n);\n\n/* land=贴合完成时刻(0..1)，之前从 H 高度加速贴落 */\nconst liftOf = (t: number, land: number, H: number) => {\n  const FALL = 0.3;\n  const p = Math.min(1, Math.max(0, (t - (land - FALL)) / FALL));\n  return (1 - easeFall(p)) * H;\n};\n\nconst mulberry32 = (a: number) => () => {\n  let t = (a += 0x6d2b79f5);\n  t = Math.imul(t ^ (t >>> 15), t | 1);\n  t ^= t + Math.imul(t ^ (t >>> 7), t | 61);\n  return ((t ^ (t >>> 14)) >>> 0) / 4294967296;\n};\n\nconst ink = '#3c3c3a';\nconst mid = '#9a9a98';\nconst line = '#e3e3e1';\n\nconst PW = 1330;\nconst PH = 900;\nconst PL = 1000; // 归一路径长\n\n// 直角矩形路径：从左缘中点出发（对应截图①左缘先亮）\nconst FRAME_D = `M 0 ${PH / 2} L 0 0 L ${PW} 0 L ${PW} ${PH} L 0 ${PH} Z`;\n\nconst Chip: React.FC<{ w: number }> = ({ w }) => (\n  <div style={{\n    width: w, height: 74, background: '#fdfdfc', border: `2px solid ${line}`,\n    borderRadius: 10, padding: '12px 14px', boxSizing: 'border-box',\n    display: 'flex', flexDirection: 'column', gap: 9,\n  }}>\n    <div style={{ height: 11, width: '70%', background: '#b5b5b3', borderRadius: 5 }} />\n    <div style={{ height: 9, width: '48%', background: line, borderRadius: 5 }} />\n  </div>\n);\n\n/* t = 贴落进程(0..1)。各组件按页面展示顺序（侧栏自上而下、主区自上而下）\n * 错峰从空中贴落，悬空时投同形软影（对标截图③虚影→④⑤贴合） */\nconst GrayHome: React.FC<{ t?: number }> = ({ t = 1 }) => {\n  const L = (land: number, H = 72) => liftOf(t, land, H * 1.7);\n  return (\n  <div style={{ width: PW, height: PH, background: '#f5f5f4', borderRadius: 6, display: 'flex', overflow: 'hidden', boxSizing: 'border-box' }}>\n    <div style={{ width: 290, borderRight: `2px solid ${line}`, padding: '26px 24px', boxSizing: 'border-box' }}>\n      <FloatWrap h={L(0.24, 84)}>\n        <div style={{ display: 'flex', alignItems: 'center', gap: 10, marginBottom: 28 }}>\n          <div style={{ width: 28, height: 28, borderRadius: 8, background: ink }} />\n          <div style={{ height: 15, width: 88, background: ink, borderRadius: 7 }} />\n        </div>\n      </FloatWrap>\n      {[76, 56, 96, 110, 66, 60].map((w, i) => (\n        <FloatWrap key={i} h={L(0.3 + i * 0.045, 66)}>\n          <div style={{ display: 'flex', alignItems: 'center', gap: 11, height: 34 }}>\n            <div style={{ width: 17, height: 17, borderRadius: 5, background: mid }} />\n            <div style={{ height: 10, width: w, background: '#c7c7c5', borderRadius: 5 }} />\n          </div>\n        </FloatWrap>\n      ))}\n      <FloatWrap h={L(0.56, 62)}>\n        <div style={{ height: 11, width: 70, background: '#b0b0ae', borderRadius: 5, margin: '24px 0 12px' }} />\n      </FloatWrap>\n      {[104, 126, 96, 118, 88].map((w, i) => (\n        <FloatWrap key={i} h={L(0.62 + i * 0.05, 66)}>\n          <div style={{ display: 'flex', alignItems: 'center', gap: 11, height: 32 }}>\n            <div style={{ width: 16, height: 16, borderRadius: 4, background: '#b8b8b6' }} />\n            <div style={{ height: 10, width: w, background: '#cfcfcd', borderRadius: 5 }} />\n          </div>\n        </FloatWrap>\n      ))}\n    </div>\n    <div style={{ flex: 1, padding: '30px 40px', boxSizing: 'border-box' }}>\n      <FloatWrap h={L(0.26, 90)}>\n        <div style={{ height: 24, width: 130, background: '#565654', borderRadius: 10, marginBottom: 22 }} />\n      </FloatWrap>\n      <FloatWrap h={L(0.34, 80)}>\n        <div style={{ height: 46, border: `2px solid ${line}`, borderRadius: 12, marginBottom: 26, display: 'flex', alignItems: 'center', padding: '0 16px', background: '#f5f5f4' }}>\n          <div style={{ width: 17, height: 17, borderRadius: 9, border: `2px solid ${mid}` }} />\n          <div style={{ height: 10, width: 250, background: line, borderRadius: 5, marginLeft: 12 }} />\n        </div>\n      </FloatWrap>\n      <div style={{ display: 'flex', gap: 16, flexWrap: 'wrap', marginBottom: 30 }}>\n        {[0, 1, 2, 3, 4, 5, 6].map((i) => (\n          <FloatWrap key={i} h={L(0.42 + i * 0.04, 76)}>\n            <Chip w={222} />\n          </FloatWrap>\n        ))}\n      </div>\n      <FloatWrap h={L(0.72, 60)}>\n        <div style={{ display: 'flex', gap: 18, marginBottom: 18 }}>\n          {[54, 84, 50, 82].map((w, i) => (\n            <div key={i} style={{ height: 11, width: w, background: i === 0 ? '#8a8a88' : line, borderRadius: 5 }} />\n          ))}\n        </div>\n      </FloatWrap>\n      {[0, 1, 2, 3].map((i) => (\n        <FloatWrap key={i} h={L(0.78 + i * 0.055, 64)}>\n          <div style={{ display: 'flex', alignItems: 'center', gap: 14, height: 46, borderBottom: `2px solid ${line}` }}>\n            <div style={{ width: 13, height: 13, borderRadius: 7, background: '#c26a6a' }} />\n            <div style={{ height: 11, width: 160 + ((i * 37) % 70), background: '#b6b6b4', borderRadius: 5 }} />\n            <div style={{ marginLeft: 'auto', display: 'flex', gap: 7 }}>\n              {[0, 1, 2].map((k) => <div key={k} style={{ width: 20, height: 20, borderRadius: 10, background: '#d2d2d0' }} />)}\n            </div>\n          </div>\n        </FloatWrap>\n      ))}\n    </div>\n  </div>\n  );\n};\n\n// 背景霓虹管框：大、亮、带透视错落（截图③④）\ntype BgFrame = { x: number; y: number; w: number; h: number; hue: string; phase: number; period: number; skew: number };\nconst rng = mulberry32(20260718);\nconst HUES = ['#b06af0', '#e879c9', '#f0a35c', '#6a7df0', '#e0679a', '#8a5cf0', '#c06af0'];\nconst BG_FRAMES: BgFrame[] = Array.from({ length: 18 }).map(() => ({\n  x: rng() * 2000 - 120, y: rng() * 1100 - 60,\n  w: 160 + rng() * 480, h: 70 + rng() * 220,\n  hue: HUES[Math.floor(rng() * HUES.length)],\n  phase: rng() * 90, period: 55 + rng() * 70,\n  skew: -14 + rng() * 10,\n}));\n\nexport const NeonFrameForerun: React.FC = () => {\n  const frame = useCurrentFrame();\n  // 滤镜/渐变 ID 按实例生成，多实例同场不串引（useId 的 «:» 在 url() 里非法，需清洗）\n  const uid = useId().replace(/[^a-zA-Z0-9]/g, '');\n  // 主框描画：左缘中点向两头奔跑，26 帧成型（截图①→②）\n  const trace = interpolate(frame, [2, 28], [0, 1], {\n    extrapolateLeft: 'clamp', extrapolateRight: 'clamp',\n    easing: Easing.bezier(0.3, 0.1, 0.3, 1),\n  });\n  // 面板原地显影：框成型后内容从近黑到暗灰（截图②），再全亮（截图③）\n  const lit = interpolate(frame, [24, 46, 78], [0.0, 0.3, 1], {\n    extrapolateLeft: 'clamp', extrapolateRight: 'clamp',\n    easing: Easing.bezier(0.35, 0, 0.3, 1),\n  });\n  // 主框独立描边可见度：面板亮起后并入面板 rim 辉光（截图③以后细线淡出，糊辉光留下）\n  const frameLine = interpolate(frame, [50, 90], [1, 0], {\n    extrapolateLeft: 'clamp', extrapolateRight: 'clamp',\n  });\n  const rimGlow = interpolate(frame, [28, 60, 108, 132], [0.9, 1, 0.75, 0.5], {\n    extrapolateLeft: 'clamp', extrapolateRight: 'clamp',\n  });\n  // 背景：中段全亮（截图③④）→ 尾段熄灭（截图⑤）\n  const bgLit = interpolate(frame, [8, 44, 96, 128], [0.15, 1, 0.85, 0.06], {\n    extrapolateLeft: 'clamp', extrapolateRight: 'clamp',\n  });\n  // 强透视 → 缓和：框飞入时角度大，面板亮起后落定（截图①梯形→③④缓斜）\n  const settle = interpolate(frame, [0, 70], [0, 1], {\n    extrapolateLeft: 'clamp', extrapolateRight: 'clamp',\n    easing: Easing.out(Easing.cubic),\n  });\n  const rotY = -26 + 15 * settle;\n  const rotX = 7 - 3 * settle;\n  const rotZ = -9 + 4.5 * settle;\n  const scale = 0.94 + 0.1 * settle;\n  const headP = trace * (PL / 2);\n  // 组件贴落进程：与页面点亮(lit 24→78)同步推进，稍滞后收尾——\n  // \"和页面的展示同步完成贴合\"\n  const drop = interpolate(frame, [34, 98], [0, 1], {\n    extrapolateLeft: 'clamp', extrapolateRight: 'clamp',\n  });\n\n  return (\n    <AbsoluteFill style={{ background: '#060509', overflow: 'hidden' }}>\n      {/* 背景霓虹管框群 */}\n      <svg width={1920} height={1080} style={{ position: 'absolute' }}>\n        <defs>\n          <filter id={`bgblur-${uid}`} x=\"-60%\" y=\"-60%\" width=\"220%\" height=\"220%\">\n            <feGaussianBlur stdDeviation={7} />\n          </filter>\n        </defs>\n        {BG_FRAMES.map((b, i) => {\n          const breath = 0.5 + 0.5 * Math.sin(((frame + b.phase) / b.period) * Math.PI * 2);\n          const op = bgLit * (0.18 + 0.4 * breath);\n          return (\n            <g key={i} transform={`translate(${b.x} ${b.y}) skewY(${b.skew * 0.4}) skewX(${b.skew})`}>\n              <rect width={b.w} height={b.h} rx={4} fill=\"none\"\n                stroke={b.hue} strokeWidth={7} filter={`url(#bgblur-${uid})`} opacity={op * 0.8} />\n              <rect width={b.w} height={b.h} rx={4} fill=\"none\"\n                stroke={b.hue} strokeWidth={2} opacity={op} />\n            </g>\n          );\n        })}\n      </svg>\n      {/* 主体：强透视斜置的框 + 面板 */}\n      <div style={{ position: 'absolute', inset: 0, perspective: 1600, perspectiveOrigin: '42% 40%' }}>\n        <div style={{\n          position: 'absolute', left: (1920 - PW) / 2, top: (1080 - PH) / 2 - 10,\n          transform: `scale(${scale}) rotateY(${rotY}deg) rotateX(${rotX}deg) rotateZ(${rotZ}deg)`,\n          transformStyle: 'preserve-3d',\n        }}>\n          {/* 面板：原地由暗转亮（无位移缩放） */}\n          <div style={{ opacity: trace > 0.55 ? 1 : 0, filter: `brightness(${Math.max(0.05, lit)})` }}>\n            <GrayHome t={drop} />\n            {/* 未点亮时的冷色压暗罩 */}\n            <div style={{\n              position: 'absolute', inset: 0, borderRadius: 6,\n              background: 'linear-gradient(150deg, rgba(30,20,60,0.5), rgba(0,0,0,0.78))',\n              opacity: 1 - lit,\n            }} />\n          </div>\n          {/* 面板 rim 辉光（框光并入后由它承担，底缘最强——对应截图③④底/右缘粉光） */}\n          <div style={{\n            position: 'absolute', left: -10, top: -10, width: PW + 20, height: PH + 20,\n            borderRadius: 12, opacity: rimGlow * Math.min(1, trace * 1.6),\n            boxShadow: '-18px -8px 42px 6px rgba(185,95,240,0.42), 22px 24px 56px 12px rgba(240,150,90,0.30), 0 14px 80px 22px rgba(200,100,220,0.20)',\n          }} />\n          {/* 霓虹描边框：左缘中点出发两头奔画，直角转角 */}\n          <svg width={PW + 80} height={PH + 80} viewBox={`-40 -40 ${PW + 80} ${PH + 80}`}\n            style={{ position: 'absolute', left: -40, top: -40 }}>\n            <defs>\n              <linearGradient id={`mainfg-${uid}`} gradientUnits=\"userSpaceOnUse\" x1={0} y1={0} x2={PW} y2={PH}>\n                <stop offset=\"0%\" stopColor=\"#c07af5\" />\n                <stop offset=\"38%\" stopColor=\"#e58bd8\" />\n                <stop offset=\"72%\" stopColor=\"#f0b06a\" />\n                <stop offset=\"100%\" stopColor=\"#e8925c\" />\n              </linearGradient>\n              <filter id={`fblur-${uid}`} x=\"-40%\" y=\"-40%\" width=\"180%\" height=\"180%\">\n                <feGaussianBlur stdDeviation={10} />\n              </filter>\n              <filter id={`fblur2-${uid}`} x=\"-40%\" y=\"-40%\" width=\"180%\" height=\"180%\">\n                <feGaussianBlur stdDeviation={3} />\n              </filter>\n            </defs>\n            {[1, -1].map((dir) => (\n              <g key={dir}>\n                {/* 糊辉光层：一直保留 */}\n                <path d={FRAME_D} pathLength={PL} fill=\"none\" stroke={`url(#mainfg-${uid})`}\n                  strokeWidth={14} strokeLinecap=\"butt\" filter={`url(#fblur-${uid})`}\n                  strokeDasharray={`${headP} ${PL}`}\n                  strokeDashoffset={dir === 1 ? 0 : -(PL - headP)}\n                  opacity={0.6 * rimGlow} />\n                {/* 亮芯细线：面板亮起后淡出并入 rim */}\n                <path d={FRAME_D} pathLength={PL} fill=\"none\" stroke={`url(#mainfg-${uid})`}\n                  strokeWidth={3.5} strokeLinecap=\"butt\"\n                  strokeDasharray={`${headP} ${PL}`}\n                  strokeDashoffset={dir === 1 ? 0 : -(PL - headP)}\n                  opacity={0.95 * Math.max(frameLine, 0.25)} />\n                {/* 奔跑亮头 */}\n                {trace < 1 && (\n                  <path d={FRAME_D} pathLength={PL} fill=\"none\" stroke=\"#ffffff\"\n                    strokeWidth={6} strokeLinecap=\"round\" filter={`url(#fblur2-${uid})`}\n                    strokeDasharray={`8 ${PL}`}\n                    strokeDashoffset={dir === 1 ? -(Math.max(0, headP - 8)) : -(PL - headP)}\n                    opacity={0.95} />\n                )}\n              </g>\n            ))}\n          </svg>\n        </div>\n      </div>\n    </AbsoluteFill>\n  );\n};\n\n\n"
}