{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "snap-click",
  "title": "Snap Click",
  "description": "The wordmark snaps together at a seam with a click, settling over a subtle caption.",
  "dependencies": ["remotion", "@remotion/google-fonts"],
  "files": [
    {
      "path": "registry/remocn/snap-click/index.tsx",
      "content": "\"use client\";\n\nimport { loadFont as loadMono } from \"@remotion/google-fonts/GeistMono\";\nimport { useId, useMemo } from \"react\";\nimport {\n  AbsoluteFill,\n  Easing,\n  interpolate,\n  useCurrentFrame,\n  useVideoConfig,\n} from \"remotion\";\n\nconst { fontFamily: mono } = loadMono(\"normal\", {\n  weights: [\"400\"],\n  subsets: [\"latin\"],\n});\n\nexport interface SnapClickProps {\n  /** Wordmark after the R mark, as in the remocn.dev logo. Lowercase a–z. */\n  text?: string;\n  /** Where the lockup splits: index into `text` plus a fraction of that glyph's ink. Defaults to the middle of the first \"m\". */\n  seam?: [number, number];\n  /** Small line typed under the lockup after the click. */\n  label?: string;\n  accent?: string;\n  theme?: \"dark\" | \"light\";\n  speed?: number;\n}\n\ntype Glyph = readonly [number, number, number, number, number, string];\n\n/** Manrope 600 (the remocn.dev logo face), lowercase a–z: [advance, xMin, xMax, yTop, yBottom, path], 1000 units/em, y down. */\nconst GLYPHS: Record<string, Glyph> = {\n  a: [\n    570,\n    40,\n    509,\n    -555,\n    15,\n    \"M222 15Q163 15 122 -7Q81 -29 61 -66Q40 -103 40 -147Q40 -188 55 -219Q69 -250 97 -272Q126 -294 168 -307Q203 -318 249 -326Q294 -334 345 -341Q395 -347 444 -355L407 -333Q407 -397 380 -428Q352 -458 285 -458Q242 -458 207 -439Q171 -419 157 -373L60 -403Q79 -473 136 -514Q192 -555 285 -555Q358 -555 412 -530Q465 -505 490 -452Q503 -425 506 -396Q509 -366 509 -333V0H417V-123L435 -108Q401 -46 350 -15Q298 15 222 15ZM241 -70Q286 -70 318 -86Q350 -102 369 -127Q388 -151 395 -177Q403 -201 404 -231Q405 -262 405 -279L439 -267Q390 -259 350 -254Q309 -248 276 -242Q244 -236 218 -228Q197 -221 180 -210Q163 -200 153 -184Q143 -169 143 -148Q143 -127 154 -109Q164 -92 186 -81Q208 -70 241 -70Z\",\n  ],\n  b: [\n    608,\n    69,\n    568,\n    -720,\n    15,\n    \"M324 15Q246 15 194 -23Q141 -60 114 -125Q87 -189 87 -270Q87 -352 114 -416Q141 -480 193 -518Q245 -555 322 -555Q398 -555 453 -518Q508 -481 538 -416Q568 -352 568 -270Q568 -189 538 -125Q508 -60 454 -23Q399 15 324 15ZM69 0V-720H175V-388H162V0ZM309 -80Q359 -80 392 -105Q425 -130 441 -174Q457 -217 457 -270Q457 -323 441 -366Q424 -409 391 -435Q357 -460 306 -460Q256 -460 225 -436Q193 -412 178 -369Q162 -326 162 -270Q162 -215 178 -171Q193 -128 225 -104Q258 -80 309 -80Z\",\n  ],\n  c: [\n    568,\n    40,\n    537,\n    -555,\n    15,\n    \"M301 15Q218 15 160 -22Q102 -59 71 -123Q40 -188 40 -270Q40 -353 72 -418Q104 -482 162 -519Q221 -555 302 -555Q391 -555 454 -511Q517 -467 537 -390L433 -361Q417 -406 382 -431Q346 -456 301 -456Q250 -456 217 -432Q183 -408 167 -366Q151 -324 151 -270Q152 -186 189 -135Q227 -84 301 -84Q352 -84 383 -107Q414 -130 430 -174L537 -148Q510 -69 449 -27Q388 15 301 15Z\",\n  ],\n  d: [\n    608,\n    40,\n    539,\n    -720,\n    15,\n    \"M284 15Q209 15 154 -23Q100 -60 70 -125Q40 -189 40 -270Q40 -352 70 -416Q100 -481 155 -518Q211 -555 286 -555Q363 -555 415 -518Q467 -480 494 -416Q521 -352 521 -270Q521 -189 494 -125Q467 -60 415 -23Q362 15 284 15ZM299 -80Q351 -80 383 -104Q415 -128 430 -171Q446 -215 446 -270Q446 -326 430 -369Q415 -412 383 -436Q352 -460 302 -460Q251 -460 217 -435Q183 -409 167 -366Q151 -323 151 -270Q151 -217 167 -174Q183 -130 216 -105Q249 -80 299 -80ZM446 0V-388H433V-720H539V0Z\",\n  ],\n  e: [\n    596,\n    40,\n    556,\n    -555,\n    15,\n    \"M310 15Q229 15 168 -20Q108 -56 74 -119Q40 -182 40 -265Q40 -354 73 -419Q107 -484 166 -519Q225 -555 304 -555Q387 -555 445 -517Q503 -478 532 -408Q560 -337 555 -241H450V-279Q449 -372 414 -417Q379 -462 308 -462Q230 -462 191 -413Q151 -363 151 -270Q151 -181 191 -132Q230 -84 304 -84Q353 -84 389 -106Q425 -128 445 -170L547 -137Q516 -65 452 -25Q388 15 310 15ZM117 -241V-322H502V-241Z\",\n  ],\n  f: [\n    370,\n    30,\n    360,\n    -735,\n    0,\n    \"M119 0V-559Q119 -580 121 -603Q122 -626 130 -649Q137 -671 154 -690Q175 -713 199 -723Q224 -732 248 -733Q272 -735 292 -735H360V-649H297Q260 -649 242 -631Q224 -612 224 -579V0ZM30 -456V-540H360V-456Z\",\n  ],\n  g: [\n    608,\n    40,\n    538,\n    -555,\n    255,\n    \"M293 255Q249 255 208 241Q167 228 134 202Q101 175 79 137L175 88Q193 122 225 139Q258 155 293 155Q338 155 369 139Q401 123 417 91Q434 60 433 13V-137H446V-540H538V15Q538 36 537 56Q535 75 531 94Q520 149 487 185Q455 220 405 238Q356 255 293 255ZM284 15Q209 15 154 -23Q100 -60 70 -125Q40 -189 40 -270Q40 -352 70 -416Q100 -481 155 -518Q211 -555 286 -555Q363 -555 415 -518Q467 -480 494 -416Q521 -352 521 -270Q521 -189 494 -125Q467 -60 415 -23Q362 15 284 15ZM299 -80Q351 -80 383 -104Q415 -128 430 -171Q446 -215 446 -270Q446 -326 430 -369Q415 -412 383 -436Q352 -460 302 -460Q251 -460 217 -435Q183 -409 167 -366Q151 -323 151 -270Q151 -217 167 -174Q183 -130 216 -105Q249 -80 299 -80Z\",\n  ],\n  h: [\n    615,\n    69,\n    555,\n    -720,\n    0,\n    \"M449 0V-265Q449 -297 444 -330Q438 -363 424 -392Q409 -421 382 -438Q356 -456 313 -456Q285 -456 260 -446Q235 -437 216 -416Q197 -396 186 -362Q175 -329 175 -281L110 -305Q110 -379 138 -435Q165 -491 217 -523Q269 -555 341 -555Q397 -555 435 -536Q474 -518 497 -489Q521 -460 534 -425Q546 -391 551 -358Q555 -325 555 -300V0ZM69 0V-720H163V-332H175V0Z\",\n  ],\n  i: [264, 80, 185, -730, 0, \"M80 -629V-730H185V-629ZM80 0V-540H185V0Z\"],\n  j: [\n    276,\n    -10,\n    202,\n    -730,\n    240,\n    \"M-10 240V141H17Q59 141 78 121Q98 101 98 60V-540H202V102Q202 168 166 204Q130 240 62 240ZM98 -629V-730H202V-629Z\",\n  ],\n  k: [\n    524,\n    69,\n    544,\n    -720,\n    0,\n    \"M69 0 70 -720H176V-280L388 -540H521L297 -270L544 0H402L176 -260V0Z\",\n  ],\n  l: [264, 80, 185, -735, 0, \"M80 0V-735H185V0Z\"],\n  m: [\n    882,\n    69,\n    822,\n    -554,\n    0,\n    \"M717 0 717 -337Q717 -395 687 -428Q657 -460 608 -460Q579 -460 554 -447Q529 -433 514 -406Q498 -378 498 -338L448 -363Q447 -420 472 -463Q498 -506 541 -530Q585 -554 639 -554Q726 -554 774 -501Q822 -449 822 -362L822 0ZM69 0V-540H162V-384H175V0ZM394 0 394 -334Q394 -393 364 -427Q335 -460 284 -460Q235 -460 205 -426Q175 -393 175 -338L124 -370Q124 -422 150 -464Q175 -505 219 -530Q263 -554 317 -554Q375 -554 415 -529Q456 -505 477 -461Q498 -418 498 -361L498 0Z\",\n  ],\n  n: [\n    615,\n    69,\n    555,\n    -555,\n    0,\n    \"M449 0V-265Q449 -297 444 -330Q438 -363 424 -392Q409 -421 382 -438Q356 -456 313 -456Q285 -456 260 -446Q235 -437 216 -416Q197 -396 186 -362Q175 -329 175 -281L110 -305Q110 -379 138 -435Q165 -491 217 -523Q269 -555 341 -555Q397 -555 435 -536Q474 -518 497 -489Q521 -460 534 -425Q546 -391 551 -358Q555 -325 555 -300V0ZM69 0V-540H163V-384H175V0Z\",\n  ],\n  o: [\n    610,\n    40,\n    569,\n    -555,\n    15,\n    \"M304 15Q223 15 164 -22Q105 -58 72 -122Q40 -187 40 -270Q40 -355 73 -419Q106 -483 165 -519Q225 -555 304 -555Q386 -555 445 -519Q505 -482 537 -418Q569 -354 569 -270Q569 -186 537 -122Q504 -57 444 -21Q385 15 304 15ZM304 -84Q382 -84 420 -136Q458 -188 458 -270Q458 -355 420 -406Q381 -456 304 -456Q252 -456 218 -433Q184 -409 168 -367Q151 -325 151 -270Q151 -185 190 -135Q229 -84 304 -84Z\",\n  ],\n  p: [\n    608,\n    69,\n    568,\n    -555,\n    240,\n    \"M324 15Q246 15 194 -23Q141 -60 114 -125Q87 -189 87 -270Q87 -352 114 -416Q141 -480 193 -518Q245 -555 322 -555Q398 -555 453 -518Q508 -481 538 -416Q568 -352 568 -270Q568 -189 538 -125Q508 -60 454 -23Q399 15 324 15ZM69 240V-540H162V-152H175V240ZM309 -80Q359 -80 392 -105Q425 -130 441 -174Q457 -217 457 -270Q457 -323 441 -366Q424 -409 391 -435Q357 -460 306 -460Q256 -460 225 -436Q193 -412 178 -369Q162 -326 162 -270Q162 -215 178 -171Q193 -128 225 -104Q258 -80 309 -80Z\",\n  ],\n  q: [\n    608,\n    40,\n    539,\n    -555,\n    240,\n    \"M284 15Q209 15 154 -23Q100 -60 70 -125Q40 -189 40 -270Q40 -352 70 -416Q100 -481 155 -518Q211 -555 286 -555Q363 -555 415 -518Q467 -480 494 -416Q521 -352 521 -270Q521 -189 494 -125Q467 -60 415 -23Q362 15 284 15ZM299 -80Q351 -80 383 -104Q415 -128 430 -171Q446 -215 446 -270Q446 -326 430 -369Q415 -412 383 -436Q352 -460 302 -460Q251 -460 217 -435Q183 -409 167 -366Q151 -323 151 -270Q151 -217 167 -174Q183 -130 216 -105Q249 -80 299 -80ZM433 240V-152H446V-540H539V240Z\",\n  ],\n  r: [\n    386,\n    70,\n    361,\n    -543,\n    0,\n    \"M70 0V-540H163V-409L150 -426Q160 -452 176 -474Q192 -495 213 -509Q233 -525 259 -533Q284 -541 311 -543Q337 -544 361 -540V-442Q335 -449 303 -446Q271 -443 244 -425Q218 -409 203 -385Q188 -362 182 -333Q175 -304 175 -273V0Z\",\n  ],\n  s: [\n    536,\n    40,\n    496,\n    -555,\n    15,\n    \"M276 15Q178 15 116 -29Q54 -73 40 -151L147 -168Q157 -126 193 -102Q229 -77 283 -77Q332 -77 360 -97Q388 -117 388 -152Q388 -173 378 -186Q369 -198 338 -210Q306 -221 243 -238Q173 -257 133 -277Q92 -298 75 -326Q57 -353 57 -393Q57 -442 84 -478Q110 -515 157 -535Q204 -555 267 -555Q330 -555 378 -535Q427 -516 457 -480Q487 -444 493 -396L386 -377Q380 -416 349 -438Q318 -461 268 -463Q221 -465 191 -447Q162 -429 162 -398Q162 -380 173 -368Q185 -356 217 -344Q250 -332 313 -316Q381 -299 421 -278Q461 -257 478 -227Q496 -198 496 -156Q496 -77 437 -31Q379 15 276 15Z\",\n  ],\n  t: [\n    422,\n    10,\n    379,\n    -690,\n    9,\n    \"M379 0Q328 10 279 8Q230 7 192 -11Q153 -28 133 -66Q116 -99 115 -134Q114 -168 114 -212V-690H218V-218Q218 -185 219 -161Q220 -137 229 -121Q247 -90 287 -85Q326 -81 379 -89ZM10 -456V-540H379V-456Z\",\n  ],\n  u: [\n    615,\n    60,\n    545,\n    -540,\n    15,\n    \"M274 15Q218 15 180 -4Q141 -22 118 -51Q94 -80 81 -115Q69 -149 64 -182Q60 -215 60 -240V-540H166V-275Q166 -243 171 -210Q177 -177 191 -148Q206 -119 233 -102Q259 -84 302 -84Q331 -84 355 -94Q380 -103 399 -124Q418 -144 429 -178Q440 -211 440 -259L505 -235Q505 -161 477 -105Q450 -49 398 -17Q347 15 274 15ZM452 0V-156H440V-540H545V0Z\",\n  ],\n  v: [538, 20, 518, -540, 0, \"M216 0 20 -540H125L269 -131L412 -540H518L322 0Z\"],\n  w: [\n    790,\n    20,\n    771,\n    -541,\n    0,\n    \"M185 0 20 -541 123 -540 236 -169 350 -540H440L554 -169L668 -540H771L606 0H522L395 -391L269 0Z\",\n  ],\n  x: [\n    545,\n    10,\n    535,\n    -540,\n    0,\n    \"M10 0 212 -273 14 -540H138L273 -355L406 -540H530L332 -273L535 0H411L273 -191L134 0Z\",\n  ],\n  y: [\n    548,\n    13,\n    540,\n    -540,\n    240,\n    \"M143 240 247 -45 249 39 13 -540H123L299 -93H267L435 -540H540L243 240Z\",\n  ],\n  z: [\n    532,\n    20,\n    492,\n    -540,\n    0,\n    \"M20 0V-16L327 -447H48V-540H492V-523L186 -93H478V0Z\",\n  ],\n};\n\n/** Manrope 600 kerning between lowercase pairs, in 1/1000 em. */\nconst KERN_PAIRS =\n  \"av-20 aw-20 ay-30 bs-10 bv-20 bw-20 bx-20 by-34 bz-20 ca-6 cc-15 cd-15 ce-15 ci-15 cl-15 co-15 cy-20 ea-10 em-15 en-15 ep-15 ev-20 ew-20 ex-20 ey-10 fa-15 fb31 fc-20 fd-20 fe-20 fh31 fi15 fk31 fl15 fo-20 kc-10 kd-10 ke-10 ko-10 kq-30 ks-10 mc-6 md-6 me-6 mo-6 my-20 nc-6 nd-6 ne-6 no-6 ny-20 os-10 ov-20 ow-20 ox-15 oy-20 oz-20 ps-10 pv-20 pw-20 px-15 py-20 pz-20 ra-15 rc-10 rd-10 re-10 rg-20 ro-10 rs-20 ry-14 sv-20 sw-20 sx-20 sy-20 tc-25 td-25 te-25 to-25 ty-15 va-30 vc-20 vd-20 ve-20 vg-20 vo-20 vq-20 vs-20 vy-5 wa-30 wc-20 wd-20 we-20 wg-20 wo-20 wq-20 ws-20 wy-5 xa-20 xc-20 xd-20 xe-20 xg-20 xo-20 xq-20 xv-10 xw-10 ya-20 yc-20 yd-20 ye-20 yf40 yg-16 yo-20 yt40 za-30 zc-40 zd-40 ze-40 zo-40 zq-30 zy-14\";\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 geometry in font units (1000/em): the R is 0.76em tall, then a 0.04em gap. */\nconst R_HEIGHT = 760;\nconst R_SCALE = R_HEIGHT / 134.26;\nconst R_WIDTH = 124.06 * R_SCALE;\nconst R_GAP = 40;\nconst TRACK = -25;\nconst SPACE = 230;\n\nconst KERN = new Map(\n  KERN_PAIRS.split(\" \").map((p) => [p.slice(0, 2), Number(p.slice(2))]),\n);\n\nconst EASE_OUT = Easing.bezier(0.22, 1, 0.36, 1);\nconst EASE_SLAM = Easing.bezier(0.55, 0, 1, 0.45);\nconst CLAMP = {\n  extrapolateLeft: \"clamp\",\n  extrapolateRight: \"clamp\",\n} as const;\n\n/** gradients.sh \"mesh\" (dark) and \"ribbon\" (light). */\nconst THEMES = {\n  dark: {\n    bg: \"#05060f\",\n    fg: \"#F3F2EF\",\n    muted: \"rgba(236,232,242,0.62)\",\n    flash: \"#ffffff\",\n    fill: [\"#9aa6f2\", \"#6f80f0\", \"ACCENT\"],\n    blobs: [\n      [\"rgba(46,69,183,0.30)\", 16, 20],\n      [\"rgba(135,150,238,0.07)\", 84, 26],\n      [\"rgba(46,69,183,0.18)\", 72, 86],\n      [\"rgba(14,22,69,0.85)\", 22, 80],\n    ],\n    grain: 0.06,\n  },\n  light: {\n    bg: \"#F5F4F0\",\n    fg: \"#121214\",\n    muted: \"rgba(18,18,20,0.58)\",\n    flash: \"#121214\",\n    fill: [\"#ff3d9a\", \"#7a5cff\", \"ACCENT\"],\n    blobs: [\n      [\"rgba(255,61,154,0.10)\", 16, 20],\n      [\"rgba(255,200,61,0.12)\", 84, 26],\n      [\"rgba(122,92,255,0.10)\", 72, 86],\n      [\"rgba(255,138,61,0.08)\", 22, 80],\n    ],\n    grain: 0.035,\n  },\n} as const;\n\ninterface Placed {\n  ch: string;\n  g: Glyph;\n  x: number;\n  index: number;\n}\n\nfunction setText(text: string) {\n  const placed: Placed[] = [];\n  let x = R_WIDTH + R_GAP;\n  let prev = \"\";\n  [...text.toLowerCase()].forEach((ch, index) => {\n    const g = GLYPHS[ch];\n    if (!g) {\n      x += SPACE;\n      prev = \"\";\n      return;\n    }\n    x += KERN.get(prev + ch) ?? 0;\n    placed.push({ ch, g, x, index });\n    x += g[0] + TRACK;\n    prev = ch;\n  });\n  const last = placed[placed.length - 1];\n  return { placed, ink: last ? last.x + last.g[2] : R_WIDTH };\n}\n\n/** Horizontal shake after the click, in px at 1280 wide: 2px at most, gone in five frames. */\nconst SHAKE = [2, -2, 1, -1, 0.5];\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={31}\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\nexport function SnapClick({\n  text = \"emocn\",\n  seam,\n  label = \"Animations for Remotion\",\n  accent = \"#3B5BFD\",\n  theme = \"dark\",\n  speed = 1,\n}: SnapClickProps) {\n  const t = useCurrentFrame() * speed;\n  const { width: W, height: H } = useVideoConfig();\n  const c = THEMES[theme];\n  const u = W / 1280;\n  const id = `sc${useId().replace(/[^a-zA-Z0-9_-]/g, \"\")}`;\n\n  const set = useMemo(() => setText(text), [text]);\n  const seamX = useMemo(() => {\n    const [at, frac] = seam ?? [\n      Math.max(0, [...text.toLowerCase()].indexOf(\"m\")),\n      0.5,\n    ];\n    const p =\n      set.placed.find((q) => q.index === at) ??\n      set.placed[Math.floor(set.placed.length / 2)];\n    if (!p) return R_WIDTH + R_GAP / 2;\n    return p.x + p.g[1] + (p.g[2] - p.g[1]) * frac;\n  }, [seam, set, text]);\n\n  const k = Math.min((W * 0.66) / set.ink, (H * 0.3) / R_HEIGHT);\n  const ox = W / 2 - (set.ink / 2) * k;\n  const baseline = H * 0.47 + (R_HEIGHT / 2) * k;\n\n  // Beats: halves slam in (0 → CLICK), snap, shake, label types from TYPE.\n  const CLICK = 13;\n  const TYPE = 24;\n  const seamScreen = ox + seamX * k;\n  // Both halves open the shot whole, pushed out to the frame margins, so the\n  // first frame is already a composed picture: two pieces and a gap.\n  const margin = W * 0.045;\n  const startL = margin - ox;\n  const startR = W - margin - (ox + set.ink * k);\n  const slam = EASE_SLAM(interpolate(t, [0, CLICK], [0, 1], CLAMP));\n  // 1-frame overshoot into each other, 1 frame of rebound, then locked.\n  const snap = t < CLICK ? 0 : t < CLICK + 1 ? 5 : t < CLICK + 2 ? -1.5 : 0;\n  const dxL = startL * (1 - slam) + snap * u;\n  const dxR = startR * (1 - slam) - snap * u;\n  const shakeIdx = Math.floor(t) - (CLICK + 1);\n  const shake =\n    shakeIdx >= 0 && shakeIdx < SHAKE.length ? SHAKE[shakeIdx] * u : 0;\n\n  const flash = interpolate(t, [CLICK, CLICK + 9], [1, 0], {\n    ...CLAMP,\n    easing: EASE_OUT,\n  });\n  const flashLen = interpolate(t, [CLICK, CLICK + 9], [0.9, 1.25], {\n    ...CLAMP,\n    easing: EASE_OUT,\n  });\n\n  const typed = Math.max(\n    0,\n    Math.min(label.length, Math.floor((t - TYPE) * 1.1)),\n  );\n  const typing = t >= TYPE - 4;\n  const done = typed >= label.length;\n  const caretOn = !done || Math.floor((t - TYPE) / 9) % 2 === 0;\n\n  const drift = Math.min(t, 105) * 0.04;\n  const background = [\n    ...c.blobs.map(\n      ([col, x, y], i) =>\n        `radial-gradient(85% 95% at ${x + (i % 2 ? -drift : drift)}% ${y}%, ${col} 0%, transparent 68%)`,\n    ),\n    c.bg,\n  ].join(\", \");\n\n  const fill = c.fill.map((s) => (s === \"ACCENT\" ? accent : s));\n  const lockup = (\n    <>\n      <path\n        d={REMOCN_R_PATH}\n        transform={`translate(0 ${-R_HEIGHT}) scale(${R_SCALE})`}\n      />\n      {set.placed.map((p) => (\n        <path\n          key={`${p.index}-${p.ch}`}\n          d={p.g[5]}\n          transform={`translate(${p.x} 0)`}\n        />\n      ))}\n    </>\n  );\n  const big = 100000;\n  const flashH = 1180 * flashLen;\n  const labelSize = 24 * u;\n\n  return (\n    <AbsoluteFill style={{ background, overflow: \"hidden\" }}>\n      <svg\n        width={W}\n        height={H}\n        viewBox={`0 0 ${W} ${H}`}\n        style={{ position: \"absolute\", inset: 0 }}\n        aria-hidden\n      >\n        <defs>\n          <clipPath id={`${id}-l`}>\n            <rect x={-big} y={-big} width={big + seamX} height={big * 2} />\n          </clipPath>\n          <clipPath id={`${id}-r`}>\n            <rect x={seamX} y={-big} width={big} height={big * 2} />\n          </clipPath>\n          <clipPath id={`${id}-glyphs`}>{lockup}</clipPath>\n          <linearGradient\n            id={`${id}-fill`}\n            gradientUnits=\"userSpaceOnUse\"\n            x1={seamX}\n            y1={-R_HEIGHT}\n            x2={set.ink}\n            y2={0}\n          >\n            <stop offset=\"0\" stopColor={fill[0]} />\n            <stop offset=\"0.45\" stopColor={fill[1]} />\n            <stop offset=\"1\" stopColor={fill[2]} />\n          </linearGradient>\n        </defs>\n        <g transform={`translate(${shake} 0)`}>\n          <g transform={`translate(${ox + dxL} ${baseline}) scale(${k})`}>\n            <g clipPath={`url(#${id}-l)`}>\n              <rect\n                x={-R_WIDTH}\n                y={-1200}\n                width={seamX + R_WIDTH * 2}\n                height={1600}\n                fill={c.fg}\n                clipPath={`url(#${id}-glyphs)`}\n              />\n            </g>\n          </g>\n          <g transform={`translate(${ox + dxR} ${baseline}) scale(${k})`}>\n            <g clipPath={`url(#${id}-r)`}>\n              <rect\n                x={seamX - 200}\n                y={-1200}\n                width={set.ink - seamX + 400}\n                height={1600}\n                fill={`url(#${id}-fill)`}\n                clipPath={`url(#${id}-glyphs)`}\n              />\n            </g>\n          </g>\n          {flash > 0 && t >= CLICK ? (\n            <rect\n              x={seamScreen - u}\n              y={baseline - (R_HEIGHT / 2) * k - (flashH / 2) * k}\n              width={2 * u}\n              height={flashH * k}\n              fill={c.flash}\n              opacity={flash}\n            />\n          ) : null}\n        </g>\n      </svg>\n      {typing ? (\n        <div\n          style={{\n            position: \"absolute\",\n            left: 0,\n            right: 0,\n            top: baseline + 92 * u,\n            textAlign: \"center\",\n            fontFamily: mono,\n            fontWeight: 400,\n            fontSize: labelSize,\n            letterSpacing: \"0.01em\",\n            lineHeight: 1,\n            color: c.muted,\n            whiteSpace: \"pre\",\n          }}\n        >\n          <span>{label.slice(0, typed)}</span>\n          <span\n            style={{\n              display: \"inline-block\",\n              width: 0,\n              position: \"relative\",\n              verticalAlign: \"top\",\n            }}\n          >\n            <span\n              style={{\n                position: \"absolute\",\n                left: labelSize * 0.08,\n                top: -labelSize * 0.08,\n                width: labelSize * 0.55,\n                height: labelSize * 1.12,\n                background: accent,\n                opacity: caretOn ? 1 : 0,\n              }}\n            />\n          </span>\n          <span style={{ color: \"transparent\" }}>{label.slice(typed)}</span>\n        </div>\n      ) : null}\n      <Grain opacity={c.grain} />\n    </AbsoluteFill>\n  );\n}\n",
      "type": "registry:component",
      "target": "components/remocn/snap-click.tsx"
    }
  ],
  "type": "registry:component"
}
