@eduardoalvarez/arrecife 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 (44) hide show
  1. package/CHANGELOG.md +55 -0
  2. package/LICENSE +21 -0
  3. package/README.md +520 -0
  4. package/assets/brand/face-annoyed.png +0 -0
  5. package/assets/brand/face-confused.png +0 -0
  6. package/assets/brand/face-hearts.png +0 -0
  7. package/assets/brand/face-laughing.png +0 -0
  8. package/assets/brand/face-shades.png +0 -0
  9. package/assets/brand/face-waiting.png +0 -0
  10. package/assets/brand/face-wink.png +0 -0
  11. package/assets/brand/fin-foam.png +0 -0
  12. package/assets/brand/fin.png +0 -0
  13. package/assets/brand/pose-desk.png +0 -0
  14. package/assets/brand/pose-laptop-coffee.png +0 -0
  15. package/assets/brand/pose-peek.png +0 -0
  16. package/assets/brand/pose-surf.png +0 -0
  17. package/dist/brand/index.cjs +228 -0
  18. package/dist/brand/index.d.cts +63 -0
  19. package/dist/brand/index.d.ts +63 -0
  20. package/dist/brand/index.js +3 -0
  21. package/dist/catalogo-Du5ID-Hi.d.cts +77 -0
  22. package/dist/catalogo-Du5ID-Hi.d.ts +77 -0
  23. package/dist/chunk-22OXRTAL.js +22 -0
  24. package/dist/chunk-DHF63QNM.js +231 -0
  25. package/dist/chunk-E3OMP2DL.js +36 -0
  26. package/dist/chunk-ZL5X6XO7.js +102 -0
  27. package/dist/index.cjs +3191 -0
  28. package/dist/index.d.cts +1024 -0
  29. package/dist/index.d.ts +1024 -0
  30. package/dist/index.js +2624 -0
  31. package/dist/og/index.cjs +322 -0
  32. package/dist/og/index.d.cts +164 -0
  33. package/dist/og/index.d.ts +164 -0
  34. package/dist/og/index.js +242 -0
  35. package/dist/shiki/index.cjs +127 -0
  36. package/dist/shiki/index.d.cts +16 -0
  37. package/dist/shiki/index.d.ts +16 -0
  38. package/dist/shiki/index.js +95 -0
  39. package/dist/tokens/index.cjs +263 -0
  40. package/dist/tokens/index.d.cts +623 -0
  41. package/dist/tokens/index.d.ts +623 -0
  42. package/dist/tokens/index.js +2 -0
  43. package/dist/tokens/theme.css +266 -0
  44. package/package.json +128 -0
package/dist/index.js ADDED
@@ -0,0 +1,2624 @@
1
+ export { tokens } from './chunk-22OXRTAL.js';
2
+ import { cn, CaraDeMascota, Mascota } from './chunk-ZL5X6XO7.js';
3
+ export { CaraDeMascota, Isotipo, Logo, Mascota, cn } from './chunk-ZL5X6XO7.js';
4
+ export { RUTA_ASSETS, aletas, caras, listaCaras, listaPoses, poses, usoDeCara } from './chunk-E3OMP2DL.js';
5
+ import { __export, naming } from './chunk-DHF63QNM.js';
6
+ export { brand, colors, control, dark, fonts, gradient, light, limits, motion, naming, radius, shadow, sintaxis, size, spacing, tagline, typeScale } from './chunk-DHF63QNM.js';
7
+ import { cva } from 'class-variance-authority';
8
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
9
+ import * as AvatarPrimitive from '@radix-ui/react-avatar';
10
+ import { Slot } from '@radix-ui/react-slot';
11
+ import { es } from 'date-fns/locale';
12
+ import { DayPicker } from 'react-day-picker';
13
+ import * as CheckboxPrimitive from '@radix-ui/react-checkbox';
14
+ import * as DialogPrimitive from '@radix-ui/react-dialog';
15
+ import * as DropdownMenuPrimitive from '@radix-ui/react-dropdown-menu';
16
+ import * as LabelPrimitive from '@radix-ui/react-label';
17
+ import * as PopoverPrimitive from '@radix-ui/react-popover';
18
+ import * as ProgressPrimitive from '@radix-ui/react-progress';
19
+ import * as RadioGroupPrimitive from '@radix-ui/react-radio-group';
20
+ import * as SelectPrimitive from '@radix-ui/react-select';
21
+ import * as SeparatorPrimitive from '@radix-ui/react-separator';
22
+ import * as SwitchPrimitive from '@radix-ui/react-switch';
23
+ import * as TabsPrimitive from '@radix-ui/react-tabs';
24
+ import * as ToastPrimitive from '@radix-ui/react-toast';
25
+ import * as TooltipPrimitive from '@radix-ui/react-tooltip';
26
+ import { useRef, useState, useEffect, useCallback, useId } from 'react';
27
+
28
+ var alert = cva("w-full rounded-card border p-md font-sans text-ui", {
29
+ variants: {
30
+ variant: {
31
+ accent: "text-text-secondary",
32
+ success: "text-text-secondary",
33
+ warning: "text-text-secondary",
34
+ error: "text-text-secondary"
35
+ },
36
+ enfasis: {
37
+ sutil: "",
38
+ fuerte: ""
39
+ }
40
+ },
41
+ compoundVariants: [
42
+ { variant: "accent", enfasis: "sutil", class: "border-accent/22 bg-accent/8" },
43
+ { variant: "success", enfasis: "sutil", class: "border-success/22 bg-success/8" },
44
+ { variant: "warning", enfasis: "sutil", class: "border-warning/22 bg-warning/8" },
45
+ { variant: "error", enfasis: "sutil", class: "border-error/22 bg-error/8" },
46
+ { variant: "accent", enfasis: "fuerte", class: "border-accent bg-accent/10" },
47
+ { variant: "success", enfasis: "fuerte", class: "border-success bg-success/10" },
48
+ { variant: "warning", enfasis: "fuerte", class: "border-warning bg-warning/10" },
49
+ { variant: "error", enfasis: "fuerte", class: "border-error bg-error/10" }
50
+ ],
51
+ defaultVariants: { variant: "accent", enfasis: "sutil" }
52
+ });
53
+ var glifoColor = {
54
+ accent: "text-accent",
55
+ success: "text-success",
56
+ warning: "text-warning",
57
+ error: "text-error"
58
+ };
59
+ var GLIFO = {
60
+ accent: "\u2726",
61
+ success: "\u2713",
62
+ warning: "!",
63
+ error: "\u2715"
64
+ };
65
+ function Alert({
66
+ className,
67
+ variant,
68
+ enfasis,
69
+ title,
70
+ icon,
71
+ children,
72
+ ...props
73
+ }) {
74
+ const tono = variant ?? "accent";
75
+ return /* @__PURE__ */ jsx(
76
+ "div",
77
+ {
78
+ role: tono === "error" ? "alert" : "status",
79
+ className: cn(alert({ variant, enfasis }), className),
80
+ ...props,
81
+ children: /* @__PURE__ */ jsxs("div", { className: "gap-sm flex items-start", children: [
82
+ /* @__PURE__ */ jsx(
83
+ "span",
84
+ {
85
+ "aria-hidden": "true",
86
+ className: cn("font-mono text-ui leading-normal select-none", glifoColor[tono]),
87
+ children: icon ?? GLIFO[tono]
88
+ }
89
+ ),
90
+ /* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
91
+ title ? /* @__PURE__ */ jsx("p", { className: "mb-xs text-text-primary font-medium", children: title }) : null,
92
+ children ? /* @__PURE__ */ jsx("div", { className: "max-w-measure", children }) : null
93
+ ] })
94
+ ] })
95
+ }
96
+ );
97
+ }
98
+ var avatar = cva(
99
+ "relative flex shrink-0 overflow-hidden rounded-pill bg-surface-raised border border-hairline",
100
+ {
101
+ variants: {
102
+ size: {
103
+ sm: "size-8",
104
+ md: "size-10",
105
+ lg: "size-14",
106
+ xl: "size-24"
107
+ }
108
+ },
109
+ defaultVariants: { size: "md" }
110
+ }
111
+ );
112
+ function Avatar({ className, size: size2, ...props }) {
113
+ return /* @__PURE__ */ jsx(AvatarPrimitive.Root, { className: cn(avatar({ size: size2 }), className), ...props });
114
+ }
115
+ function AvatarImage({
116
+ className,
117
+ ...props
118
+ }) {
119
+ return /* @__PURE__ */ jsx(AvatarPrimitive.Image, { className: cn("aspect-square size-full object-cover", className), ...props });
120
+ }
121
+ function AvatarFallback({
122
+ className,
123
+ ...props
124
+ }) {
125
+ return /* @__PURE__ */ jsx(
126
+ AvatarPrimitive.Fallback,
127
+ {
128
+ className: cn(
129
+ "text-label font-mono text-text-secondary flex size-full items-center justify-center uppercase",
130
+ className
131
+ ),
132
+ ...props
133
+ }
134
+ );
135
+ }
136
+ var badge = cva(
137
+ ["inline-flex items-center gap-xs", "rounded-chip px-xs py-0.5", "font-sans text-tag", "transition-standard"],
138
+ {
139
+ variants: {
140
+ variant: {
141
+ neutral: "bg-surface-raised text-text-secondary",
142
+ accent: "bg-accent/8 text-text-primary",
143
+ warm: "bg-warm/8 text-text-primary",
144
+ success: "bg-success/8 text-text-primary",
145
+ warning: "bg-warning/8 text-text-primary",
146
+ error: "bg-error/8 text-text-primary"
147
+ }
148
+ },
149
+ defaultVariants: { variant: "neutral" }
150
+ }
151
+ );
152
+ function Badge({ className, variant, ...props }) {
153
+ return /* @__PURE__ */ jsx("span", { className: cn(badge({ variant }), className), ...props });
154
+ }
155
+ var categoria = cva(
156
+ [
157
+ "inline-flex items-center gap-xs",
158
+ "rounded-pill px-sm py-0.5",
159
+ "font-mono text-chip",
160
+ "border transition-standard"
161
+ ],
162
+ {
163
+ variants: {
164
+ active: {
165
+ false: "border-warm/28 bg-transparent text-warm",
166
+ true: "border-warm bg-warm text-warm-on"
167
+ }
168
+ },
169
+ defaultVariants: { active: false }
170
+ }
171
+ );
172
+ function CategoryBadge({ className, active = false, ...props }) {
173
+ return /* @__PURE__ */ jsx(
174
+ "span",
175
+ {
176
+ "data-active": active || void 0,
177
+ className: cn(categoria({ active }), className),
178
+ ...props
179
+ }
180
+ );
181
+ }
182
+ var metrica = ["inline-flex items-center gap-xs", "rounded-pill", "font-mono text-chip text-text-muted"];
183
+ function MetricBadge({ className, boxed = false, ...props }) {
184
+ return /* @__PURE__ */ jsx(
185
+ "span",
186
+ {
187
+ className: cn(metrica, boxed && "border-hairline px-sm py-0.5 border", className),
188
+ ...props
189
+ }
190
+ );
191
+ }
192
+ function Glyph({ children, ...props }) {
193
+ return /* @__PURE__ */ jsx(
194
+ "svg",
195
+ {
196
+ viewBox: "0 0 16 16",
197
+ width: "1em",
198
+ height: "1em",
199
+ fill: "none",
200
+ stroke: "currentColor",
201
+ strokeWidth: 1.75,
202
+ strokeLinecap: "round",
203
+ strokeLinejoin: "round",
204
+ "aria-hidden": "true",
205
+ focusable: "false",
206
+ ...props,
207
+ children
208
+ }
209
+ );
210
+ }
211
+ var Check = (props) => /* @__PURE__ */ jsx(Glyph, { ...props, children: /* @__PURE__ */ jsx("path", { d: "M3 8.5 6.5 12 13 4.5" }) });
212
+ var Minus = (props) => /* @__PURE__ */ jsx(Glyph, { ...props, children: /* @__PURE__ */ jsx("path", { d: "M3.5 8h9" }) });
213
+ var ChevronDown = (props) => /* @__PURE__ */ jsx(Glyph, { ...props, children: /* @__PURE__ */ jsx("path", { d: "M4 6l4 4 4-4" }) });
214
+ var ChevronUp = (props) => /* @__PURE__ */ jsx(Glyph, { ...props, children: /* @__PURE__ */ jsx("path", { d: "M4 10l4-4 4 4" }) });
215
+ var ChevronLeft = (props) => /* @__PURE__ */ jsx(Glyph, { ...props, children: /* @__PURE__ */ jsx("path", { d: "M10 4L6 8l4 4" }) });
216
+ var ChevronRight = (props) => /* @__PURE__ */ jsx(Glyph, { ...props, children: /* @__PURE__ */ jsx("path", { d: "M6 4l4 4-4 4" }) });
217
+ var Close = (props) => /* @__PURE__ */ jsx(Glyph, { ...props, children: /* @__PURE__ */ jsx("path", { d: "M4 4l8 8M12 4l-8 8" }) });
218
+ var Copy = (props) => /* @__PURE__ */ jsxs(Glyph, { ...props, children: [
219
+ /* @__PURE__ */ jsx("rect", { x: "5.5", y: "5.5", width: "8", height: "8", rx: "1.5" }),
220
+ /* @__PURE__ */ jsx("path", { d: "M10.5 3.5h-7a1.5 1.5 0 0 0-1.5 1.5v7" })
221
+ ] });
222
+ var ArrowUpRight = (props) => /* @__PURE__ */ jsx(Glyph, { ...props, children: /* @__PURE__ */ jsx("path", { d: "M5 11l6-6M5.5 5h5.5v5.5" }) });
223
+ var Ellipsis = (props) => /* @__PURE__ */ jsx(Glyph, { ...props, strokeWidth: 2.25, children: /* @__PURE__ */ jsx("path", { d: "M4 8h.01M8 8h.01M12 8h.01" }) });
224
+ var Spinner = (props) => /* @__PURE__ */ jsxs(
225
+ "svg",
226
+ {
227
+ viewBox: "0 0 16 16",
228
+ width: "1em",
229
+ height: "1em",
230
+ fill: "none",
231
+ stroke: "currentColor",
232
+ strokeWidth: 2,
233
+ strokeLinecap: "round",
234
+ "aria-hidden": "true",
235
+ focusable: "false",
236
+ className: "motion-safe:animate-spin",
237
+ ...props,
238
+ children: [
239
+ /* @__PURE__ */ jsx("circle", { cx: "8", cy: "8", r: "6", opacity: 0.3 }),
240
+ /* @__PURE__ */ jsx("path", { d: "M8 2a6 6 0 0 1 6 6" })
241
+ ]
242
+ }
243
+ );
244
+ function GlifoMedia({ children, ...props }) {
245
+ return /* @__PURE__ */ jsx(
246
+ "svg",
247
+ {
248
+ xmlns: "http://www.w3.org/2000/svg",
249
+ viewBox: "0 0 24 24",
250
+ fill: "none",
251
+ "aria-hidden": "true",
252
+ focusable: "false",
253
+ ...props,
254
+ children
255
+ }
256
+ );
257
+ }
258
+ var Play = (props) => /* @__PURE__ */ jsx(GlifoMedia, { fill: "currentColor", ...props, children: /* @__PURE__ */ jsx("path", { d: "M8 5v14l11-7z" }) });
259
+ var Pause = (props) => /* @__PURE__ */ jsx(GlifoMedia, { fill: "currentColor", ...props, children: /* @__PURE__ */ jsx("path", { d: "M6 4h4v16H6V4zm8 0h4v16h-4V4z" }) });
260
+ var Retry = (props) => /* @__PURE__ */ jsx(
261
+ GlifoMedia,
262
+ {
263
+ stroke: "currentColor",
264
+ strokeWidth: 2,
265
+ strokeLinecap: "round",
266
+ strokeLinejoin: "round",
267
+ ...props,
268
+ children: /* @__PURE__ */ jsx("path", { d: "M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15" })
269
+ }
270
+ );
271
+ var GoBackSeconds = (props) => /* @__PURE__ */ jsxs(GlifoMedia, { stroke: "currentColor", strokeWidth: 1.5, strokeLinecap: "round", ...props, children: [
272
+ /* @__PURE__ */ jsx("path", { d: "M16.5 8.5H13.8604C13.6452 8.5 13.4541 8.63772 13.386 8.84189L12.7194 10.8419C12.6114 11.1657 12.8524 11.5 13.1937 11.5H14.5C15.6046 11.5 16.5 12.3954 16.5 13.5C16.5 14.6046 15.6046 15.5 14.5 15.5H12.5" }),
273
+ /* @__PURE__ */ jsx("path", { d: "M7.5 10.5L10 8.5V15.5", strokeLinejoin: "round" }),
274
+ /* @__PURE__ */ jsx(
275
+ "path",
276
+ {
277
+ d: "M14 4.5L12 2C17.5228 2 22 6.47715 22 12C22 17.5228 17.5228 22 12 22C8.7288 22 5.82446 20.4293 4 18.001M8 2.83209C6.87754 3.32251 5.86251 4.01303 5 4.85857C3.14864 6.67349 2 9.20261 2 12C2 12.6849 2.06886 13.3538 2.20004 14",
278
+ strokeLinejoin: "round"
279
+ }
280
+ )
281
+ ] });
282
+ var AdvanceSeconds = (props) => /* @__PURE__ */ jsxs(GlifoMedia, { stroke: "currentColor", strokeWidth: 1.5, strokeLinecap: "round", ...props, children: [
283
+ /* @__PURE__ */ jsx("path", { d: "M16.5 8.5H13.8604C13.6452 8.5 13.4541 8.63772 13.386 8.84189L12.7194 10.8419C12.6114 11.1657 12.8524 11.5 13.1937 11.5H14.5C15.6046 11.5 16.5 12.3954 16.5 13.5C16.5 14.6046 15.6046 15.5 14.5 15.5H12.5" }),
284
+ /* @__PURE__ */ jsx("path", { d: "M7.5 10.5L10 8.5V15.5", strokeLinejoin: "round" }),
285
+ /* @__PURE__ */ jsx(
286
+ "path",
287
+ {
288
+ d: "M10 4.5L12 2C6.47715 2 2 6.47715 2 12C2 12.6849 2.06886 13.3538 2.20004 14M16 2.83209C19.5318 4.3752 22 7.89936 22 12C22 17.5228 17.5228 22 12 22C8.72852 22 5.82443 20.4287 4 18",
289
+ strokeLinejoin: "round"
290
+ }
291
+ )
292
+ ] });
293
+ var VolumeOn = (props) => /* @__PURE__ */ jsx(GlifoMedia, { fill: "currentColor", ...props, children: /* @__PURE__ */ jsx("path", { d: "M3 9v6h4l5 5V4L7 9H3zm13.5 3c0-1.77-1.02-3.29-2.5-4.03v8.05c1.48-.73 2.5-2.25 2.5-4.02zM14 3.23v2.06c2.89.86 5 3.54 5 6.71s-2.11 5.85-5 6.71v2.06c4.01-.91 7-4.49 7-8.77s-2.99-7.86-7-8.77z" }) });
294
+ var VolumeMuted = (props) => /* @__PURE__ */ jsx(GlifoMedia, { fill: "currentColor", ...props, children: /* @__PURE__ */ jsx("path", { d: "M16.5 12c0-1.77-1.02-3.29-2.5-4.03v2.21l2.45 2.45c.03-.2.05-.41.05-.63zm2.5 0c0 .94-.2 1.82-.54 2.64l1.51 1.51C20.63 14.91 21 13.5 21 12c0-4.28-2.99-7.86-7-8.77v2.06c2.89.86 5 3.54 5 6.71zM4.27 3L3 4.27 7.73 9H3v6h4l5 5v-6.73l4.25 4.25c-.67.52-1.42.93-2.25 1.18v2.06c1.38-.31 2.63-.95 3.69-1.81L19.73 21 21 19.73l-9-9L4.27 3zM12 4L9.91 6.09 12 8.18V4z" }) });
295
+ var button = cva(
296
+ [
297
+ "inline-flex cursor-pointer items-center justify-center gap-xs whitespace-nowrap select-none",
298
+ "rounded-control font-sans font-medium",
299
+ "transition-standard",
300
+ "focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent",
301
+ "disabled:pointer-events-none disabled:opacity-50",
302
+ "[&_svg]:shrink-0"
303
+ ],
304
+ {
305
+ variants: {
306
+ variant: {
307
+ primary: [
308
+ "bg-accent text-accent-on hover:bg-accent-hover",
309
+ "light:bg-brand-hull light:text-accent-on light:hover:bg-text-secondary"
310
+ ],
311
+ conversion: "bg-warm text-warm-on hover:bg-warm-hover",
312
+ secondary: [
313
+ "border-hairline-hover border bg-transparent text-text-primary",
314
+ "hover:border-accent hover:text-accent"
315
+ ],
316
+ tertiary: [
317
+ "bg-transparent font-mono font-normal text-text-secondary",
318
+ "hover:text-accent hover:underline hover:underline-offset-4"
319
+ ]
320
+ },
321
+ size: {
322
+ sm: "h-8 px-control-sm text-label",
323
+ md: "h-10 px-control-md text-ui",
324
+ lg: "h-12 px-control-lg text-lead",
325
+ /** Cuadrado 42×42, sin texto. Lleva `aria-label` obligatorio. */
326
+ icon: "size-control-icon p-0"
327
+ }
328
+ },
329
+ compoundVariants: [
330
+ /**
331
+ * El terciario no tiene caja: ni padding horizontal ni alto de control.
332
+ * Va aquí y no como `px-0` en la variante para que gane al `px-*` del
333
+ * tamaño sin depender del orden en que cva concatena las clases.
334
+ */
335
+ { variant: "tertiary", size: ["sm", "md", "lg"], class: "h-auto px-0" }
336
+ ],
337
+ defaultVariants: { variant: "primary", size: "md" }
338
+ }
339
+ );
340
+ function Button({
341
+ className,
342
+ variant,
343
+ size: size2,
344
+ asChild = false,
345
+ loading = false,
346
+ icon,
347
+ children,
348
+ disabled,
349
+ ...props
350
+ }) {
351
+ if (asChild) {
352
+ return /* @__PURE__ */ jsx(Slot, { className: cn(button({ variant, size: size2 }), className), ...props, children });
353
+ }
354
+ return /* @__PURE__ */ jsxs(
355
+ "button",
356
+ {
357
+ className: cn(button({ variant, size: size2 }), className),
358
+ disabled: disabled === true || loading,
359
+ "aria-busy": loading || void 0,
360
+ ...props,
361
+ children: [
362
+ loading ? /* @__PURE__ */ jsx(Spinner, {}) : icon,
363
+ children
364
+ ]
365
+ }
366
+ );
367
+ }
368
+ function Calendar({
369
+ className,
370
+ classNames,
371
+ showOutsideDays = true,
372
+ fullWidth = false,
373
+ ...props
374
+ }) {
375
+ const dia = [
376
+ "relative p-0 text-center",
377
+ fullWidth ? "h-9 flex-1" : "size-9",
378
+ "text-ui font-sans text-text-primary"
379
+ ].join(" ");
380
+ const botonDia = [
381
+ fullWidth ? "h-9 w-full" : "size-9",
382
+ "rounded-chip inline-flex items-center justify-center",
383
+ "transition-standard cursor-pointer",
384
+ "hover:bg-surface-raised",
385
+ "focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent",
386
+ "disabled:pointer-events-none disabled:opacity-50"
387
+ ].join(" ");
388
+ const navegacion = [
389
+ "size-8 rounded-chip inline-flex items-center justify-center",
390
+ "text-text-secondary transition-standard cursor-pointer",
391
+ "hover:bg-surface-raised hover:text-text-primary",
392
+ "focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent",
393
+ "disabled:pointer-events-none disabled:opacity-50"
394
+ ].join(" ");
395
+ return /* @__PURE__ */ jsx(
396
+ DayPicker,
397
+ {
398
+ locale: es,
399
+ showOutsideDays,
400
+ className: cn("font-sans", className),
401
+ classNames: {
402
+ // `relative` obligatorio: la navegación se posiciona en absoluto contra
403
+ // la raíz, y sin esto se ancla al primer ancestro posicionado —o al
404
+ // viewport— y las flechas acaban en los bordes de la página.
405
+ root: cn("relative", fullWidth ? "w-full" : "w-fit"),
406
+ months: cn("gap-md flex flex-col sm:flex-row", fullWidth && "w-full"),
407
+ month: cn("gap-sm flex flex-col", fullWidth && "min-w-0 flex-1"),
408
+ month_caption: "h-8 flex items-center justify-center",
409
+ caption_label: "text-ui font-sans font-medium text-text-primary capitalize",
410
+ nav: "absolute inset-x-0 top-0 flex items-center justify-between",
411
+ button_previous: navegacion,
412
+ button_next: navegacion,
413
+ month_grid: "w-full border-collapse",
414
+ weekdays: cn("flex", fullWidth && "w-full"),
415
+ // `textMuted` no va sobre `surfaceRaised` —4.07:1—, y un calendario dentro de
416
+ // un Popover vive justo ahí.
417
+ weekday: cn(
418
+ "h-9 text-eyebrow font-mono text-text-secondary uppercase flex items-center justify-center",
419
+ fullWidth ? "flex-1" : "w-9"
420
+ ),
421
+ week: "flex w-full",
422
+ day: dia,
423
+ day_button: botonDia,
424
+ today: "text-accent font-medium",
425
+ // Los días de los meses vecinos se atenúan, pero no por debajo de AA:
426
+ // `textSecondary` al 85 % da 5.09:1 en el peor caso, que es sobre
427
+ // `surfaceRaised`. Al 75 % ya no pasa en modo claro.
428
+ outside: "text-text-secondary opacity-85",
429
+ disabled: "opacity-50",
430
+ hidden: "invisible",
431
+ selected: "[&_button]:bg-accent [&_button]:text-accent-on [&_button]:hover:bg-accent-hover",
432
+ range_start: "[&_button]:bg-accent [&_button]:text-accent-on [&_button]:rounded-r-none",
433
+ range_middle: "[&_button]:bg-surface-raised [&_button]:text-text-primary [&_button]:rounded-none",
434
+ range_end: "[&_button]:bg-accent [&_button]:text-accent-on [&_button]:rounded-l-none",
435
+ footer: "text-label font-sans text-text-secondary pt-sm",
436
+ ...classNames
437
+ },
438
+ components: {
439
+ Chevron: ({ orientation, ...rest }) => orientation === "left" ? /* @__PURE__ */ jsx(ChevronLeft, { ...rest }) : /* @__PURE__ */ jsx(ChevronRight, { ...rest })
440
+ },
441
+ ...props
442
+ }
443
+ );
444
+ }
445
+ var ETIQUETA = {
446
+ display: "h1",
447
+ stat: "p",
448
+ h1: "h1",
449
+ h2: "h2",
450
+ h3: "h3",
451
+ body: "p",
452
+ lead: "p",
453
+ ui: "p",
454
+ label: "span",
455
+ tag: "span",
456
+ meta: "p",
457
+ chip: "span",
458
+ eyebrow: "p"
459
+ };
460
+ var texto = cva("", {
461
+ variants: {
462
+ variant: {
463
+ display: "text-display font-display",
464
+ // Métricas grandes: 46px de display. Es la única escala pensada para un
465
+ // número, y por eso el interlineado es 1.
466
+ stat: "text-stat font-display",
467
+ h1: "text-h1 font-display",
468
+ h2: "text-h2 font-display",
469
+ h3: "text-h3 font-display",
470
+ body: "text-body font-sans",
471
+ // 17px: la bajada de las páginas internas y el botón grande.
472
+ lead: "text-lead font-sans",
473
+ ui: "text-ui font-sans",
474
+ label: "text-label font-sans",
475
+ // Las dos escalas de etiqueta. `tag` es el estado (sans 12.5/500) y `chip`
476
+ // la categoría y la métrica (mono 11.5). Ninguna transforma el texto.
477
+ tag: "text-tag font-sans",
478
+ chip: "text-chip font-mono",
479
+ // Mono SIN transformar: fechas, rutas, versiones, nombres de archivo y la
480
+ // firma del footer. Es el escalón que faltaba, y por el que cada sitio de
481
+ // uso terminaba escribiendo `variant="eyebrow" className="normal-case"`.
482
+ meta: "text-meta font-mono",
483
+ // `uppercase` no cabe en un token de tamaño: text-transform no es un
484
+ // modificador de --text-*. Por eso lo pone la variante y no theme.css.
485
+ eyebrow: "text-eyebrow font-mono uppercase"
486
+ },
487
+ tone: {
488
+ primary: "text-text-primary",
489
+ secondary: "text-text-secondary",
490
+ muted: "text-text-muted",
491
+ accent: "text-accent",
492
+ warm: "text-warm",
493
+ success: "text-success",
494
+ warning: "text-warning",
495
+ error: "text-error"
496
+ }
497
+ },
498
+ defaultVariants: { variant: "body", tone: "primary" }
499
+ });
500
+ function Text({
501
+ className,
502
+ variant,
503
+ tone,
504
+ as,
505
+ asChild = false,
506
+ measure,
507
+ children,
508
+ ...props
509
+ }) {
510
+ const escala = variant ?? "body";
511
+ const limitar = measure ?? escala === "body";
512
+ const clases = cn(texto({ variant, tone }), limitar && "max-w-measure", className);
513
+ if (asChild) {
514
+ return /* @__PURE__ */ jsx(Slot, { className: clases, ...props, children });
515
+ }
516
+ const Etiqueta = as ?? ETIQUETA[escala];
517
+ return /* @__PURE__ */ jsx(Etiqueta, { className: clases, ...props, children });
518
+ }
519
+ var SUPERFICIE_TARJETA = "rounded-card border-hairline bg-surface border";
520
+ var HOVER_TARJETA = "transition-standard hover:border-hairline-hover";
521
+ function Card({ className, ...props }) {
522
+ return /* @__PURE__ */ jsx("div", { className: cn(SUPERFICIE_TARJETA, className), ...props });
523
+ }
524
+ function CardHeader({ className, ...props }) {
525
+ return /* @__PURE__ */ jsx("div", { className: cn("gap-xs p-lg flex flex-col", className), ...props });
526
+ }
527
+ function CardTitle({ className, ...props }) {
528
+ return /* @__PURE__ */ jsx(Text, { as: "h3", variant: "h3", className, ...props });
529
+ }
530
+ function CardDescription({ className, ...props }) {
531
+ return /* @__PURE__ */ jsx(Text, { variant: "ui", tone: "secondary", className, ...props });
532
+ }
533
+ function CardContent({ className, ...props }) {
534
+ return /* @__PURE__ */ jsx("div", { className: cn("px-lg pb-lg", className), ...props });
535
+ }
536
+ function CardFooter({ className, ...props }) {
537
+ return /* @__PURE__ */ jsx(
538
+ "div",
539
+ {
540
+ className: cn("border-hairline px-lg py-md gap-sm flex items-center border-t", className),
541
+ ...props
542
+ }
543
+ );
544
+ }
545
+ function Checkbox({ className, ...props }) {
546
+ return /* @__PURE__ */ jsx(
547
+ CheckboxPrimitive.Root,
548
+ {
549
+ className: cn(
550
+ "rounded-chip border-border bg-surface size-5 shrink-0 cursor-pointer border",
551
+ "text-accent-on transition-standard",
552
+ "hover:border-hairline-hover",
553
+ "focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent",
554
+ "disabled:pointer-events-none disabled:opacity-50",
555
+ "data-[state=checked]:border-accent data-[state=checked]:bg-accent",
556
+ "data-[state=indeterminate]:border-accent data-[state=indeterminate]:bg-accent",
557
+ className
558
+ ),
559
+ ...props,
560
+ children: /* @__PURE__ */ jsx(CheckboxPrimitive.Indicator, { className: "flex items-center justify-center text-[13px]", children: props.checked === "indeterminate" ? /* @__PURE__ */ jsx(Minus, {}) : /* @__PURE__ */ jsx(Check, {}) })
561
+ }
562
+ );
563
+ }
564
+ function Code({ className, ...props }) {
565
+ return /* @__PURE__ */ jsx(
566
+ "code",
567
+ {
568
+ className: cn(
569
+ "rounded-chip border-hairline bg-surface-raised border",
570
+ "font-mono text-meta text-text-primary",
571
+ "px-1 py-0.5",
572
+ className
573
+ ),
574
+ ...props
575
+ }
576
+ );
577
+ }
578
+ function DateField({
579
+ className,
580
+ invalid = false,
581
+ withTime = false,
582
+ ...props
583
+ }) {
584
+ return /* @__PURE__ */ jsx(
585
+ "input",
586
+ {
587
+ type: withTime ? "datetime-local" : "date",
588
+ "data-invalid": invalid || void 0,
589
+ "aria-invalid": invalid || void 0,
590
+ className: cn(
591
+ "px-sm h-10 w-full",
592
+ "rounded-control border-border bg-surface border",
593
+ "font-mono text-ui text-text-primary",
594
+ "transition-standard",
595
+ "hover:border-hairline-hover",
596
+ "focus-visible:border-accent focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent",
597
+ "disabled:pointer-events-none disabled:opacity-50",
598
+ "data-[invalid]:border-error data-[invalid]:focus-visible:outline-error",
599
+ // El indicador nativo hereda el esquema del tema activo.
600
+ "scheme-light dark:scheme-dark [&::-webkit-calendar-picker-indicator]:cursor-pointer",
601
+ className
602
+ ),
603
+ ...props
604
+ }
605
+ );
606
+ }
607
+ var Dialog = DialogPrimitive.Root;
608
+ var DialogTrigger = DialogPrimitive.Trigger;
609
+ var DialogClose = DialogPrimitive.Close;
610
+ function DialogOverlay({
611
+ className,
612
+ ...props
613
+ }) {
614
+ return /* @__PURE__ */ jsx(
615
+ DialogPrimitive.Overlay,
616
+ {
617
+ className: cn("bg-brand-hull/70 fixed inset-0 z-50", className),
618
+ ...props
619
+ }
620
+ );
621
+ }
622
+ function DialogContent({
623
+ className,
624
+ children,
625
+ ...props
626
+ }) {
627
+ return /* @__PURE__ */ jsxs(DialogPrimitive.Portal, { children: [
628
+ /* @__PURE__ */ jsx(DialogOverlay, {}),
629
+ /* @__PURE__ */ jsxs(
630
+ DialogPrimitive.Content,
631
+ {
632
+ className: cn(
633
+ "fixed top-1/2 left-1/2 z-50 w-full max-w-content -translate-x-1/2 -translate-y-1/2",
634
+ "gap-md p-lg flex flex-col",
635
+ "rounded-panel border-border bg-surface shadow-standard border",
636
+ "text-text-primary font-sans",
637
+ className
638
+ ),
639
+ ...props,
640
+ children: [
641
+ children,
642
+ /* @__PURE__ */ jsx(
643
+ DialogPrimitive.Close,
644
+ {
645
+ "aria-label": "Cerrar",
646
+ className: cn(
647
+ "rounded-chip text-text-muted absolute top-4 right-4 flex size-8 cursor-pointer items-center justify-center",
648
+ "transition-standard",
649
+ "hover:bg-surface-raised hover:text-text-primary",
650
+ "focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent"
651
+ ),
652
+ children: /* @__PURE__ */ jsx(Close, {})
653
+ }
654
+ )
655
+ ]
656
+ }
657
+ )
658
+ ] });
659
+ }
660
+ function DialogHeader({ className, ...props }) {
661
+ return /* @__PURE__ */ jsx("div", { className: cn("gap-xs flex flex-col pr-8", className), ...props });
662
+ }
663
+ function DialogFooter({ className, ...props }) {
664
+ return /* @__PURE__ */ jsx("div", { className: cn("gap-sm flex flex-col-reverse sm:flex-row sm:justify-end", className), ...props });
665
+ }
666
+ function DialogTitle({
667
+ className,
668
+ ...props
669
+ }) {
670
+ return /* @__PURE__ */ jsx(
671
+ DialogPrimitive.Title,
672
+ {
673
+ className: cn("text-h3 font-display text-text-primary", className),
674
+ ...props
675
+ }
676
+ );
677
+ }
678
+ function DialogDescription({
679
+ className,
680
+ ...props
681
+ }) {
682
+ return /* @__PURE__ */ jsx(
683
+ DialogPrimitive.Description,
684
+ {
685
+ className: cn("text-ui text-text-secondary max-w-measure", className),
686
+ ...props
687
+ }
688
+ );
689
+ }
690
+ var DropdownMenu = DropdownMenuPrimitive.Root;
691
+ var DropdownMenuTrigger = DropdownMenuPrimitive.Trigger;
692
+ var DropdownMenuGroup = DropdownMenuPrimitive.Group;
693
+ var DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup;
694
+ var DropdownMenuSub = DropdownMenuPrimitive.Sub;
695
+ var panel = [
696
+ "z-50 min-w-40 overflow-hidden p-1",
697
+ "rounded-panel border-border bg-surface-raised shadow-standard border",
698
+ "text-text-primary font-sans"
699
+ ];
700
+ var item = [
701
+ "rounded-chip px-sm relative flex h-9 cursor-default items-center gap-2 select-none",
702
+ "text-ui text-text-secondary transition-standard",
703
+ "data-[highlighted]:bg-surface data-[highlighted]:text-text-primary",
704
+ "data-[disabled]:pointer-events-none data-[disabled]:opacity-50"
705
+ ];
706
+ function DropdownMenuContent({
707
+ className,
708
+ sideOffset = 6,
709
+ ...props
710
+ }) {
711
+ return /* @__PURE__ */ jsx(DropdownMenuPrimitive.Portal, { children: /* @__PURE__ */ jsx(
712
+ DropdownMenuPrimitive.Content,
713
+ {
714
+ sideOffset,
715
+ className: cn(panel, className),
716
+ ...props
717
+ }
718
+ ) });
719
+ }
720
+ function DropdownMenuItem({
721
+ className,
722
+ ...props
723
+ }) {
724
+ return /* @__PURE__ */ jsx(DropdownMenuPrimitive.Item, { className: cn(item, className), ...props });
725
+ }
726
+ function DropdownMenuCheckboxItem({
727
+ className,
728
+ children,
729
+ ...props
730
+ }) {
731
+ return /* @__PURE__ */ jsxs(DropdownMenuPrimitive.CheckboxItem, { className: cn(item, "pl-8", className), ...props, children: [
732
+ /* @__PURE__ */ jsx(DropdownMenuPrimitive.ItemIndicator, { className: "text-accent absolute left-2 flex items-center", children: /* @__PURE__ */ jsx(Check, {}) }),
733
+ children
734
+ ] });
735
+ }
736
+ function DropdownMenuRadioItem({
737
+ className,
738
+ children,
739
+ ...props
740
+ }) {
741
+ return /* @__PURE__ */ jsxs(DropdownMenuPrimitive.RadioItem, { className: cn(item, "pl-8", className), ...props, children: [
742
+ /* @__PURE__ */ jsx(DropdownMenuPrimitive.ItemIndicator, { className: "absolute left-2 flex items-center", children: /* @__PURE__ */ jsx("span", { className: "rounded-pill bg-accent block size-2" }) }),
743
+ children
744
+ ] });
745
+ }
746
+ function DropdownMenuLabel({
747
+ className,
748
+ ...props
749
+ }) {
750
+ return /* @__PURE__ */ jsx(
751
+ DropdownMenuPrimitive.Label,
752
+ {
753
+ className: cn("px-sm text-eyebrow font-mono text-text-secondary py-1.5 uppercase", className),
754
+ ...props
755
+ }
756
+ );
757
+ }
758
+ function DropdownMenuSeparator({
759
+ className,
760
+ ...props
761
+ }) {
762
+ return /* @__PURE__ */ jsx(DropdownMenuPrimitive.Separator, { className: cn("bg-hairline my-1 h-px", className), ...props });
763
+ }
764
+ function DropdownMenuSubTrigger({
765
+ className,
766
+ children,
767
+ ...props
768
+ }) {
769
+ return /* @__PURE__ */ jsxs(
770
+ DropdownMenuPrimitive.SubTrigger,
771
+ {
772
+ className: cn(item, "data-[state=open]:bg-surface", className),
773
+ ...props,
774
+ children: [
775
+ children,
776
+ /* @__PURE__ */ jsx(ChevronRight, { className: "text-text-muted ml-auto" })
777
+ ]
778
+ }
779
+ );
780
+ }
781
+ function DropdownMenuSubContent({
782
+ className,
783
+ ...props
784
+ }) {
785
+ return /* @__PURE__ */ jsx(DropdownMenuPrimitive.Portal, { children: /* @__PURE__ */ jsx(DropdownMenuPrimitive.SubContent, { className: cn(panel, className), ...props }) });
786
+ }
787
+ function Input({ className, invalid = false, ...props }) {
788
+ return /* @__PURE__ */ jsx(
789
+ "input",
790
+ {
791
+ "data-invalid": invalid || void 0,
792
+ "aria-invalid": invalid || void 0,
793
+ className: cn(
794
+ "h-10 w-full px-sm",
795
+ "rounded-control border border-border bg-surface",
796
+ "font-sans text-ui text-text-primary placeholder:text-text-muted",
797
+ "transition-standard",
798
+ "hover:border-hairline-hover",
799
+ "focus-visible:border-accent focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent",
800
+ "disabled:pointer-events-none disabled:opacity-50",
801
+ "data-[invalid]:border-error data-[invalid]:focus-visible:outline-error",
802
+ "file:mr-sm file:border-0 file:bg-transparent file:font-sans file:text-label file:text-text-secondary",
803
+ className
804
+ ),
805
+ ...props
806
+ }
807
+ );
808
+ }
809
+ function Label2({ className, ...props }) {
810
+ return /* @__PURE__ */ jsx(
811
+ LabelPrimitive.Root,
812
+ {
813
+ className: cn(
814
+ "text-label font-sans text-text-secondary select-none",
815
+ "peer-disabled:opacity-50 group-data-[disabled]:opacity-50",
816
+ className
817
+ ),
818
+ ...props
819
+ }
820
+ );
821
+ }
822
+ function Pagination({ className, ...props }) {
823
+ return /* @__PURE__ */ jsx(
824
+ "nav",
825
+ {
826
+ role: "navigation",
827
+ "aria-label": "Paginaci\xF3n",
828
+ className: cn("mx-auto flex w-full justify-center", className),
829
+ ...props
830
+ }
831
+ );
832
+ }
833
+ function PaginationContent({ className, ...props }) {
834
+ return /* @__PURE__ */ jsx("ul", { className: cn("gap-xs flex flex-row items-center", className), ...props });
835
+ }
836
+ function PaginationItem(props) {
837
+ return /* @__PURE__ */ jsx("li", { ...props });
838
+ }
839
+ function PaginationLink({ className, isActive = false, ...props }) {
840
+ return /* @__PURE__ */ jsx(
841
+ "a",
842
+ {
843
+ "aria-current": isActive ? "page" : void 0,
844
+ className: cn(
845
+ "rounded-chip px-sm inline-flex h-9 min-w-9 cursor-pointer items-center justify-center",
846
+ "font-sans text-ui text-text-secondary",
847
+ "transition-standard",
848
+ "hover:bg-surface hover:text-text-primary",
849
+ "focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent",
850
+ isActive && "bg-surface-raised text-text-primary",
851
+ className
852
+ ),
853
+ ...props
854
+ }
855
+ );
856
+ }
857
+ function PaginationPrevious({ className, ...props }) {
858
+ return /* @__PURE__ */ jsxs(PaginationLink, { "aria-label": "P\xE1gina anterior", className: cn("gap-xs", className), ...props, children: [
859
+ /* @__PURE__ */ jsx(ChevronLeft, {}),
860
+ "Anterior"
861
+ ] });
862
+ }
863
+ function PaginationNext({ className, ...props }) {
864
+ return /* @__PURE__ */ jsxs(PaginationLink, { "aria-label": "P\xE1gina siguiente", className: cn("gap-xs", className), ...props, children: [
865
+ "Siguiente",
866
+ /* @__PURE__ */ jsx(ChevronRight, {})
867
+ ] });
868
+ }
869
+ function PaginationEllipsis({ className, ...props }) {
870
+ return /* @__PURE__ */ jsx(
871
+ "span",
872
+ {
873
+ "aria-hidden": "true",
874
+ className: cn("text-text-muted flex size-9 items-center justify-center", className),
875
+ ...props,
876
+ children: /* @__PURE__ */ jsx(Ellipsis, {})
877
+ }
878
+ );
879
+ }
880
+ var Popover = PopoverPrimitive.Root;
881
+ var PopoverTrigger = PopoverPrimitive.Trigger;
882
+ var PopoverAnchor = PopoverPrimitive.Anchor;
883
+ function PopoverContent({
884
+ className,
885
+ align = "center",
886
+ sideOffset = 6,
887
+ ...props
888
+ }) {
889
+ return /* @__PURE__ */ jsx(PopoverPrimitive.Portal, { children: /* @__PURE__ */ jsx(
890
+ PopoverPrimitive.Content,
891
+ {
892
+ align,
893
+ sideOffset,
894
+ className: cn(
895
+ "z-50 w-72 p-md",
896
+ "rounded-panel border-border bg-surface-raised shadow-standard border",
897
+ "text-text-primary font-sans text-ui",
898
+ "outline-none",
899
+ className
900
+ ),
901
+ ...props
902
+ }
903
+ ) });
904
+ }
905
+ function Progress({ className, value, label, tone = "accent", ...props }) {
906
+ return /* @__PURE__ */ jsx(
907
+ ProgressPrimitive.Root,
908
+ {
909
+ className: cn("rounded-pill bg-surface-raised relative h-2 w-full overflow-hidden", className),
910
+ value,
911
+ "aria-label": label,
912
+ ...props,
913
+ children: /* @__PURE__ */ jsx(
914
+ ProgressPrimitive.Indicator,
915
+ {
916
+ className: cn("h-full", tone === "warm" ? "bg-warm" : "bg-accent"),
917
+ style: { width: `${value ?? 0}%` }
918
+ }
919
+ )
920
+ }
921
+ );
922
+ }
923
+ function RadioGroup2({ className, ...props }) {
924
+ return /* @__PURE__ */ jsx(RadioGroupPrimitive.Root, { className: cn("gap-sm grid", className), ...props });
925
+ }
926
+ function RadioGroupItem({ className, ...props }) {
927
+ return /* @__PURE__ */ jsx(
928
+ RadioGroupPrimitive.Item,
929
+ {
930
+ className: cn(
931
+ "rounded-pill border-border bg-surface size-5 shrink-0 cursor-pointer border",
932
+ "transition-standard",
933
+ "hover:border-hairline-hover",
934
+ "focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent",
935
+ "disabled:pointer-events-none disabled:opacity-50",
936
+ "data-[state=checked]:border-accent",
937
+ className
938
+ ),
939
+ ...props,
940
+ children: /* @__PURE__ */ jsx(RadioGroupPrimitive.Indicator, { className: "flex size-full items-center justify-center", children: /* @__PURE__ */ jsx("span", { className: "rounded-pill bg-accent block size-2.5" }) })
941
+ }
942
+ );
943
+ }
944
+ var Select = SelectPrimitive.Root;
945
+ var SelectGroup = SelectPrimitive.Group;
946
+ var SelectValue = SelectPrimitive.Value;
947
+ function SelectTrigger({
948
+ className,
949
+ children,
950
+ ...props
951
+ }) {
952
+ return /* @__PURE__ */ jsxs(
953
+ SelectPrimitive.Trigger,
954
+ {
955
+ className: cn(
956
+ "gap-sm px-sm flex h-10 w-full cursor-pointer items-center justify-between",
957
+ "rounded-control border-border bg-surface border",
958
+ "font-sans text-ui text-text-primary",
959
+ "transition-standard",
960
+ "hover:border-hairline-hover",
961
+ "focus-visible:border-accent focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent",
962
+ "disabled:pointer-events-none disabled:opacity-50",
963
+ "data-[placeholder]:text-text-muted",
964
+ className
965
+ ),
966
+ ...props,
967
+ children: [
968
+ children,
969
+ /* @__PURE__ */ jsx(SelectPrimitive.Icon, { asChild: true, children: /* @__PURE__ */ jsx(ChevronDown, { className: "text-text-muted" }) })
970
+ ]
971
+ }
972
+ );
973
+ }
974
+ function SelectContent({
975
+ className,
976
+ children,
977
+ position = "popper",
978
+ ...props
979
+ }) {
980
+ return /* @__PURE__ */ jsx(SelectPrimitive.Portal, { children: /* @__PURE__ */ jsxs(
981
+ SelectPrimitive.Content,
982
+ {
983
+ position,
984
+ className: cn(
985
+ "relative z-50 max-h-96 min-w-32 overflow-hidden",
986
+ "rounded-panel border-border bg-surface-raised shadow-standard border",
987
+ "text-text-primary font-sans",
988
+ position === "popper" && "w-full min-w-[var(--radix-select-trigger-width)]",
989
+ className
990
+ ),
991
+ ...props,
992
+ children: [
993
+ /* @__PURE__ */ jsx(SelectPrimitive.ScrollUpButton, { className: "text-text-secondary flex h-6 items-center justify-center", children: /* @__PURE__ */ jsx(ChevronUp, {}) }),
994
+ /* @__PURE__ */ jsx(SelectPrimitive.Viewport, { className: "p-1", children }),
995
+ /* @__PURE__ */ jsx(SelectPrimitive.ScrollDownButton, { className: "text-text-secondary flex h-6 items-center justify-center", children: /* @__PURE__ */ jsx(ChevronDown, {}) })
996
+ ]
997
+ }
998
+ ) });
999
+ }
1000
+ function SelectLabel({
1001
+ className,
1002
+ ...props
1003
+ }) {
1004
+ return /* @__PURE__ */ jsx(
1005
+ SelectPrimitive.Label,
1006
+ {
1007
+ className: cn("px-sm text-eyebrow font-mono text-text-secondary py-1.5 uppercase", className),
1008
+ ...props
1009
+ }
1010
+ );
1011
+ }
1012
+ function SelectItem({
1013
+ className,
1014
+ children,
1015
+ ...props
1016
+ }) {
1017
+ return /* @__PURE__ */ jsxs(
1018
+ SelectPrimitive.Item,
1019
+ {
1020
+ className: cn(
1021
+ "rounded-chip px-sm relative flex h-9 w-full cursor-default items-center pr-8 select-none",
1022
+ "text-ui text-text-secondary transition-standard",
1023
+ "data-[highlighted]:bg-surface data-[highlighted]:text-text-primary",
1024
+ "data-[state=checked]:text-text-primary",
1025
+ "data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
1026
+ className
1027
+ ),
1028
+ ...props,
1029
+ children: [
1030
+ /* @__PURE__ */ jsx(SelectPrimitive.ItemText, { children }),
1031
+ /* @__PURE__ */ jsx(SelectPrimitive.ItemIndicator, { className: "text-accent absolute right-2 flex items-center", children: /* @__PURE__ */ jsx(Check, {}) })
1032
+ ]
1033
+ }
1034
+ );
1035
+ }
1036
+ function SelectSeparator({
1037
+ className,
1038
+ ...props
1039
+ }) {
1040
+ return /* @__PURE__ */ jsx(SelectPrimitive.Separator, { className: cn("bg-hairline my-1 h-px", className), ...props });
1041
+ }
1042
+ function Separator3({
1043
+ className,
1044
+ orientation = "horizontal",
1045
+ decorative = true,
1046
+ ...props
1047
+ }) {
1048
+ return /* @__PURE__ */ jsx(
1049
+ SeparatorPrimitive.Root,
1050
+ {
1051
+ orientation,
1052
+ decorative,
1053
+ className: cn(
1054
+ "bg-hairline shrink-0",
1055
+ orientation === "horizontal" ? "h-px w-full" : "h-full w-px",
1056
+ className
1057
+ ),
1058
+ ...props
1059
+ }
1060
+ );
1061
+ }
1062
+ var Sheet = DialogPrimitive.Root;
1063
+ var SheetTrigger = DialogPrimitive.Trigger;
1064
+ var SheetClose = DialogPrimitive.Close;
1065
+ var panel2 = cva(
1066
+ [
1067
+ "bg-surface border-border shadow-standard fixed z-50 flex flex-col",
1068
+ "text-text-primary font-sans outline-none"
1069
+ ],
1070
+ {
1071
+ variants: {
1072
+ side: {
1073
+ right: [
1074
+ "inset-y-0 right-0 h-full w-3/4 max-w-content border-l",
1075
+ "motion-safe:data-[state=open]:deslizar-entra-derecha",
1076
+ "motion-safe:data-[state=closed]:deslizar-sale-derecha"
1077
+ ],
1078
+ left: [
1079
+ "inset-y-0 left-0 h-full w-3/4 max-w-content border-r",
1080
+ "motion-safe:data-[state=open]:deslizar-entra-izquierda",
1081
+ "motion-safe:data-[state=closed]:deslizar-sale-izquierda"
1082
+ ],
1083
+ top: [
1084
+ "inset-x-0 top-0 border-b",
1085
+ "motion-safe:data-[state=open]:deslizar-entra-arriba",
1086
+ "motion-safe:data-[state=closed]:deslizar-sale-arriba"
1087
+ ],
1088
+ bottom: [
1089
+ "inset-x-0 bottom-0 border-t",
1090
+ "motion-safe:data-[state=open]:deslizar-entra-abajo",
1091
+ "motion-safe:data-[state=closed]:deslizar-sale-abajo"
1092
+ ]
1093
+ }
1094
+ },
1095
+ defaultVariants: { side: "right" }
1096
+ }
1097
+ );
1098
+ function SheetContent({ className, side, children, ...props }) {
1099
+ return /* @__PURE__ */ jsxs(DialogPrimitive.Portal, { children: [
1100
+ /* @__PURE__ */ jsx(DialogPrimitive.Overlay, { className: "bg-brand-hull/70 fixed inset-0 z-50" }),
1101
+ /* @__PURE__ */ jsxs(DialogPrimitive.Content, { className: cn(panel2({ side }), className), ...props, children: [
1102
+ children,
1103
+ /* @__PURE__ */ jsx(
1104
+ DialogPrimitive.Close,
1105
+ {
1106
+ "aria-label": "Cerrar",
1107
+ className: cn(
1108
+ "rounded-chip text-text-muted absolute top-4 right-4 flex size-8 cursor-pointer items-center justify-center",
1109
+ "transition-standard",
1110
+ "hover:bg-surface-raised hover:text-text-primary",
1111
+ "focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent"
1112
+ ),
1113
+ children: /* @__PURE__ */ jsx(Close, {})
1114
+ }
1115
+ )
1116
+ ] })
1117
+ ] });
1118
+ }
1119
+ function SheetHeader({ className, ...props }) {
1120
+ return /* @__PURE__ */ jsx(
1121
+ "div",
1122
+ {
1123
+ className: cn("border-hairline gap-xs p-lg flex flex-col border-b pr-12", className),
1124
+ ...props
1125
+ }
1126
+ );
1127
+ }
1128
+ function SheetBody({ className, ...props }) {
1129
+ return /* @__PURE__ */ jsx("div", { className: cn("p-lg flex-1 overflow-y-auto", className), ...props });
1130
+ }
1131
+ function SheetFooter({ className, ...props }) {
1132
+ return /* @__PURE__ */ jsx(
1133
+ "div",
1134
+ {
1135
+ className: cn("border-hairline gap-sm p-lg flex flex-wrap justify-end border-t", className),
1136
+ ...props
1137
+ }
1138
+ );
1139
+ }
1140
+ function SheetTitle({
1141
+ className,
1142
+ ...props
1143
+ }) {
1144
+ return /* @__PURE__ */ jsx(
1145
+ DialogPrimitive.Title,
1146
+ {
1147
+ className: cn("text-h3 font-display text-text-primary", className),
1148
+ ...props
1149
+ }
1150
+ );
1151
+ }
1152
+ function SheetDescription({
1153
+ className,
1154
+ ...props
1155
+ }) {
1156
+ return /* @__PURE__ */ jsx(
1157
+ DialogPrimitive.Description,
1158
+ {
1159
+ className: cn("text-ui text-text-secondary max-w-measure", className),
1160
+ ...props
1161
+ }
1162
+ );
1163
+ }
1164
+ function Skeleton({ className, still = false, ...props }) {
1165
+ return /* @__PURE__ */ jsx(
1166
+ "div",
1167
+ {
1168
+ "aria-hidden": "true",
1169
+ className: cn(
1170
+ "rounded-chip bg-surface-raised",
1171
+ !still && "motion-safe:shimmer",
1172
+ className
1173
+ ),
1174
+ ...props
1175
+ }
1176
+ );
1177
+ }
1178
+ function Switch({ className, ...props }) {
1179
+ return /* @__PURE__ */ jsx(
1180
+ SwitchPrimitive.Root,
1181
+ {
1182
+ className: cn(
1183
+ "rounded-pill border-border bg-surface-raised inline-flex h-6 w-11 shrink-0 cursor-pointer items-center border",
1184
+ "transition-standard",
1185
+ "hover:border-hairline-hover",
1186
+ "focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent",
1187
+ "disabled:pointer-events-none disabled:opacity-50",
1188
+ "data-[state=checked]:border-accent data-[state=checked]:bg-accent",
1189
+ className
1190
+ ),
1191
+ ...props,
1192
+ children: /* @__PURE__ */ jsx(
1193
+ SwitchPrimitive.Thumb,
1194
+ {
1195
+ className: cn(
1196
+ "rounded-pill bg-text-secondary pointer-events-none block size-4 translate-x-1",
1197
+ "data-[state=checked]:bg-accent-on data-[state=checked]:translate-x-6"
1198
+ )
1199
+ }
1200
+ )
1201
+ }
1202
+ );
1203
+ }
1204
+ function Table({ className, ...props }) {
1205
+ return /* @__PURE__ */ jsx("div", { className: "w-full overflow-x-auto", children: /* @__PURE__ */ jsx(
1206
+ "table",
1207
+ {
1208
+ className: cn("w-full caption-bottom border-collapse font-sans text-ui", className),
1209
+ ...props
1210
+ }
1211
+ ) });
1212
+ }
1213
+ function TableHeader({ className, ...props }) {
1214
+ return /* @__PURE__ */ jsx("thead", { className: cn("[&_tr]:border-hairline [&_tr]:border-b", className), ...props });
1215
+ }
1216
+ function TableBody({ className, ...props }) {
1217
+ return /* @__PURE__ */ jsx("tbody", { className, ...props });
1218
+ }
1219
+ function TableFooter({ className, ...props }) {
1220
+ return /* @__PURE__ */ jsx(
1221
+ "tfoot",
1222
+ {
1223
+ className: cn("border-hairline bg-surface text-text-secondary border-t", className),
1224
+ ...props
1225
+ }
1226
+ );
1227
+ }
1228
+ function TableRow({ className, ...props }) {
1229
+ return /* @__PURE__ */ jsx(
1230
+ "tr",
1231
+ {
1232
+ className: cn(
1233
+ "border-hairline transition-standard border-b last:border-b-0",
1234
+ "hover:bg-surface data-[state=selected]:bg-surface-raised",
1235
+ className
1236
+ ),
1237
+ ...props
1238
+ }
1239
+ );
1240
+ }
1241
+ function TableHead({ className, ...props }) {
1242
+ return /* @__PURE__ */ jsx(
1243
+ "th",
1244
+ {
1245
+ className: cn(
1246
+ "px-sm h-10 text-left align-middle",
1247
+ "text-eyebrow font-mono text-text-muted uppercase",
1248
+ className
1249
+ ),
1250
+ ...props
1251
+ }
1252
+ );
1253
+ }
1254
+ function TableCell({ className, ...props }) {
1255
+ return /* @__PURE__ */ jsx("td", { className: cn("px-sm py-sm text-text-secondary align-middle", className), ...props });
1256
+ }
1257
+ function TableCaption({ className, ...props }) {
1258
+ return /* @__PURE__ */ jsx("caption", { className: cn("mt-sm text-label text-text-muted", className), ...props });
1259
+ }
1260
+ function Tabs({ className, ...props }) {
1261
+ return /* @__PURE__ */ jsx(TabsPrimitive.Root, { className: cn("gap-md flex flex-col", className), ...props });
1262
+ }
1263
+ function TabsList({
1264
+ className,
1265
+ ...props
1266
+ }) {
1267
+ return /* @__PURE__ */ jsx(
1268
+ TabsPrimitive.List,
1269
+ {
1270
+ className: cn("rounded-control bg-surface gap-xs inline-flex items-center p-1", className),
1271
+ ...props
1272
+ }
1273
+ );
1274
+ }
1275
+ function TabsTrigger({
1276
+ className,
1277
+ ...props
1278
+ }) {
1279
+ return /* @__PURE__ */ jsx(
1280
+ TabsPrimitive.Trigger,
1281
+ {
1282
+ className: cn(
1283
+ "rounded-chip px-sm inline-flex h-8 cursor-pointer items-center justify-center whitespace-nowrap",
1284
+ "font-sans text-label text-text-secondary",
1285
+ "transition-standard",
1286
+ "hover:text-text-primary",
1287
+ "focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent",
1288
+ "disabled:pointer-events-none disabled:opacity-50",
1289
+ "data-[state=active]:bg-surface-raised data-[state=active]:text-text-primary",
1290
+ className
1291
+ ),
1292
+ ...props
1293
+ }
1294
+ );
1295
+ }
1296
+ function TabsContent({
1297
+ className,
1298
+ ...props
1299
+ }) {
1300
+ return /* @__PURE__ */ jsx(
1301
+ TabsPrimitive.Content,
1302
+ {
1303
+ className: cn(
1304
+ "focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent",
1305
+ className
1306
+ ),
1307
+ ...props
1308
+ }
1309
+ );
1310
+ }
1311
+ function Textarea({ className, invalid = false, ...props }) {
1312
+ return /* @__PURE__ */ jsx(
1313
+ "textarea",
1314
+ {
1315
+ "data-invalid": invalid || void 0,
1316
+ "aria-invalid": invalid || void 0,
1317
+ className: cn(
1318
+ "min-h-24 w-full px-sm py-xs",
1319
+ "rounded-control border border-border bg-surface",
1320
+ "font-sans text-ui text-text-primary placeholder:text-text-muted",
1321
+ "transition-standard",
1322
+ "hover:border-hairline-hover",
1323
+ "focus-visible:border-accent focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent",
1324
+ "disabled:pointer-events-none disabled:opacity-50",
1325
+ "data-[invalid]:border-error data-[invalid]:focus-visible:outline-error",
1326
+ className
1327
+ ),
1328
+ ...props
1329
+ }
1330
+ );
1331
+ }
1332
+ var ToastProvider = ToastPrimitive.Provider;
1333
+ var ToastAction = ToastPrimitive.Action;
1334
+ function ToastViewport({
1335
+ className,
1336
+ ...props
1337
+ }) {
1338
+ return /* @__PURE__ */ jsx(
1339
+ ToastPrimitive.Viewport,
1340
+ {
1341
+ className: cn(
1342
+ "gap-sm p-lg fixed right-0 bottom-0 z-50 flex max-h-screen w-full flex-col-reverse",
1343
+ "sm:max-w-[420px] sm:flex-col",
1344
+ className
1345
+ ),
1346
+ ...props
1347
+ }
1348
+ );
1349
+ }
1350
+ var toast = cva(
1351
+ [
1352
+ "gap-md p-md pr-10 relative flex w-full items-start justify-between",
1353
+ "rounded-card border bg-surface shadow-standard",
1354
+ "font-sans text-ui text-text-secondary"
1355
+ ],
1356
+ {
1357
+ variants: {
1358
+ variant: {
1359
+ neutral: "border-border",
1360
+ success: "border-success/40",
1361
+ error: "border-error/40"
1362
+ }
1363
+ },
1364
+ defaultVariants: { variant: "neutral" }
1365
+ }
1366
+ );
1367
+ function Toast({ className, variant, children, ...props }) {
1368
+ return /* @__PURE__ */ jsxs(ToastPrimitive.Root, { className: cn(toast({ variant }), className), ...props, children: [
1369
+ children,
1370
+ /* @__PURE__ */ jsx(
1371
+ ToastPrimitive.Close,
1372
+ {
1373
+ "aria-label": "Cerrar",
1374
+ className: cn(
1375
+ "rounded-chip text-text-muted absolute top-3 right-3 flex size-7 cursor-pointer items-center justify-center",
1376
+ "transition-standard",
1377
+ "hover:bg-surface-raised hover:text-text-primary",
1378
+ "focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent"
1379
+ ),
1380
+ children: /* @__PURE__ */ jsx(Close, {})
1381
+ }
1382
+ )
1383
+ ] });
1384
+ }
1385
+ function ToastTitle({
1386
+ className,
1387
+ ...props
1388
+ }) {
1389
+ return /* @__PURE__ */ jsx(
1390
+ ToastPrimitive.Title,
1391
+ {
1392
+ className: cn("text-text-primary mb-1 font-medium", className),
1393
+ ...props
1394
+ }
1395
+ );
1396
+ }
1397
+ function ToastDescription({
1398
+ className,
1399
+ ...props
1400
+ }) {
1401
+ return /* @__PURE__ */ jsx(ToastPrimitive.Description, { className: cn("max-w-measure", className), ...props });
1402
+ }
1403
+ var TooltipProvider = TooltipPrimitive.Provider;
1404
+ var Tooltip = TooltipPrimitive.Root;
1405
+ var TooltipTrigger = TooltipPrimitive.Trigger;
1406
+ function TooltipContent({
1407
+ className,
1408
+ sideOffset = 6,
1409
+ ...props
1410
+ }) {
1411
+ return /* @__PURE__ */ jsx(TooltipPrimitive.Portal, { children: /* @__PURE__ */ jsx(
1412
+ TooltipPrimitive.Content,
1413
+ {
1414
+ sideOffset,
1415
+ className: cn(
1416
+ "z-50 px-sm py-1.5",
1417
+ "rounded-chip border-border bg-surface-raised shadow-standard border",
1418
+ "font-sans text-label text-text-primary",
1419
+ className
1420
+ ),
1421
+ ...props
1422
+ }
1423
+ ) });
1424
+ }
1425
+ var TARJETA = [
1426
+ "group block cursor-pointer",
1427
+ SUPERFICIE_TARJETA,
1428
+ HOVER_TARJETA,
1429
+ "focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent"
1430
+ ];
1431
+ function Tarjeta({ asChild = false, className, children, ...props }) {
1432
+ const Raiz = asChild ? Slot : "a";
1433
+ return /* @__PURE__ */ jsx(Raiz, { className: cn(TARJETA, className), ...props, children });
1434
+ }
1435
+ function ArticleCard({
1436
+ title,
1437
+ excerpt,
1438
+ date,
1439
+ dateTime,
1440
+ readingMinutes,
1441
+ tags,
1442
+ className,
1443
+ ...props
1444
+ }) {
1445
+ const meta = [
1446
+ date ? /* @__PURE__ */ jsx("time", { dateTime, children: date }, "fecha") : null,
1447
+ readingMinutes ? /* @__PURE__ */ jsxs("span", { children: [
1448
+ readingMinutes,
1449
+ " min de lectura"
1450
+ ] }, "lectura") : null
1451
+ ].filter(Boolean);
1452
+ return /* @__PURE__ */ jsx(Tarjeta, { className: cn("p-lg", className), ...props, children: /* @__PURE__ */ jsxs("article", { className: "gap-sm flex h-full flex-col", children: [
1453
+ meta.length > 0 ? /* @__PURE__ */ jsx(Text, { variant: "meta", tone: "muted", as: "p", className: "gap-xs flex items-center", children: meta.map((m, i) => /* @__PURE__ */ jsxs("span", { className: "gap-xs flex items-center", children: [
1454
+ i > 0 ? /* @__PURE__ */ jsx("span", { "aria-hidden": "true", children: "\xB7" }) : null,
1455
+ m
1456
+ ] }, i)) }) : null,
1457
+ /* @__PURE__ */ jsx(Text, { as: "h3", variant: "h3", className: "group-hover:text-accent transition-standard", children: title }),
1458
+ excerpt ? /* @__PURE__ */ jsx(Text, { variant: "ui", tone: "secondary", className: "line-clamp-2", children: excerpt }) : null,
1459
+ tags && tags.length > 0 ? /* @__PURE__ */ jsx("div", { className: "gap-xs mt-auto flex flex-wrap pt-sm", children: tags.map((t) => /* @__PURE__ */ jsx(CategoryBadge, { children: t }, t)) }) : null
1460
+ ] }) });
1461
+ }
1462
+ var AVATAR = "size-[52px]";
1463
+ function iniciales(nombre) {
1464
+ return nombre.split(/\s+/).slice(0, 2).map((p) => p[0] ?? "").join("").toUpperCase();
1465
+ }
1466
+ function AuthorCard({ name, role, src, bio, action, className, ...props }) {
1467
+ return /* @__PURE__ */ jsxs("div", { className: cn(SUPERFICIE_TARJETA, "p-lg gap-md flex items-start", className), ...props, children: [
1468
+ /* @__PURE__ */ jsxs(Avatar, { className: cn(AVATAR, "shrink-0"), children: [
1469
+ src ? /* @__PURE__ */ jsx(AvatarImage, { src, alt: "" }) : null,
1470
+ /* @__PURE__ */ jsx(AvatarFallback, { children: iniciales(name) })
1471
+ ] }),
1472
+ /* @__PURE__ */ jsxs("div", { className: "gap-xs flex min-w-0 flex-1 flex-col", children: [
1473
+ /* @__PURE__ */ jsx(Text, { variant: "ui", as: "p", className: "font-medium", children: name }),
1474
+ role ? /* @__PURE__ */ jsx(Text, { variant: "chip", tone: "muted", as: "p", children: role }) : null,
1475
+ bio ? /* @__PURE__ */ jsx(Text, { variant: "ui", tone: "secondary", className: "mt-xs", children: bio }) : null,
1476
+ action ? /* @__PURE__ */ jsx("div", { className: "mt-xs gap-sm flex flex-wrap items-center", children: action }) : null
1477
+ ] })
1478
+ ] });
1479
+ }
1480
+ function formatTime(seconds) {
1481
+ if (isNaN(seconds) || !isFinite(seconds)) return "0:00";
1482
+ const mins = Math.floor(seconds / 60);
1483
+ const secs = Math.floor(seconds % 60);
1484
+ return `${mins}:${secs.toString().padStart(2, "0")}`;
1485
+ }
1486
+ var WAVEFORM_HEIGHTS = [35, 65, 100, 65, 35];
1487
+ var RATES = [1, 1.25, 1.5, 1.75, 2];
1488
+ function Onda({ grosor, alto, sonando }) {
1489
+ return /* @__PURE__ */ jsx("div", { className: cn("flex items-end gap-[2px]", alto), "aria-hidden": "true", children: WAVEFORM_HEIGHTS.map((h, i) => /* @__PURE__ */ jsx(
1490
+ "span",
1491
+ {
1492
+ className: cn("rounded-pill bg-accent transition-standard", grosor),
1493
+ style: { height: `${h}%`, opacity: sonando ? 1 : 0.3 + h / 100 * 0.4 }
1494
+ },
1495
+ i
1496
+ )) });
1497
+ }
1498
+ function BarraProgreso({
1499
+ alto,
1500
+ perilla,
1501
+ progreso,
1502
+ redondeada = true,
1503
+ tabIndex = 0,
1504
+ ...puntero
1505
+ }) {
1506
+ return /* @__PURE__ */ jsxs(
1507
+ "div",
1508
+ {
1509
+ className: cn(
1510
+ "group bg-surface-raised relative cursor-pointer",
1511
+ alto,
1512
+ redondeada && "rounded-pill"
1513
+ ),
1514
+ role: "slider",
1515
+ "aria-label": "Progreso del audio",
1516
+ "aria-valuemin": 0,
1517
+ "aria-valuemax": 100,
1518
+ "aria-valuenow": Math.round(progreso),
1519
+ tabIndex,
1520
+ ...puntero,
1521
+ children: [
1522
+ /* @__PURE__ */ jsx(
1523
+ "div",
1524
+ {
1525
+ className: cn("bg-accent absolute h-full", redondeada && "rounded-pill"),
1526
+ style: { width: `${progreso}%` }
1527
+ }
1528
+ ),
1529
+ /* @__PURE__ */ jsx(
1530
+ "div",
1531
+ {
1532
+ className: "rounded-pill bg-text-primary absolute top-1/2 -translate-y-1/2 opacity-0 transition-opacity group-hover:opacity-100",
1533
+ style: {
1534
+ width: perilla,
1535
+ height: perilla,
1536
+ left: `calc(${progreso}% - ${perilla / 2}px)`
1537
+ }
1538
+ }
1539
+ )
1540
+ ]
1541
+ }
1542
+ );
1543
+ }
1544
+ var CONTROL = "rounded-chip transition-standard cursor-pointer focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent";
1545
+ function BotonSalto({
1546
+ segundos,
1547
+ className,
1548
+ tamano,
1549
+ onSaltar
1550
+ }) {
1551
+ return /* @__PURE__ */ jsx(
1552
+ "button",
1553
+ {
1554
+ type: "button",
1555
+ onClick: () => onSaltar(segundos),
1556
+ className: cn("text-text-muted hover:text-text-primary", CONTROL, className),
1557
+ "aria-label": segundos < 0 ? "Retroceder 15 segundos" : "Adelantar 15 segundos",
1558
+ children: segundos < 0 ? /* @__PURE__ */ jsx(GoBackSeconds, { className: tamano }) : /* @__PURE__ */ jsx(AdvanceSeconds, { className: tamano })
1559
+ }
1560
+ );
1561
+ }
1562
+ function BotonVelocidad({
1563
+ className,
1564
+ velocidad,
1565
+ onCambiar
1566
+ }) {
1567
+ return /* @__PURE__ */ jsxs(
1568
+ "button",
1569
+ {
1570
+ type: "button",
1571
+ onClick: onCambiar,
1572
+ className: cn(
1573
+ // `textMuted` sobre `surfaceRaised` da 4.07:1 en oscuro y no pasa AA.
1574
+ // El original del portafolio arrastra ese mismo fallo.
1575
+ "text-text-secondary hover:text-text-primary bg-surface-raised",
1576
+ CONTROL,
1577
+ className
1578
+ ),
1579
+ "aria-label": "Cambiar velocidad de reproducci\xF3n",
1580
+ children: [
1581
+ velocidad,
1582
+ "x"
1583
+ ]
1584
+ }
1585
+ );
1586
+ }
1587
+ function Volumen({
1588
+ tamano,
1589
+ ancho,
1590
+ silenciado,
1591
+ volumen,
1592
+ onSilenciar,
1593
+ onCambiarVolumen
1594
+ }) {
1595
+ return /* @__PURE__ */ jsxs("div", { className: "gap-xs hidden items-center sm:flex", children: [
1596
+ /* @__PURE__ */ jsx(
1597
+ "button",
1598
+ {
1599
+ type: "button",
1600
+ onClick: onSilenciar,
1601
+ className: cn("text-text-muted hover:text-text-primary p-1", CONTROL),
1602
+ "aria-label": silenciado ? "Activar sonido" : "Silenciar",
1603
+ children: silenciado || volumen === 0 ? /* @__PURE__ */ jsx(VolumeMuted, { className: tamano }) : /* @__PURE__ */ jsx(VolumeOn, { className: tamano })
1604
+ }
1605
+ ),
1606
+ /* @__PURE__ */ jsx(
1607
+ "input",
1608
+ {
1609
+ type: "range",
1610
+ min: "0",
1611
+ max: "1",
1612
+ step: "0.1",
1613
+ value: silenciado ? 0 : volumen,
1614
+ onChange: onCambiarVolumen,
1615
+ className: cn(
1616
+ "bg-surface-raised rounded-pill h-1 cursor-pointer appearance-none",
1617
+ "[accent-color:var(--color-accent)]",
1618
+ ancho
1619
+ ),
1620
+ "aria-label": "Volumen"
1621
+ }
1622
+ )
1623
+ ] });
1624
+ }
1625
+ function IconoPlay({ className, cargando, error, sonando }) {
1626
+ if (cargando) return /* @__PURE__ */ jsx(Spinner, { className: cn("motion-safe:animate-spin", className) });
1627
+ if (error) return /* @__PURE__ */ jsx(Retry, { className });
1628
+ if (sonando) return /* @__PURE__ */ jsx(Pause, { className });
1629
+ return /* @__PURE__ */ jsx(Play, { className });
1630
+ }
1631
+ function BotonPlay({
1632
+ className,
1633
+ tamano,
1634
+ etiqueta,
1635
+ texto: texto2,
1636
+ onAlternar,
1637
+ ...estado
1638
+ }) {
1639
+ return /* @__PURE__ */ jsxs(
1640
+ "button",
1641
+ {
1642
+ type: "button",
1643
+ onClick: onAlternar,
1644
+ className: cn(
1645
+ "text-accent-on transition-standard cursor-pointer",
1646
+ "focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent",
1647
+ estado.error ? "bg-error hover:bg-error/80" : "bg-accent hover:bg-accent-hover",
1648
+ className
1649
+ ),
1650
+ "aria-label": etiqueta,
1651
+ children: [
1652
+ /* @__PURE__ */ jsx(IconoPlay, { className: tamano, ...estado }),
1653
+ texto2 ? /* @__PURE__ */ jsx("span", { children: texto2 }) : null
1654
+ ]
1655
+ }
1656
+ );
1657
+ }
1658
+ function AudioPlayer({ src, title, mode = "full", onFirstPlay }) {
1659
+ const audioRef = useRef(null);
1660
+ const staticRef = useRef(null);
1661
+ const isDragging = useRef(false);
1662
+ const hasTrackedPlay = useRef(false);
1663
+ const [isPlaying, setIsPlaying] = useState(false);
1664
+ const [currentTime, setCurrentTime] = useState(0);
1665
+ const [duration, setDuration] = useState(0);
1666
+ const [isLoading, setIsLoading] = useState(false);
1667
+ const [hasError, setHasError] = useState(false);
1668
+ const [volume, setVolume] = useState(1);
1669
+ const [isMuted, setIsMuted] = useState(false);
1670
+ const [playbackRate, setPlaybackRate] = useState(1);
1671
+ const [isStaticVisible, setIsStaticVisible] = useState(true);
1672
+ const flotante = mode === "banner" || mode === "compact";
1673
+ useEffect(() => {
1674
+ const audio = audioRef.current;
1675
+ if (!audio) return;
1676
+ const handleTimeUpdate = () => setCurrentTime(audio.currentTime);
1677
+ const handleLoadedMetadata = () => {
1678
+ setDuration(audio.duration);
1679
+ setIsLoading(false);
1680
+ setHasError(false);
1681
+ };
1682
+ const handleEnded = () => setIsPlaying(false);
1683
+ const handleWaiting = () => setIsLoading(true);
1684
+ const handleCanPlay = () => setIsLoading(false);
1685
+ const handleError = () => {
1686
+ setIsLoading(false);
1687
+ setHasError(true);
1688
+ setIsPlaying(false);
1689
+ };
1690
+ const handlePlaying = () => {
1691
+ setIsLoading(false);
1692
+ setHasError(false);
1693
+ };
1694
+ audio.addEventListener("timeupdate", handleTimeUpdate);
1695
+ audio.addEventListener("loadedmetadata", handleLoadedMetadata);
1696
+ audio.addEventListener("ended", handleEnded);
1697
+ audio.addEventListener("waiting", handleWaiting);
1698
+ audio.addEventListener("canplay", handleCanPlay);
1699
+ audio.addEventListener("error", handleError);
1700
+ audio.addEventListener("playing", handlePlaying);
1701
+ if (audio.readyState >= HTMLMediaElement.HAVE_METADATA) {
1702
+ setDuration(audio.duration);
1703
+ }
1704
+ return () => {
1705
+ audio.removeEventListener("timeupdate", handleTimeUpdate);
1706
+ audio.removeEventListener("loadedmetadata", handleLoadedMetadata);
1707
+ audio.removeEventListener("ended", handleEnded);
1708
+ audio.removeEventListener("waiting", handleWaiting);
1709
+ audio.removeEventListener("canplay", handleCanPlay);
1710
+ audio.removeEventListener("error", handleError);
1711
+ audio.removeEventListener("playing", handlePlaying);
1712
+ };
1713
+ }, []);
1714
+ useEffect(() => {
1715
+ if (!flotante || !staticRef.current) return;
1716
+ const observer = new IntersectionObserver(
1717
+ (entries) => {
1718
+ const entry = entries[0];
1719
+ if (entry) setIsStaticVisible(entry.isIntersecting);
1720
+ },
1721
+ { threshold: 0.1 }
1722
+ );
1723
+ observer.observe(staticRef.current);
1724
+ return () => observer.disconnect();
1725
+ }, [flotante]);
1726
+ const togglePlay = useCallback(async () => {
1727
+ const audio = audioRef.current;
1728
+ if (!audio) return;
1729
+ if (isPlaying) {
1730
+ audio.pause();
1731
+ setIsPlaying(false);
1732
+ } else {
1733
+ setIsLoading(true);
1734
+ setHasError(false);
1735
+ try {
1736
+ await audio.play();
1737
+ setIsPlaying(true);
1738
+ if (!hasTrackedPlay.current) {
1739
+ hasTrackedPlay.current = true;
1740
+ onFirstPlay?.(title);
1741
+ }
1742
+ } catch {
1743
+ setHasError(true);
1744
+ setIsPlaying(false);
1745
+ } finally {
1746
+ setIsLoading(false);
1747
+ }
1748
+ }
1749
+ }, [isPlaying, onFirstPlay, title]);
1750
+ const seekTo = useCallback(
1751
+ (e) => {
1752
+ const audio = audioRef.current;
1753
+ if (!audio) return;
1754
+ const rect = e.currentTarget.getBoundingClientRect();
1755
+ const position = Math.max(0, Math.min(1, (e.clientX - rect.left) / rect.width));
1756
+ audio.currentTime = position * duration;
1757
+ },
1758
+ [duration]
1759
+ );
1760
+ const handlePointerDown = useCallback(
1761
+ (e) => {
1762
+ e.currentTarget.setPointerCapture(e.pointerId);
1763
+ isDragging.current = true;
1764
+ seekTo(e);
1765
+ },
1766
+ [seekTo]
1767
+ );
1768
+ const handlePointerMove = useCallback(
1769
+ (e) => {
1770
+ if (!isDragging.current) return;
1771
+ seekTo(e);
1772
+ },
1773
+ [seekTo]
1774
+ );
1775
+ const handlePointerUp = useCallback((e) => {
1776
+ e.currentTarget.releasePointerCapture(e.pointerId);
1777
+ isDragging.current = false;
1778
+ }, []);
1779
+ const handleVolumeChange = useCallback((e) => {
1780
+ const audio = audioRef.current;
1781
+ if (!audio) return;
1782
+ const newVolume = parseFloat(e.target.value);
1783
+ setVolume(newVolume);
1784
+ audio.volume = newVolume;
1785
+ setIsMuted(newVolume === 0);
1786
+ }, []);
1787
+ const toggleMute = useCallback(() => {
1788
+ const audio = audioRef.current;
1789
+ if (!audio) return;
1790
+ if (isMuted) {
1791
+ audio.volume = volume || 1;
1792
+ setIsMuted(false);
1793
+ } else {
1794
+ audio.volume = 0;
1795
+ setIsMuted(true);
1796
+ }
1797
+ }, [isMuted, volume]);
1798
+ const handlePlaybackRateChange = useCallback(() => {
1799
+ const audio = audioRef.current;
1800
+ if (!audio) return;
1801
+ const nextRate = RATES[(RATES.indexOf(playbackRate) + 1) % RATES.length] ?? 1;
1802
+ audio.playbackRate = nextRate;
1803
+ setPlaybackRate(nextRate);
1804
+ }, [playbackRate]);
1805
+ const skip = useCallback(
1806
+ (seconds) => {
1807
+ const audio = audioRef.current;
1808
+ if (!audio) return;
1809
+ audio.currentTime = Math.max(0, Math.min(audio.currentTime + seconds, duration));
1810
+ },
1811
+ [duration]
1812
+ );
1813
+ const progress = duration > 0 ? currentTime / duration * 100 : 0;
1814
+ const etiquetaPlay = hasError ? "Reintentar" : isPlaying ? "Pausar" : "Reproducir";
1815
+ const estadoPlay = { cargando: isLoading, error: hasError, sonando: isPlaying };
1816
+ const puntero = {
1817
+ onPointerDown: handlePointerDown,
1818
+ onPointerMove: handlePointerMove,
1819
+ onPointerUp: handlePointerUp
1820
+ };
1821
+ const flotanteJsx = /* @__PURE__ */ jsxs(
1822
+ "div",
1823
+ {
1824
+ "aria-hidden": isStaticVisible,
1825
+ className: cn(
1826
+ "fixed inset-x-0 bottom-0 z-40 xl:hidden",
1827
+ // Aparece y desaparece: el sistema no anima desplazamiento.
1828
+ isStaticVisible && "hidden"
1829
+ ),
1830
+ children: [
1831
+ /* @__PURE__ */ jsx(
1832
+ BarraProgreso,
1833
+ {
1834
+ alto: "h-1",
1835
+ perilla: 10,
1836
+ progreso: progress,
1837
+ redondeada: false,
1838
+ tabIndex: -1,
1839
+ ...puntero
1840
+ }
1841
+ ),
1842
+ /* @__PURE__ */ jsx("div", { className: "bg-surface/95 border-accent/25 border-t backdrop-blur-md", children: /* @__PURE__ */ jsxs("div", { className: "gap-sm px-md flex items-center py-5", children: [
1843
+ /* @__PURE__ */ jsxs("div", { className: "gap-xs flex shrink-0 items-center", children: [
1844
+ /* @__PURE__ */ jsx(Onda, { grosor: "w-[2px]", alto: "h-4", sonando: isPlaying }),
1845
+ /* @__PURE__ */ jsx("span", { className: "text-eyebrow font-mono text-accent hidden uppercase sm:block", children: "Narraci\xF3n" })
1846
+ ] }),
1847
+ /* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
1848
+ title ? /* @__PURE__ */ jsx("p", { className: "text-label font-sans text-text-secondary truncate", children: title }) : null,
1849
+ /* @__PURE__ */ jsxs("p", { className: "text-chip font-mono text-text-muted tabular-nums", children: [
1850
+ formatTime(currentTime),
1851
+ " / ",
1852
+ formatTime(duration)
1853
+ ] })
1854
+ ] }),
1855
+ /* @__PURE__ */ jsxs("div", { className: "flex shrink-0 items-center gap-1", children: [
1856
+ /* @__PURE__ */ jsx(BotonSalto, { segundos: -15, className: "p-1.5", tamano: "w-5 h-5", onSaltar: skip }),
1857
+ /* @__PURE__ */ jsx(
1858
+ BotonPlay,
1859
+ {
1860
+ className: "rounded-pill px-sm gap-xs flex items-center py-1.5",
1861
+ tamano: "w-4 h-4",
1862
+ etiqueta: etiquetaPlay,
1863
+ onAlternar: togglePlay,
1864
+ ...estadoPlay
1865
+ }
1866
+ ),
1867
+ /* @__PURE__ */ jsx(BotonSalto, { segundos: 15, className: "p-1.5", tamano: "w-5 h-5", onSaltar: skip }),
1868
+ /* @__PURE__ */ jsx(
1869
+ BotonVelocidad,
1870
+ {
1871
+ className: "text-label ml-0.5 px-1.5 py-0.5",
1872
+ velocidad: playbackRate,
1873
+ onCambiar: handlePlaybackRateChange
1874
+ }
1875
+ )
1876
+ ] })
1877
+ ] }) })
1878
+ ]
1879
+ }
1880
+ );
1881
+ if (mode === "banner") {
1882
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
1883
+ /* @__PURE__ */ jsx("audio", { ref: audioRef, src, preload: "metadata" }),
1884
+ /* @__PURE__ */ jsxs("div", { ref: staticRef, children: [
1885
+ /* @__PURE__ */ jsxs("div", { className: "gap-sm mb-md flex items-center", children: [
1886
+ /* @__PURE__ */ jsx(Onda, { grosor: "w-[3px]", alto: "h-5", sonando: isPlaying }),
1887
+ /* @__PURE__ */ jsx("span", { className: "text-eyebrow font-mono text-accent uppercase", children: "Narraci\xF3n de audio" }),
1888
+ /* @__PURE__ */ jsxs("span", { className: "text-chip font-mono text-text-muted ml-auto tabular-nums", children: [
1889
+ formatTime(currentTime),
1890
+ " / ",
1891
+ formatTime(duration)
1892
+ ] })
1893
+ ] }),
1894
+ /* @__PURE__ */ jsx("div", { className: "mb-md", children: /* @__PURE__ */ jsx(BarraProgreso, { alto: "h-1.5", perilla: 14, progreso: progress, ...puntero }) }),
1895
+ /* @__PURE__ */ jsxs("div", { className: "gap-sm flex items-center", children: [
1896
+ /* @__PURE__ */ jsx(BotonSalto, { segundos: -15, className: "p-2", tamano: "w-6 h-6", onSaltar: skip }),
1897
+ /* @__PURE__ */ jsx(
1898
+ BotonPlay,
1899
+ {
1900
+ className: "rounded-pill px-lg gap-xs text-ui flex items-center py-2 font-medium",
1901
+ tamano: "w-4 h-4",
1902
+ etiqueta: etiquetaPlay,
1903
+ texto: etiquetaPlay,
1904
+ onAlternar: togglePlay,
1905
+ ...estadoPlay
1906
+ }
1907
+ ),
1908
+ /* @__PURE__ */ jsx(BotonSalto, { segundos: 15, className: "p-2", tamano: "w-6 h-6", onSaltar: skip }),
1909
+ /* @__PURE__ */ jsxs("div", { className: "gap-sm ml-auto flex items-center", children: [
1910
+ /* @__PURE__ */ jsx(
1911
+ BotonVelocidad,
1912
+ {
1913
+ className: "text-label px-2 py-1",
1914
+ velocidad: playbackRate,
1915
+ onCambiar: handlePlaybackRateChange
1916
+ }
1917
+ ),
1918
+ /* @__PURE__ */ jsx(
1919
+ Volumen,
1920
+ {
1921
+ tamano: "w-4 h-4",
1922
+ ancho: "w-16",
1923
+ silenciado: isMuted,
1924
+ volumen: volume,
1925
+ onSilenciar: toggleMute,
1926
+ onCambiarVolumen: handleVolumeChange
1927
+ }
1928
+ )
1929
+ ] })
1930
+ ] })
1931
+ ] }),
1932
+ flotanteJsx
1933
+ ] });
1934
+ }
1935
+ if (mode === "compact") {
1936
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
1937
+ /* @__PURE__ */ jsx("audio", { ref: audioRef, src, preload: "metadata" }),
1938
+ /* @__PURE__ */ jsxs("div", { ref: staticRef, className: "w-full", children: [
1939
+ /* @__PURE__ */ jsx("div", { className: "mb-xs", children: /* @__PURE__ */ jsx(BarraProgreso, { alto: "h-1.5", perilla: 12, progreso: progress, ...puntero }) }),
1940
+ /* @__PURE__ */ jsxs("div", { className: "text-chip font-mono text-text-muted mb-sm flex justify-between", children: [
1941
+ /* @__PURE__ */ jsx("span", { children: formatTime(currentTime) }),
1942
+ /* @__PURE__ */ jsx("span", { children: formatTime(duration) })
1943
+ ] }),
1944
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
1945
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", children: [
1946
+ /* @__PURE__ */ jsx(BotonSalto, { segundos: -15, className: "p-1.5", tamano: "w-5 h-5", onSaltar: skip }),
1947
+ /* @__PURE__ */ jsx(
1948
+ BotonPlay,
1949
+ {
1950
+ className: "rounded-pill flex size-[34px] items-center justify-center",
1951
+ tamano: "w-4 h-4",
1952
+ etiqueta: etiquetaPlay,
1953
+ onAlternar: togglePlay,
1954
+ ...estadoPlay
1955
+ }
1956
+ ),
1957
+ /* @__PURE__ */ jsx(BotonSalto, { segundos: 15, className: "p-1.5", tamano: "w-5 h-5", onSaltar: skip })
1958
+ ] }),
1959
+ /* @__PURE__ */ jsx(
1960
+ BotonVelocidad,
1961
+ {
1962
+ className: "text-label px-1.5 py-0.5",
1963
+ velocidad: playbackRate,
1964
+ onCambiar: handlePlaybackRateChange
1965
+ }
1966
+ )
1967
+ ] })
1968
+ ] }),
1969
+ flotanteJsx
1970
+ ] });
1971
+ }
1972
+ return /* @__PURE__ */ jsxs("div", { className: "bg-surface rounded-control border-border p-md w-full border", children: [
1973
+ /* @__PURE__ */ jsx("audio", { ref: audioRef, src, preload: "metadata" }),
1974
+ title ? /* @__PURE__ */ jsx("p", { className: "text-ui font-sans text-text-secondary mb-sm truncate", children: title }) : null,
1975
+ /* @__PURE__ */ jsx("div", { className: "mb-sm", children: /* @__PURE__ */ jsx(BarraProgreso, { alto: "h-2", perilla: 16, progreso: progress, ...puntero }) }),
1976
+ /* @__PURE__ */ jsxs("div", { className: "text-chip font-mono text-text-muted mb-sm flex justify-between", children: [
1977
+ /* @__PURE__ */ jsx("span", { children: formatTime(currentTime) }),
1978
+ /* @__PURE__ */ jsx("span", { children: formatTime(duration) })
1979
+ ] }),
1980
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
1981
+ /* @__PURE__ */ jsxs("div", { className: "gap-xs flex items-center", children: [
1982
+ /* @__PURE__ */ jsx(BotonSalto, { segundos: -15, className: "p-2", tamano: "w-5 h-5", onSaltar: skip }),
1983
+ /* @__PURE__ */ jsx(
1984
+ BotonPlay,
1985
+ {
1986
+ className: "rounded-pill flex size-12 items-center justify-center",
1987
+ tamano: "w-6 h-6",
1988
+ etiqueta: etiquetaPlay,
1989
+ onAlternar: togglePlay,
1990
+ ...estadoPlay
1991
+ }
1992
+ ),
1993
+ /* @__PURE__ */ jsx(BotonSalto, { segundos: 15, className: "p-2", tamano: "w-5 h-5", onSaltar: skip })
1994
+ ] }),
1995
+ /* @__PURE__ */ jsxs("div", { className: "gap-sm flex items-center", children: [
1996
+ /* @__PURE__ */ jsx(
1997
+ BotonVelocidad,
1998
+ {
1999
+ className: "text-label px-2 py-1",
2000
+ velocidad: playbackRate,
2001
+ onCambiar: handlePlaybackRateChange
2002
+ }
2003
+ ),
2004
+ /* @__PURE__ */ jsx(
2005
+ Volumen,
2006
+ {
2007
+ tamano: "w-5 h-5",
2008
+ ancho: "w-20",
2009
+ silenciado: isMuted,
2010
+ volumen: volume,
2011
+ onSilenciar: toggleMute,
2012
+ onCambiarVolumen: handleVolumeChange
2013
+ }
2014
+ )
2015
+ ] })
2016
+ ] })
2017
+ ] });
2018
+ }
2019
+ function Blockquote({ children, author, source, className, ...props }) {
2020
+ return /* @__PURE__ */ jsxs(
2021
+ "blockquote",
2022
+ {
2023
+ className: cn("border-accent pl-md my-lg border-l-2", className),
2024
+ ...props,
2025
+ children: [
2026
+ /* @__PURE__ */ jsx(Text, { variant: "body", tone: "secondary", children }),
2027
+ author || source ? /* @__PURE__ */ jsx("footer", { className: "mt-sm", children: /* @__PURE__ */ jsxs(Text, { variant: "label", tone: "muted", as: "span", children: [
2028
+ author ? /* @__PURE__ */ jsx("cite", { className: "not-italic", children: author }) : null,
2029
+ author && source ? " \xB7 " : null,
2030
+ source
2031
+ ] }) }) : null
2032
+ ]
2033
+ }
2034
+ );
2035
+ }
2036
+ var ENLACE = "transition-standard hover:text-accent focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent rounded-chip cursor-pointer";
2037
+ function Breadcrumb({
2038
+ items,
2039
+ homeHref = "/",
2040
+ homeLabel = "Inicio",
2041
+ linkAsChild,
2042
+ className,
2043
+ ...props
2044
+ }) {
2045
+ const enlace = (href, contenido) => linkAsChild ? /* @__PURE__ */ jsx(Slot, { className: ENLACE, children: linkAsChild({ href, children: contenido }) }) : /* @__PURE__ */ jsx("a", { href, className: ENLACE, children: contenido });
2046
+ return /* @__PURE__ */ jsx("nav", { "aria-label": "Ruta", className: cn("font-mono text-meta text-text-muted", className), ...props, children: /* @__PURE__ */ jsxs("ol", { className: "gap-xs flex flex-wrap items-center", children: [
2047
+ /* @__PURE__ */ jsx("li", { children: enlace(homeHref, /* @__PURE__ */ jsx("span", { "aria-label": homeLabel, children: "~" })) }),
2048
+ items.map((item2, i) => {
2049
+ const ultimo = i === items.length - 1;
2050
+ return /* @__PURE__ */ jsxs("li", { className: "gap-xs flex items-center", children: [
2051
+ /* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: "text-border", children: "/" }),
2052
+ item2.href && !ultimo ? enlace(item2.href, item2.label) : /* @__PURE__ */ jsx("span", { "aria-current": ultimo ? "page" : void 0, className: "text-text-secondary", children: item2.label })
2053
+ ] }, i);
2054
+ })
2055
+ ] }) });
2056
+ }
2057
+ function CodeBlock({ children, language, copyText, className, ...props }) {
2058
+ const [copiado, setCopiado] = useState(false);
2059
+ const temporizador = useRef(null);
2060
+ const copiar = useCallback(async () => {
2061
+ if (!copyText) return;
2062
+ try {
2063
+ await navigator.clipboard.writeText(copyText);
2064
+ setCopiado(true);
2065
+ if (temporizador.current) clearTimeout(temporizador.current);
2066
+ temporizador.current = setTimeout(() => setCopiado(false), 2e3);
2067
+ } catch {
2068
+ }
2069
+ }, [copyText]);
2070
+ return /* @__PURE__ */ jsxs(
2071
+ "div",
2072
+ {
2073
+ "data-theme": "dark",
2074
+ className: cn(
2075
+ "rounded-card border-hairline bg-brand-hull overflow-hidden border",
2076
+ className
2077
+ ),
2078
+ ...props,
2079
+ children: [
2080
+ /* @__PURE__ */ jsxs("div", { className: "border-hairline px-sm flex items-center justify-between border-b py-1.5", children: [
2081
+ /* @__PURE__ */ jsxs("span", { className: "text-eyebrow font-mono text-text-muted uppercase", children: [
2082
+ /* @__PURE__ */ jsx("span", { className: "text-accent", children: "\u276F" }),
2083
+ " ",
2084
+ language ?? "c\xF3digo"
2085
+ ] }),
2086
+ copyText ? /* @__PURE__ */ jsxs(
2087
+ "button",
2088
+ {
2089
+ type: "button",
2090
+ onClick: copiar,
2091
+ "aria-label": copiado ? "C\xF3digo copiado" : "Copiar c\xF3digo",
2092
+ "aria-live": "polite",
2093
+ className: cn(
2094
+ "gap-xs rounded-chip flex items-center px-2 py-1",
2095
+ "text-label font-mono text-text-muted cursor-pointer",
2096
+ "transition-standard hover:bg-surface hover:text-text-primary",
2097
+ "focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent"
2098
+ ),
2099
+ children: [
2100
+ copiado ? /* @__PURE__ */ jsx(Check, { className: "text-accent" }) : /* @__PURE__ */ jsx(Copy, {}),
2101
+ copiado ? "Copiado" : "Copiar"
2102
+ ]
2103
+ }
2104
+ ) : null
2105
+ ] }),
2106
+ /* @__PURE__ */ jsx("pre", { className: "p-md font-mono text-meta text-text-primary overflow-x-auto leading-relaxed", children })
2107
+ ]
2108
+ }
2109
+ );
2110
+ }
2111
+ function CourseCard({
2112
+ title,
2113
+ summary,
2114
+ meta,
2115
+ status,
2116
+ progress,
2117
+ className,
2118
+ ...props
2119
+ }) {
2120
+ return /* @__PURE__ */ jsx(Tarjeta, { className: cn("p-lg", className), ...props, children: /* @__PURE__ */ jsxs("article", { className: "gap-sm flex h-full flex-col", children: [
2121
+ status ? /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(Badge, { variant: "warm", children: status }) }) : null,
2122
+ /* @__PURE__ */ jsx(Text, { as: "h3", variant: "h3", className: "group-hover:text-accent transition-standard", children: title }),
2123
+ summary ? /* @__PURE__ */ jsx(Text, { variant: "ui", tone: "secondary", className: "line-clamp-3", children: summary }) : null,
2124
+ meta && meta.length > 0 ? /* @__PURE__ */ jsx(Text, { variant: "label", tone: "muted", as: "p", className: "gap-xs flex flex-wrap items-center", children: meta.map((m, i) => /* @__PURE__ */ jsxs("span", { className: "gap-xs flex items-center", children: [
2125
+ i > 0 ? /* @__PURE__ */ jsx("span", { "aria-hidden": "true", children: "\xB7" }) : null,
2126
+ m
2127
+ ] }, i)) }) : null,
2128
+ typeof progress === "number" ? /* @__PURE__ */ jsxs("div", { className: "gap-xs mt-auto flex flex-col pt-sm", children: [
2129
+ /* @__PURE__ */ jsx(Progress, { value: progress, tone: "warm", label: `Progreso del curso: ${progress}%` }),
2130
+ /* @__PURE__ */ jsxs(Text, { variant: "label", tone: "muted", as: "p", children: [
2131
+ progress,
2132
+ "% cursado"
2133
+ ] })
2134
+ ] }) : null
2135
+ ] }) });
2136
+ }
2137
+ var CARA = "w-[66px] max-w-none";
2138
+ function EmptyState({
2139
+ expresion,
2140
+ title,
2141
+ description,
2142
+ action,
2143
+ basePath,
2144
+ className,
2145
+ ...props
2146
+ }) {
2147
+ return /* @__PURE__ */ jsxs(
2148
+ "div",
2149
+ {
2150
+ className: cn(SUPERFICIE_TARJETA, "p-lg gap-sm flex flex-col items-center text-center", className),
2151
+ ...props,
2152
+ children: [
2153
+ /* @__PURE__ */ jsx(CaraDeMascota, { expresion, className: CARA, basePath }),
2154
+ /* @__PURE__ */ jsx(Text, { variant: "ui", as: "p", className: "font-medium", children: title }),
2155
+ description ? /* @__PURE__ */ jsx(Text, { variant: "label", tone: "muted", as: "p", className: "max-w-measure font-normal", children: description }) : null,
2156
+ action ? /* @__PURE__ */ jsx("div", { className: "mt-xs", children: action }) : null
2157
+ ]
2158
+ }
2159
+ );
2160
+ }
2161
+ function Footer({
2162
+ social,
2163
+ year = (/* @__PURE__ */ new Date()).getFullYear(),
2164
+ children,
2165
+ className,
2166
+ ...props
2167
+ }) {
2168
+ return /* @__PURE__ */ jsx("footer", { className: cn("border-hairline w-full border-t", className), ...props, children: /* @__PURE__ */ jsxs("div", { className: "max-w-wide px-md py-xl gap-lg mx-auto flex flex-col", children: [
2169
+ children ? /* @__PURE__ */ jsx("div", { className: "gap-md flex flex-wrap items-center", children }) : null,
2170
+ social && social.length > 0 ? (
2171
+ // 18px de separación, del documento. No es un escalón de `spacing`:
2172
+ // es el ritmo de una fila de iconos, no el de una página.
2173
+ /* @__PURE__ */ jsx("ul", { className: "flex items-center gap-[18px]", children: social.map((red) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx(
2174
+ "a",
2175
+ {
2176
+ href: red.href,
2177
+ "aria-label": red.label,
2178
+ className: cn(
2179
+ "text-text-muted hover:text-accent transition-standard block cursor-pointer text-[19px]",
2180
+ "rounded-chip focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent"
2181
+ ),
2182
+ children: red.icon
2183
+ }
2184
+ ) }, red.href)) })
2185
+ ) : null,
2186
+ /* @__PURE__ */ jsxs(Text, { variant: "meta", tone: "muted", as: "p", children: [
2187
+ /* @__PURE__ */ jsxs("span", { "aria-hidden": "true", className: "text-accent", children: [
2188
+ "$",
2189
+ " "
2190
+ ] }),
2191
+ "cd ~/",
2192
+ naming.domain,
2193
+ "/",
2194
+ year
2195
+ ] })
2196
+ ] }) });
2197
+ }
2198
+ function FooterLink({ asChild = false, className, ...props }) {
2199
+ const Raiz = asChild ? Slot : "a";
2200
+ return /* @__PURE__ */ jsx(
2201
+ Raiz,
2202
+ {
2203
+ className: cn(
2204
+ "font-mono text-meta text-text-secondary hover:text-accent transition-standard cursor-pointer",
2205
+ "rounded-chip focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent",
2206
+ className
2207
+ ),
2208
+ ...props
2209
+ }
2210
+ );
2211
+ }
2212
+ function Hero({
2213
+ title,
2214
+ eyebrow,
2215
+ description,
2216
+ action,
2217
+ pose,
2218
+ basePath,
2219
+ className,
2220
+ ...props
2221
+ }) {
2222
+ return /* @__PURE__ */ jsxs(
2223
+ "section",
2224
+ {
2225
+ className: cn(
2226
+ "degradado-hero rounded-panel border-hairline relative overflow-hidden border",
2227
+ // 44 arriba, 40 a los lados y abajo. Del documento.
2228
+ "px-xl pt-[44px] pb-xl",
2229
+ className
2230
+ ),
2231
+ ...props,
2232
+ children: [
2233
+ /* @__PURE__ */ jsxs("div", { className: "gap-md flex flex-col md:max-w-[62%]", children: [
2234
+ eyebrow ? /* @__PURE__ */ jsx(Text, { variant: "eyebrow", tone: "accent", as: "p", children: eyebrow }) : null,
2235
+ /* @__PURE__ */ jsx(Text, { as: "h1", variant: "display", children: title }),
2236
+ description ? /* @__PURE__ */ jsx(Text, { variant: "body", tone: "secondary", children: description }) : null,
2237
+ action ? /* @__PURE__ */ jsx("div", { className: "gap-sm mt-xs flex flex-wrap items-center", children: action }) : null
2238
+ ] }),
2239
+ pose ? /* @__PURE__ */ jsx(
2240
+ Mascota,
2241
+ {
2242
+ pose,
2243
+ basePath,
2244
+ className: cn(
2245
+ // En móvil, en el flujo y bajo los botones. Desde md, sangrando por
2246
+ // la esquina inferior derecha.
2247
+ "mt-lg mx-auto w-40",
2248
+ "md:mt-0 md:absolute md:right-0 md:-bottom-4 md:mx-0 md:w-64"
2249
+ )
2250
+ }
2251
+ ) : null
2252
+ ]
2253
+ }
2254
+ );
2255
+ }
2256
+ function LinkRow({
2257
+ name,
2258
+ description,
2259
+ icon,
2260
+ external = false,
2261
+ className,
2262
+ ...props
2263
+ }) {
2264
+ const rel = external ? "noopener noreferrer" : props.rel;
2265
+ const target = external ? "_blank" : props.target;
2266
+ return /* @__PURE__ */ jsx(
2267
+ Tarjeta,
2268
+ {
2269
+ className: cn("px-md py-sm", className),
2270
+ ...props,
2271
+ rel,
2272
+ ...target ? { target } : {},
2273
+ children: /* @__PURE__ */ jsxs("span", { className: "gap-sm flex items-center", children: [
2274
+ icon ? /* @__PURE__ */ jsx("span", { className: "text-text-muted group-hover:text-accent transition-standard shrink-0 text-2xl", children: icon }) : null,
2275
+ /* @__PURE__ */ jsxs("span", { className: "min-w-0 flex-1", children: [
2276
+ /* @__PURE__ */ jsx(Text, { as: "span", variant: "ui", className: "group-hover:text-accent transition-standard block font-medium", children: name }),
2277
+ description ? /* @__PURE__ */ jsx(Text, { as: "span", variant: "label", tone: "muted", className: "block truncate", children: description }) : null
2278
+ ] }),
2279
+ external ? /* @__PURE__ */ jsx(
2280
+ ArrowUpRight,
2281
+ {
2282
+ className: "text-text-muted group-hover:text-accent transition-standard shrink-0",
2283
+ "aria-hidden": "true"
2284
+ }
2285
+ ) : null
2286
+ ] })
2287
+ }
2288
+ );
2289
+ }
2290
+ function Nav({ brand: brand2, children, actions, className, ...props }) {
2291
+ return /* @__PURE__ */ jsx(
2292
+ "header",
2293
+ {
2294
+ className: cn(
2295
+ "sticky top-0 z-50 w-full",
2296
+ // abismo al 86 % con 14px de desenfoque detrás. El alfa va sobre el
2297
+ // token, así que sigue el modo: en claro es papel al 86 %.
2298
+ "bg-background/86 backdrop-blur-[14px]",
2299
+ "border-hairline border-b",
2300
+ className
2301
+ ),
2302
+ ...props,
2303
+ children: /* @__PURE__ */ jsxs("div", { className: "max-w-wide px-md h-nav gap-lg mx-auto flex items-center", children: [
2304
+ brand2 ? /* @__PURE__ */ jsx("div", { className: "shrink-0", children: brand2 }) : null,
2305
+ children ? /* @__PURE__ */ jsx("nav", { "aria-label": "Principal", className: "min-w-0 flex-1", children: /* @__PURE__ */ jsx("ul", { className: "gap-md flex items-center", children }) }) : /* @__PURE__ */ jsx("div", { className: "flex-1" }),
2306
+ actions ? /* @__PURE__ */ jsx("div", { className: "gap-sm flex shrink-0 items-center", children: actions }) : null
2307
+ ] })
2308
+ }
2309
+ );
2310
+ }
2311
+ function NavItem({ active = false, asChild = false, className, children, ...props }) {
2312
+ const Raiz = asChild ? Slot : "a";
2313
+ return /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsxs(
2314
+ Raiz,
2315
+ {
2316
+ "aria-current": active ? "page" : void 0,
2317
+ className: cn(
2318
+ "font-mono text-meta transition-standard cursor-pointer",
2319
+ "rounded-chip focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent",
2320
+ active ? "text-accent underline decoration-1 underline-offset-4" : "text-text-secondary hover:text-accent",
2321
+ className
2322
+ ),
2323
+ ...props,
2324
+ children: [
2325
+ /* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: "text-text-muted", children: "./" }),
2326
+ children
2327
+ ]
2328
+ }
2329
+ ) });
2330
+ }
2331
+ function NewsletterForm({
2332
+ title,
2333
+ description,
2334
+ state = "reposo",
2335
+ onSubmitEmail,
2336
+ successMessage = "Ya est\xE1s dentro. Te llega un correo cada dos semanas, y nada m\xE1s.",
2337
+ errorMessage = "No se pudo suscribir ese correo. Rev\xEDsalo y vuelve a intentar.",
2338
+ disclaimer,
2339
+ expresion,
2340
+ basePath,
2341
+ submitLabel = "Suscribirme",
2342
+ placeholder = "tu@correo.dev",
2343
+ fieldLabel = "Correo electr\xF3nico",
2344
+ className,
2345
+ ...props
2346
+ }) {
2347
+ const id = useId();
2348
+ const enviando = state === "enviando";
2349
+ const error = state === "error";
2350
+ function enviar(evento) {
2351
+ evento.preventDefault();
2352
+ const datos = new FormData(evento.currentTarget);
2353
+ const correo = String(datos.get("email") ?? "");
2354
+ onSubmitEmail?.(correo);
2355
+ }
2356
+ return /* @__PURE__ */ jsxs(
2357
+ "section",
2358
+ {
2359
+ className: cn(
2360
+ "degradado-seccion rounded-panel border-hairline p-lg gap-md flex flex-col border",
2361
+ className
2362
+ ),
2363
+ ...props,
2364
+ children: [
2365
+ /* @__PURE__ */ jsxs("div", { className: "gap-xs flex flex-col", children: [
2366
+ /* @__PURE__ */ jsx(Text, { as: "h2", variant: "h3", children: title }),
2367
+ description ? /* @__PURE__ */ jsx(Text, { variant: "ui", tone: "secondary", children: description }) : null
2368
+ ] }),
2369
+ /* @__PURE__ */ jsxs("form", { onSubmit: enviar, className: "gap-sm flex flex-col sm:flex-row sm:items-end", noValidate: true, children: [
2370
+ /* @__PURE__ */ jsxs("div", { className: "gap-xs flex flex-1 flex-col", children: [
2371
+ /* @__PURE__ */ jsx(Label2, { htmlFor: id, children: fieldLabel }),
2372
+ /* @__PURE__ */ jsx(
2373
+ Input,
2374
+ {
2375
+ id,
2376
+ name: "email",
2377
+ type: "email",
2378
+ autoComplete: "email",
2379
+ required: true,
2380
+ placeholder,
2381
+ disabled: enviando,
2382
+ invalid: error,
2383
+ "aria-describedby": state === "exito" || error ? `${id}-aviso` : void 0
2384
+ }
2385
+ )
2386
+ ] }),
2387
+ /* @__PURE__ */ jsx(
2388
+ Button,
2389
+ {
2390
+ type: "submit",
2391
+ variant: "conversion",
2392
+ loading: enviando,
2393
+ className: "disabled:opacity-60",
2394
+ children: submitLabel
2395
+ }
2396
+ )
2397
+ ] }),
2398
+ state === "exito" ? /* @__PURE__ */ jsx(Alert, { id: `${id}-aviso`, variant: "success", enfasis: "fuerte", children: successMessage }) : null,
2399
+ error ? /* @__PURE__ */ jsx(Alert, { id: `${id}-aviso`, variant: "error", enfasis: "fuerte", children: errorMessage }) : null,
2400
+ disclaimer ? /* @__PURE__ */ jsxs("div", { className: "gap-sm flex items-center", children: [
2401
+ expresion ? /* @__PURE__ */ jsx(CaraDeMascota, { expresion, basePath, className: "w-10 max-w-none" }) : null,
2402
+ /* @__PURE__ */ jsx(Text, { variant: "label", tone: "muted", as: "p", className: "font-normal", children: disclaimer })
2403
+ ] }) : null
2404
+ ]
2405
+ }
2406
+ );
2407
+ }
2408
+ var cabecera = cva("gap-sm flex flex-col", {
2409
+ variants: {
2410
+ size: {
2411
+ display: "py-section",
2412
+ page: "py-xl"
2413
+ }
2414
+ },
2415
+ defaultVariants: { size: "page" }
2416
+ });
2417
+ function PageHeader({
2418
+ title,
2419
+ eyebrow,
2420
+ description,
2421
+ action,
2422
+ size: size2,
2423
+ as = "h1",
2424
+ className,
2425
+ ...props
2426
+ }) {
2427
+ return /* @__PURE__ */ jsxs("header", { className: cn(cabecera({ size: size2 }), className), ...props, children: [
2428
+ eyebrow ? /* @__PURE__ */ jsx(Text, { variant: "eyebrow", tone: "accent", as: "p", children: eyebrow }) : null,
2429
+ /* @__PURE__ */ jsx(Text, { as, variant: size2 === "display" ? "display" : "h1", className: "max-w-measure", children: title }),
2430
+ description ? /* @__PURE__ */ jsx(Text, { variant: "body", tone: "secondary", children: description }) : null,
2431
+ action ? /* @__PURE__ */ jsx("div", { className: "gap-sm mt-sm flex flex-wrap items-center", children: action }) : null
2432
+ ] });
2433
+ }
2434
+ function SidebarItem({
2435
+ active = false,
2436
+ asChild = false,
2437
+ badge: badge2,
2438
+ className,
2439
+ children,
2440
+ ...props
2441
+ }) {
2442
+ const Raiz = asChild ? Slot : "a";
2443
+ return /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsxs(
2444
+ Raiz,
2445
+ {
2446
+ "aria-current": active ? "page" : void 0,
2447
+ className: cn(
2448
+ "rounded-chip px-sm gap-xs flex cursor-pointer items-center py-1.5",
2449
+ "font-mono text-meta transition-standard",
2450
+ "focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent",
2451
+ // El activo es fondo `surfaceRaised` y tinta primaria, igual que
2452
+ // `TabsTrigger`. NO bioluz: `tokens.ts` lo dice explícito — acento
2453
+ // claro pasa sobre background y sobre surface, pero sobre
2454
+ // surfaceRaised mide 4.2 y no es color de texto ahí. El acento se
2455
+ // queda en el `▸`, que es decorativo y le aplica el umbral de 3:1.
2456
+ active ? "bg-surface-raised text-text-primary" : "text-text-secondary hover:text-text-primary hover:bg-surface-raised",
2457
+ className
2458
+ ),
2459
+ ...props,
2460
+ children: [
2461
+ /* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: active ? "text-accent" : "text-text-muted", children: "\u25B8" }),
2462
+ /* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1 truncate", children }),
2463
+ badge2 ? /* @__PURE__ */ jsx("span", { className: "text-text-muted shrink-0", children: badge2 }) : null
2464
+ ]
2465
+ }
2466
+ ) });
2467
+ }
2468
+ function SidebarNav({
2469
+ title,
2470
+ version,
2471
+ branch,
2472
+ children,
2473
+ className,
2474
+ ...props
2475
+ }) {
2476
+ const pie = [version, branch].filter(Boolean);
2477
+ return /* @__PURE__ */ jsxs(
2478
+ "nav",
2479
+ {
2480
+ "aria-label": typeof title === "string" ? title : "Administraci\xF3n",
2481
+ className: cn(
2482
+ "border-hairline bg-surface p-sm gap-sm flex h-full flex-col border-r",
2483
+ className
2484
+ ),
2485
+ ...props,
2486
+ children: [
2487
+ title ? /* @__PURE__ */ jsx(Text, { variant: "eyebrow", tone: "muted", as: "p", className: "px-sm", children: title }) : null,
2488
+ /* @__PURE__ */ jsx("ul", { className: "gap-0.5 flex flex-1 flex-col", children }),
2489
+ pie.length > 0 ? /* @__PURE__ */ jsx(Text, { variant: "meta", tone: "muted", as: "p", className: "border-hairline px-sm pt-sm border-t", children: pie.map((p, i) => /* @__PURE__ */ jsxs("span", { children: [
2490
+ i > 0 ? /* @__PURE__ */ jsx("span", { "aria-hidden": "true", children: " \xB7 " }) : null,
2491
+ p
2492
+ ] }, i)) }) : null
2493
+ ]
2494
+ }
2495
+ );
2496
+ }
2497
+ function Stat({ value, label, tone = "neutral", progress, className, ...props }) {
2498
+ return /* @__PURE__ */ jsxs("div", { className: cn(SUPERFICIE_TARJETA, "p-lg gap-xs flex flex-col", className), ...props, children: [
2499
+ /* @__PURE__ */ jsx(Text, { variant: "stat", as: "p", tone: tone === "alerta" ? "warm" : "accent", children: value }),
2500
+ /* @__PURE__ */ jsx(Text, { variant: "eyebrow", tone: "muted", as: "p", children: label }),
2501
+ typeof progress === "number" ? /* @__PURE__ */ jsx(
2502
+ Progress,
2503
+ {
2504
+ value: progress,
2505
+ tone: tone === "alerta" ? "warm" : "accent",
2506
+ label: `${label}: ${progress}%`,
2507
+ className: "mt-sm"
2508
+ }
2509
+ ) : null
2510
+ ] });
2511
+ }
2512
+ function TalkCard({
2513
+ title,
2514
+ event,
2515
+ date,
2516
+ dateTime,
2517
+ location,
2518
+ status,
2519
+ className,
2520
+ ...props
2521
+ }) {
2522
+ const pie = [
2523
+ date ? /* @__PURE__ */ jsx("time", { dateTime, children: date }, "fecha") : null,
2524
+ location ? /* @__PURE__ */ jsx("span", { children: location }, "lugar") : null
2525
+ ].filter(Boolean);
2526
+ return /* @__PURE__ */ jsx(Tarjeta, { className: cn("p-lg", className), ...props, children: /* @__PURE__ */ jsxs("article", { className: "gap-sm flex h-full flex-col", children: [
2527
+ /* @__PURE__ */ jsxs("div", { className: "gap-sm flex items-start justify-between", children: [
2528
+ /* @__PURE__ */ jsx(Text, { variant: "eyebrow", tone: "accent", as: "p", children: event }),
2529
+ status ? /* @__PURE__ */ jsx(Badge, { variant: "neutral", children: status }) : null
2530
+ ] }),
2531
+ /* @__PURE__ */ jsx(Text, { as: "h3", variant: "h3", className: "group-hover:text-accent transition-standard", children: title }),
2532
+ pie.length > 0 ? /* @__PURE__ */ jsx(Text, { variant: "label", tone: "muted", as: "p", className: "gap-xs mt-auto flex items-center pt-sm", children: pie.map((m, i) => /* @__PURE__ */ jsxs("span", { className: "gap-xs flex items-center", children: [
2533
+ i > 0 ? /* @__PURE__ */ jsx("span", { "aria-hidden": "true", children: "\xB7" }) : null,
2534
+ m
2535
+ ] }, i)) }) : null
2536
+ ] }) });
2537
+ }
2538
+ function TableOfContents({
2539
+ items,
2540
+ title = "En esta p\xE1gina",
2541
+ activeHref,
2542
+ linkAsChild,
2543
+ className,
2544
+ ...props
2545
+ }) {
2546
+ return /* @__PURE__ */ jsxs("nav", { "aria-label": typeof title === "string" ? title : "En esta p\xE1gina", className: cn("gap-sm flex flex-col", className), ...props, children: [
2547
+ /* @__PURE__ */ jsx(Text, { variant: "eyebrow", tone: "muted", as: "p", children: title }),
2548
+ /* @__PURE__ */ jsx("ul", { className: "border-hairline gap-xs flex flex-col border-l", children: items.map((item2) => {
2549
+ const activo = item2.href === activeHref;
2550
+ const clases = cn(
2551
+ "px-sm -ml-px block border-l",
2552
+ "font-sans text-label transition-standard",
2553
+ "focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent",
2554
+ "cursor-pointer",
2555
+ item2.nested && "pl-lg",
2556
+ activo ? "border-accent text-accent" : "border-transparent text-text-secondary hover:text-text-primary"
2557
+ );
2558
+ return /* @__PURE__ */ jsx("li", { children: linkAsChild ? /* @__PURE__ */ jsx(Slot, { className: clases, "aria-current": activo ? "location" : void 0, children: linkAsChild({ href: item2.href, children: item2.label }) }) : /* @__PURE__ */ jsx("a", { href: item2.href, className: clases, "aria-current": activo ? "location" : void 0, children: item2.label }) }, item2.href);
2559
+ }) })
2560
+ ] });
2561
+ }
2562
+
2563
+ // src/lib/social.tsx
2564
+ var social_exports = {};
2565
+ __export(social_exports, {
2566
+ Correo: () => Correo,
2567
+ Discord: () => Discord,
2568
+ GitHub: () => GitHub,
2569
+ Instagram: () => Instagram,
2570
+ LinkedIn: () => LinkedIn,
2571
+ Rss: () => Rss,
2572
+ X: () => X,
2573
+ YouTube: () => YouTube
2574
+ });
2575
+ function Marca({ children, ...props }) {
2576
+ return /* @__PURE__ */ jsx(
2577
+ "svg",
2578
+ {
2579
+ viewBox: "0 0 24 24",
2580
+ width: "1em",
2581
+ height: "1em",
2582
+ fill: "currentColor",
2583
+ "aria-hidden": "true",
2584
+ focusable: "false",
2585
+ ...props,
2586
+ children
2587
+ }
2588
+ );
2589
+ }
2590
+ function Funcional({ children, ...props }) {
2591
+ return /* @__PURE__ */ jsx(
2592
+ "svg",
2593
+ {
2594
+ viewBox: "0 0 24 24",
2595
+ width: "1em",
2596
+ height: "1em",
2597
+ fill: "none",
2598
+ stroke: "currentColor",
2599
+ strokeWidth: 1.6,
2600
+ strokeLinecap: "round",
2601
+ strokeLinejoin: "round",
2602
+ "aria-hidden": "true",
2603
+ focusable: "false",
2604
+ ...props,
2605
+ children
2606
+ }
2607
+ );
2608
+ }
2609
+ var GitHub = (props) => /* @__PURE__ */ jsx(Marca, { ...props, children: /* @__PURE__ */ jsx("path", { d: "M12 .5C5.73.5.5 5.73.5 12a11.5 11.5 0 0 0 7.86 10.91c.58.1.79-.25.79-.55 0-.27-.01-1.18-.02-2.14-3.2.7-3.88-1.36-3.88-1.36-.52-1.33-1.28-1.68-1.28-1.68-1.05-.72.08-.7.08-.7 1.16.08 1.77 1.19 1.77 1.19 1.03 1.77 2.7 1.26 3.36.96.1-.75.4-1.26.73-1.55-2.55-.29-5.24-1.28-5.24-5.69 0-1.26.45-2.29 1.19-3.09-.12-.29-.52-1.46.11-3.05 0 0 .97-.31 3.18 1.18a11 11 0 0 1 5.79 0c2.2-1.49 3.17-1.18 3.17-1.18.63 1.59.23 2.76.12 3.05.74.8 1.18 1.83 1.18 3.09 0 4.42-2.69 5.39-5.25 5.68.41.36.78 1.06.78 2.14 0 1.55-.01 2.79-.01 3.17 0 .3.2.66.79.55A11.5 11.5 0 0 0 23.5 12C23.5 5.73 18.27.5 12 .5Z" }) });
2610
+ var LinkedIn = (props) => /* @__PURE__ */ jsx(Marca, { ...props, children: /* @__PURE__ */ jsx("path", { d: "M4.98 3.5a2.5 2.5 0 1 1 0 5 2.5 2.5 0 0 1 0-5ZM3 9h4v12H3V9Zm7 0h3.8v1.71h.05a4.17 4.17 0 0 1 3.75-2.06c4.01 0 4.75 2.64 4.75 6.07V21h-4v-5.4c0-1.29-.02-2.95-1.8-2.95-1.8 0-2.08 1.4-2.08 2.85V21h-3.97V9Z" }) });
2611
+ var X = (props) => /* @__PURE__ */ jsx(Marca, { ...props, children: /* @__PURE__ */ jsx("path", { d: "M17.53 3h3.06l-6.69 7.64L21.75 21h-6.16l-4.83-6.3L5.25 21H2.19l7.15-8.17L2.5 3h6.32l4.36 5.77L17.53 3Zm-1.07 16.17h1.7L7.62 4.74H5.8l10.66 14.43Z" }) });
2612
+ var Instagram = (props) => /* @__PURE__ */ jsx(Marca, { ...props, children: /* @__PURE__ */ jsx("path", { d: "M12 2.16c3.2 0 3.58.01 4.85.07 1.17.05 1.8.25 2.23.41.56.22.96.48 1.38.9.42.42.68.82.9 1.38.16.42.36 1.06.41 2.23.06 1.27.07 1.65.07 4.85s-.01 3.58-.07 4.85c-.05 1.17-.25 1.8-.41 2.23-.22.56-.48.96-.9 1.38-.42.42-.82.68-1.38.9-.42.16-1.06.36-2.23.41-1.27.06-1.65.07-4.85.07s-3.58-.01-4.85-.07c-1.17-.05-1.8-.25-2.23-.41-.56-.22-.96-.48-1.38-.9-.42-.42-.68-.82-.9-1.38-.16-.42-.36-1.06-.41-2.23C2.17 15.58 2.16 15.2 2.16 12s.01-3.58.07-4.85c.05-1.17.25-1.8.41-2.23.22-.56.48-.96.9-1.38.42-.42.82-.68 1.38-.9.42-.16 1.06-.36 2.23-.41C8.42 2.17 8.8 2.16 12 2.16Zm0 3.68a6.16 6.16 0 1 0 0 12.32 6.16 6.16 0 0 0 0-12.32Zm0 10.16a4 4 0 1 1 0-8 4 4 0 0 1 0 8Zm7.85-10.4a1.44 1.44 0 1 1-2.88 0 1.44 1.44 0 0 1 2.88 0Z" }) });
2613
+ var Discord = (props) => /* @__PURE__ */ jsx(Marca, { ...props, children: /* @__PURE__ */ jsx("path", { d: "M20.32 5.56A18.5 18.5 0 0 0 15.7 4.1a.07.07 0 0 0-.07.04c-.2.36-.42.82-.58 1.19a17 17 0 0 0-5.1 0c-.16-.38-.39-.83-.59-1.19a.07.07 0 0 0-.07-.04c-1.6.28-3.15.77-4.62 1.46a.06.06 0 0 0-.03.03C1.66 10 .9 14.28 1.28 18.5a.08.08 0 0 0 .03.05 18.6 18.6 0 0 0 5.6 2.84.07.07 0 0 0 .08-.03c.43-.59.81-1.21 1.14-1.86a.07.07 0 0 0-.04-.1c-.6-.23-1.18-.51-1.74-.83a.07.07 0 0 1-.01-.12l.35-.27a.07.07 0 0 1 .07-.01 13.3 13.3 0 0 0 11.3 0 .07.07 0 0 1 .08.01l.34.27c.04.04.04.1-.01.12-.55.33-1.13.6-1.74.83a.07.07 0 0 0-.04.1c.34.65.72 1.27 1.14 1.86a.07.07 0 0 0 .08.03 18.5 18.5 0 0 0 5.6-2.84.07.07 0 0 0 .04-.05c.45-4.88-.75-9.12-3.18-12.88a.06.06 0 0 0-.03-.03ZM8.4 15.93c-1.1 0-2.01-1.01-2.01-2.25 0-1.24.89-2.25 2.01-2.25 1.13 0 2.03 1.02 2.02 2.25 0 1.24-.9 2.25-2.02 2.25Zm7.22 0c-1.1 0-2.01-1.01-2.01-2.25 0-1.24.89-2.25 2.01-2.25 1.13 0 2.03 1.02 2.02 2.25 0 1.24-.89 2.25-2.02 2.25Z" }) });
2614
+ var YouTube = (props) => /* @__PURE__ */ jsx(Marca, { ...props, children: /* @__PURE__ */ jsx("path", { d: "M23.5 6.9a3 3 0 0 0-2.12-2.12C19.5 4.27 12 4.27 12 4.27s-7.5 0-9.38.51A3 3 0 0 0 .5 6.9 31.3 31.3 0 0 0 0 12a31.3 31.3 0 0 0 .5 5.1 3 3 0 0 0 2.12 2.12c1.88.51 9.38.51 9.38.51s7.5 0 9.38-.51a3 3 0 0 0 2.12-2.12A31.3 31.3 0 0 0 24 12a31.3 31.3 0 0 0-.5-5.1ZM9.6 15.6V8.4l6.24 3.6-6.24 3.6Z" }) });
2615
+ var Rss = (props) => /* @__PURE__ */ jsxs(Funcional, { ...props, children: [
2616
+ /* @__PURE__ */ jsx("path", { d: "M4 11a9 9 0 0 1 9 9M4 4a16 16 0 0 1 16 16" }),
2617
+ /* @__PURE__ */ jsx("circle", { cx: "5", cy: "19", r: "1.6", fill: "currentColor", stroke: "none" })
2618
+ ] });
2619
+ var Correo = (props) => /* @__PURE__ */ jsxs(Funcional, { ...props, children: [
2620
+ /* @__PURE__ */ jsx("rect", { x: "2.75", y: "4.75", width: "18.5", height: "14.5", rx: "2" }),
2621
+ /* @__PURE__ */ jsx("path", { d: "m3.5 7.5 7.4 5.2a2 2 0 0 0 2.2 0l7.4-5.2" })
2622
+ ] });
2623
+
2624
+ export { Alert, ArticleCard, AudioPlayer, AuthorCard, Avatar, AvatarFallback, AvatarImage, Badge, Blockquote, Breadcrumb, Button, Calendar, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, CategoryBadge, Checkbox, Code, CodeBlock, CourseCard, DateField, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogTitle, DialogTrigger, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, EmptyState, Footer, FooterLink, HOVER_TARJETA, Hero, Input, Label2 as Label, LinkRow, MetricBadge, Nav, NavItem, NewsletterForm, PageHeader, Pagination, PaginationContent, PaginationEllipsis, PaginationItem, PaginationLink, PaginationNext, PaginationPrevious, Popover, PopoverAnchor, PopoverContent, PopoverTrigger, Progress, RadioGroup2 as RadioGroup, RadioGroupItem, SUPERFICIE_TARJETA, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectSeparator, SelectTrigger, SelectValue, Separator3 as Separator, Sheet, SheetBody, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetTitle, SheetTrigger, SidebarItem, SidebarNav, Skeleton, Stat, Switch, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableOfContents, TableRow, Tabs, TabsContent, TabsList, TabsTrigger, TalkCard, Text, Textarea, Toast, ToastAction, ToastDescription, ToastProvider, ToastTitle, ToastViewport, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, alert as alertVariants, avatar as avatarVariants, badge as badgeVariants, button as buttonVariants, categoria as categoryBadgeVariants, social_exports as social, texto as textVariants };