trama-ui 0.1.0

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 (285) hide show
  1. package/CATALOG.md +1237 -0
  2. package/LICENSE +21 -0
  3. package/README.md +78 -0
  4. package/THIRD-PARTY.md +4 -0
  5. package/assets/pixel/kenney-pixel-ui/9-slice/Ancient/brown.png +0 -0
  6. package/assets/pixel/kenney-pixel-ui/9-slice/Ancient/brown_inlay.png +0 -0
  7. package/assets/pixel/kenney-pixel-ui/9-slice/Ancient/brown_pressed.png +0 -0
  8. package/assets/pixel/kenney-pixel-ui/9-slice/Ancient/grey.png +0 -0
  9. package/assets/pixel/kenney-pixel-ui/9-slice/Ancient/grey_inlay.png +0 -0
  10. package/assets/pixel/kenney-pixel-ui/9-slice/Ancient/grey_pressed.png +0 -0
  11. package/assets/pixel/kenney-pixel-ui/9-slice/Ancient/tan.png +0 -0
  12. package/assets/pixel/kenney-pixel-ui/9-slice/Ancient/tan_inlay.png +0 -0
  13. package/assets/pixel/kenney-pixel-ui/9-slice/Ancient/tan_pressed.png +0 -0
  14. package/assets/pixel/kenney-pixel-ui/9-slice/Ancient/white.png +0 -0
  15. package/assets/pixel/kenney-pixel-ui/9-slice/Ancient/white_inlay.png +0 -0
  16. package/assets/pixel/kenney-pixel-ui/9-slice/Ancient/white_pressed.png +0 -0
  17. package/assets/pixel/kenney-pixel-ui/9-slice/Colored/blue.png +0 -0
  18. package/assets/pixel/kenney-pixel-ui/9-slice/Colored/blue_pressed.png +0 -0
  19. package/assets/pixel/kenney-pixel-ui/9-slice/Colored/green.png +0 -0
  20. package/assets/pixel/kenney-pixel-ui/9-slice/Colored/green_pressed.png +0 -0
  21. package/assets/pixel/kenney-pixel-ui/9-slice/Colored/grey.png +0 -0
  22. package/assets/pixel/kenney-pixel-ui/9-slice/Colored/grey_pressed.png +0 -0
  23. package/assets/pixel/kenney-pixel-ui/9-slice/Colored/red.png +0 -0
  24. package/assets/pixel/kenney-pixel-ui/9-slice/Colored/red_pressed.png +0 -0
  25. package/assets/pixel/kenney-pixel-ui/9-slice/Colored/yellow.png +0 -0
  26. package/assets/pixel/kenney-pixel-ui/9-slice/Colored/yellow_pressed.png +0 -0
  27. package/assets/pixel/kenney-pixel-ui/9-slice/Outline/blue.png +0 -0
  28. package/assets/pixel/kenney-pixel-ui/9-slice/Outline/blue_pressed.png +0 -0
  29. package/assets/pixel/kenney-pixel-ui/9-slice/Outline/green.png +0 -0
  30. package/assets/pixel/kenney-pixel-ui/9-slice/Outline/green_pressed.png +0 -0
  31. package/assets/pixel/kenney-pixel-ui/9-slice/Outline/red.png +0 -0
  32. package/assets/pixel/kenney-pixel-ui/9-slice/Outline/red_pressed.png +0 -0
  33. package/assets/pixel/kenney-pixel-ui/9-slice/Outline/yellow.png +0 -0
  34. package/assets/pixel/kenney-pixel-ui/9-slice/Outline/yellow_pressed.png +0 -0
  35. package/assets/pixel/kenney-pixel-ui/9-slice/list.png +0 -0
  36. package/assets/pixel/kenney-pixel-ui/9-slice/space.png +0 -0
  37. package/assets/pixel/kenney-pixel-ui/9-slice/space_inlay.png +0 -0
  38. package/assets/pixel/kenney-pixel-ui/License.txt +23 -0
  39. package/assets/pixel/kenney-pixel-ui/spritesheet/sheet.png +0 -0
  40. package/bin/trama-ui.mjs +27 -0
  41. package/dist/components/ui/Accordion.d.ts +12 -0
  42. package/dist/components/ui/Accordion.js +12 -0
  43. package/dist/components/ui/Alert.d.ts +15 -0
  44. package/dist/components/ui/Alert.js +15 -0
  45. package/dist/components/ui/ArticlesSection.d.ts +30 -0
  46. package/dist/components/ui/ArticlesSection.js +18 -0
  47. package/dist/components/ui/AsciiBackground.d.ts +58 -0
  48. package/dist/components/ui/AsciiBackground.js +173 -0
  49. package/dist/components/ui/AsciiCard.d.ts +78 -0
  50. package/dist/components/ui/AsciiCard.js +253 -0
  51. package/dist/components/ui/AsciiChart.d.ts +18 -0
  52. package/dist/components/ui/AsciiChart.js +47 -0
  53. package/dist/components/ui/Badge.d.ts +15 -0
  54. package/dist/components/ui/Badge.js +8 -0
  55. package/dist/components/ui/BitmapText.d.ts +25 -0
  56. package/dist/components/ui/BitmapText.js +21 -0
  57. package/dist/components/ui/BlogCard.d.ts +33 -0
  58. package/dist/components/ui/BlogCard.js +13 -0
  59. package/dist/components/ui/Breadcrumbs.d.ts +9 -0
  60. package/dist/components/ui/Breadcrumbs.js +7 -0
  61. package/dist/components/ui/Button.d.ts +74 -0
  62. package/dist/components/ui/Button.js +48 -0
  63. package/dist/components/ui/CTASection.d.ts +13 -0
  64. package/dist/components/ui/CTASection.js +7 -0
  65. package/dist/components/ui/Carousel.d.ts +30 -0
  66. package/dist/components/ui/Carousel.js +80 -0
  67. package/dist/components/ui/CheckboxGroup.d.ts +11 -0
  68. package/dist/components/ui/CheckboxGroup.js +20 -0
  69. package/dist/components/ui/CodeBlock.d.ts +11 -0
  70. package/dist/components/ui/CodeBlock.js +20 -0
  71. package/dist/components/ui/ContactForm.d.ts +25 -0
  72. package/dist/components/ui/ContactForm.js +26 -0
  73. package/dist/components/ui/CrtOverlay.d.ts +10 -0
  74. package/dist/components/ui/CrtOverlay.js +5 -0
  75. package/dist/components/ui/Divider.d.ts +12 -0
  76. package/dist/components/ui/Divider.js +7 -0
  77. package/dist/components/ui/Drawer.d.ts +16 -0
  78. package/dist/components/ui/Drawer.js +25 -0
  79. package/dist/components/ui/Dropdown.d.ts +10 -0
  80. package/dist/components/ui/Dropdown.js +21 -0
  81. package/dist/components/ui/FAQSection.d.ts +14 -0
  82. package/dist/components/ui/FAQSection.js +7 -0
  83. package/dist/components/ui/FeatureGrid.d.ts +18 -0
  84. package/dist/components/ui/FeatureGrid.js +14 -0
  85. package/dist/components/ui/Footer.d.ts +14 -0
  86. package/dist/components/ui/Footer.js +16 -0
  87. package/dist/components/ui/GlyphCursor.d.ts +22 -0
  88. package/dist/components/ui/GlyphCursor.js +50 -0
  89. package/dist/components/ui/GridBackground.d.ts +15 -0
  90. package/dist/components/ui/GridBackground.js +6 -0
  91. package/dist/components/ui/Hero.d.ts +21 -0
  92. package/dist/components/ui/Hero.js +12 -0
  93. package/dist/components/ui/HoverFX.d.ts +29 -0
  94. package/dist/components/ui/HoverFX.js +75 -0
  95. package/dist/components/ui/Icon.d.ts +33 -0
  96. package/dist/components/ui/Icon.js +29 -0
  97. package/dist/components/ui/ImageGallery.d.ts +31 -0
  98. package/dist/components/ui/ImageGallery.js +79 -0
  99. package/dist/components/ui/LogoCloud.d.ts +12 -0
  100. package/dist/components/ui/LogoCloud.js +9 -0
  101. package/dist/components/ui/MagneticButton.d.ts +12 -0
  102. package/dist/components/ui/MagneticButton.js +49 -0
  103. package/dist/components/ui/Marquee.d.ts +29 -0
  104. package/dist/components/ui/Marquee.js +15 -0
  105. package/dist/components/ui/Modal.d.ts +40 -0
  106. package/dist/components/ui/Modal.js +51 -0
  107. package/dist/components/ui/NavBar.d.ts +14 -0
  108. package/dist/components/ui/NavBar.js +12 -0
  109. package/dist/components/ui/NeonSign.d.ts +14 -0
  110. package/dist/components/ui/NeonSign.js +7 -0
  111. package/dist/components/ui/OtpInput.d.ts +9 -0
  112. package/dist/components/ui/OtpInput.js +27 -0
  113. package/dist/components/ui/Pagination.d.ts +10 -0
  114. package/dist/components/ui/Pagination.js +24 -0
  115. package/dist/components/ui/Panel.d.ts +21 -0
  116. package/dist/components/ui/Panel.js +8 -0
  117. package/dist/components/ui/PixelFrame.d.ts +61 -0
  118. package/dist/components/ui/PixelFrame.js +29 -0
  119. package/dist/components/ui/Presence.d.ts +51 -0
  120. package/dist/components/ui/Presence.js +343 -0
  121. package/dist/components/ui/PricingCard.d.ts +30 -0
  122. package/dist/components/ui/PricingCard.js +21 -0
  123. package/dist/components/ui/PricingSection.d.ts +35 -0
  124. package/dist/components/ui/PricingSection.js +21 -0
  125. package/dist/components/ui/Progress.d.ts +17 -0
  126. package/dist/components/ui/Progress.js +9 -0
  127. package/dist/components/ui/RadioGroup.d.ts +10 -0
  128. package/dist/components/ui/RadioGroup.js +11 -0
  129. package/dist/components/ui/RangeSlider.d.ts +14 -0
  130. package/dist/components/ui/RangeSlider.js +11 -0
  131. package/dist/components/ui/Reveal.d.ts +48 -0
  132. package/dist/components/ui/Reveal.js +181 -0
  133. package/dist/components/ui/SceneFlash.d.ts +14 -0
  134. package/dist/components/ui/SceneFlash.js +51 -0
  135. package/dist/components/ui/ScrambleText.d.ts +31 -0
  136. package/dist/components/ui/ScrambleText.js +51 -0
  137. package/dist/components/ui/ScrollArea.d.ts +15 -0
  138. package/dist/components/ui/ScrollArea.js +18 -0
  139. package/dist/components/ui/SectionHeader.d.ts +12 -0
  140. package/dist/components/ui/SectionHeader.js +6 -0
  141. package/dist/components/ui/Select.d.ts +17 -0
  142. package/dist/components/ui/Select.js +31 -0
  143. package/dist/components/ui/Skeleton.d.ts +12 -0
  144. package/dist/components/ui/Skeleton.js +18 -0
  145. package/dist/components/ui/Spinner.d.ts +15 -0
  146. package/dist/components/ui/Spinner.js +24 -0
  147. package/dist/components/ui/Spotlight.d.ts +16 -0
  148. package/dist/components/ui/Spotlight.js +16 -0
  149. package/dist/components/ui/Sprite.d.ts +27 -0
  150. package/dist/components/ui/Sprite.js +19 -0
  151. package/dist/components/ui/StatCounter.d.ts +24 -0
  152. package/dist/components/ui/StatCounter.js +70 -0
  153. package/dist/components/ui/StatsSection.d.ts +14 -0
  154. package/dist/components/ui/StatsSection.js +13 -0
  155. package/dist/components/ui/Stepper.d.ts +10 -0
  156. package/dist/components/ui/Stepper.js +7 -0
  157. package/dist/components/ui/Table.d.ts +10 -0
  158. package/dist/components/ui/Table.js +8 -0
  159. package/dist/components/ui/Tabs.d.ts +12 -0
  160. package/dist/components/ui/Tabs.js +18 -0
  161. package/dist/components/ui/TeamSection.d.ts +18 -0
  162. package/dist/components/ui/TeamSection.js +19 -0
  163. package/dist/components/ui/TerminalTyper.d.ts +20 -0
  164. package/dist/components/ui/TerminalTyper.js +45 -0
  165. package/dist/components/ui/Testimonial.d.ts +19 -0
  166. package/dist/components/ui/Testimonial.js +9 -0
  167. package/dist/components/ui/TestimonialSection.d.ts +20 -0
  168. package/dist/components/ui/TestimonialSection.js +15 -0
  169. package/dist/components/ui/TextField.d.ts +26 -0
  170. package/dist/components/ui/TextField.js +13 -0
  171. package/dist/components/ui/TextmodeBackground.d.ts +52 -0
  172. package/dist/components/ui/TextmodeBackground.js +83 -0
  173. package/dist/components/ui/Timeline.d.ts +13 -0
  174. package/dist/components/ui/Timeline.js +8 -0
  175. package/dist/components/ui/Toast.d.ts +30 -0
  176. package/dist/components/ui/Toast.js +47 -0
  177. package/dist/components/ui/Toggle.d.ts +13 -0
  178. package/dist/components/ui/Toggle.js +10 -0
  179. package/dist/components/ui/Tooltip.d.ts +20 -0
  180. package/dist/components/ui/Tooltip.js +20 -0
  181. package/dist/components/ui/Typewriter.d.ts +20 -0
  182. package/dist/components/ui/Typewriter.js +46 -0
  183. package/dist/components/ui/VideoPlayer.d.ts +81 -0
  184. package/dist/components/ui/VideoPlayer.js +379 -0
  185. package/dist/components/ui/fill.d.ts +32 -0
  186. package/dist/components/ui/fill.js +27 -0
  187. package/dist/components/ui/intent.d.ts +20 -0
  188. package/dist/components/ui/intent.js +23 -0
  189. package/dist/components/ui/styles/kit.css +31 -0
  190. package/dist/components/ui/styles/ui-carousel.css +113 -0
  191. package/dist/components/ui/styles/ui-kit.css +1135 -0
  192. package/dist/components/ui/styles/ui-video.css +75 -0
  193. package/dist/components/ui/swiperCss.d.ts +15 -0
  194. package/dist/components/ui/swiperCss.js +15 -0
  195. package/dist/components/ui/variants.d.ts +12 -0
  196. package/dist/components/ui/variants.js +10 -0
  197. package/dist/index.d.ts +77 -0
  198. package/dist/index.js +77 -0
  199. package/dist/lib/asciify/painters.d.ts +25 -0
  200. package/dist/lib/asciify/painters.js +604 -0
  201. package/dist/lib/asciify/pointer.d.ts +12 -0
  202. package/dist/lib/asciify/pointer.js +54 -0
  203. package/dist/lib/asciify/shape-painters.d.ts +44 -0
  204. package/dist/lib/asciify/shape-painters.js +335 -0
  205. package/dist/lib/asciify/theme-painters.d.ts +8 -0
  206. package/dist/lib/asciify/theme-painters.js +437 -0
  207. package/dist/lib/cells.d.ts +46 -0
  208. package/dist/lib/cells.js +114 -0
  209. package/dist/lib/scroll/store.d.ts +21 -0
  210. package/dist/lib/scroll/store.js +25 -0
  211. package/dist/lib/sketches/aurora.d.ts +3 -0
  212. package/dist/lib/sketches/aurora.js +42 -0
  213. package/dist/lib/sketches/fire.d.ts +3 -0
  214. package/dist/lib/sketches/fire.js +80 -0
  215. package/dist/lib/sketches/flow.d.ts +3 -0
  216. package/dist/lib/sketches/flow.js +70 -0
  217. package/dist/lib/sketches/life.d.ts +3 -0
  218. package/dist/lib/sketches/life.js +107 -0
  219. package/dist/lib/sketches/matrix.d.ts +3 -0
  220. package/dist/lib/sketches/matrix.js +64 -0
  221. package/dist/lib/sketches/ocean.d.ts +3 -0
  222. package/dist/lib/sketches/ocean.js +56 -0
  223. package/dist/lib/sketches/plasma.d.ts +3 -0
  224. package/dist/lib/sketches/plasma.js +29 -0
  225. package/dist/lib/sketches/registry.d.ts +6 -0
  226. package/dist/lib/sketches/registry.js +60 -0
  227. package/dist/lib/sketches/ripples.d.ts +3 -0
  228. package/dist/lib/sketches/ripples.js +84 -0
  229. package/dist/lib/sketches/scroll-assemble.d.ts +8 -0
  230. package/dist/lib/sketches/scroll-assemble.js +90 -0
  231. package/dist/lib/sketches/scroll-parallax.d.ts +6 -0
  232. package/dist/lib/sketches/scroll-parallax.js +76 -0
  233. package/dist/lib/sketches/scroll-rain.d.ts +6 -0
  234. package/dist/lib/sketches/scroll-rain.js +82 -0
  235. package/dist/lib/sketches/scroll-stats.d.ts +7 -0
  236. package/dist/lib/sketches/scroll-stats.js +81 -0
  237. package/dist/lib/sketches/scroll-terminal.d.ts +6 -0
  238. package/dist/lib/sketches/scroll-terminal.js +87 -0
  239. package/dist/lib/sketches/scroll-zoom.d.ts +7 -0
  240. package/dist/lib/sketches/scroll-zoom.js +49 -0
  241. package/dist/lib/sketches/starfield.d.ts +3 -0
  242. package/dist/lib/sketches/starfield.js +54 -0
  243. package/dist/lib/sketches/text-3d.d.ts +6 -0
  244. package/dist/lib/sketches/text-3d.js +62 -0
  245. package/dist/lib/sketches/text-combo-figlet.d.ts +6 -0
  246. package/dist/lib/sketches/text-combo-figlet.js +91 -0
  247. package/dist/lib/sketches/text-glitch.d.ts +3 -0
  248. package/dist/lib/sketches/text-glitch.js +57 -0
  249. package/dist/lib/sketches/text-marquee.d.ts +3 -0
  250. package/dist/lib/sketches/text-marquee.js +35 -0
  251. package/dist/lib/sketches/text-particles.d.ts +9 -0
  252. package/dist/lib/sketches/text-particles.js +91 -0
  253. package/dist/lib/sketches/text-rain.d.ts +3 -0
  254. package/dist/lib/sketches/text-rain.js +73 -0
  255. package/dist/lib/sketches/text-scramble.d.ts +6 -0
  256. package/dist/lib/sketches/text-scramble.js +49 -0
  257. package/dist/lib/sketches/text-wave.d.ts +3 -0
  258. package/dist/lib/sketches/text-wave.js +43 -0
  259. package/dist/lib/sketches/theme-orbit.d.ts +6 -0
  260. package/dist/lib/sketches/theme-orbit.js +119 -0
  261. package/dist/lib/sketches/theme-pulse.d.ts +7 -0
  262. package/dist/lib/sketches/theme-pulse.js +84 -0
  263. package/dist/lib/sketches/tunnel.d.ts +3 -0
  264. package/dist/lib/sketches/tunnel.js +28 -0
  265. package/dist/lib/text/banner.d.ts +5 -0
  266. package/dist/lib/text/banner.js +35 -0
  267. package/dist/lib/text/mask.d.ts +40 -0
  268. package/dist/lib/text/mask.js +143 -0
  269. package/dist/lib/text/store.d.ts +23 -0
  270. package/dist/lib/text/store.js +86 -0
  271. package/dist/lib/ui/card-fields.d.ts +52 -0
  272. package/dist/lib/ui/card-fields.js +193 -0
  273. package/dist/lib/ui/fonts.d.ts +56 -0
  274. package/dist/lib/ui/fonts.js +94 -0
  275. package/dist/lib/ui/fx.d.ts +42 -0
  276. package/dist/lib/ui/fx.js +162 -0
  277. package/dist/lib/ui/icons.d.ts +437 -0
  278. package/dist/lib/ui/icons.js +314 -0
  279. package/dist/lib/ui/placeholder.d.ts +11 -0
  280. package/dist/lib/ui/placeholder.js +65 -0
  281. package/dist/lib/ui/tokens.d.ts +49 -0
  282. package/dist/lib/ui/tokens.js +129 -0
  283. package/dist/lib/ui/useTokens.d.ts +10 -0
  284. package/dist/lib/ui/useTokens.js +32 -0
  285. package/package.json +80 -0
@@ -0,0 +1,52 @@
1
+ import type { Palette } from "./AsciiBackground.js";
2
+ /** Sketches generativos de textmode.js que no dependen del texto del usuario ni del scroll. */
3
+ export declare const TEXTMODE_SKETCHES: readonly [{
4
+ readonly id: "plasma";
5
+ readonly label: "Plasma";
6
+ }, {
7
+ readonly id: "matrix";
8
+ readonly label: "Lluvia digital";
9
+ }, {
10
+ readonly id: "starfield";
11
+ readonly label: "Warp";
12
+ }, {
13
+ readonly id: "ripples";
14
+ readonly label: "Ondas de agua";
15
+ }, {
16
+ readonly id: "life";
17
+ readonly label: "Juego de la vida";
18
+ }, {
19
+ readonly id: "flow";
20
+ readonly label: "Campo de flujo";
21
+ }, {
22
+ readonly id: "fire";
23
+ readonly label: "Fuego";
24
+ }, {
25
+ readonly id: "ocean";
26
+ readonly label: "Atardecer en el mar";
27
+ }, {
28
+ readonly id: "tunnel";
29
+ readonly label: "Túnel";
30
+ }, {
31
+ readonly id: "aurora";
32
+ readonly label: "Aurora";
33
+ }];
34
+ export type TextmodeBackgroundProps = {
35
+ sketch?: (typeof TEXTMODE_SKETCHES)[number]["id"];
36
+ /** tamaño de celda en px */
37
+ fontSize?: number;
38
+ /** cómo se reinterpretan los colores con los tokens del tema */
39
+ palette?: Palette;
40
+ /** 0–1: fuerza de la paleta */
41
+ tintAmount?: number;
42
+ frameRate?: number;
43
+ opacity?: number;
44
+ className?: string;
45
+ };
46
+ /**
47
+ * Fondo generativo de textmode.js que rellena su contenedor (`position: relative` y con tamaño).
48
+ * Cada celda es un carácter con color propio; el puntero interactúa con el sketch.
49
+ * `palette` reinterpreta los colores con los tokens del tema (CSS), sin recrear el lienzo.
50
+ * Al cambiar `sketch`, `fontSize` o `frameRate` se recrea.
51
+ */
52
+ export default function TextmodeBackground({ sketch, fontSize, palette, tintAmount, frameRate, opacity, className }: TextmodeBackgroundProps): import("react").JSX.Element;
@@ -0,0 +1,83 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { useEffect, useRef } from "react";
4
+ import { sketches } from "../../lib/sketches/registry.js";
5
+ /** Sketches generativos de textmode.js que no dependen del texto del usuario ni del scroll. */
6
+ export const TEXTMODE_SKETCHES = [
7
+ { id: "plasma", label: "Plasma" },
8
+ { id: "matrix", label: "Lluvia digital" },
9
+ { id: "starfield", label: "Warp" },
10
+ { id: "ripples", label: "Ondas de agua" },
11
+ { id: "life", label: "Juego de la vida" },
12
+ { id: "flow", label: "Campo de flujo" },
13
+ { id: "fire", label: "Fuego" },
14
+ { id: "ocean", label: "Atardecer en el mar" },
15
+ { id: "tunnel", label: "Túnel" },
16
+ { id: "aurora", label: "Aurora" },
17
+ ];
18
+ /**
19
+ * Fondo generativo de textmode.js que rellena su contenedor (`position: relative` y con tamaño).
20
+ * Cada celda es un carácter con color propio; el puntero interactúa con el sketch.
21
+ * `palette` reinterpreta los colores con los tokens del tema (CSS), sin recrear el lienzo.
22
+ * Al cambiar `sketch`, `fontSize` o `frameRate` se recrea.
23
+ */
24
+ export default function TextmodeBackground({ sketch = "plasma", fontSize = 14, palette = "tint", tintAmount = 0.6, frameRate = 60, opacity = 1, className = "" }) {
25
+ const host = useRef(null);
26
+ useEffect(() => {
27
+ const el = host.current;
28
+ const def = sketches[sketch];
29
+ if (!el || !def)
30
+ return;
31
+ let disposed = false;
32
+ let instance = null;
33
+ const canvas = document.createElement("canvas");
34
+ canvas.className = "ui-fill-canvas";
35
+ el.appendChild(canvas);
36
+ const create = async (w, h) => {
37
+ const { textmode } = await import("textmode.js");
38
+ if (disposed)
39
+ return;
40
+ // Con un canvas propio, textmode.js toma el tamaño del elemento
41
+ canvas.width = w;
42
+ canvas.height = h;
43
+ const t = textmode.create({
44
+ canvas,
45
+ width: w,
46
+ height: h,
47
+ fontSize,
48
+ frameRate,
49
+ pixelDensity: Math.min(window.devicePixelRatio || 1, 2),
50
+ });
51
+ instance = t;
52
+ def.setup(t);
53
+ };
54
+ const handleSize = (w, h) => {
55
+ if (w < 4 || h < 4)
56
+ return;
57
+ if (!instance)
58
+ void create(w, h);
59
+ else
60
+ instance.resizeCanvas(w, h);
61
+ };
62
+ // Medimos ya mismo, sin esperar al primer aviso del ResizeObserver: si este componente se
63
+ // monta dentro de un contenedor `position: fixed` (p. ej. un fondo que se intercambia al
64
+ // hacer scroll), su primer disparo puede llegar con un tamaño todavía sin asentar y, como
65
+ // luego el elemento no vuelve a cambiar de tamaño, el lienzo se queda para siempre en el
66
+ // 300×150 por defecto de <canvas> — negro a efectos prácticos. Medir el rect real aquí
67
+ // cubre ese caso sin afectar al camino normal (el ResizeObserver sigue llevando los cambios
68
+ // posteriores).
69
+ const initial = el.getBoundingClientRect();
70
+ handleSize(Math.round(initial.width), Math.round(initial.height));
71
+ const ro = new ResizeObserver(([entry]) => {
72
+ handleSize(Math.round(entry.contentRect.width), Math.round(entry.contentRect.height));
73
+ });
74
+ ro.observe(el);
75
+ return () => {
76
+ disposed = true;
77
+ ro.disconnect();
78
+ instance?.destroy();
79
+ canvas.remove();
80
+ };
81
+ }, [sketch, fontSize, frameRate]);
82
+ return (_jsxs("div", { className: `ui-fill ui-pal ui-pal--${palette} ${className}`, style: { "--tint": tintAmount, "--op": opacity }, "aria-hidden": true, children: [_jsx("div", { ref: host, className: "ui-fill__media" }), _jsx("i", { className: "ui-pal__a" }), _jsx("i", { className: "ui-pal__b" })] }));
83
+ }
@@ -0,0 +1,13 @@
1
+ import { type Variant } from "./variants.js";
2
+ export type TimelineProps = {
3
+ /** un paso por línea con el formato «Título|Descripción» */
4
+ steps?: string;
5
+ /** contenido del marcador: número, letra o carácter fijo */
6
+ marker?: "number" | "dot" | "glyph";
7
+ /** con marker="glyph": un carácter, o un icono pixel art con `icon:star` (ver Icon) */
8
+ glyph?: string;
9
+ variant?: Variant;
10
+ className?: string;
11
+ };
12
+ /** Línea de pasos vertical: proceso, hoja de ruta o historial. */
13
+ export default function Timeline({ steps, marker, glyph, variant, className }: TimelineProps): import("react").JSX.Element;
@@ -0,0 +1,8 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { renderGlyph } from "./Icon.js";
3
+ import { vcls } from "./variants.js";
4
+ /** Línea de pasos vertical: proceso, hoja de ruta o historial. */
5
+ export default function Timeline({ steps = "Reserva|Eliges día y nivel en menos de un minuto.\nLlegada|Recibes neopreno y tabla en la playa.\nClase|Dos horas con monitor titulado.\nRepite|Bono de cinco clases con descuento.", marker = "number", glyph = "*", variant = "minimal", className = "" }) {
6
+ const rows = steps.split("\n").map((l) => l.split("|")).filter((p) => p[0]?.trim());
7
+ return (_jsx("ol", { className: `ui-tl ${vcls(variant)} ${className}`, children: rows.map(([t, d], i) => (_jsxs("li", { children: [_jsx("span", { className: "ui-tl__dot", "aria-hidden": true, children: marker === "number" ? i + 1 : marker === "glyph" ? renderGlyph(glyph, 14) : "" }), _jsx("strong", { children: t }), d && _jsx("span", { children: d })] }, t + i))) }));
8
+ }
@@ -0,0 +1,30 @@
1
+ import { type Intent } from "./intent.js";
2
+ import { type Variant } from "./variants.js";
3
+ export type ToastProps = {
4
+ /** color semántico común (ver intent.ts); `accent` y `neutral` dan un mensaje sin icono de estado */
5
+ intent?: Intent;
6
+ /** notificación de «en curso», con indicador de carga (ignora `intent`) */
7
+ loading?: boolean;
8
+ /** @deprecated usa `intent` (y `loading`): "message" | "loading" | "success" | "info" | "warning" | "danger" | "error" */
9
+ kind?: "message" | "loading" | "success" | "info" | "warning" | "danger" | "error";
10
+ title?: string;
11
+ description?: string;
12
+ position?: "top-left" | "top-center" | "top-right" | "bottom-left" | "bottom-center" | "bottom-right";
13
+ variant?: Variant;
14
+ /** cambia (a más de 0) para lanzar una notificación desde fuera, igual que Modal/Drawer */
15
+ playKey?: number;
16
+ /** id fijo del Toaster: con él, código externo puede lanzar en la misma instancia pasando `toasterId` */
17
+ id?: string;
18
+ /** oculta el botón de demostración «Mostrar notificación», cuando el disparo lo controla el proyecto */
19
+ showTrigger?: boolean;
20
+ className?: string;
21
+ };
22
+ /**
23
+ * Notificación temporal apilable. Construida sobre `sonner` (apilado, temporizador, gestos táctiles
24
+ * y accesibilidad ya resueltos por una librería consolidada) en vez de reimplementarlo: solo se le da
25
+ * el aspecto del kit por encima, con `unstyled` + clases `ui-toast*` que leen tokens y `--s-*`.
26
+ * Cada instancia usa un `id` propio (o el que le pases) para no cruzarse con otras — p. ej. en
27
+ * «Comparar los 7 estilos», donde conviven 7 `<Toaster>` a la vez, o cuando otra parte de la página
28
+ * necesita lanzar en la misma instancia con `toast.success(msg, { toasterId })`.
29
+ */
30
+ export default function Toast({ intent, loading, kind, title, description, position, variant, playKey, id, showTrigger, className, }: ToastProps): import("react").JSX.Element;
@@ -0,0 +1,47 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { useEffect, useId } from "react";
4
+ import { Toaster, toast as sonnerToast } from "sonner";
5
+ import Button from "./Button.js";
6
+ import { toIntent } from "./intent.js";
7
+ import { vcls } from "./variants.js";
8
+ /**
9
+ * Notificación temporal apilable. Construida sobre `sonner` (apilado, temporizador, gestos táctiles
10
+ * y accesibilidad ya resueltos por una librería consolidada) en vez de reimplementarlo: solo se le da
11
+ * el aspecto del kit por encima, con `unstyled` + clases `ui-toast*` que leen tokens y `--s-*`.
12
+ * Cada instancia usa un `id` propio (o el que le pases) para no cruzarse con otras — p. ej. en
13
+ * «Comparar los 7 estilos», donde conviven 7 `<Toaster>` a la vez, o cuando otra parte de la página
14
+ * necesita lanzar en la misma instancia con `toast.success(msg, { toasterId })`.
15
+ */
16
+ export default function Toast({ intent, loading, kind, title = "Cambios guardados", description = "Tu perfil se actualizó correctamente.", position = "bottom-right", variant = "glass", playKey = 0, id, showTrigger = true, className = "", }) {
17
+ const autoId = useId();
18
+ const toasterId = id ?? autoId;
19
+ const fire = () => {
20
+ const opts = { description: description || undefined, toasterId };
21
+ const isLoading = loading ?? kind === "loading";
22
+ const i = intent ?? (kind === "message" ? "neutral" : kind === "loading" || kind === undefined ? "success" : toIntent(kind, "success"));
23
+ if (isLoading)
24
+ sonnerToast.loading(title, opts);
25
+ else if (i === "accent" || i === "neutral")
26
+ sonnerToast(title, opts);
27
+ else
28
+ sonnerToast[i === "danger" ? "error" : i](title, opts);
29
+ };
30
+ useEffect(() => {
31
+ if (playKey > 0)
32
+ fire();
33
+ // eslint-disable-next-line react-hooks/exhaustive-deps
34
+ }, [playKey]);
35
+ return (_jsxs("div", { className: className, children: [_jsx(Toaster, { id: toasterId, position: position, toastOptions: {
36
+ unstyled: true,
37
+ classNames: {
38
+ toast: `ui-toast ui-surface ${vcls(variant)}`,
39
+ title: "ui-toast__title",
40
+ description: "ui-toast__desc",
41
+ actionButton: "ui-toast__action",
42
+ cancelButton: "ui-toast__cancel",
43
+ closeButton: "ui-toast__close",
44
+ icon: "ui-toast__icon",
45
+ },
46
+ } }), showTrigger && _jsx(Button, { label: "Mostrar notificaci\u00F3n", variant: variant, emphasis: "primary", onClick: fire })] }));
47
+ }
@@ -0,0 +1,13 @@
1
+ import { type Variant } from "./variants.js";
2
+ export type ToggleProps = {
3
+ label?: string;
4
+ defaultChecked?: boolean;
5
+ variant?: Variant;
6
+ size?: "sm" | "md" | "lg";
7
+ /** textos de los estilos retro y terminal, que no dibujan la pista */
8
+ onText?: string;
9
+ offText?: string;
10
+ className?: string;
11
+ };
12
+ /** Interruptor accesible (`role="switch"`). Retro y terminal lo muestran como texto `[ON ]`/`[OFF]`. */
13
+ export default function Toggle({ label, defaultChecked, variant, size, onText, offText, className }: ToggleProps): import("react").JSX.Element;
@@ -0,0 +1,10 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { useEffect, useState } from "react";
4
+ import { vcls } from "./variants.js";
5
+ /** Interruptor accesible (`role="switch"`). Retro y terminal lo muestran como texto `[ON ]`/`[OFF]`. */
6
+ export default function Toggle({ label = "Notificaciones", defaultChecked = true, variant = "glass", size = "md", onText = "ON ", offText = "OFF", className = "" }) {
7
+ const [on, setOn] = useState(defaultChecked);
8
+ useEffect(() => setOn(defaultChecked), [defaultChecked]);
9
+ return (_jsxs("button", { type: "button", role: "switch", "aria-checked": on, onClick: () => setOn((v) => !v), className: `ui-toggle ui-toggle--${size} ${on ? "is-on" : ""} ${vcls(variant)} ${className}`, children: [_jsx("span", { className: "ui-toggle__track", "aria-hidden": true, children: _jsx("span", { className: "ui-toggle__thumb" }) }), _jsxs("span", { className: "ui-toggle__text", "aria-hidden": true, children: ["[", on ? onText : offText, "]"] }), label && _jsx("span", { children: label })] }));
10
+ }
@@ -0,0 +1,20 @@
1
+ import { type ReactNode } from "react";
2
+ import { type Variant } from "./variants.js";
3
+ export type TooltipProps = {
4
+ /** texto disparador cuando no hay `children` (se subraya con puntos, como una abreviatura) */
5
+ label?: string;
6
+ content?: string;
7
+ side?: "top" | "right" | "bottom" | "left";
8
+ variant?: Variant;
9
+ /** el disparador real: un botón, un icono, un enlace… Si es un único elemento, recibe `aria-describedby` */
10
+ children?: ReactNode;
11
+ className?: string;
12
+ };
13
+ /**
14
+ * Texto de ayuda al posar el ratón o el foco. Solo CSS (sin JS): aparece con `:hover` y con el foco dentro
15
+ * (`:focus-within`), así funciona igual envolviendo un texto que un botón.
16
+ *
17
+ * Con `children`, el disparador es lo que envuelves y el foco lo pone ese elemento (no se añade una parada de
18
+ * tabulador extra). Sin él, se pinta `label` como texto enfocable.
19
+ */
20
+ export default function Tooltip({ label, content, side, variant, children, className }: TooltipProps): import("react").JSX.Element;
@@ -0,0 +1,20 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { cloneElement, isValidElement, useId } from "react";
3
+ import { vcls } from "./variants.js";
4
+ /**
5
+ * Texto de ayuda al posar el ratón o el foco. Solo CSS (sin JS): aparece con `:hover` y con el foco dentro
6
+ * (`:focus-within`), así funciona igual envolviendo un texto que un botón.
7
+ *
8
+ * Con `children`, el disparador es lo que envuelves y el foco lo pone ese elemento (no se añade una parada de
9
+ * tabulador extra). Sin él, se pinta `label` como texto enfocable.
10
+ */
11
+ export default function Tooltip({ label = "Pasa el ratón por aquí", content = "Esto es una pista contextual.", side = "top", variant = "glass", children, className = "" }) {
12
+ const id = useId();
13
+ const wraps = children !== undefined && children !== null;
14
+ const trigger = !wraps
15
+ ? label
16
+ : isValidElement(children)
17
+ ? cloneElement(children, { "aria-describedby": id })
18
+ : children;
19
+ return (_jsxs("span", { className: `ui-tip ui-tip--${side} ${wraps ? "ui-tip--wrap" : ""} ${className}`, tabIndex: wraps ? undefined : 0, "aria-describedby": wraps ? undefined : id, children: [trigger, _jsx("span", { id: id, role: "tooltip", className: `ui-tip__bubble ui-surface ${vcls(variant)}`, children: content })] }));
20
+ }
@@ -0,0 +1,20 @@
1
+ import { type Variant } from "./variants.js";
2
+ export type TypewriterProps = {
3
+ /** frases, una por línea */
4
+ phrases?: string;
5
+ /** texto fijo delante de la frase que cambia */
6
+ prefix?: string;
7
+ typeSpeed?: number;
8
+ deleteSpeed?: number;
9
+ /** pausa con la frase completa, en segundos */
10
+ pause?: number;
11
+ cursor?: "bar" | "block" | "underscore" | "none";
12
+ /** tamaño de letra en px */
13
+ fontSize?: number;
14
+ /** @deprecated usa `fontSize` */
15
+ size?: number;
16
+ variant?: Variant;
17
+ className?: string;
18
+ };
19
+ /** Frase que se escribe y se borra en bucle, típica de un titular de héroe. Sin movimiento muestra la primera. */
20
+ export default function Typewriter({ phrases, prefix, typeSpeed, deleteSpeed, pause, cursor, fontSize, size: legacySize, variant, className }: TypewriterProps): import("react").JSX.Element;
@@ -0,0 +1,46 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { useEffect, useMemo, useState } from "react";
4
+ import { vcls } from "./variants.js";
5
+ /** Frase que se escribe y se borra en bucle, típica de un titular de héroe. Sin movimiento muestra la primera. */
6
+ export default function Typewriter({ phrases = "surf en Cantabria\nolas para todos\nel mar te espera", prefix = "Aprende ", typeSpeed = 14, deleteSpeed = 30, pause = 1.4, cursor = "bar", fontSize, size: legacySize, variant = "minimal", className = "" }) {
7
+ const size = fontSize ?? legacySize ?? 40;
8
+ const list = useMemo(() => phrases.split("\n").filter(Boolean), [phrases]);
9
+ const [text, setText] = useState(list[0] ?? "");
10
+ useEffect(() => {
11
+ if (window.matchMedia("(prefers-reduced-motion: reduce)").matches || !list.length) {
12
+ setText(list[0] ?? "");
13
+ return;
14
+ }
15
+ let live = true;
16
+ let idx = 0;
17
+ let n = 0;
18
+ let dir = 1;
19
+ let timer;
20
+ const step = () => {
21
+ if (!live)
22
+ return;
23
+ const full = list[idx % list.length];
24
+ n += dir;
25
+ setText(full.slice(0, n));
26
+ if (dir === 1 && n >= full.length) {
27
+ dir = -1;
28
+ timer = setTimeout(step, pause * 1000);
29
+ }
30
+ else if (dir === -1 && n <= 0) {
31
+ dir = 1;
32
+ idx++;
33
+ timer = setTimeout(step, 250);
34
+ }
35
+ else
36
+ timer = setTimeout(step, 1000 / (dir === 1 ? typeSpeed : deleteSpeed));
37
+ };
38
+ n = 0;
39
+ step();
40
+ return () => {
41
+ live = false;
42
+ clearTimeout(timer);
43
+ };
44
+ }, [list, typeSpeed, deleteSpeed, pause]);
45
+ return (_jsxs("p", { className: `ui-type ${vcls(variant)} ${className}`, style: { fontSize: size, margin: 0 }, "aria-label": `${prefix}${list[0] ?? ""}`, children: [prefix, _jsx("span", { style: { color: "var(--acc)" }, children: text }), cursor !== "none" && _jsx("i", { className: `ui-type__cursor ui-type__cursor--${cursor}`, "aria-hidden": true })] }));
46
+ }
@@ -0,0 +1,81 @@
1
+ import type { ASCII_STYLES } from "./AsciiBackground.js";
2
+ import { type Variant } from "./variants.js";
3
+ export type VideoPlayerProps = {
4
+ /** archivo (.mp4, .webm…), o un enlace de YouTube o Vimeo (se carga bajo demanda, sin cookies hasta pulsar play) */
5
+ src: string;
6
+ /** imagen previa: URL, ruta o `gen:N` (escena de ejemplo generada). En YouTube, si falta, se usa su miniatura */
7
+ poster?: string;
8
+ /** título: se muestra sobre el vídeo antes de empezar y sirve de nombre accesible */
9
+ title?: string;
10
+ /** subtítulos de un archivo: «url|idioma|etiqueta» (formato WebVTT), p. ej. `/subs/es.vtt|es|Español` */
11
+ captions?: string;
12
+ ratio?: "16/9" | "21/9" | "4/3" | "1/1" | "9/16";
13
+ autoplay?: boolean;
14
+ muted?: boolean;
15
+ loop?: boolean;
16
+ /** full = barra completa · minimal = solo play, progreso y pantalla completa · none = sin controles (clic para pausar) */
17
+ controls?: "full" | "minimal" | "none";
18
+ /** segundo en el que empieza */
19
+ startAt?: number;
20
+ /**
21
+ * Modo fondo: rellena su contenedor (que debe tener `position: relative` y tamaño), sin controles, mudo, en bucle y
22
+ * decorativo — igual que los fondos de escena del kit. Se pausa fuera de pantalla y con `prefers-reduced-motion`.
23
+ */
24
+ background?: boolean;
25
+ /** pausa el vídeo cuando sale de pantalla y lo reanuda al volver (por defecto sí) */
26
+ pauseOffscreen?: boolean;
27
+ /** capa de líneas de barrido tipo CRT sobre la imagen */
28
+ scanlines?: boolean;
29
+ /**
30
+ * Convierte el vídeo en tiempo real a caracteres con asciify-engine (Studio) y lo dibuja encima del original, que sigue
31
+ * reproduciéndose debajo — pensado para poder revelarlo más adelante (p. ej. con hover). Necesita que el servidor del
32
+ * vídeo permita CORS (Cloudinary y los archivos del propio sitio lo permiten); si no, se avisa y se muestra el vídeo normal.
33
+ * No aplica a YouTube/Vimeo.
34
+ */
35
+ ascii?: boolean;
36
+ /** estilo del efecto ASCII (los mismos que `AsciiBackground`) */
37
+ asciiStyle?: (typeof ASCII_STYLES)[number];
38
+ /** tamaño de celda del efecto ASCII en px: menos = más detalle y más coste */
39
+ asciiCell?: number;
40
+ /** source = colores del vídeo · accent = monocromo con el acento · gray = grises */
41
+ asciiColor?: "source" | "accent" | "gray";
42
+ /** hover del efecto ASCII (los mismos que `AsciiBackground`): reacciona al puntero sobre el vídeo */
43
+ asciiHover?: "none" | "trail" | "water" | "contour" | "dissolve" | "silk" | "vortex";
44
+ /** 0–1: fuerza del hover ASCII */
45
+ asciiHoverStrength?: number;
46
+ /** 0–1: radio del hover ASCII, relativo al tamaño del vídeo */
47
+ asciiHoverRadius?: number;
48
+ variant?: Variant;
49
+ className?: string;
50
+ };
51
+ type Embed = {
52
+ kind: "youtube" | "vimeo";
53
+ /** id del vídeo; vacío si el enlace es solo una lista de reproducción de YouTube */
54
+ id: string;
55
+ /** lista de reproducción de YouTube (`list=`) */
56
+ list?: string;
57
+ /** segundo de inicio (`t=` o `start=`) */
58
+ start?: number;
59
+ /** el enlace original, para ofrecer «abrir en YouTube» si el autor no permite incrustarlo */
60
+ url: string;
61
+ };
62
+ /**
63
+ * Reconoce enlaces de YouTube (watch, youtu.be, shorts, live, embed, playlist, con `list=` y `t=`) y de Vimeo; cualquier
64
+ * otra cosa se trata como un archivo de vídeo.
65
+ */
66
+ export declare function parseEmbed(src: string): Embed | null;
67
+ /**
68
+ * Carátula de un vídeo alojado en Cloudinary: la propia URL con otra extensión y una transformación que extrae un fotograma
69
+ * (`so_` = segundo, `w_` = ancho). Devuelve `undefined` para cualquier otra fuente.
70
+ */
71
+ export declare function cloudinaryPoster(src: string, second?: number, width?: number): string | undefined;
72
+ /**
73
+ * Reproductor de vídeo del kit, construido sobre el `<video>` nativo: sin dependencias, con controles propios del estilo
74
+ * (cuadrados, borde duro, acento) y todo lo que una landing necesita — poster, atajos de teclado, arrastre en la barra,
75
+ * velocidad, volumen, subtítulos, imagen en imagen, pantalla completa, pausa fuera de pantalla y modo fondo.
76
+ * Los enlaces de YouTube/Vimeo se cargan con una carátula que solo crea el iframe (sin cookies) al pulsar play.
77
+ *
78
+ * Atajos con el reproductor enfocado: espacio/K play·pausa, ←/→ ±5 s (J/L ±10 s), ↑/↓ volumen, M silencio, F pantalla completa, C subtítulos, 0–9 salta al 0–90 %.
79
+ */
80
+ export default function VideoPlayer({ src, poster, title, captions, ratio, autoplay, muted, loop, controls, startAt, background, pauseOffscreen, scanlines, ascii, asciiStyle, asciiCell, asciiColor, asciiHover, asciiHoverStrength, asciiHoverRadius, variant, className }: VideoPlayerProps): import("react").JSX.Element;
81
+ export {};