{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "level-up",
  "title": "Level Up",
  "description": "'LEVEL UP' ticks from one level to the next, 42, with an XP bar and a stat chip.",
  "dependencies": ["remotion", "@remotion/google-fonts"],
  "files": [
    {
      "path": "registry/remocn/level-up/index.tsx",
      "content": "\"use client\";\n\nimport { loadFont } from \"@remotion/google-fonts/ChakraPetch\";\nimport { loadFont as loadManrope } from \"@remotion/google-fonts/Manrope\";\nimport { useId } from \"react\";\nimport {\n  AbsoluteFill,\n  Easing,\n  interpolate,\n  useCurrentFrame,\n  useVideoConfig,\n} from \"remotion\";\n\nconst { fontFamily: hud } = loadFont(\"normal\", {\n  weights: [\"400\", \"500\"],\n  subsets: [\"latin\"],\n});\nconst manrope = loadManrope(\"normal\", {\n  weights: [\"600\"],\n  subsets: [\"latin\"],\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/** 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      }}\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\nexport interface LevelUpProps {\n  /** Level before the level-up. The new level is `level + 1`. */\n  level?: number;\n  /** XP already in the bar when the shot opens. */\n  startXp?: number;\n  /** XP needed for the next level. The chips should add up to `maxXp - startXp`. */\n  maxXp?: number;\n  /** One chip per entry, each flies into the bar. */\n  chips?: number[];\n  /** Big erupting call. */\n  title?: string;\n  /** Stat line that ticks up on the poster. */\n  stat?: { label: string; value: number; suffix?: string };\n  /** Small accent: the stat arrow and the level label marker. */\n  accent?: string;\n  theme?: \"dark\" | \"light\";\n  speed?: number;\n}\n\n// Beat sheet (30fps, speed 1):\n//   0–10   the segmented XP bar builds left to right, labels slide in\n//   6–48   XP chips fly into the fill head one after another, speeding up;\n//          each hit fills the bar a step, flashes the new segment and ticks the\n//          counter\n//  48–51   the bar maxes out and flashes\n//  51–58   the bar collapses into the centre point\n//  58–66   \"LEVEL UP\" erupts from that point with a burst of gradient rays and\n//          one shockwave ring\n//  68–76   the call ducks to a kicker, the old level number rises in big\n//  82–90   the changed digit rolls 41 → 42 and lands with a kick\n//  94–106  the stat line slides in and ticks up; poster hold to the end\nconst BAR_AT = 0;\nconst CHIP_FLY = 12;\nconst ARRIVALS = [18, 25, 31, 37, 42];\nconst FILL_LEN = 6;\nconst MAX_AT = 48;\nconst COLLAPSE_AT = 51;\nconst COLLAPSE_LEN = 7;\nconst BURST_AT = 58;\nconst DUCK_AT = 68;\nconst DUCK_LEN = 8;\nconst ROLL_AT = 82;\nconst ROLL_LEN = 8;\nconst STAT_AT = 94;\nconst STAT_LEN = 12;\nconst SEGMENTS = 10;\n\nconst OUT = Easing.bezier(0.22, 1, 0.36, 1);\nconst SLAM = Easing.bezier(0.12, 0.9, 0.25, 1);\nconst INOUT = Easing.bezier(0.65, 0, 0.25, 1);\nconst IN = Easing.bezier(0.5, 0, 0.9, 0.6);\nconst CLAMP = {\n  extrapolateLeft: \"clamp\",\n  extrapolateRight: \"clamp\",\n} as const;\n\n// gradients.sh \"beam\": bg #02030a, [#f4f7ff, #8fb4ff, #3d5bff, #1a1660].\nconst BEAM = [\"#F4F7FF\", \"#8FB4FF\", \"#3D5BFF\", \"#1A1660\"] as const;\n\nconst THEMES = {\n  dark: {\n    stage: \"#050609\",\n    ink: \"#F3F2EF\",\n    dim: \"#8A8A93\",\n    track: \"#16171E\",\n    chip: \"#0E1020\",\n    chipEdge: BEAM[1],\n    rayAlpha: 1,\n    rays: [BEAM[0], BEAM[1], BEAM[2], BEAM[3]],\n    fill: `linear-gradient(90deg, ${BEAM[3]} 0%, ${BEAM[2]} 38%, ${BEAM[1]} 78%, ${BEAM[0]} 100%)`,\n    number: `linear-gradient(180deg, ${BEAM[0]} 8%, ${BEAM[1]} 52%, ${BEAM[2]} 96%)`,\n  },\n  light: {\n    stage: \"#F5F4F0\",\n    ink: \"#121214\",\n    dim: \"#7E7D77\",\n    track: \"#E3E1DA\",\n    chip: \"#FFFFFF\",\n    chipEdge: BEAM[2],\n    rayAlpha: 0.7,\n    rays: [BEAM[2], BEAM[2], BEAM[1], BEAM[1]],\n    fill: `linear-gradient(90deg, ${BEAM[3]} 0%, ${BEAM[2]} 45%, ${BEAM[1]} 100%)`,\n    number: `linear-gradient(180deg, ${BEAM[2]} 8%, #2A2FB8 55%, ${BEAM[3]} 96%)`,\n  },\n} as const;\n\nfunction ramp(t: number, from: number, len: number) {\n  return interpolate(t, [from, from + len], [0, 1], CLAMP);\n}\n\nfunction hash(n: number) {\n  const x = Math.sin(n * 127.1 + 311.7) * 43758.5453;\n  return x - Math.floor(x);\n}\n\nfunction fmt(n: number) {\n  return String(Math.round(n)).replace(/\\B(?=(\\d{3})+(?!\\d))/g, \",\");\n}\n\n/** A short hit: up in 2 frames, eases back over 8. */\nfunction kick(d: number) {\n  if (d < 0) return 0;\n  if (d < 2) return d / 2;\n  const k = Math.max(0, 1 - (d - 2) / 8);\n  return k * k;\n}\n\n// Chip launch points, relative to the bar centre in units of W and H.\nconst LAUNCH = [\n  { x: -0.36, y: -0.36 },\n  { x: 0.3, y: -0.4 },\n  { x: -0.22, y: 0.36 },\n  { x: 0.06, y: -0.42 },\n  { x: 0.34, y: 0.34 },\n];\n\nexport function LevelUp({\n  level = 41,\n  startXp = 2800,\n  maxXp = 4000,\n  chips = [120, 240, 180, 300, 360],\n  title = \"LEVEL UP\",\n  stat = { label: \"Render speed\", value: 40, suffix: \"%\" },\n  accent = \"#3B5BFD\",\n  theme = \"dark\",\n  speed = 1,\n}: LevelUpProps) {\n  const t = useCurrentFrame() * speed;\n  const { width: W, height: H } = useVideoConfig();\n  const c = THEMES[theme];\n  const u = Math.min(W / 1280, H / 720);\n  const id = useId().replace(/[^a-zA-Z0-9_-]/g, \"\");\n\n  const cx = W / 2;\n  const cy = 0.53 * H;\n\n  // ── XP state ──────────────────────────────────────────────────────────────\n  const arrivals = chips.map(\n    (_, i) => ARRIVALS[i] ?? ARRIVALS[ARRIVALS.length - 1] + (i - 4) * 5,\n  );\n  let xp = startXp;\n  chips.forEach((v, i) => {\n    xp += v * OUT(ramp(t, arrivals[i], FILL_LEN));\n  });\n  const fill = Math.min(1, xp / maxXp);\n  const lastHit = arrivals.reduce((acc, a) => (t >= a ? a : acc), -99);\n  const hitKick = kick(t - lastHit);\n\n  // ── Bar geometry ──────────────────────────────────────────────────────────\n  const barW = 0.66 * W;\n  const barH = 34 * u;\n  const gap = 7 * u;\n  const segW = (barW - gap * (SEGMENTS - 1)) / SEGMENTS;\n  const collapse = INOUT(ramp(t, COLLAPSE_AT, COLLAPSE_LEN));\n  const maxFlash = t >= MAX_AT ? Math.max(0, 1 - (t - MAX_AT) / 6) : 0;\n  const barGone = t >= COLLAPSE_AT + COLLAPSE_LEN;\n  const labelsIn = OUT(ramp(t, BAR_AT + 3, 9));\n  const labelsOut = ramp(t, COLLAPSE_AT, 4);\n\n  // ── Burst ─────────────────────────────────────────────────────────────────\n  const burst = OUT(ramp(t, BURST_AT, 16));\n  const burstOp = ramp(t, BURST_AT, 3);\n  const rollHit = ROLL_AT + ROLL_LEN;\n  const rayPulse = kick(t - rollHit + 1);\n  const spin = Math.max(0, t - BURST_AT) * 0.22;\n  const ring = ramp(t, BURST_AT, 16);\n\n  const titleFs = 140 * u;\n  const titleIn = SLAM(ramp(t, BURST_AT, 7));\n  const duck = INOUT(ramp(t, DUCK_AT, DUCK_LEN));\n  const titleScale =\n    interpolate(titleIn, [0, 1], [1.7, 1]) *\n    interpolate(duck, [0, 1], [1, 0.36]);\n  const titleY = interpolate(duck, [0, 1], [cy, 0.2 * H]);\n\n  // ── Big level number ──────────────────────────────────────────────────────\n  const numFs = 360 * u;\n  const numIn = OUT(ramp(t, DUCK_AT + 5, 10));\n  const roll = SLAM(ramp(t, ROLL_AT, ROLL_LEN));\n  const from = String(level);\n  const to = String(level + 1);\n  const len = Math.max(from.length, to.length);\n  const fromP = from.padStart(len, \" \");\n  const toP = to.padStart(len, \" \");\n  const numKick = 1 + 0.045 * kick(t - rollHit);\n\n  // ── Stat line ─────────────────────────────────────────────────────────────\n  const statP = OUT(ramp(t, STAT_AT, 10));\n  const statN = stat.value * OUT(ramp(t, STAT_AT + 2, STAT_LEN));\n  const logoP = OUT(ramp(t, STAT_AT + 6, 10));\n\n  // Rays: wedges from an inner radius out, alternating widths and lengths.\n  const RAYS = 24;\n  const r0 = interpolate(burst, [0, 1], [0.05, 0.3]) * H;\n  const reach = interpolate(burst, [0, 1], [0.3, 1]) * (1 + 0.06 * rayPulse);\n  const rays = Array.from({ length: RAYS }, (_, i) => {\n    const a = ((i / RAYS) * 360 + spin) * (Math.PI / 180);\n    const half = (i % 2 === 0 ? 2.2 : 0.9) * (Math.PI / 180);\n    const R = (0.42 + 0.38 * hash(i)) * W * reach;\n    const ri = r0;\n    const p = (ang: number, r: number) =>\n      `${cx + Math.cos(ang) * r},${cy + Math.sin(ang) * r}`;\n    return `M${p(a - half * 0.4, ri)} L${p(a - half, R)} L${p(a + half, R)} L${p(a + half * 0.4, ri)} Z`;\n  });\n\n  const chipFs = 30 * u;\n\n  return (\n    <AbsoluteFill style={{ background: c.stage, overflow: \"hidden\" }}>\n      {/* Burst rays and the shockwave ring. */}\n      {t >= BURST_AT ? (\n        <svg\n          width={W}\n          height={H}\n          style={{\n            position: \"absolute\",\n            inset: 0,\n            opacity:\n              burstOp *\n              c.rayAlpha *\n              (0.5 + 0.5 * (1 - ramp(t, BURST_AT + 8, 14)) + 0.3 * rayPulse),\n          }}\n          aria-hidden\n        >\n          <defs>\n            <radialGradient\n              id={`${id}-ray`}\n              cx={cx}\n              cy={cy}\n              r={0.8 * W}\n              gradientUnits=\"userSpaceOnUse\"\n            >\n              <stop offset=\"0.12\" stopColor={c.rays[0]} stopOpacity={0.95} />\n              <stop offset=\"0.3\" stopColor={c.rays[1]} stopOpacity={0.75} />\n              <stop offset=\"0.6\" stopColor={c.rays[2]} stopOpacity={0.45} />\n              <stop offset=\"1\" stopColor={c.rays[3]} stopOpacity={0} />\n            </radialGradient>\n          </defs>\n          {rays.map((d, i) => (\n            <path key={i} d={d} fill={`url(#${id}-ray)`} />\n          ))}\n          {ring < 1 ? (\n            <circle\n              cx={cx}\n              cy={cy}\n              r={interpolate(OUT(ring), [0, 1], [0.04 * W, 0.5 * W])}\n              fill=\"none\"\n              stroke={BEAM[1]}\n              strokeWidth={interpolate(ring, [0, 1], [5 * u, 0.5 * u])}\n              opacity={1 - ring}\n            />\n          ) : null}\n        </svg>\n      ) : null}\n\n      {t >= BURST_AT ? (\n        <div\n          style={{\n            position: \"absolute\",\n            inset: 0,\n            opacity: ramp(t, BURST_AT + 4, 10),\n            background: [\n              `radial-gradient(30% 34% at 50% ${(cy / H) * 100}%, ${c.stage} 45%, transparent 100%)`,\n              `linear-gradient(0deg, ${c.stage} 0%, ${c.stage} 12%, transparent 34%)`,\n            ].join(\", \"),\n          }}\n        />\n      ) : null}\n\n      {/* XP bar. */}\n      {!barGone ? (\n        <div\n          style={{\n            position: \"absolute\",\n            left: cx - barW / 2,\n            top: cy - barH / 2,\n            width: barW,\n            height: barH,\n            transform: `scaleX(${1 - collapse}) scaleY(${1 - 0.6 * collapse})`,\n            transformOrigin: \"50% 50%\",\n          }}\n        >\n          {Array.from({ length: SEGMENTS }, (_, i) => {\n            const x = i * (segW + gap);\n            const appear = OUT(ramp(t, BAR_AT + i * 0.8, 6));\n            const f = Math.max(0, Math.min(1, fill * SEGMENTS - i));\n            const justFilled =\n              f > 0 && fill * SEGMENTS - i < 1.6 && hitKick > 0 ? hitKick : 0;\n            return (\n              <div\n                key={i}\n                style={{\n                  position: \"absolute\",\n                  left: x,\n                  top: 0,\n                  width: segW,\n                  height: barH,\n                  background: c.track,\n                  transform: `skewX(-20deg) scaleY(${0.3 + 0.7 * appear})`,\n                  opacity: appear,\n                  overflow: \"hidden\",\n                }}\n              >\n                <div\n                  style={{\n                    position: \"absolute\",\n                    left: 0,\n                    top: 0,\n                    bottom: 0,\n                    width: `${f * 100}%`,\n                    backgroundImage: c.fill,\n                    backgroundSize: `${barW}px ${barH}px`,\n                    backgroundPosition: `${-x}px 0`,\n                  }}\n                />\n                <div\n                  style={{\n                    position: \"absolute\",\n                    left: 0,\n                    top: 0,\n                    bottom: 0,\n                    width: `${f * 100}%`,\n                    background: BEAM[0],\n                    opacity: Math.max(0.85 * justFilled, maxFlash),\n                  }}\n                />\n              </div>\n            );\n          })}\n        </div>\n      ) : null}\n\n      {/* Labels above the bar. */}\n      {labelsOut < 1 ? (\n        <div\n          style={{\n            position: \"absolute\",\n            left: cx - barW / 2,\n            width: barW,\n            top: cy - barH / 2 - 128 * u,\n            height: 110 * u,\n            display: \"flex\",\n            alignItems: \"flex-end\",\n            justifyContent: \"space-between\",\n            opacity: labelsIn * (1 - labelsOut),\n            transform: `translateY(${(1 - labelsIn) * 16 * u}px)`,\n            fontFamily: hud,\n            fontWeight: 500,\n            color: c.ink,\n          }}\n        >\n          <div style={{ display: \"flex\", alignItems: \"baseline\", gap: 14 * u }}>\n            <span\n              style={{\n                fontSize: 30 * u,\n                letterSpacing: \"0.14em\",\n                color: c.dim,\n              }}\n            >\n              LV\n            </span>\n            <span\n              style={{\n                fontSize: 112 * u,\n                lineHeight: 0.8,\n                letterSpacing: \"-0.02em\",\n              }}\n            >\n              {level}\n            </span>\n          </div>\n          <div\n            style={{\n              fontSize: 32 * u,\n              letterSpacing: \"0.04em\",\n              fontVariantNumeric: \"tabular-nums\",\n              marginBottom: 2 * u,\n            }}\n          >\n            {fmt(xp)}\n            <span style={{ color: c.dim }}> / {fmt(maxXp)} XP</span>\n          </div>\n        </div>\n      ) : null}\n      {labelsOut < 1 ? (\n        <div\n          style={{\n            position: \"absolute\",\n            left: cx - barW / 2,\n            width: barW,\n            top: cy + barH / 2 + 18 * u,\n            display: \"flex\",\n            justifyContent: \"space-between\",\n            opacity: labelsIn * (1 - labelsOut),\n            fontFamily: hud,\n            fontWeight: 400,\n            fontSize: 20 * u,\n            letterSpacing: \"0.16em\",\n            color: c.dim,\n          }}\n        >\n          <span>EXPERIENCE</span>\n          <span style={{ color: fill >= 1 ? c.ink : c.dim }}>\n            {fill >= 1 ? \"MAX\" : `NEXT  LV ${level + 1}`}\n          </span>\n        </div>\n      ) : null}\n\n      {/* XP chips flying into the fill head. */}\n      {chips.map((v, i) => {\n        const at = arrivals[i];\n        const launch = at - CHIP_FLY;\n        if (t < launch || t >= at + 1) return null;\n        const p = ramp(t, launch, CHIP_FLY);\n        const e = IN(p);\n        const L = LAUNCH[i % LAUNCH.length];\n        const sx = cx + L.x * W;\n        const sy = cy + L.y * H;\n        const headX = cx - barW / 2 + barW * Math.min(1, (xp + 0) / maxXp);\n        const tx = headX;\n        const ty = cy;\n        const mx = (sx + tx) / 2 + (L.y < 0 ? -1 : 1) * 0.06 * W;\n        const my = (sy + ty) / 2 + (L.y < 0 ? -0.12 : 0.12) * H;\n        const x = (1 - e) * (1 - e) * sx + 2 * (1 - e) * e * mx + e * e * tx;\n        const y = (1 - e) * (1 - e) * sy + 2 * (1 - e) * e * my + e * e * ty;\n        const appear = OUT(ramp(t, launch, 4));\n        const k = interpolate(e, [0, 1], [1, 0.5]) * (0.85 + 0.15 * appear);\n        const op = appear * (1 - ramp(t, at - 2, 3));\n        return (\n          <div\n            key={`${i}-${v}`}\n            style={{\n              position: \"absolute\",\n              left: x,\n              top: y,\n              transform: `translate(-50%, -50%) scale(${k})`,\n              opacity: op,\n              padding: `${9 * u}px ${18 * u}px ${8 * u}px`,\n              borderRadius: 999,\n              background: c.chip,\n              border: `${1.5 * u}px solid ${c.chipEdge}`,\n              fontFamily: hud,\n              fontWeight: 500,\n              fontSize: chipFs,\n              lineHeight: 1,\n              letterSpacing: \"0.02em\",\n              color: c.ink,\n              whiteSpace: \"nowrap\",\n            }}\n          >\n            +{v} <span style={{ color: c.chipEdge }}>XP</span>\n          </div>\n        );\n      })}\n\n      {/* LEVEL UP call. */}\n      {t >= BURST_AT ? (\n        <div\n          style={{\n            position: \"absolute\",\n            left: 0,\n            width: W,\n            top: titleY - titleFs * 0.6,\n            height: titleFs * 1.2,\n            display: \"flex\",\n            alignItems: \"center\",\n            justifyContent: \"center\",\n            transform: `scale(${titleScale})`,\n            opacity: ramp(t, BURST_AT, 2),\n            fontFamily: hud,\n            fontWeight: 500,\n            fontSize: titleFs,\n            lineHeight: 1,\n            letterSpacing: \"0.04em\",\n            color: theme === \"dark\" ? \"#FFFFFF\" : c.ink,\n            whiteSpace: \"nowrap\",\n          }}\n        >\n          {title}\n        </div>\n      ) : null}\n\n      {/* Big level number: the changed digits roll. */}\n      {t >= DUCK_AT + 5 ? (\n        <div\n          style={{\n            position: \"absolute\",\n            left: 0,\n            width: W,\n            top: cy - numFs * 0.5,\n            height: numFs,\n            display: \"flex\",\n            justifyContent: \"center\",\n            opacity: numIn,\n            transform: `translateY(${(1 - numIn) * 50 * u}px) scale(${numKick})`,\n            fontFamily: hud,\n            fontWeight: 500,\n            fontSize: numFs,\n            lineHeight: 1,\n            letterSpacing: \"-0.03em\",\n          }}\n        >\n          {Array.from({ length: len }, (_, i) => {\n            const a = fromP[i];\n            const b = toP[i];\n            const same = a === b;\n            const glyph = (ch: string) => (\n              <div\n                style={{\n                  height: numFs,\n                  display: \"flex\",\n                  alignItems: \"center\",\n                  justifyContent: \"center\",\n                  backgroundImage: c.number,\n                  WebkitBackgroundClip: \"text\",\n                  backgroundClip: \"text\",\n                  color: \"transparent\",\n                }}\n              >\n                {ch.trim() === \"\" ? \" \" : ch}\n              </div>\n            );\n            return (\n              <div\n                key={i}\n                style={{\n                  width: \"0.6em\",\n                  height: numFs,\n                  overflow: \"hidden\",\n                  position: \"relative\",\n                }}\n              >\n                <div\n                  style={{\n                    transform: same\n                      ? undefined\n                      : `translateY(${-roll * numFs}px)`,\n                  }}\n                >\n                  {glyph(a)}\n                  {same ? null : glyph(b)}\n                </div>\n              </div>\n            );\n          })}\n        </div>\n      ) : null}\n\n      {/* Stat line. */}\n      {t >= STAT_AT ? (\n        <div\n          style={{\n            position: \"absolute\",\n            left: 0,\n            width: W,\n            top: 0.8 * H,\n            display: \"flex\",\n            justifyContent: \"center\",\n            alignItems: \"baseline\",\n            gap: 18 * u,\n            opacity: statP,\n            transform: `translateY(${(1 - statP) * 22 * u}px)`,\n            fontFamily: hud,\n            fontWeight: 500,\n            fontSize: 34 * u,\n            lineHeight: 1,\n            letterSpacing: \"0.02em\",\n            color: c.ink,\n          }}\n        >\n          <span style={{ color: c.dim }}>{stat.label}</span>\n          <span\n            style={{\n              display: \"flex\",\n              alignItems: \"baseline\",\n              gap: 8 * u,\n              fontVariantNumeric: \"tabular-nums\",\n            }}\n          >\n            <svg\n              width={18 * u}\n              height={15 * u}\n              viewBox=\"0 0 18 15\"\n              aria-hidden\n              style={{ alignSelf: \"center\" }}\n            >\n              <path d=\"M9 0 L18 15 L0 15 Z\" fill={accent} />\n            </svg>\n            +{Math.round(statN)}\n            {stat.suffix ?? \"\"}\n          </span>\n        </div>\n      ) : null}\n\n      {/* Logo. */}\n      <div\n        style={{\n          position: \"absolute\",\n          left: 0,\n          width: W,\n          top: 0.9 * H,\n          display: \"flex\",\n          justifyContent: \"center\",\n          opacity: logoP,\n        }}\n      >\n        <RemocnLogo fontSize={26 * u} color={c.ink} />\n      </div>\n    </AbsoluteFill>\n  );\n}\n",
      "type": "registry:component",
      "target": "components/remocn/level-up.tsx"
    }
  ],
  "type": "registry:component"
}
