{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "logo-construct",
  "title": "Logo Construct",
  "description": "A blueprint grid draws the logo construction lines and the wordmark inks in.",
  "dependencies": ["remotion", "@remotion/google-fonts"],
  "files": [
    {
      "path": "registry/remocn/logo-construct/index.tsx",
      "content": "\"use client\";\n\nimport { loadFont as loadMono } from \"@remotion/google-fonts/IBMPlexMono\";\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: mono } = loadMono(\"normal\", {\n  weights: [\"400\", \"500\"],\n  subsets: [\"latin\"],\n});\nconst manrope = loadManrope(\"normal\", {\n  weights: [\"500\", \"600\"],\n  subsets: [\"latin\"],\n});\n\nexport interface LogoConstructProps {\n  /** Replaces the constructed R. The construction still draws, then your logo settles in its place. */\n  logo?: React.ReactNode;\n  /** Letters set after the R, on its baseline, in Manrope 600. The real logo reads R + \"emocn\". */\n  name?: string;\n  accent?: string;\n  /** Playback multiplier. */\n  speed?: number;\n  /** Light = blueprint paper (default); dark = drafting film on black. */\n  theme?: \"light\" | \"dark\";\n}\n\nconst EASE_IO = Easing.bezier(0.65, 0, 0.35, 1);\nconst EASE_OUT = Easing.bezier(0.22, 1, 0.36, 1);\nconst EASE_DRAW = Easing.bezier(0.45, 0, 0.2, 1);\nconst CLAMP = {\n  extrapolateLeft: \"clamp\",\n  extrapolateRight: \"clamp\",\n} as const;\n\n// gradients.sh \"mesh\" palette: bg #0a0d24, [#ecdcf2, #8796ee, #2e45b7, #0e1645].\n// It fills the constructed R: a mesh of soft blobs inside the letter.\nconst THEMES = {\n  light: {\n    bg: \"#F5F4F0\",\n    ink: \"#121214\",\n    guideMix: 0,\n    gridAlpha: 0.075,\n    majorAlpha: 0.13,\n    guideAlpha: 0.62,\n    label: 0.9,\n    vignette: \"rgba(120,110,90,0.10)\",\n    grain: 0.05,\n    meshBase: \"#0a0d24\",\n    // [colour, x, y, radius, opacity] per blob, in the R's bounding box\n    mesh: [\n      [\"#ecdcf2\", 0.58, 0.1, 0.42, 0.55],\n      [\"#8796ee\", 0.95, 0.32, 0.7, 1],\n      [\"#2e45b7\", 0.74, 0.92, 0.7, 1],\n      [\"#0e1645\", 0.12, 0.72, 0.7, 1],\n    ],\n  },\n  dark: {\n    bg: \"#0A0A0B\",\n    ink: \"#F3F2EF\",\n    guideMix: 0.45,\n    gridAlpha: 0.07,\n    majorAlpha: 0.12,\n    guideAlpha: 0.7,\n    label: 0.95,\n    vignette: \"rgba(0,0,0,0.55)\",\n    grain: 0.06,\n    meshBase: \"#2e45b7\",\n    mesh: [\n      [\"#ecdcf2\", 0.6, 0.12, 0.5, 0.9],\n      [\"#8796ee\", 0.12, 0.22, 0.7, 1],\n      [\"#2e45b7\", 0.74, 0.9, 0.7, 1],\n      [\"#8796ee\", 0.2, 0.86, 0.5, 0.8],\n    ],\n  },\n} as const;\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// Construction geometry, measured off the R path (R units, y down, 134.26 tall).\nconst R_W = 121.44;\nconst H = 134.26;\n/** One stroke module: the bar, stem, mid bar and bowl are all ~1/7 of the height. */\nconst M = H / 7;\n/** Bowl: concentric arcs around one centre. */\nconst BOWL = { x: 79.6, y: 42.6, ro: 41.9, ri: 23.1 };\nconst BAR_IN = 19.3;\nconst MID_TOP = 67.7;\nconst MID_BOT = 87.6;\nconst STEM_R = 19;\n/** Leg: the outer edge runs from (84.4, 91.6) to the foot at (117, 134.2). */\nconst LEG = { x0: 84.4, y0: 91.6, x1: 117, y1: 134.2 };\nconst LEG_DEG = (Math.atan2(LEG.y1 - LEG.y0, LEG.x1 - LEG.x0) * 180) / Math.PI;\n/** Bezier anchors + handles of the two transitions that give the R its voice. */\nconst HANDLES = [\n  // the top-left swash\n  { a: [21.7, 18.9], h: [13.45, 17.16] },\n  { a: [1.09, 4.13], h: [4.91, 11.04] },\n  // the mid bar turning down into the stem\n  { a: [10.65, 79.89], h: [14.84, 75.7] },\n  { a: [10.65, 79.89], h: [4.86, 85.68] },\n  { a: [19.82, 101.04], h: [21.79, 93.65] },\n  { a: [36.45, 87.63], h: [27.86, 88.75] },\n] as const;\n\n// The wordmark, set like the site header: R is 0.76em tall, \"emocn\" Manrope 600 at -0.025em.\nconst FONT = H / 0.76;\nconst X_HEIGHT = 0.54;\nconst WORD_XLINE = H - FONT * X_HEIGHT;\nconst TRACK = -0.025;\n/** Manrope 600 advances, per em. */\nconst ADV: Record<string, number> = {\n  a: 0.57,\n  c: 0.568,\n  e: 0.596,\n  i: 0.264,\n  l: 0.264,\n  m: 0.882,\n  n: 0.615,\n  o: 0.61,\n  r: 0.386,\n  s: 0.536,\n  t: 0.422,\n  \" \": 0.26,\n};\nconst WORD_X = 124.06 + FONT * 0.04;\nconst RISE = FONT * 0.8;\n\nfunction hexRgb(hex: string) {\n  const h = hex.replace(\"#\", \"\");\n  const n = Number.parseInt(\n    h.length === 3\n      ? h\n          .split(\"\")\n          .map((c) => c + c)\n          .join(\"\")\n      : h,\n    16,\n  );\n  return [(n >> 16) & 255, (n >> 8) & 255, n & 255];\n}\n\nfunction tint(hex: string, mixWhite: number, alpha: number) {\n  const [r, g, b] = hexRgb(hex).map((c) =>\n    Math.round(c + (255 - c) * mixWhite),\n  );\n  return `rgba(${r},${g},${b},${alpha})`;\n}\n\n/** Polyline of a circular arc, angles in degrees, y down (270 = up). */\nfunction arc(cx: number, cy: number, r: number, a0: number, sweep: number) {\n  const steps = Math.max(2, Math.ceil(Math.abs(sweep) / 3));\n  let d = \"\";\n  for (let i = 0; i <= steps; i++) {\n    const a = ((a0 + (sweep * i) / steps) * Math.PI) / 180;\n    d += `${i ? \"L\" : \"M\"}${cx + Math.cos(a) * r} ${cy + Math.sin(a) * r}`;\n  }\n  return d;\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 }}\n      aria-hidden\n    >\n      <filter id={id}>\n        <feTurbulence\n          type=\"fractalNoise\"\n          baseFrequency=\"0.85\"\n          numOctaves={2}\n          seed={11}\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 LogoConstruct({\n  logo,\n  name = \"emocn\",\n  accent = \"#3B5BFD\",\n  speed = 1,\n  theme = \"light\",\n}: LogoConstructProps) {\n  const t = useCurrentFrame() * speed;\n  const { width, height } = useVideoConfig();\n  const u = height / 720;\n  const pal = THEMES[theme];\n  const uid = useId().replace(/[^a-zA-Z0-9_-]/g, \"\");\n\n  const p = (a: number, b: number, easing = EASE_DRAW) =>\n    interpolate(t, [a, b], [0, 1], { ...CLAMP, easing });\n\n  // ---- camera: tight on the R, then an eased pull back to the lockup ----\n  const wordW =\n    name.split(\"\").reduce((w, ch) => w + (ADV[ch] ?? 0.6) + TRACK, 0) * FONT;\n  const lockL = 0;\n  const lockR = WORD_X + wordW;\n  const dimRoom = 30;\n  const s1 = 3.05 * u;\n  const s2 = Math.min((width * 0.6) / (lockR + dimRoom - lockL), 1.25 * u);\n  const pull = p(120, 168, EASE_IO);\n  const drift = interpolate(t, [0, 120], [0, 1], CLAMP);\n  const sCam = Math.exp(\n    interpolate(\n      pull,\n      [0, 1],\n      [Math.log(s1 * (0.965 + drift * 0.035)), Math.log(s2)],\n    ),\n  );\n  const camX = interpolate(pull, [0, 1], [R_W / 2 + 4, (lockL + lockR) / 2]);\n  const camY = interpolate(pull, [0, 1], [H / 2 - 2, H / 2 + 4]);\n  const hold = interpolate(t, [160, 260], [1, 1.03], {\n    ...CLAMP,\n    easing: EASE_IO,\n  });\n  const s = sCam * hold;\n  const tx = width / 2 - camX * s;\n  const ty = height / 2 - camY * s;\n  const px = (n: number) => n / s; // screen px -> units at the current zoom\n\n  // visible range in units, for grid + infinite guides\n  const vx0 = (0 - tx) / s;\n  const vx1 = (width - tx) / s;\n  const vy0 = (0 - ty) / s;\n  const vy1 = (height - ty) / s;\n\n  // ---- colours ----\n  const guide = tint(accent, pal.guideMix, 1);\n  const guideA = (a: number) => tint(accent, pal.guideMix, a);\n\n  // guides settle to hairlines once the mark is solid\n  const settle = p(112, 150, EASE_IO);\n  const guideLevel = interpolate(settle, [0, 1], [pal.guideAlpha, 0.2]);\n  const labelLevel = interpolate(p(110, 132, EASE_IO), [0, 1], [pal.label, 0]);\n\n  // ---- paper grid on the module (half-module minor, module major) ----\n  const gridIn = 0.45 + 0.55 * p(0, 18, EASE_OUT);\n  const minorStep = M / 2;\n  const minorAlpha =\n    pal.gridAlpha *\n    gridIn *\n    interpolate(minorStep * s, [10 * u, 26 * u], [0.25, 1], CLAMP);\n  const gridLines: React.ReactNode[] = [];\n  for (let i = Math.floor(vx0 / minorStep); i * minorStep <= vx1; i++) {\n    const gx = i * minorStep;\n    const major = i % 2 === 0;\n    gridLines.push(\n      <line\n        key={`gx${i}`}\n        x1={gx}\n        x2={gx}\n        y1={vy0}\n        y2={vy1}\n        stroke={guideA(major ? pal.majorAlpha * gridIn : minorAlpha)}\n        strokeWidth={px(1)}\n      />,\n    );\n  }\n  for (let i = Math.floor(vy0 / minorStep); i * minorStep <= vy1; i++) {\n    const gy = i * minorStep;\n    const major = i % 2 === 0;\n    gridLines.push(\n      <line\n        key={`gy${i}`}\n        y1={gy}\n        y2={gy}\n        x1={vx0}\n        x2={vx1}\n        stroke={guideA(major ? pal.majorAlpha * gridIn : minorAlpha)}\n        strokeWidth={px(1)}\n      />,\n    );\n  }\n\n  // ---- infinite guides that grow out from the R ----\n  const span = Math.max(vx1 - vx0, vy1 - vy0) * 1.2;\n  const hGuides = [\n    { y: 0, from: 60, at: 8 },\n    { y: H, from: 60, at: 11 },\n    { y: BOWL.y, from: BOWL.x, at: 16 },\n    { y: BAR_IN, from: 50, at: 19 },\n    { y: MID_TOP, from: 50, at: 22 },\n    { y: MID_BOT, from: 50, at: 25 },\n  ];\n  const vGuides = [\n    { x: 0, from: 67, at: 13 },\n    { x: STEM_R, from: 67, at: 17 },\n    { x: BOWL.x, from: BOWL.y, at: 21 },\n    { x: R_W, from: BOWL.y, at: 24 },\n  ];\n  // the wordmark re-lights the baseline\n  const relight = p(146, 166, EASE_OUT) * (1 - p(196, 230, EASE_IO) * 0.5);\n  const lineAlpha = (y?: number) =>\n    y === H ? guideLevel + relight * (pal.guideAlpha - 0.2) * 0.9 : guideLevel;\n\n  // ---- construction draw windows ----\n  const crossIn = p(28, 40, EASE_OUT);\n  const radius = p(32, 46);\n  const outer = p(36, 66);\n  const inner = p(48, 64);\n  const dims = p(44, 60, EASE_OUT);\n  const ruler = p(40, 64);\n  const leg = p(54, 72);\n  const legArc = p(60, 76);\n  const handles = HANDLES.map((_, i) => p(58 + i * 3, 70 + i * 3, EASE_OUT));\n  const outline = p(72, 106);\n  const fill = p(96, 128, EASE_IO);\n  const markDone = p(122, 134, EASE_OUT);\n\n  const hair = px(1 * u);\n  const thin = px(1.25 * u);\n  const dash = `${px(3 * u)} ${px(3.5 * u)}`;\n  const fs = px(12 * u);\n\n  const Label = ({\n    x,\n    y,\n    children,\n    anchor = \"start\",\n    o = 1,\n    rotate,\n  }: {\n    x: number;\n    y: number;\n    children: React.ReactNode;\n    anchor?: \"start\" | \"middle\" | \"end\";\n    o?: number;\n    rotate?: number;\n  }) => (\n    <text\n      x={x}\n      y={y}\n      textAnchor={anchor}\n      fontFamily={mono}\n      fontSize={fs}\n      fontWeight={500}\n      letterSpacing={px(0.2 * u)}\n      fill={guide}\n      opacity={o * labelLevel}\n      transform={rotate ? `rotate(${rotate} ${x} ${y})` : undefined}\n      style={{ fontVariantNumeric: \"tabular-nums\" }}\n    >\n      {children}\n    </text>\n  );\n\n  const tick = (x: number, y: number, vertical: boolean, len = 3) =>\n    vertical ? (\n      <line x1={x} x2={x} y1={y - len} y2={y + len} />\n    ) : (\n      <line x1={x - len} x2={x + len} y1={y} y2={y} />\n    );\n\n  // the fill sweeps round the bowl centre, like the compass did\n  const wedge = (() => {\n    const sweep = 360 * fill;\n    if (sweep <= 0) return \"M0 0z\";\n    if (sweep >= 359.9) return `M-400 -400H600V600H-400z`;\n    return `M${BOWL.x} ${BOWL.y}${arc(BOWL.x, BOWL.y, 400, 180, sweep).replace(\"M\", \"L\")}Z`;\n  })();\n\n  // mesh blobs drift a few percent over the shot\n  const blob = (bx: number, by: number, k: number) => ({\n    cx: R_W * (bx + Math.sin(t / 47 + k * 1.7) * 0.04),\n    cy: H * (by + Math.cos(t / 53 + k * 2.3) * 0.03),\n  });\n  const blobs = pal.mesh.map(([c, bx, by, r, o], k) => ({\n    ...blob(bx, by, k),\n    c,\n    r: R_W * r,\n    o,\n  }));\n\n  // wordmark letters rise out of the baseline, 3 frames apart\n  const letters = name.split(\"\");\n  const letterP = (i: number) => p(144 + i * 3, 164 + i * 3, EASE_OUT);\n  const wordGuides = p(140, 160, EASE_OUT);\n  const xGrow = p(138, 166);\n  const wordSettle = p(198, 232, EASE_IO);\n  const dimX = lockR + 14;\n\n  // logo overlay geometry (screen)\n  const markScreen = {\n    left: tx,\n    top: ty,\n    size: H * s,\n  };\n  const logoIn = p(100, 126, EASE_OUT);\n\n  const legLen = Math.hypot(LEG.x1 - LEG.x0, LEG.y1 - LEG.y0);\n  const legUx = (LEG.x1 - LEG.x0) / legLen;\n  const legUy = (LEG.y1 - LEG.y0) / legLen;\n\n  return (\n    <AbsoluteFill style={{ background: pal.bg, overflow: \"hidden\" }}>\n      <svg\n        width={width}\n        height={height}\n        style={{ position: \"absolute\", inset: 0 }}\n        aria-hidden\n      >\n        <defs>\n          <clipPath id={`fill${uid}`} clipPathUnits=\"userSpaceOnUse\">\n            <path d={wedge} />\n          </clipPath>\n          {blobs.map((b, i) => (\n            <radialGradient\n              key={i}\n              id={`mesh${uid}${i}`}\n              gradientUnits=\"userSpaceOnUse\"\n              cx={b.cx}\n              cy={b.cy}\n              r={b.r}\n            >\n              <stop offset=\"0%\" stopColor={b.c} stopOpacity={b.o} />\n              <stop offset=\"68%\" stopColor={b.c} stopOpacity={0} />\n            </radialGradient>\n          ))}\n          <clipPath id={`word${uid}`} clipPathUnits=\"userSpaceOnUse\">\n            <rect\n              x={WORD_X - 10}\n              y={-200}\n              width={wordW + 60}\n              height={H + 200.5}\n            />\n          </clipPath>\n        </defs>\n        <g transform={`translate(${tx} ${ty}) scale(${s})`}>\n          {gridLines}\n\n          {/* infinite construction guides */}\n          <g stroke={guide} strokeWidth={hair} fill=\"none\">\n            {hGuides.map((g) => {\n              const k = p(g.at, g.at + 26);\n              return (\n                <line\n                  key={`h${g.y}`}\n                  x1={g.from - span * k}\n                  x2={g.from + span * k}\n                  y1={g.y}\n                  y2={g.y}\n                  opacity={lineAlpha(g.y)}\n                />\n              );\n            })}\n            {vGuides.map((g) => {\n              const k = p(g.at, g.at + 26);\n              return (\n                <line\n                  key={`v${g.x}`}\n                  y1={g.from - span * k}\n                  y2={g.from + span * k}\n                  x1={g.x}\n                  x2={g.x}\n                  opacity={guideLevel}\n                />\n              );\n            })}\n          </g>\n\n          {/* compass, ruler and handle work */}\n          <g\n            stroke={guide}\n            fill=\"none\"\n            strokeWidth={thin}\n            opacity={interpolate(settle, [0, 1], [1, 0.3])}\n          >\n            <g opacity={crossIn}>\n              <line x1={BOWL.x - 5} x2={BOWL.x + 5} y1={BOWL.y} y2={BOWL.y} />\n              <line y1={BOWL.y - 5} y2={BOWL.y + 5} x1={BOWL.x} x2={BOWL.x} />\n              <circle cx={BOWL.x} cy={BOWL.y} r={1.4} />\n            </g>\n            {radius > 0 && (\n              <line\n                x1={BOWL.x}\n                y1={BOWL.y}\n                x2={BOWL.x + Math.cos(-Math.PI / 4) * BOWL.ro * radius}\n                y2={BOWL.y + Math.sin(-Math.PI / 4) * BOWL.ro * radius}\n              />\n            )}\n            {outer > 0 && (\n              <path\n                d={arc(BOWL.x, BOWL.y, BOWL.ro, 180, 360 * outer)}\n                strokeDasharray={dash}\n              />\n            )}\n            {inner > 0 && (\n              <path\n                d={arc(BOWL.x, BOWL.y, BOWL.ri, 180, 360 * inner)}\n                strokeDasharray={dash}\n              />\n            )}\n            {/* 90° quadrant marker */}\n            <path\n              d={arc(BOWL.x, BOWL.y, 9, 270, 90 * p(46, 60))}\n              opacity={0.8}\n            />\n\n            {/* leg: its axis, extended, and the angle off the baseline */}\n            {leg > 0 && (\n              <line\n                x1={LEG.x0 - legUx * 26}\n                y1={LEG.y0 - legUy * 26}\n                x2={LEG.x0 - legUx * 26 + legUx * (legLen + 46) * leg}\n                y2={LEG.y0 - legUy * 26 + legUy * (legLen + 46) * leg}\n                strokeDasharray={dash}\n              />\n            )}\n            {legArc > 0 && (\n              <path\n                d={arc(LEG.x1, LEG.y1, 16, 180, LEG_DEG * legArc)}\n                transform={`translate(0 0)`}\n              />\n            )}\n\n            {/* bezier handles of the swash and the stem join */}\n            {HANDLES.map((hd, i) =>\n              handles[i] > 0 ? (\n                <g key={`hd${i}`} opacity={handles[i]}>\n                  <line\n                    x1={hd.a[0]}\n                    y1={hd.a[1]}\n                    x2={hd.a[0] + (hd.h[0] - hd.a[0]) * handles[i]}\n                    y2={hd.a[1] + (hd.h[1] - hd.a[1]) * handles[i]}\n                  />\n                  <circle\n                    cx={hd.a[0] + (hd.h[0] - hd.a[0]) * handles[i]}\n                    cy={hd.a[1] + (hd.h[1] - hd.a[1]) * handles[i]}\n                    r={px(3 * u)}\n                    fill={pal.bg}\n                  />\n                  <rect\n                    x={hd.a[0] - px(3.5 * u)}\n                    y={hd.a[1] - px(3.5 * u)}\n                    width={px(7 * u)}\n                    height={px(7 * u)}\n                    fill={pal.bg}\n                  />\n                </g>\n              ) : null,\n            )}\n\n            {/* module ruler: seven strokes tall */}\n            <g opacity={dims}>\n              <line x1={-14} x2={-14} y1={0} y2={H * ruler} />\n              {Array.from({ length: 8 }, (_, i) =>\n                i * M <= H * ruler + 0.01 ? (\n                  <g key={`m${i}`}>\n                    {tick(-14, i * M, false, i % 7 === 0 ? 4 : 2.4)}\n                  </g>\n                ) : null,\n              )}\n              {/* width */}\n              <line x1={0} x2={R_W * ruler} y1={-14} y2={-14} />\n              {tick(0, -14, true, 4)}\n              {ruler >= 1 && tick(R_W, -14, true, 4)}\n              {/* bar thickness */}\n              <line x1={56} x2={56} y1={0} y2={BAR_IN} />\n              {tick(56, 0, false, 2.4)}\n              {tick(56, BAR_IN, false, 2.4)}\n            </g>\n          </g>\n\n          {/* measurement labels */}\n          <g opacity={dims}>\n            <Label x={R_W / 2} y={-14 - px(8 * u)} anchor=\"middle\">\n              124\n            </Label>\n            <Label x={-14 - px(10 * u)} y={H / 2} anchor=\"middle\" rotate={-90}>\n              7m · 134\n            </Label>\n            <Label x={56 + px(8 * u)} y={BAR_IN / 2 + px(4 * u)}>\n              m 19.2\n            </Label>\n          </g>\n          <Label\n            x={BOWL.x + Math.cos(-Math.PI / 4) * BOWL.ro + px(6 * u)}\n            y={BOWL.y + Math.sin(-Math.PI / 4) * BOWL.ro - px(4 * u)}\n            o={radius}\n          >\n            R42\n          </Label>\n          <Label\n            x={BOWL.x - BOWL.ri - px(8 * u)}\n            y={BOWL.y - px(8 * u)}\n            anchor=\"end\"\n            o={inner}\n          >\n            R23\n          </Label>\n          <Label x={BOWL.x + px(8 * u)} y={BOWL.y + px(18 * u)} o={crossIn}>\n            80,43\n          </Label>\n          <Label x={LEG.x1 - 20} y={LEG.y1 - 6} anchor=\"end\" o={legArc}>\n            {`${LEG_DEG.toFixed(0)}°`}\n          </Label>\n\n          {/* the R: outline first, then the mesh fill sweeps round the bowl centre */}\n          {!logo && (\n            <g>\n              {outline > 0 && (\n                <path\n                  d={REMOCN_R_PATH}\n                  fill=\"none\"\n                  stroke={pal.ink}\n                  strokeWidth={px(1.4 * u)}\n                  strokeLinejoin=\"round\"\n                  pathLength={1}\n                  strokeDasharray={`${outline} 2`}\n                  opacity={1 - markDone}\n                />\n              )}\n              <g clipPath={`url(#fill${uid})`}>\n                <path d={REMOCN_R_PATH} fill={pal.meshBase} />\n                {blobs.map((_, i) => (\n                  <path\n                    key={i}\n                    d={REMOCN_R_PATH}\n                    fill={`url(#mesh${uid}${i})`}\n                  />\n                ))}\n              </g>\n            </g>\n          )}\n\n          {/* wordmark guides: its x-height, the shared baseline, a side bearing */}\n          <g stroke={guide} strokeWidth={hair} fill=\"none\">\n            <line\n              x1={WORD_X - span * xGrow}\n              x2={WORD_X + span * xGrow}\n              y1={WORD_XLINE}\n              y2={WORD_XLINE}\n              opacity={pal.guideAlpha * 0.85 * (1 - wordSettle * 0.7)}\n            />\n          </g>\n          <g\n            opacity={wordGuides * (1 - wordSettle * 0.75)}\n            stroke={guide}\n            strokeWidth={thin}\n            fill=\"none\"\n          >\n            <line\n              x1={WORD_X - 3}\n              x2={WORD_X - 3}\n              y1={WORD_XLINE - 10}\n              y2={H + 10}\n              strokeDasharray={dash}\n            />\n          </g>\n          <g\n            opacity={p(156, 174, EASE_OUT) * (1 - wordSettle * 0.75)}\n            stroke={guide}\n            strokeWidth={thin}\n          >\n            <line x1={dimX} x2={dimX} y1={WORD_XLINE} y2={H} />\n            {tick(dimX, WORD_XLINE, false, 4)}\n            {tick(dimX, H, false, 4)}\n          </g>\n          <g\n            opacity={p(156, 174, EASE_OUT) * (1 - wordSettle * 0.75)}\n            fontFamily={mono}\n            fontSize={fs}\n            fontWeight={500}\n            fill={guide}\n            style={{ fontVariantNumeric: \"tabular-nums\" }}\n          >\n            <text x={dimX + px(8 * u)} y={(WORD_XLINE + H) / 2 + px(4 * u)}>\n              0.54em\n            </text>\n            <text x={WORD_X} y={WORD_XLINE - px(7 * u)}>\n              x-height\n            </text>\n            <text x={WORD_X} y={H + px(17 * u)}>\n              baseline\n            </text>\n          </g>\n          <g clipPath={`url(#word${uid})`}>\n            <text\n              x={WORD_X}\n              y={H}\n              fontFamily={manrope.fontFamily}\n              fontWeight={600}\n              fontSize={FONT}\n              letterSpacing={FONT * TRACK}\n              fill={pal.ink}\n            >\n              {letters.map((ch, i) => {\n                const k = letterP(i);\n                const prev = i === 0 ? 0 : (1 - letterP(i - 1)) * RISE;\n                return (\n                  <tspan\n                    key={i}\n                    dy={(1 - k) * RISE - prev}\n                    fillOpacity={0.15 + k * 0.85}\n                  >\n                    {ch}\n                  </tspan>\n                );\n              })}\n            </text>\n          </g>\n        </g>\n      </svg>\n\n      {logo && (\n        <div\n          style={{\n            position: \"absolute\",\n            left: markScreen.left,\n            top: markScreen.top,\n            height: markScreen.size,\n            display: \"flex\",\n            alignItems: \"center\",\n            opacity: logoIn,\n            filter: `blur(${(1 - logoIn) * 6 * u}px)`,\n            transform: `scale(${0.96 + logoIn * 0.04})`,\n            transformOrigin: \"left center\",\n          }}\n        >\n          {logo}\n        </div>\n      )}\n\n      <AbsoluteFill\n        style={{\n          background: `radial-gradient(ellipse 75% 70% at 50% 48%, transparent 55%, ${pal.vignette} 100%)`,\n        }}\n      />\n      <Grain opacity={pal.grain} />\n    </AbsoluteFill>\n  );\n}\n",
      "type": "registry:component",
      "target": "components/remocn/logo-construct.tsx"
    }
  ],
  "type": "registry:component"
}
