bits-lab 0.0.0-stage → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (323) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +57 -2
  3. package/dist/Accordion.d.ts +52 -0
  4. package/dist/Accordion.js +192 -0
  5. package/dist/AchievementToast.d.ts +36 -0
  6. package/dist/AchievementToast.js +162 -0
  7. package/dist/AgentCard.d.ts +41 -0
  8. package/dist/AgentCard.js +168 -0
  9. package/dist/ArcadeButtons.d.ts +23 -0
  10. package/dist/ArcadeButtons.js +169 -0
  11. package/dist/AuroraBands.d.ts +19 -0
  12. package/dist/AuroraBands.js +126 -0
  13. package/dist/AvatarTooltips.d.ts +32 -0
  14. package/dist/AvatarTooltips.js +121 -0
  15. package/dist/BarRace.d.ts +39 -0
  16. package/dist/BarRace.js +227 -0
  17. package/dist/BentoGrid.d.ts +50 -0
  18. package/dist/BentoGrid.js +145 -0
  19. package/dist/BootSequence.d.ts +48 -0
  20. package/dist/BootSequence.js +234 -0
  21. package/dist/BreadcrumbTrail.d.ts +31 -0
  22. package/dist/BreadcrumbTrail.js +181 -0
  23. package/dist/CRTPower.d.ts +30 -0
  24. package/dist/CRTPower.js +142 -0
  25. package/dist/CardDeck.d.ts +29 -0
  26. package/dist/CardDeck.js +154 -0
  27. package/dist/ChangelogTimeline.d.ts +35 -0
  28. package/dist/ChangelogTimeline.js +137 -0
  29. package/dist/ChapterProgress.d.ts +23 -0
  30. package/dist/ChapterProgress.js +211 -0
  31. package/dist/ChatBubbles.d.ts +42 -0
  32. package/dist/ChatBubbles.js +198 -0
  33. package/dist/ChiptuneKit.d.ts +158 -0
  34. package/dist/ChiptuneKit.js +207 -0
  35. package/dist/CipherCard.d.ts +22 -0
  36. package/dist/CipherCard.js +91 -0
  37. package/dist/CloudSky.d.ts +28 -0
  38. package/dist/CloudSky.js +222 -0
  39. package/dist/CodeRain.d.ts +24 -0
  40. package/dist/CodeRain.js +158 -0
  41. package/dist/CodeShowcase.d.ts +50 -0
  42. package/dist/CodeShowcase.js +307 -0
  43. package/dist/ColorDial.d.ts +42 -0
  44. package/dist/ColorDial.js +288 -0
  45. package/dist/CommandPalette.d.ts +59 -0
  46. package/dist/CommandPalette.js +349 -0
  47. package/dist/CompareSlider.d.ts +33 -0
  48. package/dist/CompareSlider.js +152 -0
  49. package/dist/Confetti.d.ts +61 -0
  50. package/dist/Confetti.js +176 -0
  51. package/dist/ConnectBeams.d.ts +39 -0
  52. package/dist/ConnectBeams.js +132 -0
  53. package/dist/ContextOrb.d.ts +34 -0
  54. package/dist/ContextOrb.js +269 -0
  55. package/dist/ContourLines.d.ts +20 -0
  56. package/dist/ContourLines.js +159 -0
  57. package/dist/Coverflow.d.ts +27 -0
  58. package/dist/Coverflow.js +167 -0
  59. package/dist/CursorAttractor.d.ts +21 -0
  60. package/dist/CursorAttractor.js +136 -0
  61. package/dist/CutReveal.d.ts +21 -0
  62. package/dist/CutReveal.js +116 -0
  63. package/dist/DateRange.d.ts +45 -0
  64. package/dist/DateRange.js +327 -0
  65. package/dist/DeviceFrame.d.ts +30 -0
  66. package/dist/DeviceFrame.js +145 -0
  67. package/dist/DiffReveal.d.ts +36 -0
  68. package/dist/DiffReveal.js +247 -0
  69. package/dist/DirectionHover.d.ts +15 -0
  70. package/dist/DirectionHover.js +90 -0
  71. package/dist/Discard.d.ts +18 -0
  72. package/dist/Discard.js +61 -0
  73. package/dist/DitherField.d.ts +15 -0
  74. package/dist/DitherField.js +157 -0
  75. package/dist/DotGlobe.d.ts +48 -0
  76. package/dist/DotGlobe.js +312 -0
  77. package/dist/DotMap.d.ts +47 -0
  78. package/dist/DotMap.js +172 -0
  79. package/dist/DropZone.d.ts +57 -0
  80. package/dist/DropZone.js +304 -0
  81. package/dist/DynamicIsland.d.ts +32 -0
  82. package/dist/DynamicIsland.js +92 -0
  83. package/dist/EdgeFX.d.ts +27 -0
  84. package/dist/EdgeFX.js +98 -0
  85. package/dist/ElasticString.d.ts +22 -0
  86. package/dist/ElasticString.js +127 -0
  87. package/dist/ExpandCard.d.ts +44 -0
  88. package/dist/ExpandCard.js +182 -0
  89. package/dist/FeatureTabs.d.ts +34 -0
  90. package/dist/FeatureTabs.js +169 -0
  91. package/dist/FeedList.d.ts +37 -0
  92. package/dist/FeedList.js +163 -0
  93. package/dist/FlickerGrid.d.ts +29 -0
  94. package/dist/FlickerGrid.js +156 -0
  95. package/dist/FocusGrid.d.ts +20 -0
  96. package/dist/FocusGrid.js +48 -0
  97. package/dist/FocusPull.d.ts +26 -0
  98. package/dist/FocusPull.js +106 -0
  99. package/dist/Footprints.d.ts +24 -0
  100. package/dist/Footprints.js +126 -0
  101. package/dist/FunnelFlow.d.ts +34 -0
  102. package/dist/FunnelFlow.js +267 -0
  103. package/dist/GameOver.d.ts +46 -0
  104. package/dist/GameOver.js +191 -0
  105. package/dist/GaugeMeter.d.ts +38 -0
  106. package/dist/GaugeMeter.js +195 -0
  107. package/dist/GlassPanel.d.ts +27 -0
  108. package/dist/GlassPanel.js +80 -0
  109. package/dist/GrainFX.d.ts +34 -0
  110. package/dist/GrainFX.js +122 -0
  111. package/dist/GravityBox.d.ts +30 -0
  112. package/dist/GravityBox.js +220 -0
  113. package/dist/HealthBar.d.ts +33 -0
  114. package/dist/HealthBar.js +140 -0
  115. package/dist/Heatmap.d.ts +42 -0
  116. package/dist/Heatmap.js +232 -0
  117. package/dist/HexField.d.ts +29 -0
  118. package/dist/HexField.js +188 -0
  119. package/dist/HoldToConfirm.d.ts +29 -0
  120. package/dist/HoldToConfirm.js +163 -0
  121. package/dist/HorizontalTrack.d.ts +28 -0
  122. package/dist/HorizontalTrack.js +195 -0
  123. package/dist/HotbarDock.d.ts +40 -0
  124. package/dist/HotbarDock.js +148 -0
  125. package/dist/InkText.d.ts +27 -0
  126. package/dist/InkText.js +65 -0
  127. package/dist/InlineEdit.d.ts +30 -0
  128. package/dist/InlineEdit.js +198 -0
  129. package/dist/InteractiveGrid.d.ts +25 -0
  130. package/dist/InteractiveGrid.js +194 -0
  131. package/dist/InventoryGrid.d.ts +45 -0
  132. package/dist/InventoryGrid.js +272 -0
  133. package/dist/JellyBlob.d.ts +30 -0
  134. package/dist/JellyBlob.js +209 -0
  135. package/dist/KineticHeadline.d.ts +30 -0
  136. package/dist/KineticHeadline.js +133 -0
  137. package/dist/LavaLamp.d.ts +21 -0
  138. package/dist/LavaLamp.js +133 -0
  139. package/dist/LetterSwap.d.ts +20 -0
  140. package/dist/LetterSwap.js +78 -0
  141. package/dist/LevelMap.d.ts +35 -0
  142. package/dist/LevelMap.js +189 -0
  143. package/dist/LightShafts.d.ts +22 -0
  144. package/dist/LightShafts.js +170 -0
  145. package/dist/LightboxGallery.d.ts +26 -0
  146. package/dist/LightboxGallery.js +327 -0
  147. package/dist/LinkPeek.d.ts +36 -0
  148. package/dist/LinkPeek.js +194 -0
  149. package/dist/LogoOrbit.d.ts +37 -0
  150. package/dist/LogoOrbit.js +117 -0
  151. package/dist/Marquee.d.ts +33 -0
  152. package/dist/Marquee.js +148 -0
  153. package/dist/MarqueeLine.d.ts +33 -0
  154. package/dist/MarqueeLine.js +167 -0
  155. package/dist/MasonryWall.d.ts +13 -0
  156. package/dist/MasonryWall.js +90 -0
  157. package/dist/MegaMenu.d.ts +32 -0
  158. package/dist/MegaMenu.js +280 -0
  159. package/dist/MeteorShower.d.ts +24 -0
  160. package/dist/MeteorShower.js +155 -0
  161. package/dist/Minimap.d.ts +21 -0
  162. package/dist/Minimap.js +236 -0
  163. package/dist/MobileTabBar.d.ts +38 -0
  164. package/dist/MobileTabBar.js +148 -0
  165. package/dist/MorphDialog.d.ts +34 -0
  166. package/dist/MorphDialog.js +199 -0
  167. package/dist/MorphPopover.d.ts +33 -0
  168. package/dist/MorphPopover.js +168 -0
  169. package/dist/MorphWords.d.ts +18 -0
  170. package/dist/MorphWords.js +136 -0
  171. package/dist/OTPInput.d.ts +43 -0
  172. package/dist/OTPInput.js +174 -0
  173. package/dist/OverlayKit.d.ts +97 -0
  174. package/dist/OverlayKit.js +466 -0
  175. package/dist/OverlayMenu.d.ts +32 -0
  176. package/dist/OverlayMenu.js +154 -0
  177. package/dist/ParallaxCollage.d.ts +41 -0
  178. package/dist/ParallaxCollage.js +143 -0
  179. package/dist/PasswordMeter.d.ts +44 -0
  180. package/dist/PasswordMeter.js +165 -0
  181. package/dist/PegBoard.d.ts +26 -0
  182. package/dist/PegBoard.js +184 -0
  183. package/dist/PinCard.d.ts +21 -0
  184. package/dist/PinCard.js +84 -0
  185. package/dist/PixelAvatar.d.ts +33 -0
  186. package/dist/PixelAvatar.js +144 -0
  187. package/dist/PixelButton.d.ts +20 -0
  188. package/dist/PixelButton.js +128 -0
  189. package/dist/PixelExplode.d.ts +31 -0
  190. package/dist/PixelExplode.js +164 -0
  191. package/dist/PixelLoader.d.ts +32 -0
  192. package/dist/PixelLoader.js +142 -0
  193. package/dist/PixelParallax.d.ts +41 -0
  194. package/dist/PixelParallax.js +151 -0
  195. package/dist/PixelSpinners.d.ts +21 -0
  196. package/dist/PixelSpinners.js +110 -0
  197. package/dist/PixelType.d.ts +26 -0
  198. package/dist/PixelType.js +220 -0
  199. package/dist/PointerKit.d.ts +23 -0
  200. package/dist/PointerKit.js +222 -0
  201. package/dist/Polaroids.d.ts +41 -0
  202. package/dist/Polaroids.js +293 -0
  203. package/dist/PressStart.d.ts +28 -0
  204. package/dist/PressStart.js +99 -0
  205. package/dist/PricingFlip.d.ts +52 -0
  206. package/dist/PricingFlip.js +190 -0
  207. package/dist/ProximityType.d.ts +26 -0
  208. package/dist/ProximityType.js +135 -0
  209. package/dist/QuestDialog.d.ts +50 -0
  210. package/dist/QuestDialog.js +204 -0
  211. package/dist/QuestLog.d.ts +39 -0
  212. package/dist/QuestLog.js +214 -0
  213. package/dist/RangeDual.d.ts +34 -0
  214. package/dist/RangeDual.js +238 -0
  215. package/dist/RatingPips.d.ts +25 -0
  216. package/dist/RatingPips.js +129 -0
  217. package/dist/RetroHorizon.d.ts +27 -0
  218. package/dist/RetroHorizon.js +169 -0
  219. package/dist/Reveal.d.ts +30 -0
  220. package/dist/Reveal.js +92 -0
  221. package/dist/RingProgress.d.ts +45 -0
  222. package/dist/RingProgress.js +180 -0
  223. package/dist/RollingNumber.d.ts +28 -0
  224. package/dist/RollingNumber.js +108 -0
  225. package/dist/ScanScope.d.ts +24 -0
  226. package/dist/ScanScope.js +164 -0
  227. package/dist/ScoreTicker.d.ts +32 -0
  228. package/dist/ScoreTicker.js +176 -0
  229. package/dist/ScreenScroller.d.ts +24 -0
  230. package/dist/ScreenScroller.js +138 -0
  231. package/dist/Screensaver.d.ts +31 -0
  232. package/dist/Screensaver.js +221 -0
  233. package/dist/ScrollTilt.d.ts +27 -0
  234. package/dist/ScrollTilt.js +100 -0
  235. package/dist/ScrollTypography.d.ts +26 -0
  236. package/dist/ScrollTypography.js +124 -0
  237. package/dist/ScrollZoom.d.ts +31 -0
  238. package/dist/ScrollZoom.js +123 -0
  239. package/dist/ScrubNumber.d.ts +29 -0
  240. package/dist/ScrubNumber.js +152 -0
  241. package/dist/ShadowStack.d.ts +28 -0
  242. package/dist/ShadowStack.js +116 -0
  243. package/dist/SideRail.d.ts +43 -0
  244. package/dist/SideRail.js +253 -0
  245. package/dist/SignalText.d.ts +25 -0
  246. package/dist/SignalText.js +178 -0
  247. package/dist/SkeletonShimmer.d.ts +18 -0
  248. package/dist/SkeletonShimmer.js +111 -0
  249. package/dist/SketchHighlight.d.ts +27 -0
  250. package/dist/SketchHighlight.js +180 -0
  251. package/dist/SlideTabs.d.ts +40 -0
  252. package/dist/SlideTabs.js +190 -0
  253. package/dist/SmartNavbar.d.ts +48 -0
  254. package/dist/SmartNavbar.js +188 -0
  255. package/dist/SparkChart.d.ts +41 -0
  256. package/dist/SparkChart.js +188 -0
  257. package/dist/Spoiler.d.ts +22 -0
  258. package/dist/Spoiler.js +97 -0
  259. package/dist/SpotlightTour.d.ts +38 -0
  260. package/dist/SpotlightTour.js +231 -0
  261. package/dist/SpringDrawer.d.ts +39 -0
  262. package/dist/SpringDrawer.js +360 -0
  263. package/dist/SpriteAnimator.d.ts +41 -0
  264. package/dist/SpriteAnimator.js +124 -0
  265. package/dist/StatCard.d.ts +43 -0
  266. package/dist/StatCard.js +168 -0
  267. package/dist/StepLoader.d.ts +41 -0
  268. package/dist/StepLoader.js +191 -0
  269. package/dist/StepperForm.d.ts +41 -0
  270. package/dist/StepperForm.js +206 -0
  271. package/dist/StickerBoard.d.ts +39 -0
  272. package/dist/StickerBoard.js +209 -0
  273. package/dist/StickyReveal.d.ts +42 -0
  274. package/dist/StickyReveal.js +181 -0
  275. package/dist/StoryViewer.d.ts +36 -0
  276. package/dist/StoryViewer.js +175 -0
  277. package/dist/StreamingText.d.ts +29 -0
  278. package/dist/StreamingText.js +271 -0
  279. package/dist/SuggestionChips.d.ts +32 -0
  280. package/dist/SuggestionChips.js +96 -0
  281. package/dist/SwipeActions.d.ts +30 -0
  282. package/dist/SwipeActions.js +141 -0
  283. package/dist/TagInput.d.ts +30 -0
  284. package/dist/TagInput.js +284 -0
  285. package/dist/TallyUp.d.ts +38 -0
  286. package/dist/TallyUp.js +157 -0
  287. package/dist/TerminalDemo.d.ts +63 -0
  288. package/dist/TerminalDemo.js +214 -0
  289. package/dist/TestimonialWall.d.ts +35 -0
  290. package/dist/TestimonialWall.js +131 -0
  291. package/dist/TextOnPath.d.ts +36 -0
  292. package/dist/TextOnPath.js +130 -0
  293. package/dist/ThinkingShimmer.d.ts +36 -0
  294. package/dist/ThinkingShimmer.js +132 -0
  295. package/dist/ToastStack.d.ts +62 -0
  296. package/dist/ToastStack.js +289 -0
  297. package/dist/ToggleGroup.d.ts +39 -0
  298. package/dist/ToggleGroup.js +190 -0
  299. package/dist/ToggleKit.d.ts +70 -0
  300. package/dist/ToggleKit.js +229 -0
  301. package/dist/TracingLine.d.ts +24 -0
  302. package/dist/TracingLine.js +139 -0
  303. package/dist/TradingCard.d.ts +30 -0
  304. package/dist/TradingCard.js +147 -0
  305. package/dist/VanishInput.d.ts +34 -0
  306. package/dist/VanishInput.js +190 -0
  307. package/dist/VideoHero.d.ts +32 -0
  308. package/dist/VideoHero.js +207 -0
  309. package/dist/VoiceOrb.d.ts +23 -0
  310. package/dist/VoiceOrb.js +182 -0
  311. package/dist/VoxelTiles.d.ts +38 -0
  312. package/dist/VoxelTiles.js +201 -0
  313. package/dist/WarpField.d.ts +18 -0
  314. package/dist/WarpField.js +160 -0
  315. package/dist/WebcamPixels.d.ts +38 -0
  316. package/dist/WebcamPixels.js +292 -0
  317. package/dist/WheelPicker.d.ts +29 -0
  318. package/dist/WheelPicker.js +199 -0
  319. package/dist/WobbleCard.d.ts +23 -0
  320. package/dist/WobbleCard.js +112 -0
  321. package/dist/index.d.ts +158 -0
  322. package/dist/index.js +159 -0
  323. package/package.json +58 -4
@@ -0,0 +1,91 @@
1
+ 'use client';
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
+ import { useEffect, useInsertionEffect, useRef, useState } from "react";
4
+ const STYLE_ID = "bl-cipher-card";
5
+ const CSS = `
6
+ .bl-cipher { position: relative; display: grid; place-items: center; width: var(--bl-w); max-width: 100%; aspect-ratio: var(--bl-ratio); overflow: hidden; border-radius: var(--bl-radius); background: var(--bl-bg); box-shadow: 0 0 0 1px var(--bl-line); color: var(--bl-ink); font-family: var(--bl-font); }
7
+ .bl-cipher__glow { position: absolute; inset: 0; background: var(--bl-gradient); opacity: 0; transition: opacity 300ms; -webkit-mask-image: radial-gradient(var(--bl-r) circle at var(--bl-mx, 50%) var(--bl-my, 50%), #000 0%, transparent 100%); mask-image: radial-gradient(var(--bl-r) circle at var(--bl-mx, 50%) var(--bl-my, 50%), #000 0%, transparent 100%); }
8
+ .bl-cipher__chars { position: absolute; inset: 0; margin: 0; padding: 6px; overflow: hidden; color: var(--bl-char); font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 11px; line-height: 1.2; word-break: break-all; white-space: normal; opacity: 0; transition: opacity 300ms; -webkit-mask-image: radial-gradient(var(--bl-r) circle at var(--bl-mx, 50%) var(--bl-my, 50%), #000 10%, transparent 100%); mask-image: radial-gradient(var(--bl-r) circle at var(--bl-mx, 50%) var(--bl-my, 50%), #000 10%, transparent 100%); user-select: none; }
9
+ .bl-cipher[data-active] .bl-cipher__glow { opacity: 0.55; }
10
+ .bl-cipher[data-active] .bl-cipher__chars { opacity: 1; }
11
+ .bl-cipher__badge { position: relative; z-index: 1; display: grid; place-items: center; min-width: 40%; aspect-ratio: 1; padding: 14px; box-sizing: border-box; border-radius: 50%; background: color-mix(in srgb, var(--bl-bg) 82%, transparent); box-shadow: 0 0 0 1px var(--bl-line); backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px); text-align: center; }
12
+ `;
13
+ function useStyles() {
14
+ useInsertionEffect(() => {
15
+ if (typeof document === "undefined") return;
16
+ const style = document.getElementById(STYLE_ID) ?? Object.assign(document.createElement("style"), { id: STYLE_ID });
17
+ style.textContent = CSS;
18
+ if (!style.isConnected) document.head.appendChild(style);
19
+ }, []);
20
+ }
21
+ const CHARSET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789#$%&*+<>/=?@";
22
+ const scramble = (length, charset) => Array.from({ length }, () => charset[Math.floor(Math.random() * charset.length)]).join("");
23
+ function CipherCard({
24
+ children,
25
+ charset = CHARSET,
26
+ density = 1800,
27
+ spotlight = 160,
28
+ width = 320,
29
+ aspectRatio = "1",
30
+ radius = 18,
31
+ gradient = "linear-gradient(135deg, #41a6f6, #73eff7 45%, #a7f070)",
32
+ backgroundColor = "#0b0b14",
33
+ textColor = "#f4f4f4",
34
+ charColor = "#f4f4f4",
35
+ lineColor = "#333c57",
36
+ fontFamily = "ui-sans-serif, system-ui, sans-serif",
37
+ className = "",
38
+ style
39
+ }) {
40
+ useStyles();
41
+ const ref = useRef(null);
42
+ const [chars, setChars] = useState(() => scramble(density, charset));
43
+ const [active, setActive] = useState(false);
44
+ const last = useRef(0);
45
+ useEffect(() => setChars(scramble(density, charset)), [density, charset]);
46
+ const onMove = (event) => {
47
+ const node = ref.current;
48
+ const rect = node.getBoundingClientRect();
49
+ node.style.setProperty("--bl-mx", `${event.clientX - rect.left}px`);
50
+ node.style.setProperty("--bl-my", `${event.clientY - rect.top}px`);
51
+ const now = performance.now();
52
+ if (now - last.current > 33 && !window.matchMedia?.("(prefers-reduced-motion: reduce)").matches) {
53
+ last.current = now;
54
+ setChars(scramble(density, charset));
55
+ }
56
+ };
57
+ return /* @__PURE__ */ jsxs(
58
+ "div",
59
+ {
60
+ ref,
61
+ className: `bl-cipher ${className}`,
62
+ "data-active": active || void 0,
63
+ onPointerMove: onMove,
64
+ onPointerEnter: () => setActive(true),
65
+ onPointerLeave: () => setActive(false),
66
+ onFocus: () => setActive(true),
67
+ onBlur: () => setActive(false),
68
+ style: {
69
+ "--bl-w": `${width}px`,
70
+ "--bl-ratio": aspectRatio,
71
+ "--bl-radius": `${radius}px`,
72
+ "--bl-r": `${spotlight}px`,
73
+ "--bl-gradient": gradient,
74
+ "--bl-bg": backgroundColor,
75
+ "--bl-ink": textColor,
76
+ "--bl-char": charColor,
77
+ "--bl-line": lineColor,
78
+ "--bl-font": fontFamily,
79
+ ...style
80
+ },
81
+ children: [
82
+ /* @__PURE__ */ jsx("div", { className: "bl-cipher__glow", "aria-hidden": "true" }),
83
+ /* @__PURE__ */ jsx("p", { className: "bl-cipher__chars", "aria-hidden": "true", children: chars }),
84
+ /* @__PURE__ */ jsx("div", { className: "bl-cipher__badge", children })
85
+ ]
86
+ }
87
+ );
88
+ }
89
+ export {
90
+ CipherCard as default
91
+ };
@@ -0,0 +1,28 @@
1
+ import { type CSSProperties, type ReactNode } from 'react';
2
+ export interface CloudSkyProps {
3
+ /** Ray steps, noise detail and render resolution. */
4
+ quality?: 'low' | 'medium' | 'high';
5
+ /** One sample per N px, scaled up crisply; 0 for smooth. Overrides the quality resolution. */
6
+ pixelSize?: number;
7
+ /** Drift speed. */
8
+ speed?: number;
9
+ /** How much of the sky is cloud (0–1). */
10
+ coverage?: number;
11
+ /** Light direction in degrees, left (-) to right (+). */
12
+ sunAngle?: number;
13
+ sunHeight?: number;
14
+ /** Sky gradient; also the fallback without WebGL. */
15
+ topColor?: string;
16
+ bottomColor?: string;
17
+ /** Lit cloud tops. */
18
+ cloudColor?: string;
19
+ /** Shaded cloud bellies. */
20
+ shadeColor?: string;
21
+ /** Fills its parent by default. */
22
+ height?: number | string;
23
+ /** Content on top of the sky. */
24
+ children?: ReactNode;
25
+ className?: string;
26
+ style?: CSSProperties;
27
+ }
28
+ export default function CloudSky({ quality, pixelSize, speed, coverage, sunAngle, sunHeight, topColor, bottomColor, cloudColor, shadeColor, height, children, className, style }: CloudSkyProps): import("react").JSX.Element;
@@ -0,0 +1,222 @@
1
+ 'use client';
2
+ import { jsx } from "react/jsx-runtime";
3
+ import { useEffect, useRef } from "react";
4
+ const QUALITY = {
5
+ low: { steps: 14, scale: 0.35, octaves: 3 },
6
+ medium: { steps: 22, scale: 0.5, octaves: 4 },
7
+ high: { steps: 36, scale: 0.8, octaves: 5 }
8
+ };
9
+ const VERTEX = "attribute vec2 p; void main() { gl_Position = vec4(p, 0.0, 1.0); }";
10
+ const fragment = (octaves, steps) => `
11
+ #ifdef GL_FRAGMENT_PRECISION_HIGH
12
+ precision highp float;
13
+ #else
14
+ precision mediump float;
15
+ #endif
16
+ uniform vec2 uRes;
17
+ uniform float uTime;
18
+ uniform float uCover;
19
+ uniform vec3 uTop;
20
+ uniform vec3 uBottom;
21
+ uniform vec3 uCloud;
22
+ uniform vec3 uShade;
23
+ uniform vec3 uSun;
24
+
25
+ float hash(vec3 p) {
26
+ p = fract(p * 0.3183099 + 0.1);
27
+ p *= 17.0;
28
+ return fract(p.x * p.y * p.z * (p.x + p.y + p.z));
29
+ }
30
+ float noise(vec3 x) {
31
+ vec3 i = floor(x);
32
+ vec3 f = fract(x);
33
+ f = f * f * (3.0 - 2.0 * f);
34
+ return mix(mix(mix(hash(i), hash(i + vec3(1, 0, 0)), f.x), mix(hash(i + vec3(0, 1, 0)), hash(i + vec3(1, 1, 0)), f.x), f.y),
35
+ mix(mix(hash(i + vec3(0, 0, 1)), hash(i + vec3(1, 0, 1)), f.x), mix(hash(i + vec3(0, 1, 1)), hash(i + vec3(1, 1, 1)), f.x), f.y), f.z);
36
+ }
37
+ float fbm(vec3 p) {
38
+ float a = 0.5;
39
+ float s = 0.0;
40
+ for (int i = 0; i < ${octaves}; i++) {
41
+ s += a * noise(p);
42
+ p = p * 2.03 + vec3(1.7, 9.2, 3.1);
43
+ a *= 0.5;
44
+ }
45
+ return s;
46
+ }
47
+ // Cloud layer between heights 0 and 1.4, drifting with time.
48
+ float density(vec3 p) {
49
+ vec3 q = p * 0.85 + vec3(uTime, 0.0, uTime * 0.4);
50
+ float layer = smoothstep(0.0, 0.35, p.y) * smoothstep(1.4, 0.75, p.y);
51
+ return clamp((fbm(q) - (1.0 - uCover)) * 4.0, 0.0, 1.0) * layer;
52
+ }
53
+
54
+ void main() {
55
+ vec2 uv = (gl_FragCoord.xy - 0.5 * uRes) / uRes.y;
56
+ vec3 rd = normalize(vec3(uv.x, uv.y + 0.32, 1.0));
57
+ vec3 ro = vec3(0.0, -0.7, 0.0);
58
+ vec3 sky = mix(uBottom, uTop, smoothstep(-0.05, 0.75, rd.y));
59
+ sky += pow(max(dot(rd, uSun), 0.0), 14.0) * 0.35 * uCloud;
60
+ if (rd.y < 0.02) {
61
+ gl_FragColor = vec4(sky, 1.0);
62
+ return;
63
+ }
64
+ float t0 = (0.0 - ro.y) / rd.y;
65
+ float t1 = min((1.4 - ro.y) / rd.y, t0 + 9.0);
66
+ float dt = (t1 - t0) / float(${steps});
67
+ float dither = fract(sin(dot(gl_FragCoord.xy, vec2(12.9898, 78.233))) * 43758.5453);
68
+ float T = 1.0;
69
+ vec3 col = vec3(0.0);
70
+ for (int i = 0; i < ${steps}; i++) {
71
+ vec3 p = ro + rd * (t0 + (float(i) + dither) * dt);
72
+ float d = density(p);
73
+ if (d > 0.01) {
74
+ // One sample toward the sun: more cloud in the way means a darker sample.
75
+ float occ = density(p + uSun * 0.35);
76
+ vec3 lit = mix(uShade, uCloud, exp(-occ * 2.4));
77
+ lit = mix(lit * 0.82, lit, smoothstep(0.1, 1.1, p.y));
78
+ float a = 1.0 - exp(-d * dt * 3.0);
79
+ col += T * a * lit;
80
+ T *= 1.0 - a;
81
+ if (T < 0.03) break;
82
+ }
83
+ }
84
+ vec3 color = sky * T + col;
85
+ // Melt distant clouds into the horizon haze.
86
+ color = mix(sky, color, smoothstep(0.02, 0.2, rd.y));
87
+ gl_FragColor = vec4(color, 1.0);
88
+ }
89
+ `;
90
+ const rgb = (hex) => {
91
+ const n = parseInt(hex.replace("#", "").replace(/^(.)(.)(.)$/, "$1$1$2$2$3$3"), 16);
92
+ return [(n >> 16 & 255) / 255, (n >> 8 & 255) / 255, (n & 255) / 255];
93
+ };
94
+ function CloudSky({
95
+ quality = "medium",
96
+ pixelSize = 0,
97
+ speed = 0.06,
98
+ coverage = 0.55,
99
+ sunAngle = 30,
100
+ sunHeight = 0.35,
101
+ topColor = "#29366f",
102
+ bottomColor = "#ef7d57",
103
+ cloudColor = "#f4f4f4",
104
+ shadeColor = "#5d275d",
105
+ height = "100%",
106
+ children,
107
+ className = "",
108
+ style
109
+ }) {
110
+ const rootRef = useRef(null);
111
+ const timeRef = useRef(0);
112
+ useEffect(() => {
113
+ const canvas = document.createElement("canvas");
114
+ canvas.setAttribute("aria-hidden", "true");
115
+ Object.assign(canvas.style, { position: "absolute", inset: "0", display: "block", width: "100%", height: "100%", imageRendering: pixelSize > 0 ? "pixelated" : "" });
116
+ rootRef.current.prepend(canvas);
117
+ const gl = canvas.getContext("webgl", { antialias: false, alpha: true, premultipliedAlpha: false, powerPreference: "low-power" });
118
+ if (!gl) {
119
+ canvas.remove();
120
+ return void 0;
121
+ }
122
+ const reduced = window.matchMedia?.("(prefers-reduced-motion: reduce)").matches;
123
+ const preset = QUALITY[quality] ?? QUALITY.medium;
124
+ const compile = (type, source) => {
125
+ const shader = gl.createShader(type);
126
+ gl.shaderSource(shader, source);
127
+ gl.compileShader(shader);
128
+ return shader;
129
+ };
130
+ const vs = compile(gl.VERTEX_SHADER, VERTEX);
131
+ const fs = compile(gl.FRAGMENT_SHADER, fragment(preset.octaves, preset.steps));
132
+ const program = gl.createProgram();
133
+ gl.attachShader(program, vs);
134
+ gl.attachShader(program, fs);
135
+ gl.linkProgram(program);
136
+ if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
137
+ gl.getExtension("WEBGL_lose_context")?.loseContext();
138
+ canvas.remove();
139
+ return void 0;
140
+ }
141
+ gl.useProgram(program);
142
+ const buffer = gl.createBuffer();
143
+ gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
144
+ gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([-1, -1, 3, -1, -1, 3]), gl.STATIC_DRAW);
145
+ const loc = gl.getAttribLocation(program, "p");
146
+ gl.enableVertexAttribArray(loc);
147
+ gl.vertexAttribPointer(loc, 2, gl.FLOAT, false, 0, 0);
148
+ const u = (name) => gl.getUniformLocation(program, name);
149
+ const a = sunAngle * Math.PI / 180;
150
+ const sun = [Math.sin(a), sunHeight, Math.cos(a)];
151
+ const len = Math.hypot(...sun);
152
+ gl.uniform3fv(u("uSun"), sun.map((v) => v / len));
153
+ gl.uniform3fv(u("uTop"), rgb(topColor));
154
+ gl.uniform3fv(u("uBottom"), rgb(bottomColor));
155
+ gl.uniform3fv(u("uCloud"), rgb(cloudColor));
156
+ gl.uniform3fv(u("uShade"), rgb(shadeColor));
157
+ gl.uniform1f(u("uCover"), coverage);
158
+ const uTime = u("uTime");
159
+ const uRes = u("uRes");
160
+ let visible = true;
161
+ let raf = 0;
162
+ let last = 0;
163
+ const size = () => {
164
+ const scale = pixelSize > 0 ? 1 / pixelSize : preset.scale * Math.min(2, window.devicePixelRatio || 1);
165
+ canvas.width = Math.max(1, Math.round(canvas.clientWidth * scale));
166
+ canvas.height = Math.max(1, Math.round(canvas.clientHeight * scale));
167
+ gl.viewport(0, 0, canvas.width, canvas.height);
168
+ gl.uniform2f(uRes, canvas.width, canvas.height);
169
+ };
170
+ const draw = () => {
171
+ gl.uniform1f(uTime, timeRef.current);
172
+ gl.drawArrays(gl.TRIANGLES, 0, 3);
173
+ };
174
+ const tick = (now) => {
175
+ timeRef.current += Math.min(50, now - last) / 1e3 * speed;
176
+ last = now;
177
+ draw();
178
+ raf = requestAnimationFrame(tick);
179
+ };
180
+ const start = () => {
181
+ if (raf || reduced || !visible || document.hidden) return;
182
+ last = performance.now();
183
+ raf = requestAnimationFrame(tick);
184
+ };
185
+ const stop = () => {
186
+ cancelAnimationFrame(raf);
187
+ raf = 0;
188
+ };
189
+ const resize = new ResizeObserver(() => {
190
+ size();
191
+ draw();
192
+ });
193
+ resize.observe(canvas);
194
+ const observer = new IntersectionObserver(([entry]) => {
195
+ visible = entry.isIntersecting;
196
+ if (visible) start();
197
+ else stop();
198
+ });
199
+ observer.observe(canvas);
200
+ const onVisibility = () => document.hidden ? stop() : start();
201
+ document.addEventListener("visibilitychange", onVisibility);
202
+ size();
203
+ draw();
204
+ start();
205
+ return () => {
206
+ stop();
207
+ resize.disconnect();
208
+ observer.disconnect();
209
+ document.removeEventListener("visibilitychange", onVisibility);
210
+ gl.deleteBuffer(buffer);
211
+ gl.deleteProgram(program);
212
+ gl.deleteShader(vs);
213
+ gl.deleteShader(fs);
214
+ gl.getExtension("WEBGL_lose_context")?.loseContext();
215
+ canvas.remove();
216
+ };
217
+ }, [quality, pixelSize, speed, coverage, sunAngle, sunHeight, topColor, bottomColor, cloudColor, shadeColor]);
218
+ return /* @__PURE__ */ jsx("div", { ref: rootRef, className, style: { position: "relative", width: "100%", height, overflow: "hidden", background: `linear-gradient(${topColor}, ${bottomColor})`, ...style }, children: children && /* @__PURE__ */ jsx("div", { style: { position: "relative", height: "100%" }, children }) });
219
+ }
220
+ export {
221
+ CloudSky as default
222
+ };
@@ -0,0 +1,24 @@
1
+ import { type CSSProperties } from 'react';
2
+ export interface CodeRainProps {
3
+ /** A preset set of glyphs, or your own characters. */
4
+ glyphs?: 'hex' | 'binary' | 'blocks' | 'arrows' | (string & {});
5
+ /** Glyph size, also the column width, in px. */
6
+ fontSize?: number;
7
+ fontFamily?: string;
8
+ speed?: number;
9
+ /** Share of columns that are falling. */
10
+ density?: number;
11
+ /** About how many seconds a tail lingers. */
12
+ tail?: number;
13
+ /** Chance of glyph flips and glitch rows. */
14
+ glitch?: number;
15
+ /** Columns within this many px of the pointer run hot. */
16
+ hotRadius?: number;
17
+ headColor?: string;
18
+ color?: string;
19
+ hotColor?: string;
20
+ backgroundColor?: string;
21
+ className?: string;
22
+ style?: CSSProperties;
23
+ }
24
+ export default function CodeRain({ glyphs, fontSize, fontFamily, speed, density, tail, glitch, hotRadius, headColor, color, hotColor, backgroundColor, className, style }: CodeRainProps): import("react").JSX.Element;
@@ -0,0 +1,158 @@
1
+ 'use client';
2
+ import { jsx } from "react/jsx-runtime";
3
+ import { useEffect, useRef } from "react";
4
+ const hexToRgb = (hex) => {
5
+ const n = parseInt(hex.replace("#", "").replace(/^(.)(.)(.)$/, "$1$1$2$2$3$3"), 16);
6
+ return [n >> 16 & 255, n >> 8 & 255, n & 255];
7
+ };
8
+ const GLYPHS = {
9
+ hex: "0123456789ABCDEF",
10
+ binary: "01",
11
+ blocks: "\u2596\u2597\u2598\u2599\u259A\u259B\u259C\u259D\u259E\u259F\u2588\u2584\u2580",
12
+ arrows: "\u2190\u2191\u2192\u2193\u2196\u2197\u2198\u2199\u25C4\u25BA\u25B2\u25BC"
13
+ };
14
+ function CodeRain({
15
+ glyphs = "hex",
16
+ fontSize = 14,
17
+ fontFamily = '"Press Start 2P", ui-monospace, monospace',
18
+ speed = 1,
19
+ density = 0.8,
20
+ tail = 1.2,
21
+ glitch = 4e-3,
22
+ hotRadius = 120,
23
+ headColor = "#f4f4f4",
24
+ color = "#38b764",
25
+ hotColor = "#ffcd75",
26
+ backgroundColor = "#0b0b14",
27
+ className = "",
28
+ style
29
+ }) {
30
+ const canvasRef = useRef(null);
31
+ useEffect(() => {
32
+ const canvas = canvasRef.current;
33
+ const ctx = canvas.getContext("2d");
34
+ const reduced = window.matchMedia?.("(prefers-reduced-motion: reduce)").matches;
35
+ const set = GLYPHS[glyphs] ?? glyphs;
36
+ const [br, bg, bb] = hexToRgb(backgroundColor);
37
+ const pick = () => set[Math.floor(Math.random() * set.length)];
38
+ let W = 0;
39
+ let H = 0;
40
+ let dpr = 1;
41
+ let cols = [];
42
+ let rows = 0;
43
+ let raf = 0;
44
+ let last = 0;
45
+ let visible = true;
46
+ const hand = { x: -1e4, y: -1e4 };
47
+ const fit = () => {
48
+ dpr = Math.min(2, window.devicePixelRatio || 1);
49
+ W = canvas.clientWidth;
50
+ H = canvas.clientHeight;
51
+ canvas.width = Math.round(W * dpr);
52
+ canvas.height = Math.round(H * dpr);
53
+ const count = Math.ceil(W / fontSize);
54
+ rows = Math.ceil(H / fontSize);
55
+ cols = Array.from({ length: count }, () => ({ y: -Math.random() * rows, rate: 6 + Math.random() * 10, on: Math.random() < density, glyph: pick() }));
56
+ ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
57
+ ctx.fillStyle = backgroundColor;
58
+ ctx.fillRect(0, 0, W, H);
59
+ };
60
+ const step = (dt) => {
61
+ ctx.fillStyle = `rgba(${br},${bg},${bb},${(1 - Math.exp(-dt * 4 / Math.max(0.05, tail))).toFixed(3)})`;
62
+ ctx.fillRect(0, 0, W, H);
63
+ ctx.font = `${fontSize}px ${fontFamily}`;
64
+ ctx.textBaseline = "top";
65
+ cols.forEach((c, i) => {
66
+ if (!c.on) return;
67
+ const x = i * fontSize;
68
+ const near = Math.abs(x - hand.x) < hotRadius && hand.y > -1e3;
69
+ const prev = Math.floor(c.y);
70
+ c.y += c.rate * speed * dt * (near ? 2.2 : 1);
71
+ const row = Math.floor(c.y);
72
+ if (row !== prev) {
73
+ ctx.fillStyle = near ? hotColor : color;
74
+ ctx.fillText(c.glyph, x, prev * fontSize);
75
+ c.glyph = pick();
76
+ ctx.fillStyle = headColor;
77
+ ctx.fillText(c.glyph, x, row * fontSize);
78
+ }
79
+ if (row > rows + 4) {
80
+ c.y = -Math.random() * rows * 0.5;
81
+ c.rate = 6 + Math.random() * 10;
82
+ c.on = Math.random() < density;
83
+ }
84
+ if (Math.random() < glitch * 6) {
85
+ ctx.fillStyle = color;
86
+ ctx.fillText(pick(), x, Math.floor(Math.random() * Math.max(1, row)) * fontSize);
87
+ }
88
+ });
89
+ if (Math.random() < glitch) {
90
+ const y = Math.floor(Math.random() * rows) * fontSize;
91
+ ctx.fillStyle = hotColor;
92
+ for (let x = 0; x < W; x += fontSize) if (Math.random() < 0.6) ctx.fillText(pick(), x, y);
93
+ }
94
+ };
95
+ const still = () => {
96
+ ctx.font = `${fontSize}px ${fontFamily}`;
97
+ ctx.textBaseline = "top";
98
+ cols.forEach((c, i) => {
99
+ if (!c.on) return;
100
+ const len = 4 + i * 7 % 12;
101
+ const head = i * 5 % (rows + 4);
102
+ for (let k = 0; k < len; k++) {
103
+ ctx.fillStyle = k === 0 ? headColor : color;
104
+ ctx.globalAlpha = 1 - k / len;
105
+ ctx.fillText(pick(), i * fontSize, (head - k) * fontSize);
106
+ }
107
+ });
108
+ ctx.globalAlpha = 1;
109
+ };
110
+ const tick = (now) => {
111
+ step(Math.max(0, Math.min(0.05, (now - last) / 1e3)));
112
+ last = now;
113
+ raf = visible && !document.hidden ? requestAnimationFrame(tick) : 0;
114
+ };
115
+ const start = () => {
116
+ if (raf || reduced || !visible || document.hidden) return;
117
+ last = performance.now();
118
+ raf = requestAnimationFrame(tick);
119
+ };
120
+ const onMove = (event) => {
121
+ const r = canvas.getBoundingClientRect();
122
+ hand.x = event.clientX - r.left;
123
+ hand.y = event.clientY - r.top;
124
+ };
125
+ const onLeave = () => {
126
+ hand.x = -1e4;
127
+ hand.y = -1e4;
128
+ };
129
+ const resize = new ResizeObserver(() => {
130
+ fit();
131
+ if (reduced) still();
132
+ });
133
+ resize.observe(canvas);
134
+ const observer = new IntersectionObserver(([entry]) => {
135
+ visible = entry.isIntersecting;
136
+ start();
137
+ });
138
+ observer.observe(canvas);
139
+ document.addEventListener("visibilitychange", start);
140
+ canvas.addEventListener("pointermove", onMove);
141
+ canvas.addEventListener("pointerleave", onLeave);
142
+ fit();
143
+ if (reduced) document.fonts?.load(`${fontSize}px ${fontFamily}`).then(() => canvas.isConnected && still());
144
+ start();
145
+ return () => {
146
+ cancelAnimationFrame(raf);
147
+ resize.disconnect();
148
+ observer.disconnect();
149
+ document.removeEventListener("visibilitychange", start);
150
+ canvas.removeEventListener("pointermove", onMove);
151
+ canvas.removeEventListener("pointerleave", onLeave);
152
+ };
153
+ }, [glyphs, fontSize, fontFamily, speed, density, tail, glitch, hotRadius, headColor, color, hotColor, backgroundColor]);
154
+ return /* @__PURE__ */ jsx("canvas", { ref: canvasRef, "aria-hidden": "true", className, style: { display: "block", width: "100%", height: "100%", background: backgroundColor, ...style } });
155
+ }
156
+ export {
157
+ CodeRain as default
158
+ };
@@ -0,0 +1,50 @@
1
+ import { type CSSProperties } from 'react';
2
+ export interface CodeFile {
3
+ /** Tab label. */
4
+ name: string;
5
+ code: string;
6
+ /** Treat lines starting with + / - as added / removed. */
7
+ diff?: boolean;
8
+ /** 1-based line numbers to emphasise. */
9
+ highlight?: number[];
10
+ }
11
+ export interface CodeShowcaseProps {
12
+ files?: CodeFile[];
13
+ defaultFile?: number;
14
+ /** Controlled active tab index. */
15
+ file?: number;
16
+ onFileChange?: (index: number) => void;
17
+ /** Advance every N ms until a tab is clicked; 0 is off. */
18
+ autoPlay?: number;
19
+ /** Line-by-line reveal on first view. */
20
+ reveal?: boolean;
21
+ stagger?: number;
22
+ /** Fold-out and fold-in time for changed lines, in ms. */
23
+ morphDuration?: number;
24
+ showChrome?: boolean;
25
+ showLineNumbers?: boolean;
26
+ copyable?: boolean;
27
+ width?: number;
28
+ fontSize?: number;
29
+ backgroundColor?: string;
30
+ barColor?: string;
31
+ textColor?: string;
32
+ mutedColor?: string;
33
+ dimColor?: string;
34
+ lineColor?: string;
35
+ accentColor?: string;
36
+ keywordColor?: string;
37
+ stringColor?: string;
38
+ numberColor?: string;
39
+ tagColor?: string;
40
+ functionColor?: string;
41
+ addColor?: string;
42
+ removeColor?: string;
43
+ radius?: number;
44
+ fontFamily?: string;
45
+ uiFontFamily?: string;
46
+ label?: string;
47
+ className?: string;
48
+ style?: CSSProperties;
49
+ }
50
+ export default function CodeShowcase({ files, defaultFile, file: controlled, onFileChange, autoPlay, reveal, stagger, morphDuration, showChrome, showLineNumbers, copyable, width, fontSize, backgroundColor, barColor, textColor, mutedColor, dimColor, lineColor, accentColor, keywordColor, stringColor, numberColor, tagColor, functionColor, addColor, removeColor, radius, fontFamily, uiFontFamily, label, className, style }: CodeShowcaseProps): import("react").JSX.Element;