{
  "slug": "dashboard-glow-highlight-pill",
  "title": "Dashboard Glow Highlight Pill",
  "tagline": "A gold wordmark hangs in a black void as a data dashboard rises up in perspective and keeps drifting in 3D; a gold light patch cruises from the right to the bottom, stretching into a pill, then traces the glowing outline of a popup from that pill.",
  "description": "A gold wordmark hangs in a black void as a data dashboard rises up in perspective and keeps drifting in 3D; a gold light patch cruises from the right to the b",
  "category": "effects",
  "tags": [
    "shotcraft",
    "remotion",
    "effects"
  ],
  "tier": "free",
  "license": "Apache-2.0",
  "spec": {
    "width": 1920,
    "height": 1080,
    "fps": 30,
    "duration": 2.5,
    "aspect": "16:9"
  },
  "kind": "remotion",
  "params_schema": {
    "type": "object",
    "properties": {}
  },
  "default_params": {},
  "preview": {
    "poster": "https://gimgs.net/motion/media/dashboard-glow-highlight-pill/poster-3f941a9a2ea9.jpg",
    "video": "https://gimgs.net/motion/media/dashboard-glow-highlight-pill/video-52ffc258b504.mp4"
  },
  "variants": [
    {
      "key": "dashboard-glow-highlight-pill",
      "label": "dashboard-glow-highlight-pill",
      "description": "A gold wordmark hangs in a black void as a data dashboard rises up in perspective and keeps drifting in 3D; a gold light patch cruises from the right to the bottom, stretching into a pill, then traces the glowing outline of a popup from that pill.",
      "use": "",
      "video": "https://gimgs.net/motion/media/dashboard-glow-highlight-pill/video-52ffc258b504.mp4",
      "poster": "https://gimgs.net/motion/media/dashboard-glow-highlight-pill/poster-3f941a9a2ea9.jpg"
    }
  ],
  "credits": {
    "author": "video-shotcraft (Vincent Wei)",
    "url": "https://github.com/Vincentwei1021/video-shotcraft"
  },
  "page_url": "https://gimgs.net/motion/dashboard-glow-highlight-pill.html",
  "json_url": "https://gimgs.net/motion/dashboard-glow-highlight-pill.json",
  "template_url": "https://gimgs.net/motion/dashboard-glow-highlight-pill/template.html",
  "play_url": null,
  "markdown_url": "https://gimgs.net/motion/dashboard-glow-highlight-pill.md",
  "updated_at": "2026-09-24T07:39:54.167Z",
  "prompt": "## When to use\n\nA key-feature reveal for finance/data products; a premium \"pay attention here\" cue; the core beat of a black-and-gold brand film.\n\n## Intention\n\nUse a beam of light to draw the viewer's attention from \"the whole dashboard\" down to \"this one popup.\" The light patch first cruises between panels (announcing something is coming), stretches into a pill (winding up), then traces the popup's outline starting from the pill's landing point (the handoff) — three beats are one continuous deformation of the same beam of light; breaking any one of them turns it into three unrelated animations. The whole shot is only 2s, and every beat starts from where the last one landed.\n\n## Duration & energy\n\n- Duration: About 2.0s (60f@30fps).\n- Energy: High (four beats — rise, cruise, trace, popup — packed into 2s, handoffs must be seamless).\n\n## Shot recipe (original Chinese — timing, easing, parameter table, known pitfalls)\n\n## 意图\n用一束光把观众的注意力从\"整个仪表盘\"收到\"这一个弹窗\"上。光斑先在\n面板间巡游（宣布有东西要来），拉成胶囊（蓄力），再从胶囊落点起笔\n描出弹窗轮廓（交棒）——三段是同一束光的连续变形，任何一处断开就\n变成三个不相干的动画。全片仅 2s，每段都靠上一段的落点做起点。\n\n## 动效核心\n- 金字 \"Ready.\" 用 `background-clip:text` + `drop-shadow` 三层辉光，\n  满亮保持到 t≈0.30 再 `inQuad` 淡出；辉光走 `0.85±0.15·sin(t·π·9)` 呼吸\n- 仪表盘走 10 段 POSE 关键帧（`[t, rotateX, rotateY, tx%, ty%, scale]`，\n  段间 `inOutQuad`）：0.300 时 `rotateX 34°/scale 1.62` 只露顶栏切片，\n  0.365 就基本摆正满幅，之后 yaw 由 −13° 缓扫到 +2.6°，\n  0.62→0.72 有一次 `scale 0.943→0.707` 的后拉让位给弹窗\n- 背景虚化\"先起后退\"：`blur 0→4.5px`（0.58→0.66 inOutQuad）后在\n  0.80→0.93 退掉 52%，压暗层 `dim` 峰值 0.22 保留\n- 光斑 6 段关键帧从 `(80.5%,42%) 22×22` 单调走到 `(44.1%,67.4%) 96×16`\n  ——向左下 + 持续横向拉长，中途不回摆；0.655→0.678 淡出交棒\n- 辉光描边 `stroke-dashoffset` draw-on（0.655→0.775 outQuad），起笔点\n  `SX` 由光斑末帧 x=44.1% 反算；0.79→0.93 收敛：笔宽 2.9→1.0px、\n  `#fff0c4→#e6c887`、辉光几乎撤掉，变成常驻金色细框\n- 弹窗底板 0.665→0.75 先到（opacity×0.72），文字 0.715→0.84 才清晰；\n  弹窗与描边共用完全相同的 transform 链，并按相机姿态的 0.45/0.5 倍\n  做半幅漂移\n\n## 参数表\n| 参数 | 典型值 | 调节手感 |\n|------|--------|----------|\n| 金字淡出 | 满亮到 t≈0.30，0.30→0.355 inQuad | 要和仪表盘升入叠着走；先清场再升入就断了 |\n| 仪表盘升入 | rotateX 34°→5.5°、scale 1.62→1.055，t 0.300→0.365 | 0.065（≈4f）内摆正是故意的：慢了读作\"面板飘上来\"而非\"镜头压下去\" |\n| 常驻 3D 漂移 | yaw −13°→+2.6°，scale 0.943→0.707 | 漂移不能停：一静止就露出这是张贴图 |\n| 光斑巡游 | 6 帧关键帧，22×22 → 96×16 | 单调向左下 + 只拉长不回摆；回摆一次就读作\"光在找东西\" |\n| 背景虚化 | blur 峰值 4.5px，0.80→0.93 退掉 52%，dim 0.22 | 只起不退 = 结尾整幅糊；退到 0 又失去弹窗的层次 |\n| 描边 draw-on | dashoffset 0.655→0.775 outQuad，从底边起笔逆时针 | outQuad 快起步才接得住胶囊的\"甩出去\"的势 |\n| 描边收敛 | 0.79→0.93：2.9→1.0px、#fff0c4→#e6c887 | 收敛是\"光变成 UI\"的语义；不收敛就一直是特效 |\n| 弹窗淡入 | 底板 0.665→0.75（上限 0.72 透明度）、文字 0.715→0.84 | 底板先于文字，才有\"框先在、内容后填\"的顺序 |\n\n## 已知坑\n- **描边 SVG 与弹窗必须共用同一个盒子和 1:1 px 的 viewBox**。曾用\n  `300×220` + `preserveAspectRatio=\"none\"`，被非等比压成 x0.39/y0.49：\n  笔宽横竖不一、圆角拉成椭圆、整条描边浮在轮廓外——这是\"画光位置和\n  弹窗不一致\"的根因\n- 光斑不能用 `mix-blend-mode:screen`：root 上有 `perspective` 会把混合\n  隔离掉导致光斑发灰；改用实心亮核 + `box-shadow` 外扩辉光\n- 描边起笔点 `SX` 必须由光斑末帧 x 反算。写死坐标后一改巡游路径，\n  \"光拉成胶囊再描边\"的交棒就断了\n- 金字用 `background-clip:text`，辉光只能走 `filter: drop-shadow`——\n  `text-shadow` 对透明字无效\n- 仪表盘的订单簿/K 线/买卖面板与弹窗文案全是占位数据（确定性随机\n  游走生成），落地要换成项目真实界面\n\n## 参考实现\ndemos/effects/dashboard-glow-highlight-pill/\n（DashboardGlowHighlightPill.tsx）\n\n## Reference implementation (Remotion)\n\n- demos/effects/dashboard-glow-highlight-pill/DashboardGlowHighlightPill.tsx — https://raw.githubusercontent.com/Vincentwei1021/video-shotcraft/main/demos/effects/dashboard-glow-highlight-pill/DashboardGlowHighlightPill.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/effects/dashboard-glow-highlight-pill/DashboardGlowHighlightPill.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/effects/dashboard-glow-highlight-pill/DashboardGlowHighlightPill.tsx",
      "url": "https://raw.githubusercontent.com/Vincentwei1021/video-shotcraft/main/demos/effects/dashboard-glow-highlight-pill/DashboardGlowHighlightPill.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": 75,
    "repo": "https://github.com/Vincentwei1021/video-shotcraft",
    "files": [
      "https://raw.githubusercontent.com/Vincentwei1021/video-shotcraft/main/demos/effects/dashboard-glow-highlight-pill/DashboardGlowHighlightPill.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/effects/dashboard-glow-highlight-pill/DashboardGlowHighlightPill.tsx =====\n// dashboard-glow-highlight-pill — Glow Highlight Pill 金色胶囊指引（motion-lab 定稿转原生 Remotion）\n// 金字 \"Ready.\" 悬于黑场，数据仪表盘（订单簿+K线+买卖面板，内容为占位数据）自底带透视升入后\n// 保持缓慢 rotateX/rotateY 3D 漂移；金色光斑从右侧面板巡游至底部中央拉成胶囊，背景虚化压暗\n// （仪表盘继续漂），辉光描边从底边逆时针描出 Focus Mode 弹窗轮廓，内容淡入后描边收敛为金色细框。\n// 设计坐标 480×270（DesignStage raster=\"zoom\" 等比放大），参数表数值以此坐标系标定。\n// 验收：SSIM mean=0.9583/min=0.9510（BORDERLINE，对照条逐帧肉眼一致）。余差为近黑底\n// 的 x264 暗场量化：把首帧自渲 PNG 过同参数 x264 后与原样片比对得 0.9977——内容已\n// 像素级一致，直接比对的 -0.04 全部来自样片解码端的暗部压缩（2-30 电平带被压到 ~0.8x）。\nimport React from 'react';\nimport { DesignStage, E, lerp, rand, seg, useT } from '../../_fixtures/Motion';\n\nexport const DASHBOARD_GLOW_HIGHLIGHT_PILL_DURATION = 60; // 2000ms @30fps\n\n// ---- 订单簿行（上红下绿，渐变量条；种子与 effect.js 逐一对应） ----\nconst OB_ROWS = Array.from({ length: 7 }, (_, i) => ({\n  wRed: (30 + rand(i * 3 + 1) * 65).toFixed(0),\n  wGreen: (30 + rand(i * 7 + 4) * 65).toFixed(0),\n  priceRed: `1${(155.4 - i * 0.12).toFixed(2)}`,\n  priceGreen: `1${(155.0 - i * 0.12).toFixed(2)}`,\n  amtRed: (rand(i * 11) * 9 + 0.4).toFixed(3),\n  amtGreen: (rand(i * 13 + 6) * 9 + 0.4).toFixed(3),\n}));\n\n// ---- K 线（确定性随机游走，dv 负偏置 → 整体上行；SVG y 轴向下） ----\nconst CANDLES: Array<{ x: number; hi: string; lo: string; yTop: string; h: string; col: string; volY: string }> = (() => {\n  const out = [];\n  let px = 104;\n  for (let i = 0; i < 36; i++) {\n    const dv = (rand(i * 2.7 + 9) - 0.6) * 13;\n    const o = px;\n    const c = px + dv;\n    px = c;\n    const hi = Math.min(o, c) - rand(i * 5.1) * 5;\n    const lo = Math.max(o, c) + rand(i * 3.3) * 5;\n    const up = c < o;\n    out.push({\n      x: 6 + i * 7.6,\n      hi: hi.toFixed(1),\n      lo: lo.toFixed(1),\n      yTop: Math.min(o, c).toFixed(1),\n      h: Math.max(1.5, Math.abs(dv)).toFixed(1),\n      col: up ? '#2bbf8a' : '#d6455a',\n      volY: (128 - rand(i * 1.9 + 3) * 16).toFixed(1),\n    });\n  }\n  return out;\n})();\n\n// ---- Focus Mode 弹窗几何（原片逐帧实测，注释见 effect.js） ----\nconst MW = 24.5, MH = 40, MCX = 48.4, MCY = 47; // % of root\nconst MRAD = 5; // 弹窗圆角（px），描边共用\nconst RW = 480, RH = 270;\nconst BW = (RW * MW) / 100, BH = (RH * MH) / 100; // 弹窗盒子像素尺寸\nconst BO = 0.5; // 描边压在 1px 边框中线上\n// 起笔点 = 胶囊停住的位置（BLOB 末帧 x 44.1%），换算成盒内坐标\nconst SX = ((44.1 - (MCX - MW / 2)) / MW) * BW;\n// 描边路径：底边中点起、逆时针一整圈（与 effect.js 的 D 字符串逐字节一致）\nconst TRACE_D =\n  `M${SX.toFixed(1)} ${(BH - BO).toFixed(1)}` +\n  ` L${(MRAD + BO).toFixed(1)} ${(BH - BO).toFixed(1)}` +\n  ` A${MRAD} ${MRAD} 0 0 1 ${BO} ${(BH - MRAD - BO).toFixed(1)}` +\n  ` L${BO} ${(MRAD + BO).toFixed(1)}` +\n  ` A${MRAD} ${MRAD} 0 0 1 ${(MRAD + BO).toFixed(1)} ${BO}` +\n  ` L${(BW - MRAD - BO).toFixed(1)} ${BO}` +\n  ` A${MRAD} ${MRAD} 0 0 1 ${(BW - BO).toFixed(1)} ${(MRAD + BO).toFixed(1)}` +\n  ` L${(BW - BO).toFixed(1)} ${(BH - MRAD - BO).toFixed(1)}` +\n  ` A${MRAD} ${MRAD} 0 0 1 ${(BW - MRAD - BO).toFixed(1)} ${(BH - BO).toFixed(1)}` +\n  ` L${SX.toFixed(1)} ${(BH - BO).toFixed(1)}`;\n// pathLength 归一化：dashoffset 直接按百分比走，免去 getTotalLength 运行时测量\nconst P_L = 100;\n\n// 关键帧插值（segments 间 inOutQuad；lerp 签名是 lerp(t, a, b)）\nconst KF = (rows: number[][], t: number): number[] => {\n  if (t <= rows[0][0]) return rows[0].slice(1);\n  for (let i = 1; i < rows.length; i++) {\n    if (t <= rows[i][0]) {\n      const a = rows[i - 1], b = rows[i];\n      const p = E.inOutQuad((t - a[0]) / (b[0] - a[0]));\n      return a.slice(1).map((_, k) => lerp(p, a[k + 1], b[k + 1]));\n    }\n  }\n  return rows[rows.length - 1].slice(1);\n};\n\n// ---- 逐帧校准的姿态关键帧：[t, rotateX, rotateY, translateX%, translateY%, scale]\n// 0.30 只有顶栏切片露在画面底部 → 0.365 基本满幅摆正 → 之后缓慢 3D 漂移；\n// 0.62-0.72 有一次明显镜头后拉（87% → 61.5% 宽），把画面让给弹窗。\nconst POSE = [\n  [0.3, 34.0, -13.0, -7.0, 47.0, 1.62],\n  [0.322, 24.0, -11.0, -5.5, 30.0, 1.44],\n  [0.345, 13.0, -8.0, -3.5, 14.0, 1.22],\n  [0.365, 5.5, -5.0, -1.6, 4.0, 1.055],\n  [0.42, 2.6, -3.0, -0.6, 0.4, 1.005],\n  [0.5, 2.2, -2.0, -0.3, 0.0, 0.966],\n  [0.62, 1.8, -0.6, 0.0, -0.5, 0.943],\n  [0.67, 1.6, 0.6, -0.4, -0.8, 0.852],\n  [0.72, 1.4, 1.4, -0.8, -1.1, 0.707],\n  [1.0, 1.2, 2.6, -0.9, -1.3, 0.7],\n];\n\n// 光斑巡游关键帧 [t, x%, y%, w, h]：右侧面板圆斑 → 左下移动拉长 → 停在弹窗底边偏左（=描边起笔点）\nconst BLOB = [\n  [0.4, 80.5, 42.0, 22, 22],\n  [0.44, 79.7, 46.5, 27, 30],\n  [0.5, 77.7, 56.3, 29, 36],\n  [0.56, 71.1, 63.9, 56, 25],\n  [0.61, 57.6, 65.2, 82, 21],\n  [0.65, 44.1, 67.4, 96, 16],\n];\n\nconst FS = (n: number): React.CSSProperties => ({ fontSize: n });\nconst rowBetween: React.CSSProperties = { display: 'flex', justifyContent: 'space-between' };\n\n// 订单簿一行（红/绿共用结构，量条右对齐渐变）\nconst ObRow: React.FC<{ w: string; price: string; amt: string; red?: boolean }> = ({ w, price, amt, red }) => (\n  <div style={{ position: 'relative', height: 8.5, margin: '1px 0' }}>\n    <div\n      style={{\n        position: 'absolute', right: 0, top: 0, bottom: 0, width: `${w}%`,\n        background: red\n          ? 'linear-gradient(90deg,rgba(214,69,90,.08),rgba(214,69,90,.4))'\n          : 'linear-gradient(90deg,rgba(43,191,138,.08),rgba(43,191,138,.4))',\n      }}\n    />\n    <span style={{ position: 'relative', fontSize: 5, color: red ? '#e05a70' : '#3ecf96', paddingLeft: 2 }}>{price}</span>\n    <span style={{ position: 'relative', float: 'right', fontSize: 5, color: '#7c828c', paddingRight: 2 }}>{amt}</span>\n  </div>\n);\n\nexport const DashboardGlowHighlightPill: React.FC = () => {\n  const t = useT();\n\n  // 金字：满亮保持到 t≈0.30，0.30-0.355 淡出；辉光轻微呼吸\n  const yOut = seg(t, 0.3, 0.355, E.inQuad);\n  const br = 0.85 + 0.15 * Math.sin(t * Math.PI * 9);\n\n  // 仪表盘姿态（全部走 KF，不叠加二次 ease）\n  const [prx, pry, ptx, pty, ps] = KF(POSE, t);\n  const dashOp = t >= 0.298 ? seg(t, 0.298, 0.315) : 0;\n\n  // 背景虚化\"先起后退\"：0.58-0.66 起，0.80-0.93 退掉约一半（原片终帧清晰度仍低于满清晰）\n  const blUp = seg(t, 0.58, 0.66, E.inOutQuad);\n  const blDown = seg(t, 0.8, 0.93, E.inOutQuad);\n  const bl = blUp * (1 - blDown * 0.52);\n\n  // 光斑 0.385-0.425 浮现 → 巡游拉长 → 0.655-0.678 交棒给描边\n  const gOn = seg(t, 0.385, 0.425, E.outCubic);\n  const gOff = seg(t, 0.655, 0.678, E.inQuad);\n  const [bx, by, bw, bh] = KF(BLOB, t);\n\n  // 描边 draw-on 0.655-0.775 走完一圈（outQuad 快起步），0.79-0.93 收敛成金色细框\n  const dr = seg(t, 0.655, 0.775, E.outQuad);\n  const settle = seg(t, 0.79, 0.93, E.inOutQuad);\n\n  // 弹窗内容淡入：底板比文字早一点到位\n  const mBase = seg(t, 0.665, 0.75, E.outCubic);\n  const mc = seg(t, 0.715, 0.84, E.outCubic);\n  // 弹窗/描边跟随半幅相机漂移，与背景仪表盘同向浮动\n  const mDrift =\n    ` rotateX(${(prx * 0.45).toFixed(2)}deg) rotateY(${(pry * 0.45).toFixed(2)}deg)` +\n    ` translate(${(ptx * 0.5).toFixed(2)}%,${(pty * 0.5).toFixed(2)}%)`;\n  const modalTransform = `translate(-50%,-50%) scale(${(0.985 + mc * 0.015).toFixed(4)})` + mDrift;\n\n  return (\n    <DesignStage bg=\"#050403\" raster=\"zoom\">\n      <div\n        style={{\n          position: 'absolute', inset: 0, background: '#050403', overflow: 'hidden',\n          perspective: 800, fontFamily: '-apple-system,system-ui,sans-serif',\n        }}\n      >\n        {/* 暖色底光（原片黑场并非纯黑，顶部偏暖褐） */}\n        <div\n          style={{\n            position: 'absolute', inset: 0, pointerEvents: 'none',\n            background: 'radial-gradient(130% 95% at 42% -8%,rgba(104,74,30,.32),rgba(44,32,14,.14) 42%,rgba(0,0,0,0) 74%)',\n          }}\n        />\n        {/* 开场发光金字（上端浅暖白、下端沉到金褐；background-clip:text 辉光只能走 filter） */}\n        <div\n          style={{\n            position: 'absolute', left: '50%', top: '49%', transform: 'translate(-50%,-50%)',\n            fontSize: 27, fontWeight: 400, letterSpacing: 0.2, whiteSpace: 'nowrap',\n            background: 'linear-gradient(178deg,#fff8e2 6%,#f6dfa4 44%,#e0bd72 70%,#c99a45 100%)',\n            WebkitBackgroundClip: 'text', backgroundClip: 'text', color: 'transparent',\n            opacity: 1 - yOut,\n            filter:\n              `drop-shadow(0 0 7px rgba(255,232,168,${(0.8 * br).toFixed(2)}))` +\n              ` drop-shadow(0 0 20px rgba(233,190,105,${(0.5 * br).toFixed(2)})) drop-shadow(0 0 44px rgba(200,158,78,.3))`,\n          }}\n        >\n          Ready.\n        </div>\n\n        {/* 交易所仪表盘（自底带透视升入；基准尺寸=落位后满幅，靠 scale 推拉） */}\n        <div\n          style={{\n            position: 'absolute', left: '50%', top: '50%', width: '87%', height: '91%',\n            opacity: dashOp,\n            transform:\n              `translate(-50%,-50%) translate(${ptx.toFixed(2)}%,${pty.toFixed(2)}%)` +\n              ` rotateX(${prx.toFixed(2)}deg) rotateY(${pry.toFixed(2)}deg) scale(${ps.toFixed(4)})`,\n          }}\n        >\n          <div\n            style={{\n              position: 'absolute', inset: 0, borderRadius: 6, background: '#101114',\n              border: '1px solid #24272d', overflow: 'hidden', boxShadow: '0 20px 50px rgba(0,0,0,.6)',\n              filter: `blur(${(bl * 4.5).toFixed(2)}px) brightness(${(1.5 + bl * 0.05).toFixed(3)}) saturate(1.06)`,\n            }}\n          >\n            {/* 顶栏 */}\n            <div style={{ height: '9%', borderBottom: '1px solid #1a1c20', display: 'flex', alignItems: 'center', padding: '0 8px', gap: 10 }}>\n              <span style={{ fontSize: 8, fontWeight: 800, color: '#e8e6df', letterSpacing: 1 }}>◆ ACME</span>\n              <span style={{ ...FS(6), color: '#9aa0aa' }}>Trade</span>\n              <span style={{ ...FS(6), color: '#565c66' }}>Earn</span>\n              <span style={{ ...FS(6), color: '#565c66' }}>Vault</span>\n              <span style={{ marginLeft: 'auto', ...FS(6), color: '#565c66' }}>Support {' '} 0x8f...c2 {' '}</span>\n              <span style={{ ...FS(6), color: '#0b0c0e', background: '#e6c476', borderRadius: 3, padding: '1px 5px', fontWeight: 700 }}>Connect</span>\n            </div>\n            {/* 左：订单簿 */}\n            <div style={{ position: 'absolute', left: 0, top: '9%', bottom: '16%', width: '24%', borderRight: '1px solid #1a1c20', padding: '4px 5px', boxSizing: 'border-box' }}>\n              <div style={{ display: 'flex', gap: 8, marginBottom: 3 }}>\n                <span style={{ ...FS(6), color: '#d8dbe0', borderBottom: '1px solid #e6c476', paddingBottom: 1 }}>Orderbook</span>\n                <span style={{ ...FS(6), color: '#565c66' }}>Trades</span>\n              </div>\n              {OB_ROWS.map((r, i) => (\n                <ObRow key={`r${i}`} w={r.wRed} price={r.priceRed} amt={r.amtRed} red />\n              ))}\n              <div style={{ fontSize: 7, fontWeight: 800, color: '#e05a70', padding: 2 }}>155.01 ▼</div>\n              {OB_ROWS.map((r, i) => (\n                <ObRow key={`g${i}`} w={r.wGreen} price={r.priceGreen} amt={r.amtGreen} />\n              ))}\n            </div>\n            {/* 中：K 线 */}\n            <div style={{ position: 'absolute', left: '24%', top: '9%', bottom: '16%', right: '22%', padding: '4px 6px', boxSizing: 'border-box' }}>\n              <div style={{ display: 'flex', alignItems: 'baseline', gap: 6 }}>\n                <span style={{ fontSize: 7, fontWeight: 700, color: '#e8e6df' }}>\n                  ● TOKEN-USD <span style={{ color: '#565c66', fontSize: 5 }}>PERP</span>\n                </span>\n                <span style={{ fontSize: 8, fontWeight: 800, color: '#3ecf96' }}>155.01</span>\n                <span style={{ ...FS(5), color: '#7c828c' }}>24h Vol $1,891,145.10 {' '} Funding 0.0042% {' '} OI $9.4M</span>\n              </div>\n              <svg viewBox=\"0 0 290 130\" style={{ width: '100%', height: '84%' }} preserveAspectRatio=\"none\">\n                {CANDLES.map((c, i) => (\n                  <React.Fragment key={i}>\n                    <line x1={c.x + 2} y1={c.hi} x2={c.x + 2} y2={c.lo} stroke={c.col} strokeWidth={0.8} />\n                    <rect x={c.x} y={c.yTop} width={4} height={c.h} fill={c.col} />\n                    <rect x={c.x} y={c.volY} width={4} height={16} fill={c.col} opacity={0.45} />\n                  </React.Fragment>\n                ))}\n              </svg>\n            </div>\n            {/* 右：买卖面板 */}\n            <div style={{ position: 'absolute', right: 0, top: '9%', bottom: '16%', width: '22%', borderLeft: '1px solid #1a1c20', padding: '4px 6px', boxSizing: 'border-box' }}>\n              <div style={{ display: 'flex', gap: 3, marginBottom: 4 }}>\n                <span style={{ flex: 1, textAlign: 'center', fontSize: 5.5, color: '#d8dbe0', background: '#1d2026', borderRadius: 3, padding: '2px 0' }}>Cross</span>\n                <span style={{ flex: 1, textAlign: 'center', fontSize: 5.5, color: '#7c828c', background: '#14161a', borderRadius: 3, padding: '2px 0' }}>10x</span>\n                <span style={{ flex: 1, textAlign: 'center', fontSize: 5.5, color: '#7c828c', background: '#14161a', borderRadius: 3, padding: '2px 0' }}>One-Way</span>\n              </div>\n              <div style={{ ...rowBetween, ...FS(5), color: '#7c828c', marginBottom: 2 }}>\n                <span>Market</span><span>Limit</span><span>Pro</span>\n              </div>\n              <div style={{ height: 5, margin: '4px 0', background: 'linear-gradient(90deg,#e6c476,#e6c476 60%,#2a2d33 60%)', borderRadius: 2 }} />\n              <div style={{ ...FS(5), color: '#7c828c', marginBottom: 4 }}>▢ Reduce Only</div>\n              <div style={{ display: 'flex', gap: 4, marginBottom: 5 }}>\n                <div style={{ flex: 1, height: 14, borderRadius: 3, background: '#19a374', display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: 6, fontWeight: 700, color: '#04120c' }}>Buy</div>\n                <div style={{ flex: 1, height: 14, borderRadius: 3, background: '#d6455a', display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: 6, fontWeight: 700, color: '#1c0508' }}>Sell</div>\n              </div>\n              {(['Current Position|0.00 TOKEN', 'Liq. Price|--', 'Order Value|$0.00', 'Margin Required|$0.00', 'Fees|0.035% / 0.010%'] as const).map((s) => {\n                const p = s.split('|');\n                return (\n                  <div key={p[0]} style={{ ...rowBetween, ...FS(5), color: '#7c828c', marginBottom: 2.5 }}>\n                    <span>{p[0]}</span><span style={{ color: '#b9bec6' }}>{p[1]}</span>\n                  </div>\n                );\n              })}\n              <div style={{ borderTop: '1px solid #1a1c20', marginTop: 4, paddingTop: 3, fontSize: 5.5, color: '#d8dbe0' }}>Account</div>\n              {(['Portfolio Margin|$20,182.49', 'Unrealized PNL|+$142.11', 'Available|$1,021.19'] as const).map((s) => {\n                const p = s.split('|');\n                return (\n                  <div key={p[0]} style={{ ...rowBetween, ...FS(5), color: '#7c828c', marginTop: 2.5 }}>\n                    <span>{p[0]}</span><span style={{ color: '#b9bec6' }}>{p[1]}</span>\n                  </div>\n                );\n              })}\n            </div>\n            {/* 底：持仓表 */}\n            <div style={{ position: 'absolute', left: 0, right: 0, bottom: 0, height: '16%', borderTop: '1px solid #1a1c20', padding: '3px 8px', boxSizing: 'border-box' }}>\n              <div style={{ display: 'flex', gap: 9, marginBottom: 3 }}>\n                {['Positions (2)', 'Open Orders (0)', 'Balances', 'Order History', 'Trade History', 'Funding History', 'Position History'].map((s, i) => (\n                  <span key={s} style={{ ...FS(5), color: i === 0 ? '#d8dbe0' : '#565c66' }}>{s}</span>\n                ))}\n              </div>\n              {[0, 1].map((i) => (\n                <div key={i} style={{ display: 'flex', gap: 12, ...FS(5), color: '#7c828c', marginBottom: 2 }}>\n                  <span style={{ color: '#d8dbe0' }}>{i === 0 ? 'TOKEN' : 'ALT'}-USD</span>\n                  <span style={{ color: i === 0 ? '#3ecf96' : '#e05a70' }}>{i === 0 ? '+12.40' : '-3.61'}</span>\n                  <span>152.30</span><span>$7,801.75</span><span>$1,775.00</span><span>74,212.07</span><span>$53,225.00</span>\n                  <span style={{ color: '#e6c476' }}>Market | Limit</span>\n                  <span style={{ color: '#7c828c' }}>Reverse</span>\n                </div>\n              ))}\n            </div>\n          </div>\n        </div>\n\n        {/* 虚化压暗层 */}\n        <div style={{ position: 'absolute', inset: 0, background: 'rgba(6,5,4,.4)', opacity: blUp * 0.22, pointerEvents: 'none' }} />\n\n        {/* 金色巡游光斑：实心亮核 + box-shadow 外扩辉光（root 有 perspective，screen 混合会被隔离，见 effect.js） */}\n        <div\n          style={{\n            position: 'absolute',\n            left: `${bx.toFixed(2)}%`, top: `${by.toFixed(2)}%`,\n            width: Number(bw.toFixed(1)), height: Number(bh.toFixed(1)),\n            borderRadius: Number((bh / 2).toFixed(1)),\n            transform: 'translate(-50%,-50%)',\n            background: 'radial-gradient(60% 60% at 50% 50%,#fffefa 0%,#fffdf2 40%,#ffeec2 66%,rgba(255,206,110,.5) 85%,rgba(212,165,70,0))',\n            filter: 'blur(2px)',\n            opacity: gOn * (1 - gOff),\n            pointerEvents: 'none',\n            boxShadow: '0 0 18px rgba(255,235,175,.95),0 0 44px rgba(240,200,120,.6),0 0 90px rgba(212,175,90,.35)',\n          }}\n        />\n\n        {/* Focus Mode 弹窗（描边与它共用同一个盒子与 transform 链，全程贴合轮廓） */}\n        <div\n          style={{\n            position: 'absolute', left: `${MCX}%`, top: `${MCY}%`, width: `${MW}%`, height: `${MH}%`,\n            transform: modalTransform,\n            opacity: Math.max(mBase * 0.72, mc),\n            borderRadius: MRAD,\n            background: 'linear-gradient(170deg,#141310,#0d0c0a)',\n            border: '1px solid rgba(230,196,118,.3)',\n            boxShadow: `0 0 ${(12 * mc).toFixed(1)}px rgba(212,175,90,${(0.3 * mc).toFixed(3)}),0 18px 44px rgba(0,0,0,.72)`,\n            padding: '6px 7px', boxSizing: 'border-box',\n          }}\n        >\n          <div style={{ fontSize: 5.5, fontWeight: 700, color: '#f2ead2', marginBottom: 4 }}>Focus Mode</div>\n          <div style={{ fontSize: 3.4, lineHeight: 1.62, color: '#8b8f98', marginBottom: 3 }}>\n            All panels share one unified workspace layout. Changes in one panel are reflected in the others,{' '}\n            <span style={{ color: '#cbb26a' }}>keeping context in one place</span>.\n          </div>\n          <div style={{ fontSize: 3.4, color: '#8b8f98', marginBottom: 4 }}>Choose how panels are arranged:</div>\n          <div style={{ border: '1px solid rgba(230,196,118,.42)', borderRadius: 3, background: 'rgba(230,196,118,.05)', padding: '4px 5px', marginBottom: 4 }}>\n            <div style={{ fontSize: 4, fontWeight: 700, color: '#eee6cc' }}>● Standard</div>\n            <div style={{ fontSize: 3.3, lineHeight: 1.55, color: '#8b8f98', marginTop: 1.5 }}>\n              Placeholder body copy for option one. The selected option directly determines the layout of each panel — simple and predictable.\n            </div>\n          </div>\n          <div style={{ border: '1px solid #23252a', borderRadius: 3, padding: '4px 5px' }}>\n            <div style={{ fontSize: 4, fontWeight: 700, color: '#b9bec6' }}>○ Pro</div>\n            <div style={{ fontSize: 3.3, lineHeight: 1.55, color: '#71757e', marginTop: 1.5 }}>\n              Placeholder body copy for option two, written a little longer so the block keeps its shape. Replace both with your own wording.\n            </div>\n          </div>\n          <div\n            style={{\n              position: 'absolute', left: 7, right: 7, bottom: 6, height: 9, borderRadius: 2.5,\n              background: 'linear-gradient(180deg,#e2bd63,#caa03e)',\n              display: 'flex', alignItems: 'center', justifyContent: 'center',\n              fontSize: 4, fontWeight: 700, color: '#241b06',\n            }}\n          >\n            Confirm\n          </div>\n        </div>\n\n        {/* 辉光描边（viewBox 1 unit = 1 CSS px；pathLength 归一化免运行时 getTotalLength） */}\n        <div\n          style={{\n            position: 'absolute', left: `${MCX}%`, top: `${MCY}%`, width: `${MW}%`, height: `${MH}%`,\n            transform: modalTransform,\n            pointerEvents: 'none',\n            opacity: dr > 0.001 ? 1 - settle * 0.42 : 0,\n            mixBlendMode: 'screen',\n          }}\n        >\n          <svg viewBox={`0 0 ${BW.toFixed(2)} ${BH.toFixed(2)}`} style={{ width: '100%', height: '100%', overflow: 'visible' }}>\n            <path\n              d={TRACE_D}\n              pathLength={P_L}\n              fill=\"none\"\n              stroke={settle > 0.5 ? '#e6c887' : '#fff0c4'}\n              strokeWidth={Number((2.9 - settle * 1.9).toFixed(2))}\n              strokeLinecap=\"round\"\n              strokeDasharray={`${P_L} ${P_L}`}\n              strokeDashoffset={Number((P_L * (1 - dr)).toFixed(1))}\n              style={{\n                filter:\n                  settle > 0.001\n                    ? `drop-shadow(0 0 ${(3 - settle * 2.3).toFixed(2)}px rgba(255,232,160,${(0.95 - settle * 0.5).toFixed(2)}))` +\n                      ` drop-shadow(0 0 ${(10 - settle * 8).toFixed(1)}px rgba(240,200,110,${(0.75 - settle * 0.62).toFixed(2)}))`\n                    : 'drop-shadow(0 0 3px rgba(255,232,160,.95)) drop-shadow(0 0 10px rgba(240,200,110,.75)) drop-shadow(0 0 26px rgba(212,175,90,.4))',\n              }}\n            />\n          </svg>\n        </div>\n      </div>\n    </DesignStage>\n  );\n};\n\n\n"
}