{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "uplink-loader",
  "title": "Uplink Loader",
  "description": "Controlled or automatic secure-link progress sequence with telemetry.",
  "files": [
    {
      "path": "src/components/effects/uplink-loader.tsx",
      "content": "\"use client\"\n\nimport * as React from \"react\"\n\n/*\n * SPDX-License-Identifier: MIT\n * Inspired by ThreeUI's Uplink Loader by Meng To.\n * Upstream: https://github.com/MengTo/threeui\n * Sources: src/shaders/uplink-loader/uplink-loader.html and\n * src/shaders/uplink-loader/UplinkLoader.tsx\n * Audited revision: fbc9b3d61b0ef4b2e93b42e4fffa617ca277429b\n * This implementation is a from-scratch React/CSS adaptation.\n */\n\nconst THREE_UI_NOTICE =\n  \"ThreeUI © 2026 Meng To · MIT · github.com/MengTo/threeui · fbc9b3d61b0ef4b2e93b42e4fffa617ca277429b\"\n\nexport type UplinkLoaderProps = {\n  progress?: number\n  label?: string\n  accent?: string\n  className?: string\n  style?: React.CSSProperties\n}\n\nconst INCREMENTS = [1, 1, 2, 1, 3, 1, 2, 1, 1, 2] as const\n\nfunction phaseFor(progress: number) {\n  if (progress >= 100) return \"LINK ESTABLISHED\"\n  if (progress >= 82) return \"VERIFYING HANDSHAKE\"\n  if (progress >= 58) return \"SYNCHRONIZING KEYS\"\n  if (progress >= 31) return \"NEGOTIATING CHANNEL\"\n  return \"ACQUIRING RELAY\"\n}\n\nexport function UplinkLoader({\n  progress,\n  label = \"Secure uplink\",\n  accent = \"#87f6a1\",\n  className,\n  style,\n}: UplinkLoaderProps) {\n  const [automaticProgress, setAutomaticProgress] = React.useState(0)\n  const progressRef = React.useRef(0)\n  const incrementRef = React.useRef(0)\n  const [hidden, setHidden] = React.useState(false)\n  const [reduced, setReduced] = React.useState(false)\n\n  React.useEffect(() => {\n    const media = window.matchMedia(\"(prefers-reduced-motion: reduce)\")\n    const syncMotion = () => setReduced(media.matches)\n    const syncVisibility = () => setHidden(document.hidden)\n    syncMotion()\n    syncVisibility()\n    media.addEventListener(\"change\", syncMotion)\n    document.addEventListener(\"visibilitychange\", syncVisibility)\n    return () => {\n      media.removeEventListener(\"change\", syncMotion)\n      document.removeEventListener(\"visibilitychange\", syncVisibility)\n    }\n  }, [])\n\n  React.useEffect(() => {\n    if (progress !== undefined || hidden) return\n    if (reduced) {\n      progressRef.current = 100\n      setAutomaticProgress(100)\n      return\n    }\n\n    let timer = 0\n    const advance = () => {\n      if (progressRef.current >= 100) {\n        timer = window.setTimeout(() => {\n          progressRef.current = 0\n          incrementRef.current = 0\n          setAutomaticProgress(0)\n          timer = window.setTimeout(advance, 360)\n        }, 1400)\n        return\n      }\n\n      const increment = INCREMENTS[incrementRef.current % INCREMENTS.length]\n      incrementRef.current += 1\n      progressRef.current = Math.min(100, progressRef.current + increment)\n      setAutomaticProgress(progressRef.current)\n      const atCheckpoint = [31, 58, 82].some(\n        (checkpoint) => Math.abs(progressRef.current - checkpoint) <= 1\n      )\n      timer = window.setTimeout(advance, atCheckpoint ? 360 : 68)\n    }\n\n    timer = window.setTimeout(advance, 220)\n    return () => window.clearTimeout(timer)\n  }, [hidden, progress, reduced])\n\n  const value = Math.round(\n    Math.min(100, Math.max(0, progress ?? automaticProgress))\n  )\n  const complete = value >= 100\n  const phase = phaseFor(value)\n  const rootStyle = {\n    \"--uplink-accent\": accent,\n    \"--uplink-progress\": value / 100,\n    ...style,\n  } as React.CSSProperties\n\n  return (\n    <section\n      data-uplink-loader=\"\"\n      data-source-license={THREE_UI_NOTICE}\n      data-paused={hidden ? \"true\" : \"false\"}\n      data-complete={complete ? \"true\" : \"false\"}\n      className={className}\n      style={rootStyle}\n      aria-label={`${label}: ${phase.toLowerCase()}`}\n    >\n      <style>{`\n        @keyframes uplink-scan {\n          from { transform: translateY(-100%); }\n          to { transform: translateY(100%); }\n        }\n        @keyframes uplink-pulse {\n          0%, 100% { opacity: .22; transform: scale(.96); }\n          50% { opacity: .72; transform: scale(1); }\n        }\n        @keyframes uplink-caret {\n          0%, 42% { opacity: 1; }\n          43%, 100% { opacity: .16; }\n        }\n        [data-uplink-loader] .uplink-loader__scan {\n          animation: uplink-scan 3.2s linear infinite;\n        }\n        [data-uplink-loader] .uplink-loader__pulse {\n          transform-origin: center;\n          animation: uplink-pulse 1.6s cubic-bezier(.77, 0, .175, 1) infinite;\n        }\n        [data-uplink-loader] .uplink-loader__caret {\n          animation: uplink-caret .9s linear infinite;\n        }\n        [data-uplink-loader][data-paused=\"true\"] .uplink-loader__scan,\n        [data-uplink-loader][data-paused=\"true\"] .uplink-loader__pulse,\n        [data-uplink-loader][data-paused=\"true\"] .uplink-loader__caret {\n          animation-play-state: paused;\n        }\n        [data-uplink-loader][data-complete=\"true\"] .uplink-loader__pulse {\n          opacity: .9;\n          animation-duration: .8s;\n        }\n        @media (prefers-reduced-motion: reduce) {\n          [data-uplink-loader] .uplink-loader__scan,\n          [data-uplink-loader] .uplink-loader__pulse,\n          [data-uplink-loader] .uplink-loader__caret {\n            animation: none;\n          }\n          [data-uplink-loader] .uplink-loader__pulse { opacity: .7; }\n        }\n      `}</style>\n      <div className=\"relative aspect-[16/10] min-h-72 w-full overflow-hidden rounded-[1.25rem] border border-[#87f6a1]/20 bg-[#030806] text-[#dfffe6] shadow-[inset_0_0_100px_rgba(21,104,48,.08),0_24px_80px_rgba(0,0,0,.25)]\">\n        <div\n          aria-hidden=\"true\"\n          className=\"absolute inset-0 opacity-35\"\n          style={{\n            backgroundImage:\n              \"linear-gradient(rgba(135,246,161,.055) 1px, transparent 1px), linear-gradient(90deg, rgba(135,246,161,.035) 1px, transparent 1px)\",\n            backgroundSize: \"24px 24px\",\n          }}\n        />\n        <div\n          aria-hidden=\"true\"\n          className=\"uplink-loader__scan pointer-events-none absolute inset-x-0 h-1/2 opacity-60\"\n          style={{\n            background:\n              \"linear-gradient(to bottom, transparent, rgba(135,246,161,.08), transparent)\",\n          }}\n        />\n\n        <div className=\"absolute inset-x-5 top-5 flex items-start justify-between font-mono text-[9px] tracking-[0.18em] uppercase sm:inset-x-7 sm:top-6 sm:text-[10px]\">\n          <div className=\"space-y-1\">\n            <p style={{ color: accent }}>SYS.LINK / 09</p>\n            <p className=\"text-[#78907f]\">Encrypted transport</p>\n          </div>\n          <div className=\"space-y-1 text-right\">\n            <p className=\"text-[#c7dbcc]\">CH 0x4E</p>\n            <p className=\"text-[#78907f]\">TLS / AES-256</p>\n          </div>\n        </div>\n\n        <div className=\"absolute inset-0 grid place-items-center px-6\">\n          <div\n            role=\"progressbar\"\n            aria-label={label}\n            aria-valuemin={0}\n            aria-valuemax={100}\n            aria-valuenow={value}\n            aria-valuetext={`${phase}, ${value} percent`}\n            className=\"w-full max-w-lg\"\n          >\n            <div className=\"relative mx-auto mb-8 grid size-24 place-items-center sm:size-28\">\n              <div\n                aria-hidden=\"true\"\n                className=\"uplink-loader__pulse absolute inset-0 rounded-full border\"\n                style={{\n                  borderColor: `${accent}4d`,\n                  boxShadow: `0 0 34px ${accent}1f`,\n                }}\n              />\n              <div\n                aria-hidden=\"true\"\n                className=\"absolute inset-3 rotate-45 border\"\n                style={{ borderColor: `${accent}29` }}\n              />\n              <div\n                className=\"relative font-mono text-2xl tabular-nums sm:text-3xl\"\n                style={{ color: accent }}\n              >\n                {String(value).padStart(3, \"0\")}\n                <span className=\"ml-0.5 text-[10px] opacity-60\">%</span>\n              </div>\n            </div>\n\n            <p\n              className=\"text-center font-mono text-[10px] tracking-[0.22em] uppercase sm:text-xs\"\n              style={{ color: accent }}\n            >\n              {phase}\n              <span className=\"uplink-loader__caret\">_</span>\n            </p>\n\n            <div\n              className=\"mt-5 grid grid-cols-[repeat(32,minmax(0,1fr))] gap-1\"\n              aria-hidden=\"true\"\n            >\n              {Array.from({ length: 32 }, (_, index) => {\n                const active = (index + 1) / 32 <= value / 100\n                return (\n                  <span\n                    key={index}\n                    className=\"h-5 border sm:h-6\"\n                    style={{\n                      borderColor: active\n                        ? `${accent}66`\n                        : \"rgba(135,246,161,.1)\",\n                      background: active\n                        ? `${accent}bd`\n                        : \"rgba(135,246,161,.035)\",\n                      boxShadow: active ? `0 0 8px ${accent}33` : undefined,\n                      opacity: active ? 0.45 + (index / 32) * 0.55 : 1,\n                    }}\n                  />\n                )\n              })}\n            </div>\n            <div className=\"mt-2 h-px overflow-hidden bg-[#87f6a1]/10\">\n              <div\n                className=\"h-full origin-left\"\n                style={{\n                  background: accent,\n                  transform: `scaleX(${value / 100})`,\n                  transition: reduced ? undefined : \"transform 140ms linear\",\n                }}\n              />\n            </div>\n          </div>\n        </div>\n\n        <div className=\"absolute inset-x-5 bottom-5 flex justify-between font-mono text-[8px] tracking-[0.15em] text-[#617569] uppercase sm:inset-x-7 sm:bottom-6 sm:text-[9px]\">\n          <span>RX {String(3482 + value * 17).padStart(5, \"0\")} KB</span>\n          <span>LAT 12.4 MS</span>\n          <span>TX {String(1240 + value * 9).padStart(5, \"0\")} KB</span>\n        </div>\n\n        {[\n          \"left-3 top-3 border-l border-t\",\n          \"right-3 top-3 border-r border-t\",\n          \"bottom-3 left-3 border-b border-l\",\n          \"right-3 bottom-3 border-r border-b\",\n        ].map((position) => (\n          <span\n            key={position}\n            aria-hidden=\"true\"\n            className={`absolute size-5 ${position}`}\n            style={{ borderColor: `${accent}52` }}\n          />\n        ))}\n      </div>\n    </section>\n  )\n}\n",
      "type": "registry:ui",
      "target": "src/components/effects/uplink-loader.tsx"
    }
  ],
  "meta": {
    "collection": "motion-effects",
    "license": "MIT",
    "source": "https://github.com/MengTo/threeui",
    "sourceRevision": "fbc9b3d61b0ef4b2e93b42e4fffa617ca277429b"
  },
  "type": "registry:ui"
}