{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "shape-cut",
  "title": "Shape Cut",
  "description": "A circle, square or pill grows from the text and cuts to the next scene with the logo.",
  "dependencies": ["remotion", "@remotion/google-fonts"],
  "files": [
    {
      "path": "registry/remocn/shape-cut/index.tsx",
      "content": "\"use client\";\n\nimport { loadFont as loadDisplay } from \"@remotion/google-fonts/BricolageGrotesque\";\nimport { loadFont as loadManrope } from \"@remotion/google-fonts/Manrope\";\nimport type React from \"react\";\nimport { useId } from \"react\";\nimport {\n  AbsoluteFill,\n  Easing,\n  interpolate,\n  useCurrentFrame,\n  useVideoConfig,\n} from \"remotion\";\n\nconst { fontFamily: display } = loadDisplay(\"normal\", {\n  weights: [\"500\"],\n  subsets: [\"latin\"],\n});\nconst manrope = loadManrope(\"normal\", {\n  weights: [\"600\"],\n  subsets: [\"latin\"],\n});\n\nexport type ShapeCutShape = \"circle\" | \"square\" | \"pill\";\n\nexport interface ShapeCutProps {\n  from?: string;\n  to?: string;\n  shape?: ShapeCutShape;\n  accent?: string;\n  theme?: \"dark\" | \"light\";\n  speed?: number;\n}\n\nconst CLAMP = {\n  extrapolateLeft: \"clamp\",\n  extrapolateRight: \"clamp\",\n} as const;\n\nconst G0 = 12;\nconst GP = 34;\nconst G1 = 62;\n\nconst PATH = Easing.bezier(0.65, 0, 0.35, 1);\nconst GROW = Easing.bezier(0.55, 0, 0.5, 1);\nconst SHRINK = Easing.bezier(0.4, 0, 0.15, 1);\nconst SETTLE = Easing.bezier(0.22, 1, 0.36, 1);\n\nconst STAGES = {\n  dark: { bg: \"#0A0A0B\", fg: \"#F3F2EF\", light: \"rgba(143,180,255,0.075)\" },\n  light: { bg: \"#F5F4F0\", fg: \"#121214\", light: \"rgba(255,255,255,0.9)\" },\n};\n\n// Bricolage Grotesque 500 advances (1/1000 em, ASCII 32–126) and kerning pairs, from HarfBuzz.\nconst BRIC_ADV = [\n  246, 266, 317, 613, 630, 947, 756, 159, 305, 290, 395, 516, 165, 339, 196,\n  354, 656, 320, 583, 595, 595, 600, 646, 494, 646, 641, 207, 188, 516, 516,\n  516, 413, 952, 671, 666, 671, 691, 599, 578, 706, 709, 275, 358, 666, 508,\n  909, 747, 716, 629, 719, 660, 641, 553, 718, 657, 957, 653, 600, 560, 315,\n  342, 300, 547, 578, 283, 567, 618, 555, 617, 570, 380, 589, 608, 260, 266,\n  561, 257, 913, 608, 604, 618, 617, 411, 535, 380, 599, 547, 827, 534, 591,\n  500, 353, 260, 331, 516,\n];\nconst BRIC_KERN =\n  \"AA16 AC-25 AG-24 AJ21 AO-25 AQ-15 AS-9 AT-67 AU-26 AV-83 AW-53 AY-78 AZ20 Ac-13 Ad-13 Ae-13 Af-24 Ao-14 Aq-13 At-25 Au-18 Av-52 Aw-37 Ax9 Ay-10 Az13 A.28 A,25 BT-12 BV-18 BW-8 BX-17 BY-20 B,-8 CA-9 CS16 CV-13 CX-17 CY-16 Cg-8 DA-27 DJ-17 DT-25 DV-24 DW-13 DX-40 DY-32 DZ-15 D.-18 D,-25 EA12 EC-15 EG-15 EJ32 EO-15 ET23 EV14 EW19 EX19 EY22 EZ27 Ec-14 Ed-13 Ee-14 Em-9 En-9 Eo-14 Ep-9 Eq-13 Er-9 Eu-14 Ey-16 Ez8 E.27 E,26 FA-46 FC-10 FG-10 FJ-41 FO-10 FQ-10 FT40 FV23 FW29 FX14 FY31 FZ18 Fa-30 Fc-13 Fd-13 Fe-13 Fg-20 Fm-17 Fn-17 Fo-13 Fp-17 Fq-13 Fr-17 Fs-16 Fu-12 Fy-16 Fz-14 F.-59 F,-57 GA8 GJ19 GT-14 GV-20 GW-8 GY-23 GZ13 G.13 G,18 JA-23 Jg-9 Jy-9 J.-9 J,-15 KC-24 KG-24 KJ16 KO-24 KQ-10 KT15 KX24 KY10 KZ29 Kc-20 Kd-20 Ke-20 Kf-10 Ko-22 Kq-20 Kt-9 Ku-21 Kv-16 Kw-13 Ky-16 K.22 K,18 LA26 LC-18 LG-17 LJ57 LO-18 LQ-8 LT-74 LU-17 LV-74 LW-45 LX16 LY-87 LZ41 Lc-9 Ld-9 Le-9 Lf-21 Lo-10 Lq-9 Lt-19 Lu-10 Lv-52 Lw-33 Lx16 Ly-11 Lz19 L.42 L,50 OA-25 OJ-9 OT-22 OV-25 OW-13 OX-38 OY-31 OZ-13 O.-15 O,-21 PA-43 PJ-48 PX-20 PZ-9 Pf11 Pt15 Pv14 Pw16 Px8 P.-60 P,-66 QA-11 QQ18 QT-22 QV-25 QW-13 QX-10 QY-31 Qg13 Qj40 Qy8 Q.-8 Q,21 RJ10 RT-8 RV-15 RW-9 RY-16 RZ17 R.15 R,12 SS11 ST-10 SV-20 SX-14 SY-20 SZ8 Sg-8 TA-67 TC-25 TG-23 TJ-47 TO-23 TQ-23 TT44 TV27 TW31 TX16 TY33 TZ21 Ta-67 Tc-71 Td-62 Te-71 Tg-67 Tm-30 Tn-30 To-71 Tp-30 Tq-62 Tr-30 Ts-61 Tu-25 Tw-8 Tx-9 Ty-29 Tz-12 T.-62 T,-60 UA-26 UJ-11 Ug-9 Uy-9 U.-15 U,-20 VA-83 VC-26 VG-24 VJ-47 VO-25 VQ-25 VS-10 VT27 VV19 VW31 VY29 VZ9 Va-44 Vc-46 Vd-42 Ve-46 Vg-41 Vm-26 Vn-26 Vo-45 Vp-26 Vq-42 Vr-26 Vs-30 Vu-21 Vy-24 Vz-11 V.-60 V,-57 WA-55 WC-15 WG-14 WJ-40 WO-14 WQ-14 WT31 WV31 WW30 WY26 WZ16 Wa-28 Wc-28 Wd-26 We-28 Wg-27 Wm-18 Wn-18 Wo-26 Wp-18 Wq-26 Wr-18 Ws-20 Wu-14 Wy-19 W.-39 W,-43 XC-38 XG-39 XJ17 XO-39 XQ-9 XS-13 XT14 XX17 XY11 XZ21 Xa-9 Xc-31 Xd-28 Xe-31 Xf-12 Xo-32 Xq-28 Xs-12 Xt-15 Xu-28 Xv-22 Xw-20 Xy-18 X.18 X,15 YA-78 YC-33 YG-32 YJ-46 YO-32 YQ-32 YS-13 YT33 YV29 YW26 YX12 YY38 YZ15 Ya-62 Yc-62 Yd-57 Ye-62 Yg-55 Ym-33 Yn-33 Yo-61 Yp-33 Yq-57 Yr-33 Ys-45 Yu-27 Yw-9 Yx-13 Yy-31 Yz-17 Y.-75 Y,-72 ZA17 ZC-15 ZG-16 ZJ40 ZO-16 ZT27 ZV19 ZW21 ZX20 ZY20 ZZ31 Zc-11 Zd-12 Ze-11 Zo-13 Zq-12 Zu-13 Zy-13 Zz12 Z.30 Z,32 aT-62 aU-11 aV-48 aW-33 aY-60 av-13 bA-12 bT-63 bV-42 bW-25 bX-28 bY-59 bx-15 cJ10 cT-54 cV-30 cW-17 cX-10 cY-45 ca10 cs12 c.13 eT-65 eV-43 eW-24 eX-18 eY-57 ex-11 fA-37 fJ-34 fT29 fU10 fV26 fW29 fX14 fY32 fZ11 ff18 ft13 fw10 f.-33 f,-35 gJ18 gT-11 gV-8 gY-14 gj31 go-9 gt17 gv13 gw12 gx21 gz15 g.23 g,48 hT-62 hU-10 hV-48 hW-31 hY-60 hv-13 jj9 j,15 kA11 kC-9 kG-9 kJ23 kO-9 kQ-9 kT-13 kU-8 kV-13 kY-18 kZ13 kc-12 kd-11 ke-12 ko-14 kq-11 kt12 kx23 kz16 k.25 k,22 mT-62 mU-10 mV-48 mW-31 mY-60 mv-13 nT-62 nU-10 nV-48 nW-31 nY-60 nv-13 oA-13 oT-73 oV-45 oW-26 oX-33 oY-62 ov-9 ox-21 o,-10 pA-12 pT-63 pV-42 pW-25 pX-28 pY-59 px-15 qT-30 qV-25 qW-17 qX-8 qY-33 qj21 q,25 rA-56 rJ-52 rX-21 rZ-8 ra-8 rf11 rt26 rv29 rw30 rx18 rz13 r.-68 r,-66 sT-58 sV-36 sW-23 sX-10 sY-50 ss9 s.11 tA14 tJ27 tT-9 tY-12 tZ24 tt18 tv11 tw9 tx23 tz24 t.32 t,32 uT-30 uV-25 uW-17 uX-8 uY-33 vA-52 vJ-44 vX-21 vZ-11 va-10 vc-10 ve-10 vg-8 vo-9 vt27 vv29 vw30 vx17 vz12 v.-41 v,-45 wA-37 wJ-26 wT-8 wX-20 wY-9 wZ-8 wf8 wt24 wv30 ww29 wx13 wz11 w.-24 w,-28 xA10 xJ19 xT-10 xY-13 xZ9 xc-21 xd-17 xe-21 xo-21 xq-17 xt17 xv15 xw12 xx24 xz19 x.22 x,19 yT-29 yV-24 yW-17 yX-12 yY-32 zJ19 zT-10 zY-14 zZ10 zt19 zv19 zw19 zx22 zz18 z.25 z,26 .A28 .C-14 .G-14 .J45 .O-14 .T-62 .U-15 .V-60 .W-37 .X16 .Y-76 .Z38 .a12 .f-14 .g14 .t-10 .v-40 .w-24 .x21 .y-8 .z30 ..26\";\nconst KERN = new Map(\n  BRIC_KERN.split(\" \").map((p) => [p.slice(0, 2), Number(p.slice(2))]),\n);\nconst TRACK = -0.035;\n// Bricolage at line-height 1: baseline sits 0.83em below the line-box top.\nconst BRIC_BASE = 0.83;\n\nfunction widthEm(text: string) {\n  let w = 0;\n  let prev = \"\";\n  for (const ch of text) {\n    const c = ch.charCodeAt(0);\n    w += (c >= 32 && c < 127 ? BRIC_ADV[c - 32] : 560) / 1000 + TRACK;\n    if (prev) w += (KERN.get(prev + ch) ?? 0) / 1000;\n    prev = ch;\n  }\n  return Math.max(w, 0.5);\n}\n\nconst REMOCN_R_PATH =\n  \"M 0.01 0.81 C 0.01 1.73, 0.36 2.79, 1.09 4.13 C 4.91 11.04, 13.45 17.16, 21.7 18.9 C 22.94 19.16, 23.18 19.16, 51.39 19.27 C 76.07 19.36, 80.02 19.4, 81.32 19.57 C 89.89 20.69, 96.2 24.68, 99.38 31.01 C 103.19 38.56, 102.53 50.1, 97.91 57.07 C 94.66 61.96, 89.68 64.99, 83.26 66 C 82.81 66.07, 70.18 66.83, 55.2 67.69 C 24.82 69.43, 27.03 69.23, 24.18 70.4 C 19.9 72.15, 14.84 75.7, 10.65 79.89 C 4.86 85.68, 1.3 91.91, 0.25 98.13 C 0.12 98.85, 0.08 103.13, 0.04 116.66 L 0 134.26 9.5 134.26 L 19 134.26 19.05 119.41 C 19.1 103.27, 19.08 103.82, 19.82 101.04 C 21.79 93.65, 27.86 88.75, 36.45 87.63 C 37.23 87.53, 39.41 87.5, 43.57 87.53 C 50.12 87.59, 50.75 87.65, 53.22 88.45 C 56.61 89.56, 59.67 91.86, 62.02 95.07 C 62.52 95.76, 69.35 103.85, 77.2 113.07 C 85.04 122.28, 91.63 130.04, 91.85 130.32 C 92.07 130.59, 92.5 131.34, 92.82 131.97 C 93.52 133.35, 94.11 133.93, 95.06 134.13 C 95.5 134.23, 98.97 134.26, 106.36 134.23 L 117.01 134.19 100.82 113.07 C 91.91 101.45, 84.52 91.78, 84.39 91.57 C 83.36 89.89, 83.66 87.53, 85.09 86 C 85.79 85.25, 86.36 84.94, 88.07 84.38 C 96.18 81.72, 104.15 76.62, 109.97 70.36 C 120.59 58.93, 124.06 44.32, 119.44 30.43 C 114.59 15.81, 101.93 4.02, 87.64 0.83 C 83.93 0.01, 88.09 0.08, 41.85 0.04 L 0.01 0 0.01 0.81 Z\";\n\n// Logo metrics in em: R mark (0.76em tall) + 0.04em gap + \"emocn\" in Manrope 600 at -0.025em tracking.\nconst LOGO_W = (0.76 * 124.06) / 134.26 + 0.04 + 3.256 - 5 * 0.025;\n// Manrope at line-height 1: baseline sits 0.883em below the line-box top.\nconst LOGO_BASE = 0.883;\n\n/** Full logo as on remocn.dev: R mark (0.76em tall, baseline-aligned) + \"emocn\" in Manrope 600. */\nfunction RemocnLogo({ fontSize, color }: { fontSize: number; color: string }) {\n  return (\n    <div\n      style={{\n        display: \"flex\",\n        alignItems: \"baseline\",\n        color,\n        fontFamily: manrope.fontFamily,\n        fontWeight: 600,\n        fontSize,\n        letterSpacing: \"-0.025em\",\n        lineHeight: 1,\n        whiteSpace: \"nowrap\",\n      }}\n    >\n      <svg\n        viewBox=\"0 0 124.06 134.26\"\n        style={{ height: \"0.76em\", width: \"auto\" }}\n        aria-hidden\n      >\n        <path fill=\"currentColor\" d={REMOCN_R_PATH} />\n      </svg>\n      <span style={{ marginLeft: \"0.04em\" }}>emocn</span>\n    </div>\n  );\n}\n\n// \"beam\" palette from gradients.sh (#f4f7ff, #8fb4ff, accent, #1a1660): a soft diagonal light\n// beam over the accent, pinned to the frame so the shape reads as a window onto one lit surface\n// (never as a shaded ball). The beam drifts a few percent over the shot.\nfunction beamGround(theme: \"dark\" | \"light\", accent: string, k: number) {\n  const dark = theme === \"dark\";\n  const c = (dark ? 40 : 26) + 6 * k;\n  const a = dark ? 1 : 0.6;\n  return [\n    `linear-gradient(118deg, rgba(143,180,255,0) ${c - 34}%, rgba(143,180,255,${0.34 * a}) ${c - 14}%, rgba(244,247,255,${0.4 * a}) ${c}%, rgba(143,180,255,${0.3 * a}) ${c + 12}%, rgba(143,180,255,0) ${c + 32}%)`,\n    `radial-gradient(90% 110% at ${96 - 4 * k}% 110%, rgba(26,22,96,${dark ? 0.7 : 0.85}) 0%, rgba(26,22,96,0) 70%)`,\n    `radial-gradient(70% 90% at 0% 0%, rgba(26,22,96,${dark ? 0.35 : 0.5}) 0%, rgba(26,22,96,0) 70%)`,\n    accent,\n  ].join(\", \");\n}\n\ninterface Geo {\n  cx: number;\n  cy: number;\n  hw: number;\n  hh: number;\n  rad: number;\n}\n\nfunction covers(g: Geo, px: number, py: number) {\n  const dx = Math.abs(px - g.cx);\n  const dy = Math.abs(py - g.cy);\n  if (dx > g.hw || dy > g.hh) return false;\n  const qx = Math.max(dx - (g.hw - g.rad), 0);\n  const qy = Math.max(dy - (g.hh - g.rad), 0);\n  return qx * qx + qy * qy <= g.rad * g.rad;\n}\n\nfunction coversBox(g: Geo, x0: number, y0: number, x1: number, y1: number) {\n  return (\n    covers(g, x0, y0) &&\n    covers(g, x1, y0) &&\n    covers(g, x0, y1) &&\n    covers(g, x1, y1)\n  );\n}\n\nfunction Grain({ opacity }: { opacity: number }) {\n  const id = `g${useId().replace(/[^a-zA-Z0-9_-]/g, \"\")}`;\n  return (\n    <svg\n      width=\"100%\"\n      height=\"100%\"\n      style={{ position: \"absolute\", inset: 0, opacity, pointerEvents: \"none\" }}\n      aria-hidden\n    >\n      <filter id={id}>\n        <feTurbulence\n          type=\"fractalNoise\"\n          baseFrequency=\"0.9\"\n          numOctaves={2}\n          seed={7}\n          stitchTiles=\"stitch\"\n        />\n        <feColorMatrix values=\"0 0 0 0 0.5  0 0 0 0 0.5  0 0 0 0 0.5  0 0 0 0.9 0\" />\n      </filter>\n      <rect width=\"100%\" height=\"100%\" filter={`url(#${id})`} />\n    </svg>\n  );\n}\n\nconst type = (size: number): React.CSSProperties => ({\n  position: \"absolute\",\n  fontFamily: display,\n  fontWeight: 500,\n  fontSize: size,\n  letterSpacing: `${TRACK}em`,\n  lineHeight: 1,\n  whiteSpace: \"nowrap\",\n});\n\nexport function ShapeCut({\n  from = \"Ideas move fast\",\n  to = \"remocn\",\n  shape = \"circle\",\n  accent = \"#3B5BFD\",\n  theme = \"dark\",\n  speed = 1,\n}: ShapeCutProps) {\n  const t = useCurrentFrame() * speed;\n  const { width: W, height: H } = useVideoConfig();\n  const u = H / 720;\n  const stage = STAGES[theme];\n  const pill = shape === \"pill\";\n\n  const isLogo = to.trim().toLowerCase() === \"remocn\";\n  const emB = isLogo ? LOGO_W : widthEm(to);\n  const fsA = Math.min(136 * u, (0.82 * W) / widthEm(from));\n  const fsB = Math.min((isLogo ? 156 : 150) * u, (0.7 * W) / emB);\n  const wA = widthEm(from) * fsA;\n  const wB = emB * fsB;\n  const baseline = H / 2 + (isLogo ? 0.36 : 0.33) * fsB;\n  const topB = baseline - (isLogo ? LOGO_BASE : BRIC_BASE) * fsB;\n\n  const endR = pill ? 5 * u : 0.072 * fsB;\n  const gap = 0.05 * fsB;\n  const groupW = pill ? wB : wB + gap + 2 * endR;\n  const left = W / 2 - groupW / 2;\n  const textRight = left + wB;\n  const barW = 0.4 * wB;\n  const anchor = pill\n    ? { x: left + 0.03 * fsB + barW / 2, y: baseline + 0.3 * fsB }\n    : { x: textRight + gap + endR, y: baseline - endR };\n  const endHw = pill ? barW / 2 : endR;\n  const startAspect = pill ? 1.6 : 1;\n  const corner = (hh: number) => (shape === \"square\" ? hh * 0.42 : hh);\n\n  const settle = SETTLE(interpolate(t, [GP, G1 + 14], [0, 1], CLAMP));\n  const bScale = 1 + 0.035 * (1 - settle);\n  const bShift = -0.035 * W * (1 - settle);\n  const toB = (x: number, y: number) => ({\n    x: W / 2 + bScale * (x - W / 2) + bShift,\n    y: H / 2 + bScale * (y - H / 2),\n  });\n\n  const r0 = 0.06 * H;\n  const start = { x: -r0 * startAspect, y: anchor.y };\n  const peakTarget = toB(anchor.x, anchor.y);\n  const peakP = PATH(interpolate(GP, [G0, G1], [0, 1], CLAMP));\n  const peakC = {\n    x: start.x + (peakTarget.x - start.x) * peakP,\n    y: start.y + (peakTarget.y - start.y) * peakP,\n  };\n  const reach = Math.max(\n    Math.hypot(peakC.x, peakC.y),\n    Math.hypot(W - peakC.x, peakC.y),\n    Math.hypot(peakC.x, H - peakC.y),\n    Math.hypot(W - peakC.x, H - peakC.y),\n  );\n  const rPk = 1.12 * reach;\n\n  const geoAt = (f: number): Geo => {\n    const target = toB(anchor.x, anchor.y);\n    const p = PATH(interpolate(f, [G0, G1], [0, 1], CLAMP));\n    const cx = start.x + (target.x - start.x) * p;\n    const cy = start.y + (target.y - start.y) * p;\n    if (f <= GP) {\n      const g = GROW(interpolate(f, [G0, GP], [0, 1], CLAMP));\n      const hh = Math.exp(Math.log(r0) + (Math.log(rPk) - Math.log(r0)) * g);\n      return { cx, cy, hw: hh * startAspect, hh, rad: corner(hh) };\n    }\n    const s = SHRINK(interpolate(f, [GP, G1], [0, 1], CLAMP));\n    const hh = rPk + (endR - rPk) * s;\n    return {\n      cx,\n      cy,\n      hw: Math.max(hh * startAspect, endHw),\n      hh,\n      rad: corner(hh),\n    };\n  };\n\n  const geo = geoAt(t);\n  const swapped = t >= GP;\n\n  const boxA = {\n    x0: W / 2 - wA / 2 - 0.02 * fsA,\n    x1: W / 2 + wA / 2 + 0.02 * fsA,\n    y0: H / 2 - 0.42 * fsA,\n    y1: H / 2 + 0.42 * fsA,\n  };\n  let tc = GP;\n  for (let f = G0; f <= GP; f += 0.25) {\n    if (coversBox(geoAt(f), boxA.x0, boxA.y0, boxA.x1, boxA.y1)) {\n      tc = f;\n      break;\n    }\n  }\n\n  const drift = (f: number) =>\n    1 + 0.018 * interpolate(f, [0, GP], [0, 1], CLAMP);\n  const q = interpolate(t, [tc, G1 - 6], [0, 1], CLAMP);\n  const pull = PATH(q);\n  const sA = drift(Math.min(t, tc)) * Math.min(1, (1.3 * geo.hh) / rPk);\n  const aX = W / 2 + (geo.cx - W / 2) * pull;\n  const aY = H / 2 + (geo.cy - H / 2) * pull;\n  const aOpacity = interpolate(sA, [0.26, 0.5], [0, 1], CLAMP);\n  const inverse = stage.bg;\n  const ground = beamGround(\n    theme,\n    accent,\n    interpolate(t, [0, 110], [0, 1], CLAMP),\n  );\n\n  const titleA = (color: string, x: number, y: number, s: number) => (\n    <div\n      style={{\n        ...type(fsA),\n        left: 0,\n        top: 0,\n        color,\n        transform: `translate(${x}px, ${y}px) translate(-50%, -50%) scale(${s})`,\n        paddingBottom: 0.08 * fsA,\n      }}\n    >\n      {from}\n    </div>\n  );\n\n  const shapeLeft = geo.cx - geo.hw;\n  const shapeTop = geo.cy - geo.hh;\n  const visible =\n    geo.cx + geo.hw > -1 &&\n    geo.cx - geo.hw < W + 1 &&\n    geo.cy + geo.hh > -1 &&\n    geo.cy - geo.hh < H + 1;\n\n  return (\n    <AbsoluteFill style={{ background: stage.bg, overflow: \"hidden\" }}>\n      <AbsoluteFill\n        style={{\n          background: `radial-gradient(ellipse 80% 90% at 24% 0%, ${stage.light}, transparent 70%)`,\n        }}\n      />\n      {swapped ? (\n        <AbsoluteFill\n          style={{\n            transform: `translateX(${bShift}px) scale(${bScale})`,\n          }}\n        >\n          {isLogo ? (\n            <div style={{ position: \"absolute\", left, top: topB }}>\n              <RemocnLogo fontSize={fsB} color={stage.fg} />\n            </div>\n          ) : (\n            <div\n              style={{\n                ...type(fsB),\n                left,\n                top: topB,\n                color: stage.fg,\n              }}\n            >\n              {to}\n            </div>\n          )}\n        </AbsoluteFill>\n      ) : (\n        titleA(stage.fg, W / 2, H / 2, drift(t))\n      )}\n      {visible ? (\n        <div\n          style={{\n            position: \"absolute\",\n            left: shapeLeft,\n            top: shapeTop,\n            width: geo.hw * 2,\n            height: geo.hh * 2,\n            borderRadius: geo.rad,\n            overflow: \"hidden\",\n          }}\n        >\n          <div\n            style={{\n              position: \"absolute\",\n              left: -shapeLeft,\n              top: -shapeTop,\n              width: W,\n              height: H,\n              background: ground,\n            }}\n          />\n          {aOpacity > 0 ? (\n            <div\n              style={{\n                position: \"absolute\",\n                left: -shapeLeft,\n                top: -shapeTop,\n                width: W,\n                height: H,\n                opacity: aOpacity,\n              }}\n            >\n              {t < tc\n                ? titleA(inverse, W / 2, H / 2, drift(t))\n                : titleA(inverse, aX, aY, sA)}\n            </div>\n          ) : null}\n        </div>\n      ) : null}\n      <Grain opacity={theme === \"light\" ? 0.04 : 0.055} />\n    </AbsoluteFill>\n  );\n}\n",
      "type": "registry:component",
      "target": "components/remocn/shape-cut.tsx"
    }
  ],
  "type": "registry:component"
}
