@eduardoalvarez/arrecife 0.5.0 → 0.6.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 (66) hide show
  1. package/CHANGELOG.md +52 -0
  2. package/README.md +706 -470
  3. package/dist/brand/index.cjs +112 -95
  4. package/dist/brand/index.d.cts +40 -39
  5. package/dist/brand/index.d.ts +40 -39
  6. package/dist/brand/index.js +5 -4
  7. package/dist/catalog-D13txprv.d.cts +78 -0
  8. package/dist/catalog-D13txprv.d.ts +78 -0
  9. package/dist/chart/index.cjs +100 -83
  10. package/dist/chart/index.d.cts +66 -66
  11. package/dist/chart/index.d.ts +66 -66
  12. package/dist/chart/index.js +14 -12
  13. package/dist/chunk-25YNFCIF.js +141 -0
  14. package/dist/{chunk-YZ2SDOVZ.js → chunk-6O3KWB6P.js} +30 -30
  15. package/dist/chunk-CKRSQPTX.js +36 -0
  16. package/dist/{chunk-ZEOQKRQ7.js → chunk-DKCN7BAL.js} +1 -1
  17. package/dist/chunk-GCRII2KQ.js +86 -0
  18. package/dist/chunk-JMOOFZ3B.js +42 -0
  19. package/dist/chunk-O4TAH7YJ.js +276 -0
  20. package/dist/chunk-ODBFN44D.js +45 -0
  21. package/dist/{chunk-VPT32GPG.js → chunk-PMN7NR3G.js} +2 -2
  22. package/dist/chunk-XKYHTOUJ.js +27 -0
  23. package/dist/form/index.cjs +109 -92
  24. package/dist/form/index.d.cts +43 -42
  25. package/dist/form/index.d.ts +43 -42
  26. package/dist/form/index.js +25 -23
  27. package/dist/index.cjs +1068 -929
  28. package/dist/index.d.cts +770 -773
  29. package/dist/index.d.ts +770 -773
  30. package/dist/index.js +629 -675
  31. package/dist/{label-DuTvJGxD.d.ts → label-MgHFKnFy.d.cts} +3 -3
  32. package/dist/{label-DuTvJGxD.d.cts → label-MgHFKnFy.d.ts} +3 -3
  33. package/dist/og/index.cjs +130 -130
  34. package/dist/og/index.d.cts +93 -89
  35. package/dist/og/index.d.ts +93 -89
  36. package/dist/og/index.js +106 -106
  37. package/dist/shiki/index.cjs +28 -30
  38. package/dist/shiki/index.d.cts +4 -4
  39. package/dist/shiki/index.d.ts +4 -4
  40. package/dist/shiki/index.js +12 -12
  41. package/dist/theme/index.cjs +97 -0
  42. package/dist/theme/index.d.cts +144 -0
  43. package/dist/theme/index.d.ts +144 -0
  44. package/dist/theme/index.js +2 -0
  45. package/dist/tokens/index.cjs +133 -86
  46. package/dist/tokens/index.d.cts +246 -161
  47. package/dist/tokens/index.d.ts +246 -161
  48. package/dist/tokens/index.js +2 -2
  49. package/dist/tokens/theme.css +133 -98
  50. package/dist/variants/index.cjs +192 -0
  51. package/dist/variants/index.d.cts +192 -0
  52. package/dist/variants/index.d.ts +192 -0
  53. package/dist/variants/index.js +3 -0
  54. package/llms.txt +810 -744
  55. package/package.json +20 -11
  56. package/dist/catalogo-Du5ID-Hi.d.cts +0 -77
  57. package/dist/catalogo-Du5ID-Hi.d.ts +0 -77
  58. package/dist/chunk-E3OMP2DL.js +0 -36
  59. package/dist/chunk-KPZNNMV5.js +0 -83
  60. package/dist/chunk-NHS7ETKJ.js +0 -27
  61. package/dist/chunk-TSPJOM6K.js +0 -229
  62. package/dist/chunk-UOWIDFCB.js +0 -81
  63. package/dist/tema/index.cjs +0 -94
  64. package/dist/tema/index.d.cts +0 -110
  65. package/dist/tema/index.d.ts +0 -110
  66. package/dist/tema/index.js +0 -2
package/dist/index.js CHANGED
@@ -1,25 +1,29 @@
1
- export { tokens } from './chunk-VPT32GPG.js';
2
- import { alternarTema, temaActual, escucharTema } from './chunk-KPZNNMV5.js';
3
- export { TEMA_ATRIBUTO, TEMA_CLAVE, TEMA_EVENTO, alternarTema, aplicarTema, escucharTema, scriptTema, temaActual, temaGuardado, temaPreferido } from './chunk-KPZNNMV5.js';
4
- import { CaraDeMascota, Mascota } from './chunk-YZ2SDOVZ.js';
5
- export { CaraDeMascota, Isotipo, Logo, Mascota } from './chunk-YZ2SDOVZ.js';
6
- export { RUTA_ASSETS, aletas, caras, listaCaras, listaPoses, poses, usoDeCara } from './chunk-E3OMP2DL.js';
7
- import { Label } from './chunk-ZEOQKRQ7.js';
8
- export { Label } from './chunk-ZEOQKRQ7.js';
9
- import { Text } from './chunk-UOWIDFCB.js';
10
- export { Text, texto as textVariants } from './chunk-UOWIDFCB.js';
11
- import { cn } from './chunk-NHS7ETKJ.js';
12
- export { cn } from './chunk-NHS7ETKJ.js';
13
- import { naming } from './chunk-TSPJOM6K.js';
14
- export { brand, colors, control, dark, fonts, gradient, light, limits, motion, naming, radius, series, shadow, sintaxis, size, spacing, tagline, typeScale } from './chunk-TSPJOM6K.js';
1
+ 'use client';
2
+ export { tokens } from './chunk-PMN7NR3G.js';
3
+ import { toggleTheme, currentTheme, watchTheme } from './chunk-GCRII2KQ.js';
4
+ export { THEME_ATTRIBUTE, THEME_EVENT, THEME_KEY, applyTheme, currentTheme, preferredTheme, storedTheme, themeScript, toggleTheme, watchTheme } from './chunk-GCRII2KQ.js';
5
+ import { alert, button, avatar, badge, category, metric, CARD_SURFACE, CARD } from './chunk-25YNFCIF.js';
6
+ export { CARD, CARD_HOVER, CARD_SURFACE, alert as alertVariants, avatar as avatarVariants, badge as badgeVariants, button as buttonVariants, category as categoryBadgeVariants, metric as metricBadgeVariants } from './chunk-25YNFCIF.js';
7
+ import { MascotFace, Mascot } from './chunk-6O3KWB6P.js';
8
+ export { Isotype, Logo, Mascot, MascotFace } from './chunk-6O3KWB6P.js';
9
+ export { ASSETS_PATH, faceList, faceUsage, faces, fins, poseList, poses } from './chunk-CKRSQPTX.js';
10
+ import { Label } from './chunk-DKCN7BAL.js';
11
+ export { Label } from './chunk-DKCN7BAL.js';
12
+ import { Text } from './chunk-JMOOFZ3B.js';
13
+ export { Text } from './chunk-JMOOFZ3B.js';
14
+ export { text as textVariants } from './chunk-ODBFN44D.js';
15
+ import { cn } from './chunk-XKYHTOUJ.js';
16
+ export { cn } from './chunk-XKYHTOUJ.js';
17
+ import { naming } from './chunk-O4TAH7YJ.js';
18
+ export { brand, colors, control, dark, fonts, gradient, light, limits, motion, naming, radius, series, shadow, size, spacing, syntax, tagline, typeScale } from './chunk-O4TAH7YJ.js';
15
19
  import { __export } from './chunk-MLKGABMK.js';
16
20
  import * as AccordionPrimitive from '@radix-ui/react-accordion';
17
21
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
18
22
  import { cva } from 'class-variance-authority';
19
23
  import * as AlertDialogPrimitive from '@radix-ui/react-alert-dialog';
20
- import { Slot } from '@radix-ui/react-slot';
21
24
  import * as AvatarPrimitive from '@radix-ui/react-avatar';
22
25
  import { useId, useState, useEffect, useSyncExternalStore, useRef, useCallback } from 'react';
26
+ import { Slot } from '@radix-ui/react-slot';
23
27
  import { es } from 'date-fns/locale';
24
28
  import { DayPicker } from 'react-day-picker';
25
29
  import * as CheckboxPrimitive from '@radix-ui/react-checkbox';
@@ -88,16 +92,16 @@ var Spinner = (props) => /* @__PURE__ */ jsxs(
88
92
  ]
89
93
  }
90
94
  );
91
- var Camara = (props) => /* @__PURE__ */ jsxs(Glyph, { ...props, children: [
95
+ var Camera = (props) => /* @__PURE__ */ jsxs(Glyph, { ...props, children: [
92
96
  /* @__PURE__ */ jsx("path", { d: "M2 5.5h2.6l1-1.5h4.8l1 1.5H14v7.5H2z" }),
93
97
  /* @__PURE__ */ jsx("circle", { cx: "8", cy: "9", r: "2.4" })
94
98
  ] });
95
- var Sol = (props) => /* @__PURE__ */ jsxs(Glyph, { ...props, children: [
99
+ var Sun = (props) => /* @__PURE__ */ jsxs(Glyph, { ...props, children: [
96
100
  /* @__PURE__ */ jsx("circle", { cx: "8", cy: "8", r: "3" }),
97
101
  /* @__PURE__ */ jsx("path", { d: "M8 1.5v1.2M8 13.3v1.2M14.5 8h-1.2M2.7 8H1.5M12.6 3.4l-.85.85M4.25 11.75l-.85.85M12.6 12.6l-.85-.85M4.25 4.25l-.85-.85" })
98
102
  ] });
99
- var Luna = (props) => /* @__PURE__ */ jsx(Glyph, { ...props, children: /* @__PURE__ */ jsx("path", { d: "M13.5 9.4A5.8 5.8 0 0 1 6.6 2.5a5.8 5.8 0 1 0 6.9 6.9Z" }) });
100
- function GlifoMedia({ children, ...props }) {
103
+ var Moon = (props) => /* @__PURE__ */ jsx(Glyph, { ...props, children: /* @__PURE__ */ jsx("path", { d: "M13.5 9.4A5.8 5.8 0 0 1 6.6 2.5a5.8 5.8 0 1 0 6.9 6.9Z" }) });
104
+ function MediaGlyph({ children, ...props }) {
101
105
  return /* @__PURE__ */ jsx(
102
106
  "svg",
103
107
  {
@@ -111,10 +115,10 @@ function GlifoMedia({ children, ...props }) {
111
115
  }
112
116
  );
113
117
  }
114
- var Play = (props) => /* @__PURE__ */ jsx(GlifoMedia, { fill: "currentColor", ...props, children: /* @__PURE__ */ jsx("path", { d: "M8 5v14l11-7z" }) });
115
- var Pause = (props) => /* @__PURE__ */ jsx(GlifoMedia, { fill: "currentColor", ...props, children: /* @__PURE__ */ jsx("path", { d: "M6 4h4v16H6V4zm8 0h4v16h-4V4z" }) });
118
+ var Play = (props) => /* @__PURE__ */ jsx(MediaGlyph, { fill: "currentColor", ...props, children: /* @__PURE__ */ jsx("path", { d: "M8 5v14l11-7z" }) });
119
+ var Pause = (props) => /* @__PURE__ */ jsx(MediaGlyph, { fill: "currentColor", ...props, children: /* @__PURE__ */ jsx("path", { d: "M6 4h4v16H6V4zm8 0h4v16h-4V4z" }) });
116
120
  var Retry = (props) => /* @__PURE__ */ jsx(
117
- GlifoMedia,
121
+ MediaGlyph,
118
122
  {
119
123
  stroke: "currentColor",
120
124
  strokeWidth: 2,
@@ -124,7 +128,7 @@ var Retry = (props) => /* @__PURE__ */ jsx(
124
128
  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" })
125
129
  }
126
130
  );
127
- var GoBackSeconds = (props) => /* @__PURE__ */ jsxs(GlifoMedia, { stroke: "currentColor", strokeWidth: 1.5, strokeLinecap: "round", ...props, children: [
131
+ var GoBackSeconds = (props) => /* @__PURE__ */ jsxs(MediaGlyph, { stroke: "currentColor", strokeWidth: 1.5, strokeLinecap: "round", ...props, children: [
128
132
  /* @__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" }),
129
133
  /* @__PURE__ */ jsx("path", { d: "M7.5 10.5L10 8.5V15.5", strokeLinejoin: "round" }),
130
134
  /* @__PURE__ */ jsx(
@@ -135,7 +139,7 @@ var GoBackSeconds = (props) => /* @__PURE__ */ jsxs(GlifoMedia, { stroke: "curre
135
139
  }
136
140
  )
137
141
  ] });
138
- var AdvanceSeconds = (props) => /* @__PURE__ */ jsxs(GlifoMedia, { stroke: "currentColor", strokeWidth: 1.5, strokeLinecap: "round", ...props, children: [
142
+ var AdvanceSeconds = (props) => /* @__PURE__ */ jsxs(MediaGlyph, { stroke: "currentColor", strokeWidth: 1.5, strokeLinecap: "round", ...props, children: [
139
143
  /* @__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" }),
140
144
  /* @__PURE__ */ jsx("path", { d: "M7.5 10.5L10 8.5V15.5", strokeLinejoin: "round" }),
141
145
  /* @__PURE__ */ jsx(
@@ -146,8 +150,8 @@ var AdvanceSeconds = (props) => /* @__PURE__ */ jsxs(GlifoMedia, { stroke: "curr
146
150
  }
147
151
  )
148
152
  ] });
149
- 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" }) });
150
- 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" }) });
153
+ var VolumeOn = (props) => /* @__PURE__ */ jsx(MediaGlyph, { 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" }) });
154
+ var VolumeMuted = (props) => /* @__PURE__ */ jsx(MediaGlyph, { 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" }) });
151
155
  function Accordion({ className, ...props }) {
152
156
  return /* @__PURE__ */ jsx(
153
157
  AccordionPrimitive.Root,
@@ -169,8 +173,8 @@ function AccordionTrigger({
169
173
  headingLevel = 3,
170
174
  ...props
171
175
  }) {
172
- const Encabezado = `h${headingLevel}`;
173
- return /* @__PURE__ */ jsx(AccordionPrimitive.Header, { asChild: true, children: /* @__PURE__ */ jsx(Encabezado, { children: /* @__PURE__ */ jsxs(
176
+ const Heading = `h${headingLevel}`;
177
+ return /* @__PURE__ */ jsx(AccordionPrimitive.Header, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: /* @__PURE__ */ jsxs(
174
178
  AccordionPrimitive.Trigger,
175
179
  {
176
180
  className: cn(
@@ -201,45 +205,20 @@ function AccordionContent({
201
205
  {
202
206
  className: cn(
203
207
  "overflow-hidden",
204
- "motion-safe:data-[state=open]:desplegar motion-safe:data-[state=closed]:replegar"
208
+ "motion-safe:data-[state=open]:expand motion-safe:data-[state=closed]:collapse"
205
209
  ),
206
210
  ...props,
207
211
  children: /* @__PURE__ */ jsx("div", { className: cn("pb-step-md font-sans text-ui text-text-secondary max-w-measure", className), children })
208
212
  }
209
213
  );
210
214
  }
211
- var alert = cva("w-full rounded-card border p-step-md font-sans text-ui", {
212
- variants: {
213
- variant: {
214
- accent: "text-text-secondary",
215
- success: "text-text-secondary",
216
- warning: "text-text-secondary",
217
- error: "text-text-secondary"
218
- },
219
- enfasis: {
220
- sutil: "",
221
- fuerte: ""
222
- }
223
- },
224
- compoundVariants: [
225
- { variant: "accent", enfasis: "sutil", class: "border-accent/22 bg-accent/8" },
226
- { variant: "success", enfasis: "sutil", class: "border-success/22 bg-success/8" },
227
- { variant: "warning", enfasis: "sutil", class: "border-warning/22 bg-warning/8" },
228
- { variant: "error", enfasis: "sutil", class: "border-error/22 bg-error/8" },
229
- { variant: "accent", enfasis: "fuerte", class: "border-accent bg-accent/10" },
230
- { variant: "success", enfasis: "fuerte", class: "border-success bg-success/10" },
231
- { variant: "warning", enfasis: "fuerte", class: "border-warning bg-warning/10" },
232
- { variant: "error", enfasis: "fuerte", class: "border-error bg-error/10" }
233
- ],
234
- defaultVariants: { variant: "accent", enfasis: "sutil" }
235
- });
236
- var glifoColor = {
215
+ var colorGlyph = {
237
216
  accent: "text-accent",
238
217
  success: "text-success",
239
218
  warning: "text-warning",
240
219
  error: "text-error"
241
220
  };
242
- var GLIFO = {
221
+ var GLYPH = {
243
222
  accent: "\u2726",
244
223
  success: "\u2713",
245
224
  warning: "!",
@@ -248,26 +227,26 @@ var GLIFO = {
248
227
  function Alert({
249
228
  className,
250
229
  variant,
251
- enfasis,
230
+ emphasis,
252
231
  title,
253
232
  icon,
254
233
  children,
255
234
  ...props
256
235
  }) {
257
- const tono = variant ?? "accent";
236
+ const tone = variant ?? "accent";
258
237
  return /* @__PURE__ */ jsx(
259
238
  "div",
260
239
  {
261
- role: tono === "error" ? "alert" : "status",
262
- className: cn(alert({ variant, enfasis }), className),
240
+ role: tone === "error" ? "alert" : "status",
241
+ className: cn(alert({ variant, emphasis }), className),
263
242
  ...props,
264
243
  children: /* @__PURE__ */ jsxs("div", { className: "gap-step-sm flex items-start", children: [
265
244
  /* @__PURE__ */ jsx(
266
245
  "span",
267
246
  {
268
247
  "aria-hidden": "true",
269
- className: cn("font-mono text-ui leading-normal select-none", glifoColor[tono]),
270
- children: icon ?? GLIFO[tono]
248
+ className: cn("font-mono text-ui leading-normal select-none", colorGlyph[tone]),
249
+ children: icon ?? GLYPH[tone]
271
250
  }
272
251
  ),
273
252
  /* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
@@ -278,79 +257,6 @@ function Alert({
278
257
  }
279
258
  );
280
259
  }
281
- var button = cva(
282
- [
283
- "inline-flex cursor-pointer items-center justify-center gap-step-xs whitespace-nowrap select-none",
284
- "rounded-control font-sans font-medium",
285
- "transition-standard",
286
- "focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent",
287
- "disabled:pointer-events-none disabled:opacity-50",
288
- "[&_svg]:shrink-0"
289
- ],
290
- {
291
- variants: {
292
- variant: {
293
- primary: [
294
- "bg-accent text-accent-on hover:bg-accent-hover",
295
- "light:bg-brand-hull light:text-accent-on light:hover:bg-text-secondary"
296
- ],
297
- conversion: "bg-warm text-warm-on hover:bg-warm-hover",
298
- secondary: [
299
- "border-hairline-hover border bg-transparent text-text-primary",
300
- "hover:border-accent hover:text-accent"
301
- ],
302
- tertiary: [
303
- "bg-transparent font-mono font-normal text-text-secondary",
304
- "hover:text-accent hover:underline hover:underline-offset-4"
305
- ]
306
- },
307
- size: {
308
- sm: "h-8 px-control-sm text-label",
309
- md: "h-10 px-control-md text-ui",
310
- lg: "h-12 px-control-lg text-lead",
311
- /** Cuadrado 42×42, sin texto. Lleva `aria-label` obligatorio. */
312
- icon: "size-control-icon p-0"
313
- }
314
- },
315
- compoundVariants: [
316
- /**
317
- * El terciario no tiene caja: ni padding horizontal ni alto de control.
318
- * Va aquí y no como `px-0` en la variante para que gane al `px-*` del
319
- * tamaño sin depender del orden en que cva concatena las clases.
320
- */
321
- { variant: "tertiary", size: ["sm", "md", "lg"], class: "h-auto px-0" }
322
- ],
323
- defaultVariants: { variant: "primary", size: "md" }
324
- }
325
- );
326
- function Button({
327
- className,
328
- variant,
329
- size: size2,
330
- asChild = false,
331
- loading = false,
332
- icon,
333
- children,
334
- disabled,
335
- ...props
336
- }) {
337
- if (asChild) {
338
- return /* @__PURE__ */ jsx(Slot, { className: cn(button({ variant, size: size2 }), className), ...props, children });
339
- }
340
- return /* @__PURE__ */ jsxs(
341
- "button",
342
- {
343
- className: cn(button({ variant, size: size2 }), className),
344
- disabled: disabled === true || loading,
345
- "aria-busy": loading || void 0,
346
- ...props,
347
- children: [
348
- loading ? /* @__PURE__ */ jsx(Spinner, {}) : icon,
349
- children
350
- ]
351
- }
352
- );
353
- }
354
260
  var AlertDialog = AlertDialogPrimitive.Root;
355
261
  var AlertDialogTrigger = AlertDialogPrimitive.Trigger;
356
262
  function AlertDialogOverlay({
@@ -448,20 +354,6 @@ function AlertDialogAction({
448
354
  }
449
355
  );
450
356
  }
451
- var avatar = cva(
452
- "relative flex shrink-0 overflow-hidden rounded-pill bg-surface-raised border border-hairline",
453
- {
454
- variants: {
455
- size: {
456
- sm: "size-8",
457
- md: "size-10",
458
- lg: "size-14",
459
- xl: "size-24"
460
- }
461
- },
462
- defaultVariants: { size: "md" }
463
- }
464
- );
465
357
  function Avatar({ className, size: size2, ...props }) {
466
358
  return /* @__PURE__ */ jsx(AvatarPrimitive.Root, { className: cn(avatar({ size: size2 }), className), ...props });
467
359
  }
@@ -498,22 +390,22 @@ function AvatarUpload({
498
390
  ...props
499
391
  }) {
500
392
  const id = useId();
501
- const [previa, setPrevia] = useState(null);
393
+ const [preview, setPreview] = useState(null);
502
394
  useEffect(() => {
503
- if (!previa) return;
504
- return () => URL.revokeObjectURL(previa);
505
- }, [previa]);
506
- function elegir(evento) {
507
- const archivo = evento.target.files?.[0];
508
- if (!archivo) return;
509
- setPrevia(URL.createObjectURL(archivo));
510
- onSelectFile?.(archivo);
511
- evento.target.value = "";
395
+ if (!preview) return;
396
+ return () => URL.revokeObjectURL(preview);
397
+ }, [preview]);
398
+ function pick(event) {
399
+ const file = event.target.files?.[0];
400
+ if (!file) return;
401
+ setPreview(URL.createObjectURL(file));
402
+ onSelectFile?.(file);
403
+ event.target.value = "";
512
404
  }
513
- const imagen = previa ?? src;
405
+ const image = preview ?? src;
514
406
  return /* @__PURE__ */ jsxs("div", { className: cn("relative inline-flex", className), ...props, children: [
515
407
  /* @__PURE__ */ jsxs(Avatar, { size: size2, children: [
516
- imagen ? /* @__PURE__ */ jsx(AvatarImage, { src: imagen, alt: "" }) : null,
408
+ image ? /* @__PURE__ */ jsx(AvatarImage, { src: image, alt: "" }) : null,
517
409
  /* @__PURE__ */ jsx(AvatarFallback, { children: fallback })
518
410
  ] }),
519
411
  /* @__PURE__ */ jsxs(
@@ -524,13 +416,13 @@ function AvatarUpload({
524
416
  "rounded-pill absolute -right-1 -bottom-1 flex size-6 cursor-pointer items-center justify-center",
525
417
  "border-hairline bg-surface-raised text-text-secondary border",
526
418
  "transition-standard hover:text-accent hover:border-accent",
527
- // El foco vive en el input, que está oculto: sin esto, tabular hasta
528
- // el control no se ve por ninguna parte.
419
+ // Focus lives on the input, which is hidden: without this, tabbing to
420
+ // the control shows up nowhere.
529
421
  "has-[:focus-visible]:outline-2 has-[:focus-visible]:outline-offset-2 has-[:focus-visible]:outline-accent",
530
422
  disabled && "pointer-events-none opacity-50"
531
423
  ),
532
424
  children: [
533
- /* @__PURE__ */ jsx(Camara, { "aria-hidden": "true" }),
425
+ /* @__PURE__ */ jsx(Camera, { "aria-hidden": "true" }),
534
426
  /* @__PURE__ */ jsx("span", { className: "sr-only", children: label }),
535
427
  /* @__PURE__ */ jsx(
536
428
  "input",
@@ -539,7 +431,7 @@ function AvatarUpload({
539
431
  type: "file",
540
432
  accept,
541
433
  disabled,
542
- onChange: elegir,
434
+ onChange: pick,
543
435
  className: "sr-only"
544
436
  }
545
437
  )
@@ -548,62 +440,56 @@ function AvatarUpload({
548
440
  )
549
441
  ] });
550
442
  }
551
- var badge = cva(
552
- ["inline-flex items-center gap-step-xs", "rounded-chip px-step-xs py-0.5", "font-sans text-tag", "transition-standard"],
553
- {
554
- variants: {
555
- variant: {
556
- neutral: "bg-surface-raised text-text-secondary",
557
- accent: "bg-accent/8 text-text-primary",
558
- warm: "bg-warm/8 text-text-primary",
559
- success: "bg-success/8 text-text-primary",
560
- warning: "bg-warning/8 text-text-primary",
561
- error: "bg-error/8 text-text-primary"
562
- }
563
- },
564
- defaultVariants: { variant: "neutral" }
565
- }
566
- );
567
443
  function Badge({ className, variant, ...props }) {
568
444
  return /* @__PURE__ */ jsx("span", { className: cn(badge({ variant }), className), ...props });
569
445
  }
570
- var categoria = cva(
571
- [
572
- "inline-flex items-center gap-step-xs",
573
- "rounded-pill px-step-sm py-0.5",
574
- "font-mono text-chip",
575
- "border transition-standard"
576
- ],
577
- {
578
- variants: {
579
- active: {
580
- false: "border-warm/28 bg-transparent text-warm",
581
- true: "border-warm bg-warm text-warm-on"
582
- }
583
- },
584
- defaultVariants: { active: false }
585
- }
586
- );
587
446
  function CategoryBadge({ className, active = false, ...props }) {
588
447
  return /* @__PURE__ */ jsx(
589
448
  "span",
590
449
  {
591
450
  "data-active": active || void 0,
592
- className: cn(categoria({ active }), className),
451
+ className: cn(category({ active }), className),
593
452
  ...props
594
453
  }
595
454
  );
596
455
  }
597
- var metrica = ["inline-flex items-center gap-step-xs", "rounded-pill", "font-mono text-chip text-text-muted"];
598
456
  function MetricBadge({ className, boxed = false, ...props }) {
599
457
  return /* @__PURE__ */ jsx(
600
458
  "span",
601
459
  {
602
- className: cn(metrica, boxed && "border-hairline px-step-sm py-0.5 border", className),
460
+ className: cn(metric, boxed && "border-hairline px-step-sm py-0.5 border", className),
603
461
  ...props
604
462
  }
605
463
  );
606
464
  }
465
+ function Button({
466
+ className,
467
+ variant,
468
+ size: size2,
469
+ asChild = false,
470
+ loading = false,
471
+ icon,
472
+ children,
473
+ disabled,
474
+ ...props
475
+ }) {
476
+ if (asChild) {
477
+ return /* @__PURE__ */ jsx(Slot, { className: cn(button({ variant, size: size2 }), className), ...props, children });
478
+ }
479
+ return /* @__PURE__ */ jsxs(
480
+ "button",
481
+ {
482
+ className: cn(button({ variant, size: size2 }), className),
483
+ disabled: disabled === true || loading,
484
+ "aria-busy": loading || void 0,
485
+ ...props,
486
+ children: [
487
+ loading ? /* @__PURE__ */ jsx(Spinner, {}) : icon,
488
+ children
489
+ ]
490
+ }
491
+ );
492
+ }
607
493
  function Calendar({
608
494
  className,
609
495
  classNames,
@@ -611,12 +497,12 @@ function Calendar({
611
497
  fullWidth = false,
612
498
  ...props
613
499
  }) {
614
- const dia = [
500
+ const day = [
615
501
  "relative p-0 text-center",
616
502
  fullWidth ? "h-9 flex-1" : "size-9",
617
503
  "text-ui font-sans text-text-primary"
618
504
  ].join(" ");
619
- const botonDia = [
505
+ const dayButton = [
620
506
  fullWidth ? "h-9 w-full" : "size-9",
621
507
  "rounded-chip inline-flex items-center justify-center",
622
508
  "transition-standard cursor-pointer",
@@ -624,7 +510,7 @@ function Calendar({
624
510
  "focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent",
625
511
  "disabled:pointer-events-none disabled:opacity-50"
626
512
  ].join(" ");
627
- const navegacion = [
513
+ const navigation = [
628
514
  "size-8 rounded-chip inline-flex items-center justify-center",
629
515
  "text-text-secondary transition-standard cursor-pointer",
630
516
  "hover:bg-surface-raised hover:text-text-primary",
@@ -638,32 +524,32 @@ function Calendar({
638
524
  showOutsideDays,
639
525
  className: cn("font-sans", className),
640
526
  classNames: {
641
- // `relative` obligatorio: la navegación se posiciona en absoluto contra
642
- // la raíz, y sin esto se ancla al primer ancestro posicionado —o al
643
- // viewport— y las flechas acaban en los bordes de la página.
527
+ // `relative` is mandatory: the navigation is absolutely positioned
528
+ // against the root, and without this it anchors to the first positioned
529
+ // ancestor — or to the viewport — and the arrows end up at the page edges.
644
530
  root: cn("relative", fullWidth ? "w-full" : "w-fit"),
645
531
  months: cn("gap-step-md flex flex-col sm:flex-row", fullWidth && "w-full"),
646
532
  month: cn("gap-step-sm flex flex-col", fullWidth && "min-w-0 flex-1"),
647
533
  month_caption: "h-8 flex items-center justify-center",
648
534
  caption_label: "text-ui font-sans font-medium text-text-primary capitalize",
649
535
  nav: "absolute inset-x-0 top-0 flex items-center justify-between",
650
- button_previous: navegacion,
651
- button_next: navegacion,
536
+ button_previous: navigation,
537
+ button_next: navigation,
652
538
  month_grid: "w-full border-collapse",
653
539
  weekdays: cn("flex", fullWidth && "w-full"),
654
- // `textMuted` no va sobre `surfaceRaised` —4.07:1—, y un calendario dentro de
655
- // un Popover vive justo ahí.
540
+ // `textMuted` does not go over `surfaceRaised` — 4.07:1 — and a calendar
541
+ // inside a Popover lives exactly there.
656
542
  weekday: cn(
657
543
  "h-9 text-eyebrow font-mono text-text-secondary uppercase flex items-center justify-center",
658
544
  fullWidth ? "flex-1" : "w-9"
659
545
  ),
660
546
  week: "flex w-full",
661
- day: dia,
662
- day_button: botonDia,
547
+ day,
548
+ day_button: dayButton,
663
549
  today: "text-accent font-medium",
664
- // Los días de los meses vecinos se atenúan, pero no por debajo de AA:
665
- // `textSecondary` al 85 % da 5.09:1 en el peor caso, que es sobre
666
- // `surfaceRaised`. Al 75 % ya no pasa en modo claro.
550
+ // Days from neighbouring months are dimmed, but not below AA:
551
+ // `textSecondary` at 85 % gives 5.09:1 in the worst case, which is over
552
+ // `surfaceRaised`. At 75 % it no longer passes in light mode.
667
553
  outside: "text-text-secondary opacity-85",
668
554
  disabled: "opacity-50",
669
555
  hidden: "invisible",
@@ -681,10 +567,8 @@ function Calendar({
681
567
  }
682
568
  );
683
569
  }
684
- var SUPERFICIE_TARJETA = "rounded-card border-hairline bg-surface border";
685
- var HOVER_TARJETA = "transition-standard hover:border-hairline-hover";
686
570
  function Card({ className, ...props }) {
687
- return /* @__PURE__ */ jsx("div", { className: cn(SUPERFICIE_TARJETA, className), ...props });
571
+ return /* @__PURE__ */ jsx("div", { className: cn(CARD_SURFACE, className), ...props });
688
572
  }
689
573
  function CardHeader({ className, ...props }) {
690
574
  return /* @__PURE__ */ jsx("div", { className: cn("gap-step-xs p-step-lg flex flex-col", className), ...props });
@@ -761,7 +645,7 @@ function DateField({
761
645
  "focus-visible:border-accent focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent",
762
646
  "disabled:pointer-events-none disabled:opacity-50",
763
647
  "data-[invalid]:border-error data-[invalid]:focus-visible:outline-error",
764
- // El indicador nativo hereda el esquema del tema activo.
648
+ // The native indicator inherits the active theme's scheme.
765
649
  "scheme-light dark:scheme-dark [&::-webkit-calendar-picker-indicator]:cursor-pointer",
766
650
  className
767
651
  ),
@@ -1013,7 +897,7 @@ function PaginationPrevious({ className, ...props }) {
1013
897
  ] });
1014
898
  }
1015
899
  function PaginationNext({ className, ...props }) {
1016
- return /* @__PURE__ */ jsxs(PaginationLink, { "aria-label": "P\xE1gina siguiente", className: cn("gap-step-xs", className), ...props, children: [
900
+ return /* @__PURE__ */ jsxs(PaginationLink, { "aria-label": "P\xE1gina next", className: cn("gap-step-xs", className), ...props, children: [
1017
901
  "Siguiente",
1018
902
  /* @__PURE__ */ jsx(ChevronRight, {})
1019
903
  ] });
@@ -1224,23 +1108,23 @@ var panel2 = cva(
1224
1108
  side: {
1225
1109
  right: [
1226
1110
  "inset-y-0 right-0 h-full w-3/4 max-w-content border-l",
1227
- "motion-safe:data-[state=open]:deslizar-entra-derecha",
1228
- "motion-safe:data-[state=closed]:deslizar-sale-derecha"
1111
+ "motion-safe:data-[state=open]:slide-in-right",
1112
+ "motion-safe:data-[state=closed]:slide-out-right"
1229
1113
  ],
1230
1114
  left: [
1231
1115
  "inset-y-0 left-0 h-full w-3/4 max-w-content border-r",
1232
- "motion-safe:data-[state=open]:deslizar-entra-izquierda",
1233
- "motion-safe:data-[state=closed]:deslizar-sale-izquierda"
1116
+ "motion-safe:data-[state=open]:slide-in-left",
1117
+ "motion-safe:data-[state=closed]:slide-out-left"
1234
1118
  ],
1235
1119
  top: [
1236
1120
  "inset-x-0 top-0 border-b",
1237
- "motion-safe:data-[state=open]:deslizar-entra-arriba",
1238
- "motion-safe:data-[state=closed]:deslizar-sale-arriba"
1121
+ "motion-safe:data-[state=open]:slide-in-top",
1122
+ "motion-safe:data-[state=closed]:slide-out-top"
1239
1123
  ],
1240
1124
  bottom: [
1241
1125
  "inset-x-0 bottom-0 border-t",
1242
- "motion-safe:data-[state=open]:deslizar-entra-abajo",
1243
- "motion-safe:data-[state=closed]:deslizar-sale-abajo"
1126
+ "motion-safe:data-[state=open]:slide-in-bottom",
1127
+ "motion-safe:data-[state=closed]:slide-out-bottom"
1244
1128
  ]
1245
1129
  }
1246
1130
  },
@@ -1552,62 +1436,62 @@ function ToastDescription({
1552
1436
  }) {
1553
1437
  return /* @__PURE__ */ jsx(ToastPrimitive.Description, { className: cn("max-w-measure", className), ...props });
1554
1438
  }
1555
- var avisos = [];
1556
- var suscriptores = /* @__PURE__ */ new Set();
1557
- var contador = 0;
1558
- function emitir(siguientes) {
1559
- avisos = siguientes;
1560
- for (const avisar of suscriptores) avisar();
1439
+ var warnings = [];
1440
+ var subscribers = /* @__PURE__ */ new Set();
1441
+ var counter = 0;
1442
+ function emit(next) {
1443
+ warnings = next;
1444
+ for (const warn of subscribers) warn();
1561
1445
  }
1562
- var suscribirse = (avisar) => {
1563
- suscriptores.add(avisar);
1446
+ var subscribe = (warn) => {
1447
+ subscribers.add(warn);
1564
1448
  return () => {
1565
- suscriptores.delete(avisar);
1449
+ subscribers.delete(warn);
1566
1450
  };
1567
1451
  };
1568
- var leer = () => avisos;
1569
- var VACIO = [];
1570
- var enServidor = () => VACIO;
1571
- function crear(mensaje, opciones = {}) {
1572
- contador += 1;
1573
- const id = `arrecife-toast-${contador}`;
1574
- const { description, ...resto } = opciones;
1575
- emitir([
1576
- ...avisos,
1577
- {
1578
- ...resto,
1579
- // El primer argumento es la línea principal. Si además llega `title`, el
1580
- // mensaje pasa a ser la descripción: así `toast('Guardado')` y
1581
- // `toast('No se pudo guardar', { title: 'Error' })` se leen igual de bien.
1582
- ...opciones.title ? { description: description ?? mensaje } : { title: mensaje, ...description === void 0 ? {} : { description } },
1452
+ var read = () => warnings;
1453
+ var EMPTY = [];
1454
+ var onServer = () => EMPTY;
1455
+ function create(message, options = {}) {
1456
+ counter += 1;
1457
+ const id = `arrecife-toast-${counter}`;
1458
+ const { description, ...rest } = options;
1459
+ emit([
1460
+ ...warnings,
1461
+ {
1462
+ ...rest,
1463
+ // The first argument is the main line. If a `title` also arrives, the
1464
+ // message becomes the description: that way `toast('Guardado')` and
1465
+ // `toast('No se pudo guardar', { title: 'Error' })` both read well.
1466
+ ...options.title ? { description: description ?? message } : { title: message, ...description === void 0 ? {} : { description } },
1583
1467
  id,
1584
- abierto: true
1468
+ open: true
1585
1469
  }
1586
1470
  ]);
1587
1471
  return id;
1588
1472
  }
1589
- function descartar(id) {
1590
- emitir(avisos.map((a) => id === void 0 || a.id === id ? { ...a, abierto: false } : a));
1473
+ function discard(id) {
1474
+ emit(warnings.map((a) => id === void 0 || a.id === id ? { ...a, open: false } : a));
1591
1475
  }
1592
- function retirar(id) {
1593
- emitir(avisos.filter((a) => a.id !== id));
1476
+ function remove(id) {
1477
+ emit(warnings.filter((a) => a.id !== id));
1594
1478
  }
1595
- var toast2 = Object.assign(crear, {
1596
- success: (mensaje, opciones = {}) => crear(mensaje, { ...opciones, variant: "success" }),
1597
- error: (mensaje, opciones = {}) => crear(mensaje, { ...opciones, variant: "error" }),
1598
- dismiss: descartar
1479
+ var toast2 = Object.assign(create, {
1480
+ success: (message, options = {}) => create(message, { ...options, variant: "success" }),
1481
+ error: (message, options = {}) => create(message, { ...options, variant: "error" }),
1482
+ dismiss: discard
1599
1483
  });
1600
1484
  function Toaster({ duration = 5e3, label = "Avisos" }) {
1601
- const lista = useSyncExternalStore(suscribirse, leer, enServidor);
1485
+ const list = useSyncExternalStore(subscribe, read, onServer);
1602
1486
  return /* @__PURE__ */ jsxs(ToastProvider, { duration, label, children: [
1603
- lista.map(({ id, title, description, variant, duration: propio, action, abierto }) => /* @__PURE__ */ jsxs(
1487
+ list.map(({ id, title, description, variant, duration: own, action, open }) => /* @__PURE__ */ jsxs(
1604
1488
  Toast,
1605
1489
  {
1606
- open: abierto,
1490
+ open,
1607
1491
  variant: variant ?? "neutral",
1608
- ...propio === void 0 ? {} : { duration: propio },
1609
- onOpenChange: (sigue) => {
1610
- if (!sigue) retirar(id);
1492
+ ...own === void 0 ? {} : { duration: own },
1493
+ onOpenChange: (stillOpen) => {
1494
+ if (!stillOpen) remove(id);
1611
1495
  },
1612
1496
  children: [
1613
1497
  /* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
@@ -1644,15 +1528,9 @@ function TooltipContent({
1644
1528
  }
1645
1529
  ) });
1646
1530
  }
1647
- var TARJETA = [
1648
- "group block cursor-pointer",
1649
- SUPERFICIE_TARJETA,
1650
- HOVER_TARJETA,
1651
- "focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent"
1652
- ];
1653
- function Tarjeta({ asChild = false, className, children, ...props }) {
1654
- const Raiz = asChild ? Slot : "a";
1655
- return /* @__PURE__ */ jsx(Raiz, { className: cn(TARJETA, className), ...props, children });
1531
+ function CardShell({ asChild = false, className, children, ...props }) {
1532
+ const Root17 = asChild ? Slot : "a";
1533
+ return /* @__PURE__ */ jsx(Root17, { className: cn(CARD, className), ...props, children });
1656
1534
  }
1657
1535
  function ArticleCard({
1658
1536
  title,
@@ -1662,17 +1540,18 @@ function ArticleCard({
1662
1540
  readingMinutes,
1663
1541
  tags,
1664
1542
  headingLevel = 3,
1543
+ tagAsChild,
1665
1544
  className,
1666
1545
  ...props
1667
1546
  }) {
1668
1547
  const meta = [
1669
- date ? /* @__PURE__ */ jsx("time", { dateTime, children: date }, "fecha") : null,
1548
+ date ? /* @__PURE__ */ jsx("time", { dateTime, children: date }, "date") : null,
1670
1549
  readingMinutes ? /* @__PURE__ */ jsxs("span", { children: [
1671
1550
  readingMinutes,
1672
1551
  " min de lectura"
1673
1552
  ] }, "lectura") : null
1674
1553
  ].filter(Boolean);
1675
- return /* @__PURE__ */ jsx(Tarjeta, { className: cn("p-step-lg", className), ...props, children: /* @__PURE__ */ jsxs("article", { className: "gap-step-sm flex h-full flex-col", children: [
1554
+ return /* @__PURE__ */ jsx(CardShell, { className: cn("p-step-lg", className), ...props, children: /* @__PURE__ */ jsxs("article", { className: "gap-step-sm flex h-full flex-col", children: [
1676
1555
  meta.length > 0 ? /* @__PURE__ */ jsx(Text, { variant: "meta", tone: "muted", as: "p", className: "gap-step-xs flex items-center", children: meta.map((m, i) => /* @__PURE__ */ jsxs("span", { className: "gap-step-xs flex items-center", children: [
1677
1556
  i > 0 ? /* @__PURE__ */ jsx("span", { "aria-hidden": "true", children: "\xB7" }) : null,
1678
1557
  m
@@ -1687,18 +1566,20 @@ function ArticleCard({
1687
1566
  }
1688
1567
  ),
1689
1568
  excerpt ? /* @__PURE__ */ jsx(Text, { variant: "ui", tone: "secondary", className: "line-clamp-2", children: excerpt }) : null,
1690
- tags && tags.length > 0 ? /* @__PURE__ */ jsx("div", { className: "gap-step-xs mt-auto flex flex-wrap pt-step-sm", children: tags.map((t) => /* @__PURE__ */ jsx(CategoryBadge, { children: t }, t)) }) : null
1569
+ tags && tags.length > 0 ? /* @__PURE__ */ jsx("div", { className: "gap-step-xs mt-auto flex flex-wrap pt-step-sm", children: tags.map(
1570
+ (t) => tagAsChild ? /* @__PURE__ */ jsx(Slot, { className: category({ active: false }), children: tagAsChild({ tag: t, children: t }) }, t) : /* @__PURE__ */ jsx(CategoryBadge, { children: t }, t)
1571
+ ) }) : null
1691
1572
  ] }) });
1692
1573
  }
1693
1574
  var AVATAR = "size-[52px]";
1694
- function iniciales(nombre) {
1695
- return nombre.split(/\s+/).slice(0, 2).map((p) => p[0] ?? "").join("").toUpperCase();
1575
+ function initials(name) {
1576
+ return name.split(/\s+/).slice(0, 2).map((p) => p[0] ?? "").join("").toUpperCase();
1696
1577
  }
1697
1578
  function AuthorCard({ name, role, src, bio, action, className, ...props }) {
1698
- return /* @__PURE__ */ jsxs("div", { className: cn(SUPERFICIE_TARJETA, "p-step-lg gap-step-md flex items-start", className), ...props, children: [
1579
+ return /* @__PURE__ */ jsxs("div", { className: cn(CARD_SURFACE, "p-step-lg gap-step-md flex items-start", className), ...props, children: [
1699
1580
  /* @__PURE__ */ jsxs(Avatar, { className: cn(AVATAR, "shrink-0"), children: [
1700
1581
  src ? /* @__PURE__ */ jsx(AvatarImage, { src, alt: "" }) : null,
1701
- /* @__PURE__ */ jsx(AvatarFallback, { children: iniciales(name) })
1582
+ /* @__PURE__ */ jsx(AvatarFallback, { children: initials(name) })
1702
1583
  ] }),
1703
1584
  /* @__PURE__ */ jsxs("div", { className: "gap-step-xs flex min-w-0 flex-1 flex-col", children: [
1704
1585
  /* @__PURE__ */ jsx(Text, { variant: "ui", as: "p", className: "font-medium", children: name }),
@@ -1716,45 +1597,45 @@ function formatTime(seconds) {
1716
1597
  }
1717
1598
  var WAVEFORM_HEIGHTS = [35, 65, 100, 65, 35];
1718
1599
  var RATES = [1, 1.25, 1.5, 1.75, 2];
1719
- function Onda({ grosor, alto, sonando }) {
1720
- return /* @__PURE__ */ jsx("div", { className: cn("flex items-end gap-[2px]", alto), "aria-hidden": "true", children: WAVEFORM_HEIGHTS.map((h, i) => /* @__PURE__ */ jsx(
1600
+ function Wave({ strokeWidth, height, playing }) {
1601
+ return /* @__PURE__ */ jsx("div", { className: cn("flex items-end gap-[2px]", height), "aria-hidden": "true", children: WAVEFORM_HEIGHTS.map((h, i) => /* @__PURE__ */ jsx(
1721
1602
  "span",
1722
1603
  {
1723
- className: cn("rounded-pill bg-accent transition-standard", grosor),
1724
- style: { height: `${h}%`, opacity: sonando ? 1 : 0.3 + h / 100 * 0.4 }
1604
+ className: cn("rounded-pill bg-accent transition-standard", strokeWidth),
1605
+ style: { height: `${h}%`, opacity: playing ? 1 : 0.3 + h / 100 * 0.4 }
1725
1606
  },
1726
1607
  i
1727
1608
  )) });
1728
1609
  }
1729
- function BarraProgreso({
1730
- alto,
1731
- perilla,
1732
- progreso,
1610
+ function ProgressBar({
1611
+ height,
1612
+ knob,
1613
+ progress,
1733
1614
  redondeada = true,
1734
1615
  tabIndex = 0,
1735
- ...puntero
1616
+ ...pointer
1736
1617
  }) {
1737
1618
  return /* @__PURE__ */ jsxs(
1738
1619
  "div",
1739
1620
  {
1740
1621
  className: cn(
1741
1622
  "group bg-surface-raised relative cursor-pointer",
1742
- alto,
1623
+ height,
1743
1624
  redondeada && "rounded-pill"
1744
1625
  ),
1745
1626
  role: "slider",
1746
1627
  "aria-label": "Progreso del audio",
1747
1628
  "aria-valuemin": 0,
1748
1629
  "aria-valuemax": 100,
1749
- "aria-valuenow": Math.round(progreso),
1630
+ "aria-valuenow": Math.round(progress),
1750
1631
  tabIndex,
1751
- ...puntero,
1632
+ ...pointer,
1752
1633
  children: [
1753
1634
  /* @__PURE__ */ jsx(
1754
1635
  "div",
1755
1636
  {
1756
1637
  className: cn("bg-accent absolute h-full", redondeada && "rounded-pill"),
1757
- style: { width: `${progreso}%` }
1638
+ style: { width: `${progress}%` }
1758
1639
  }
1759
1640
  ),
1760
1641
  /* @__PURE__ */ jsx(
@@ -1762,9 +1643,9 @@ function BarraProgreso({
1762
1643
  {
1763
1644
  className: "rounded-pill bg-text-primary absolute top-1/2 -translate-y-1/2 opacity-0 transition-opacity group-hover:opacity-100",
1764
1645
  style: {
1765
- width: perilla,
1766
- height: perilla,
1767
- left: `calc(${progreso}% - ${perilla / 2}px)`
1646
+ width: knob,
1647
+ height: knob,
1648
+ left: `calc(${progress}% - ${knob / 2}px)`
1768
1649
  }
1769
1650
  }
1770
1651
  )
@@ -1773,10 +1654,10 @@ function BarraProgreso({
1773
1654
  );
1774
1655
  }
1775
1656
  var CONTROL = "rounded-chip transition-standard cursor-pointer focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent";
1776
- function BotonSalto({
1657
+ function SkipButton({
1777
1658
  segundos,
1778
1659
  className,
1779
- tamano,
1660
+ size: size2,
1780
1661
  onSaltar
1781
1662
  }) {
1782
1663
  return /* @__PURE__ */ jsx(
@@ -1786,52 +1667,52 @@ function BotonSalto({
1786
1667
  onClick: () => onSaltar(segundos),
1787
1668
  className: cn("text-text-muted hover:text-text-primary", CONTROL, className),
1788
1669
  "aria-label": segundos < 0 ? "Retroceder 15 segundos" : "Adelantar 15 segundos",
1789
- children: segundos < 0 ? /* @__PURE__ */ jsx(GoBackSeconds, { className: tamano }) : /* @__PURE__ */ jsx(AdvanceSeconds, { className: tamano })
1670
+ children: segundos < 0 ? /* @__PURE__ */ jsx(GoBackSeconds, { className: size2 }) : /* @__PURE__ */ jsx(AdvanceSeconds, { className: size2 })
1790
1671
  }
1791
1672
  );
1792
1673
  }
1793
- function BotonVelocidad({
1674
+ function SpeedButton({
1794
1675
  className,
1795
- velocidad,
1796
- onCambiar
1676
+ speed,
1677
+ onChange
1797
1678
  }) {
1798
1679
  return /* @__PURE__ */ jsxs(
1799
1680
  "button",
1800
1681
  {
1801
1682
  type: "button",
1802
- onClick: onCambiar,
1683
+ onClick: onChange,
1803
1684
  className: cn(
1804
- // `textMuted` sobre `surfaceRaised` da 4.07:1 en oscuro y no pasa AA.
1805
- // El original del portafolio arrastra ese mismo fallo.
1685
+ // `textMuted` over `surfaceRaised` gives 4.07:1 in dark and fails AA.
1686
+ // The portfolio original carries that same failure.
1806
1687
  "text-text-secondary hover:text-text-primary bg-surface-raised",
1807
1688
  CONTROL,
1808
1689
  className
1809
1690
  ),
1810
1691
  "aria-label": "Cambiar velocidad de reproducci\xF3n",
1811
1692
  children: [
1812
- velocidad,
1693
+ speed,
1813
1694
  "x"
1814
1695
  ]
1815
1696
  }
1816
1697
  );
1817
1698
  }
1818
- function Volumen({
1819
- tamano,
1820
- ancho,
1699
+ function Volume({
1700
+ size: size2,
1701
+ width,
1821
1702
  silenciado,
1822
1703
  volumen,
1823
- onSilenciar,
1824
- onCambiarVolumen
1704
+ onMute,
1705
+ onVolumeChange
1825
1706
  }) {
1826
1707
  return /* @__PURE__ */ jsxs("div", { className: "gap-step-xs hidden items-center sm:flex", children: [
1827
1708
  /* @__PURE__ */ jsx(
1828
1709
  "button",
1829
1710
  {
1830
1711
  type: "button",
1831
- onClick: onSilenciar,
1712
+ onClick: onMute,
1832
1713
  className: cn("text-text-muted hover:text-text-primary p-1", CONTROL),
1833
1714
  "aria-label": silenciado ? "Activar sonido" : "Silenciar",
1834
- children: silenciado || volumen === 0 ? /* @__PURE__ */ jsx(VolumeMuted, { className: tamano }) : /* @__PURE__ */ jsx(VolumeOn, { className: tamano })
1715
+ children: silenciado || volumen === 0 ? /* @__PURE__ */ jsx(VolumeMuted, { className: size2 }) : /* @__PURE__ */ jsx(VolumeOn, { className: size2 })
1835
1716
  }
1836
1717
  ),
1837
1718
  /* @__PURE__ */ jsx(
@@ -1842,46 +1723,46 @@ function Volumen({
1842
1723
  max: "1",
1843
1724
  step: "0.1",
1844
1725
  value: silenciado ? 0 : volumen,
1845
- onChange: onCambiarVolumen,
1726
+ onChange: onVolumeChange,
1846
1727
  className: cn(
1847
1728
  "bg-surface-raised rounded-pill h-1 cursor-pointer appearance-none",
1848
1729
  "[accent-color:var(--color-accent)]",
1849
- ancho
1730
+ width
1850
1731
  ),
1851
- "aria-label": "Volumen"
1732
+ "aria-label": "Volume"
1852
1733
  }
1853
1734
  )
1854
1735
  ] });
1855
1736
  }
1856
- function IconoPlay({ className, cargando, error, sonando }) {
1737
+ function PlayIcon({ className, cargando, error, playing }) {
1857
1738
  if (cargando) return /* @__PURE__ */ jsx(Spinner, { className: cn("motion-safe:animate-spin", className) });
1858
1739
  if (error) return /* @__PURE__ */ jsx(Retry, { className });
1859
- if (sonando) return /* @__PURE__ */ jsx(Pause, { className });
1740
+ if (playing) return /* @__PURE__ */ jsx(Pause, { className });
1860
1741
  return /* @__PURE__ */ jsx(Play, { className });
1861
1742
  }
1862
- function BotonPlay({
1743
+ function PlayButton({
1863
1744
  className,
1864
- tamano,
1865
- etiqueta,
1866
- texto: texto2,
1867
- onAlternar,
1868
- ...estado
1745
+ size: size2,
1746
+ label,
1747
+ text: text2,
1748
+ onToggle,
1749
+ ...state
1869
1750
  }) {
1870
1751
  return /* @__PURE__ */ jsxs(
1871
1752
  "button",
1872
1753
  {
1873
1754
  type: "button",
1874
- onClick: onAlternar,
1755
+ onClick: onToggle,
1875
1756
  className: cn(
1876
1757
  "text-accent-on transition-standard cursor-pointer",
1877
1758
  "focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent",
1878
- estado.error ? "bg-error hover:bg-error/80" : "bg-accent hover:bg-accent-hover",
1759
+ state.error ? "bg-error hover:bg-error/80" : "bg-accent hover:bg-accent-hover",
1879
1760
  className
1880
1761
  ),
1881
- "aria-label": etiqueta,
1762
+ "aria-label": label,
1882
1763
  children: [
1883
- /* @__PURE__ */ jsx(IconoPlay, { className: tamano, ...estado }),
1884
- texto2 ? /* @__PURE__ */ jsx("span", { children: texto2 }) : null
1764
+ /* @__PURE__ */ jsx(PlayIcon, { className: size2, ...state }),
1765
+ text2 ? /* @__PURE__ */ jsx("span", { children: text2 }) : null
1885
1766
  ]
1886
1767
  }
1887
1768
  );
@@ -1900,7 +1781,7 @@ function AudioPlayer({ src, title, mode = "full", onFirstPlay }) {
1900
1781
  const [isMuted, setIsMuted] = useState(false);
1901
1782
  const [playbackRate, setPlaybackRate] = useState(1);
1902
1783
  const [isStaticVisible, setIsStaticVisible] = useState(true);
1903
- const flotante = mode === "banner" || mode === "compact";
1784
+ const floating = mode === "banner" || mode === "compact";
1904
1785
  useEffect(() => {
1905
1786
  const audio = audioRef.current;
1906
1787
  if (!audio) return;
@@ -1943,7 +1824,7 @@ function AudioPlayer({ src, title, mode = "full", onFirstPlay }) {
1943
1824
  };
1944
1825
  }, []);
1945
1826
  useEffect(() => {
1946
- if (!flotante || !staticRef.current) return;
1827
+ if (!floating || !staticRef.current) return;
1947
1828
  const observer = new IntersectionObserver(
1948
1829
  (entries) => {
1949
1830
  const entry = entries[0];
@@ -1953,7 +1834,7 @@ function AudioPlayer({ src, title, mode = "full", onFirstPlay }) {
1953
1834
  );
1954
1835
  observer.observe(staticRef.current);
1955
1836
  return () => observer.disconnect();
1956
- }, [flotante]);
1837
+ }, [floating]);
1957
1838
  const togglePlay = useCallback(async () => {
1958
1839
  const audio = audioRef.current;
1959
1840
  if (!audio) return;
@@ -2042,37 +1923,37 @@ function AudioPlayer({ src, title, mode = "full", onFirstPlay }) {
2042
1923
  [duration]
2043
1924
  );
2044
1925
  const progress = duration > 0 ? currentTime / duration * 100 : 0;
2045
- const etiquetaPlay = hasError ? "Reintentar" : isPlaying ? "Pausar" : "Reproducir";
2046
- const estadoPlay = { cargando: isLoading, error: hasError, sonando: isPlaying };
2047
- const puntero = {
1926
+ const playLabel = hasError ? "Reintentar" : isPlaying ? "Pausar" : "Reproducir";
1927
+ const playState = { cargando: isLoading, error: hasError, playing: isPlaying };
1928
+ const pointer = {
2048
1929
  onPointerDown: handlePointerDown,
2049
1930
  onPointerMove: handlePointerMove,
2050
1931
  onPointerUp: handlePointerUp
2051
1932
  };
2052
- const flotanteJsx = /* @__PURE__ */ jsxs(
1933
+ const floatingJsx = /* @__PURE__ */ jsxs(
2053
1934
  "div",
2054
1935
  {
2055
1936
  "aria-hidden": isStaticVisible,
2056
1937
  className: cn(
2057
1938
  "fixed inset-x-0 bottom-0 z-40 xl:hidden",
2058
- // Aparece y desaparece: el sistema no anima desplazamiento.
1939
+ // It appears and disappears: the system does not animate displacement.
2059
1940
  isStaticVisible && "hidden"
2060
1941
  ),
2061
1942
  children: [
2062
1943
  /* @__PURE__ */ jsx(
2063
- BarraProgreso,
1944
+ ProgressBar,
2064
1945
  {
2065
- alto: "h-1",
2066
- perilla: 10,
2067
- progreso: progress,
1946
+ height: "h-1",
1947
+ knob: 10,
1948
+ progress,
2068
1949
  redondeada: false,
2069
1950
  tabIndex: -1,
2070
- ...puntero
1951
+ ...pointer
2071
1952
  }
2072
1953
  ),
2073
1954
  /* @__PURE__ */ jsx("div", { className: "bg-surface/95 border-accent/25 border-t backdrop-blur-md", children: /* @__PURE__ */ jsxs("div", { className: "gap-step-sm px-step-md flex items-center py-5", children: [
2074
1955
  /* @__PURE__ */ jsxs("div", { className: "gap-step-xs flex shrink-0 items-center", children: [
2075
- /* @__PURE__ */ jsx(Onda, { grosor: "w-[2px]", alto: "h-4", sonando: isPlaying }),
1956
+ /* @__PURE__ */ jsx(Wave, { strokeWidth: "w-[2px]", height: "h-4", playing: isPlaying }),
2076
1957
  /* @__PURE__ */ jsx("span", { className: "text-eyebrow font-mono text-accent hidden uppercase sm:block", children: "Narraci\xF3n" })
2077
1958
  ] }),
2078
1959
  /* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
@@ -2084,24 +1965,24 @@ function AudioPlayer({ src, title, mode = "full", onFirstPlay }) {
2084
1965
  ] })
2085
1966
  ] }),
2086
1967
  /* @__PURE__ */ jsxs("div", { className: "flex shrink-0 items-center gap-1", children: [
2087
- /* @__PURE__ */ jsx(BotonSalto, { segundos: -15, className: "p-1.5", tamano: "w-5 h-5", onSaltar: skip }),
1968
+ /* @__PURE__ */ jsx(SkipButton, { segundos: -15, className: "p-1.5", size: "w-5 h-5", onSaltar: skip }),
2088
1969
  /* @__PURE__ */ jsx(
2089
- BotonPlay,
1970
+ PlayButton,
2090
1971
  {
2091
1972
  className: "rounded-pill px-step-sm gap-step-xs flex items-center py-1.5",
2092
- tamano: "w-4 h-4",
2093
- etiqueta: etiquetaPlay,
2094
- onAlternar: togglePlay,
2095
- ...estadoPlay
1973
+ size: "w-4 h-4",
1974
+ label: playLabel,
1975
+ onToggle: togglePlay,
1976
+ ...playState
2096
1977
  }
2097
1978
  ),
2098
- /* @__PURE__ */ jsx(BotonSalto, { segundos: 15, className: "p-1.5", tamano: "w-5 h-5", onSaltar: skip }),
1979
+ /* @__PURE__ */ jsx(SkipButton, { segundos: 15, className: "p-1.5", size: "w-5 h-5", onSaltar: skip }),
2099
1980
  /* @__PURE__ */ jsx(
2100
- BotonVelocidad,
1981
+ SpeedButton,
2101
1982
  {
2102
1983
  className: "text-label ml-0.5 px-1.5 py-0.5",
2103
- velocidad: playbackRate,
2104
- onCambiar: handlePlaybackRateChange
1984
+ speed: playbackRate,
1985
+ onChange: handlePlaybackRateChange
2105
1986
  }
2106
1987
  )
2107
1988
  ] })
@@ -2114,7 +1995,7 @@ function AudioPlayer({ src, title, mode = "full", onFirstPlay }) {
2114
1995
  /* @__PURE__ */ jsx("audio", { ref: audioRef, src, preload: "metadata" }),
2115
1996
  /* @__PURE__ */ jsxs("div", { ref: staticRef, children: [
2116
1997
  /* @__PURE__ */ jsxs("div", { className: "gap-step-sm mb-step-md flex items-center", children: [
2117
- /* @__PURE__ */ jsx(Onda, { grosor: "w-[3px]", alto: "h-5", sonando: isPlaying }),
1998
+ /* @__PURE__ */ jsx(Wave, { strokeWidth: "w-[3px]", height: "h-5", playing: isPlaying }),
2118
1999
  /* @__PURE__ */ jsx("span", { className: "text-eyebrow font-mono text-accent uppercase", children: "Narraci\xF3n de audio" }),
2119
2000
  /* @__PURE__ */ jsxs("span", { className: "text-chip font-mono text-text-muted ml-auto tabular-nums", children: [
2120
2001
  formatTime(currentTime),
@@ -2122,125 +2003,125 @@ function AudioPlayer({ src, title, mode = "full", onFirstPlay }) {
2122
2003
  formatTime(duration)
2123
2004
  ] })
2124
2005
  ] }),
2125
- /* @__PURE__ */ jsx("div", { className: "mb-step-md", children: /* @__PURE__ */ jsx(BarraProgreso, { alto: "h-1.5", perilla: 14, progreso: progress, ...puntero }) }),
2006
+ /* @__PURE__ */ jsx("div", { className: "mb-step-md", children: /* @__PURE__ */ jsx(ProgressBar, { height: "h-1.5", knob: 14, progress, ...pointer }) }),
2126
2007
  /* @__PURE__ */ jsxs("div", { className: "gap-step-sm flex items-center", children: [
2127
- /* @__PURE__ */ jsx(BotonSalto, { segundos: -15, className: "p-2", tamano: "w-6 h-6", onSaltar: skip }),
2008
+ /* @__PURE__ */ jsx(SkipButton, { segundos: -15, className: "p-2", size: "w-6 h-6", onSaltar: skip }),
2128
2009
  /* @__PURE__ */ jsx(
2129
- BotonPlay,
2010
+ PlayButton,
2130
2011
  {
2131
2012
  className: "rounded-pill px-step-lg gap-step-xs text-ui flex items-center py-2 font-medium",
2132
- tamano: "w-4 h-4",
2133
- etiqueta: etiquetaPlay,
2134
- texto: etiquetaPlay,
2135
- onAlternar: togglePlay,
2136
- ...estadoPlay
2013
+ size: "w-4 h-4",
2014
+ label: playLabel,
2015
+ text: playLabel,
2016
+ onToggle: togglePlay,
2017
+ ...playState
2137
2018
  }
2138
2019
  ),
2139
- /* @__PURE__ */ jsx(BotonSalto, { segundos: 15, className: "p-2", tamano: "w-6 h-6", onSaltar: skip }),
2020
+ /* @__PURE__ */ jsx(SkipButton, { segundos: 15, className: "p-2", size: "w-6 h-6", onSaltar: skip }),
2140
2021
  /* @__PURE__ */ jsxs("div", { className: "gap-step-sm ml-auto flex items-center", children: [
2141
2022
  /* @__PURE__ */ jsx(
2142
- BotonVelocidad,
2023
+ SpeedButton,
2143
2024
  {
2144
2025
  className: "text-label px-2 py-1",
2145
- velocidad: playbackRate,
2146
- onCambiar: handlePlaybackRateChange
2026
+ speed: playbackRate,
2027
+ onChange: handlePlaybackRateChange
2147
2028
  }
2148
2029
  ),
2149
2030
  /* @__PURE__ */ jsx(
2150
- Volumen,
2031
+ Volume,
2151
2032
  {
2152
- tamano: "w-4 h-4",
2153
- ancho: "w-16",
2033
+ size: "w-4 h-4",
2034
+ width: "w-16",
2154
2035
  silenciado: isMuted,
2155
2036
  volumen: volume,
2156
- onSilenciar: toggleMute,
2157
- onCambiarVolumen: handleVolumeChange
2037
+ onMute: toggleMute,
2038
+ onVolumeChange: handleVolumeChange
2158
2039
  }
2159
2040
  )
2160
2041
  ] })
2161
2042
  ] })
2162
2043
  ] }),
2163
- flotanteJsx
2044
+ floatingJsx
2164
2045
  ] });
2165
2046
  }
2166
2047
  if (mode === "compact") {
2167
2048
  return /* @__PURE__ */ jsxs(Fragment, { children: [
2168
2049
  /* @__PURE__ */ jsx("audio", { ref: audioRef, src, preload: "metadata" }),
2169
2050
  /* @__PURE__ */ jsxs("div", { ref: staticRef, className: "w-full", children: [
2170
- /* @__PURE__ */ jsx("div", { className: "mb-step-xs", children: /* @__PURE__ */ jsx(BarraProgreso, { alto: "h-1.5", perilla: 12, progreso: progress, ...puntero }) }),
2051
+ /* @__PURE__ */ jsx("div", { className: "mb-step-xs", children: /* @__PURE__ */ jsx(ProgressBar, { height: "h-1.5", knob: 12, progress, ...pointer }) }),
2171
2052
  /* @__PURE__ */ jsxs("div", { className: "text-chip font-mono text-text-muted mb-step-sm flex justify-between", children: [
2172
2053
  /* @__PURE__ */ jsx("span", { children: formatTime(currentTime) }),
2173
2054
  /* @__PURE__ */ jsx("span", { children: formatTime(duration) })
2174
2055
  ] }),
2175
2056
  /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
2176
2057
  /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", children: [
2177
- /* @__PURE__ */ jsx(BotonSalto, { segundos: -15, className: "p-1.5", tamano: "w-5 h-5", onSaltar: skip }),
2058
+ /* @__PURE__ */ jsx(SkipButton, { segundos: -15, className: "p-1.5", size: "w-5 h-5", onSaltar: skip }),
2178
2059
  /* @__PURE__ */ jsx(
2179
- BotonPlay,
2060
+ PlayButton,
2180
2061
  {
2181
2062
  className: "rounded-pill flex size-[34px] items-center justify-center",
2182
- tamano: "w-4 h-4",
2183
- etiqueta: etiquetaPlay,
2184
- onAlternar: togglePlay,
2185
- ...estadoPlay
2063
+ size: "w-4 h-4",
2064
+ label: playLabel,
2065
+ onToggle: togglePlay,
2066
+ ...playState
2186
2067
  }
2187
2068
  ),
2188
- /* @__PURE__ */ jsx(BotonSalto, { segundos: 15, className: "p-1.5", tamano: "w-5 h-5", onSaltar: skip })
2069
+ /* @__PURE__ */ jsx(SkipButton, { segundos: 15, className: "p-1.5", size: "w-5 h-5", onSaltar: skip })
2189
2070
  ] }),
2190
2071
  /* @__PURE__ */ jsx(
2191
- BotonVelocidad,
2072
+ SpeedButton,
2192
2073
  {
2193
2074
  className: "text-label px-1.5 py-0.5",
2194
- velocidad: playbackRate,
2195
- onCambiar: handlePlaybackRateChange
2075
+ speed: playbackRate,
2076
+ onChange: handlePlaybackRateChange
2196
2077
  }
2197
2078
  )
2198
2079
  ] })
2199
2080
  ] }),
2200
- flotanteJsx
2081
+ floatingJsx
2201
2082
  ] });
2202
2083
  }
2203
2084
  return /* @__PURE__ */ jsxs("div", { className: "bg-surface rounded-control border-border p-step-md w-full border", children: [
2204
2085
  /* @__PURE__ */ jsx("audio", { ref: audioRef, src, preload: "metadata" }),
2205
2086
  title ? /* @__PURE__ */ jsx("p", { className: "text-ui font-sans text-text-secondary mb-step-sm truncate", children: title }) : null,
2206
- /* @__PURE__ */ jsx("div", { className: "mb-step-sm", children: /* @__PURE__ */ jsx(BarraProgreso, { alto: "h-2", perilla: 16, progreso: progress, ...puntero }) }),
2087
+ /* @__PURE__ */ jsx("div", { className: "mb-step-sm", children: /* @__PURE__ */ jsx(ProgressBar, { height: "h-2", knob: 16, progress, ...pointer }) }),
2207
2088
  /* @__PURE__ */ jsxs("div", { className: "text-chip font-mono text-text-muted mb-step-sm flex justify-between", children: [
2208
2089
  /* @__PURE__ */ jsx("span", { children: formatTime(currentTime) }),
2209
2090
  /* @__PURE__ */ jsx("span", { children: formatTime(duration) })
2210
2091
  ] }),
2211
2092
  /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
2212
2093
  /* @__PURE__ */ jsxs("div", { className: "gap-step-xs flex items-center", children: [
2213
- /* @__PURE__ */ jsx(BotonSalto, { segundos: -15, className: "p-2", tamano: "w-5 h-5", onSaltar: skip }),
2094
+ /* @__PURE__ */ jsx(SkipButton, { segundos: -15, className: "p-2", size: "w-5 h-5", onSaltar: skip }),
2214
2095
  /* @__PURE__ */ jsx(
2215
- BotonPlay,
2096
+ PlayButton,
2216
2097
  {
2217
2098
  className: "rounded-pill flex size-12 items-center justify-center",
2218
- tamano: "w-6 h-6",
2219
- etiqueta: etiquetaPlay,
2220
- onAlternar: togglePlay,
2221
- ...estadoPlay
2099
+ size: "w-6 h-6",
2100
+ label: playLabel,
2101
+ onToggle: togglePlay,
2102
+ ...playState
2222
2103
  }
2223
2104
  ),
2224
- /* @__PURE__ */ jsx(BotonSalto, { segundos: 15, className: "p-2", tamano: "w-5 h-5", onSaltar: skip })
2105
+ /* @__PURE__ */ jsx(SkipButton, { segundos: 15, className: "p-2", size: "w-5 h-5", onSaltar: skip })
2225
2106
  ] }),
2226
2107
  /* @__PURE__ */ jsxs("div", { className: "gap-step-sm flex items-center", children: [
2227
2108
  /* @__PURE__ */ jsx(
2228
- BotonVelocidad,
2109
+ SpeedButton,
2229
2110
  {
2230
2111
  className: "text-label px-2 py-1",
2231
- velocidad: playbackRate,
2232
- onCambiar: handlePlaybackRateChange
2112
+ speed: playbackRate,
2113
+ onChange: handlePlaybackRateChange
2233
2114
  }
2234
2115
  ),
2235
2116
  /* @__PURE__ */ jsx(
2236
- Volumen,
2117
+ Volume,
2237
2118
  {
2238
- tamano: "w-5 h-5",
2239
- ancho: "w-20",
2119
+ size: "w-5 h-5",
2120
+ width: "w-20",
2240
2121
  silenciado: isMuted,
2241
2122
  volumen: volume,
2242
- onSilenciar: toggleMute,
2243
- onCambiarVolumen: handleVolumeChange
2123
+ onMute: toggleMute,
2124
+ onVolumeChange: handleVolumeChange
2244
2125
  }
2245
2126
  )
2246
2127
  ] })
@@ -2264,7 +2145,7 @@ function Blockquote({ children, author, source, className, ...props }) {
2264
2145
  }
2265
2146
  );
2266
2147
  }
2267
- var ENLACE = "transition-standard hover:text-accent focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent rounded-chip cursor-pointer";
2148
+ var LINK = "transition-standard hover:text-accent focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent rounded-chip cursor-pointer";
2268
2149
  function Breadcrumb({
2269
2150
  items,
2270
2151
  homeHref = "/",
@@ -2273,28 +2154,28 @@ function Breadcrumb({
2273
2154
  className,
2274
2155
  ...props
2275
2156
  }) {
2276
- const enlace = (href, contenido) => linkAsChild ? /* @__PURE__ */ jsx(Slot, { className: ENLACE, children: linkAsChild({ href, children: contenido }) }) : /* @__PURE__ */ jsx("a", { href, className: ENLACE, children: contenido });
2157
+ const link = (href, content) => linkAsChild ? /* @__PURE__ */ jsx(Slot, { className: LINK, children: linkAsChild({ href, children: content }) }) : /* @__PURE__ */ jsx("a", { href, className: LINK, children: content });
2277
2158
  return /* @__PURE__ */ jsx("nav", { "aria-label": "Ruta", className: cn("font-mono text-meta text-text-muted", className), ...props, children: /* @__PURE__ */ jsxs("ol", { className: "gap-step-xs flex flex-wrap items-center", children: [
2278
- /* @__PURE__ */ jsx("li", { children: enlace(homeHref, /* @__PURE__ */ jsx("span", { "aria-label": homeLabel, children: "~" })) }),
2159
+ /* @__PURE__ */ jsx("li", { children: link(homeHref, /* @__PURE__ */ jsx("span", { "aria-label": homeLabel, children: "~" })) }),
2279
2160
  items.map((item2, i) => {
2280
- const ultimo = i === items.length - 1;
2161
+ const last = i === items.length - 1;
2281
2162
  return /* @__PURE__ */ jsxs("li", { className: "gap-step-xs flex items-center", children: [
2282
2163
  /* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: "text-border", children: "/" }),
2283
- item2.href && !ultimo ? enlace(item2.href, item2.label) : /* @__PURE__ */ jsx("span", { "aria-current": ultimo ? "page" : void 0, className: "text-text-secondary", children: item2.label })
2164
+ item2.href && !last ? link(item2.href, item2.label) : /* @__PURE__ */ jsx("span", { "aria-current": last ? "page" : void 0, className: "text-text-secondary", children: item2.label })
2284
2165
  ] }, i);
2285
2166
  })
2286
2167
  ] }) });
2287
2168
  }
2288
2169
  function CodeBlock({ children, language, copyText, className, ...props }) {
2289
2170
  const [copiado, setCopiado] = useState(false);
2290
- const temporizador = useRef(null);
2291
- const copiar = useCallback(async () => {
2171
+ const timer = useRef(null);
2172
+ const copy = useCallback(async () => {
2292
2173
  if (!copyText) return;
2293
2174
  try {
2294
2175
  await navigator.clipboard.writeText(copyText);
2295
2176
  setCopiado(true);
2296
- if (temporizador.current) clearTimeout(temporizador.current);
2297
- temporizador.current = setTimeout(() => setCopiado(false), 2e3);
2177
+ if (timer.current) clearTimeout(timer.current);
2178
+ timer.current = setTimeout(() => setCopiado(false), 2e3);
2298
2179
  } catch {
2299
2180
  }
2300
2181
  }, [copyText]);
@@ -2318,7 +2199,7 @@ function CodeBlock({ children, language, copyText, className, ...props }) {
2318
2199
  "button",
2319
2200
  {
2320
2201
  type: "button",
2321
- onClick: copiar,
2202
+ onClick: copy,
2322
2203
  "aria-label": copiado ? "C\xF3digo copiado" : "Copiar c\xF3digo",
2323
2204
  "aria-live": "polite",
2324
2205
  className: cn(
@@ -2348,7 +2229,7 @@ function CourseCard({
2348
2229
  className,
2349
2230
  ...props
2350
2231
  }) {
2351
- return /* @__PURE__ */ jsx(Tarjeta, { className: cn("p-step-lg", className), ...props, children: /* @__PURE__ */ jsxs("article", { className: "gap-step-sm flex h-full flex-col", children: [
2232
+ return /* @__PURE__ */ jsx(CardShell, { className: cn("p-step-lg", className), ...props, children: /* @__PURE__ */ jsxs("article", { className: "gap-step-sm flex h-full flex-col", children: [
2352
2233
  status ? /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(Badge, { variant: "warm", children: status }) }) : null,
2353
2234
  /* @__PURE__ */ jsx(Text, { as: "h3", variant: "h3", className: "group-hover:text-accent transition-standard", children: title }),
2354
2235
  summary ? /* @__PURE__ */ jsx(Text, { variant: "ui", tone: "secondary", className: "line-clamp-3", children: summary }) : null,
@@ -2365,9 +2246,9 @@ function CourseCard({
2365
2246
  ] }) : null
2366
2247
  ] }) });
2367
2248
  }
2368
- var CARA = "w-[66px] max-w-none";
2249
+ var FACE = "w-[66px] max-w-none";
2369
2250
  function EmptyState({
2370
- expresion,
2251
+ expression,
2371
2252
  title,
2372
2253
  description,
2373
2254
  action,
@@ -2378,10 +2259,10 @@ function EmptyState({
2378
2259
  return /* @__PURE__ */ jsxs(
2379
2260
  "div",
2380
2261
  {
2381
- className: cn(SUPERFICIE_TARJETA, "p-step-lg gap-step-sm flex flex-col items-center text-center", className),
2262
+ className: cn(CARD_SURFACE, "p-step-lg gap-step-sm flex flex-col items-center text-center", className),
2382
2263
  ...props,
2383
2264
  children: [
2384
- /* @__PURE__ */ jsx(CaraDeMascota, { expresion, className: CARA, basePath }),
2265
+ /* @__PURE__ */ jsx(MascotFace, { expression, className: FACE, basePath }),
2385
2266
  /* @__PURE__ */ jsx(Text, { variant: "ui", as: "p", className: "font-medium", children: title }),
2386
2267
  description ? /* @__PURE__ */ jsx(Text, { variant: "label", tone: "muted", as: "p", className: "max-w-measure font-normal", children: description }) : null,
2387
2268
  action ? /* @__PURE__ */ jsx("div", { className: "mt-step-xs", children: action }) : null
@@ -2389,12 +2270,12 @@ function EmptyState({
2389
2270
  }
2390
2271
  );
2391
2272
  }
2392
- var mismoDia = (a, b) => a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() && a.getDate() === b.getDate();
2393
- function aValorDeCampo(fecha) {
2394
- const dos = (n) => String(n).padStart(2, "0");
2395
- return `${fecha.getFullYear()}-${dos(fecha.getMonth() + 1)}-${dos(fecha.getDate())}T${dos(
2396
- fecha.getHours()
2397
- )}:${dos(fecha.getMinutes())}`;
2273
+ var sameDay = (a, b) => a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() && a.getDate() === b.getDate();
2274
+ function toFieldValue(date) {
2275
+ const two = (n) => String(n).padStart(2, "0");
2276
+ return `${date.getFullYear()}-${two(date.getMonth() + 1)}-${two(date.getDate())}T${two(
2277
+ date.getHours()
2278
+ )}:${two(date.getMinutes())}`;
2398
2279
  }
2399
2280
  function EventCalendar({
2400
2281
  events,
@@ -2403,68 +2284,68 @@ function EventCalendar({
2403
2284
  onDeleteEvent,
2404
2285
  selected,
2405
2286
  onSelectDay,
2406
- formatDay = (dia) => format(dia, "EEEE d 'de' MMMM", { locale: es }),
2407
- formatTime: formatTime2 = (fecha) => format(fecha, "HH:mm", { locale: es }),
2287
+ formatDay = (day) => format(day, "EEEE d 'de' MMMM", { locale: es }),
2288
+ formatTime: formatTime2 = (date) => format(date, "HH:mm", { locale: es }),
2408
2289
  emptyMessage = "Nada en este d\xEDa.",
2409
2290
  className,
2410
2291
  ...props
2411
2292
  }) {
2412
2293
  const id = useId();
2413
2294
  const [diaInterno, setDiaInterno] = useState(() => selected ?? /* @__PURE__ */ new Date());
2414
- const dia = selected ?? diaInterno;
2415
- const [mes, setMes] = useState(() => dia);
2416
- const [editando, setEditando] = useState(null);
2417
- const [titulo, setTitulo] = useState("");
2418
- const [cuando, setCuando] = useState("");
2295
+ const day = selected ?? diaInterno;
2296
+ const [month, setMonth] = useState(() => day);
2297
+ const [editing, setEditing] = useState(null);
2298
+ const [title, setTitle] = useState("");
2299
+ const [when, setWhen] = useState("");
2419
2300
  const editable = Boolean(onCreateEvent ?? onUpdateEvent);
2420
- const delDia = events.filter((e) => mismoDia(e.start, dia)).sort((a, b) => a.start.getTime() - b.start.getTime());
2421
- function elegirDia(nuevo) {
2301
+ const ofTheDay = events.filter((e) => sameDay(e.start, day)).sort((a, b) => a.start.getTime() - b.start.getTime());
2302
+ function pickDay(nuevo) {
2422
2303
  if (!nuevo) return;
2423
2304
  setDiaInterno(nuevo);
2424
- setMes(nuevo);
2305
+ setMonth(nuevo);
2425
2306
  onSelectDay?.(nuevo);
2426
- cancelar();
2307
+ cancel();
2427
2308
  }
2428
- function cancelar() {
2429
- setEditando(null);
2430
- setTitulo("");
2431
- setCuando("");
2309
+ function cancel() {
2310
+ setEditing(null);
2311
+ setTitle("");
2312
+ setWhen("");
2432
2313
  }
2433
- function editar(evento) {
2434
- setEditando(evento.id);
2435
- setTitulo(evento.title);
2436
- setCuando(aValorDeCampo(evento.start));
2314
+ function edit(event) {
2315
+ setEditing(event.id);
2316
+ setTitle(event.title);
2317
+ setWhen(toFieldValue(event.start));
2437
2318
  }
2438
- function enviar(e) {
2319
+ function submit(e) {
2439
2320
  e.preventDefault();
2440
- if (!titulo.trim() || !cuando) return;
2441
- const start = new Date(cuando);
2321
+ if (!title.trim() || !when) return;
2322
+ const start = new Date(when);
2442
2323
  if (Number.isNaN(start.getTime())) return;
2443
- if (editando) {
2444
- const previo = events.find((ev) => ev.id === editando);
2445
- if (previo) onUpdateEvent?.({ ...previo, title: titulo.trim(), start });
2324
+ if (editing) {
2325
+ const previous = events.find((ev) => ev.id === editing);
2326
+ if (previous) onUpdateEvent?.({ ...previous, title: title.trim(), start });
2446
2327
  } else {
2447
- onCreateEvent?.({ title: titulo.trim(), start });
2328
+ onCreateEvent?.({ title: title.trim(), start });
2448
2329
  }
2449
- cancelar();
2330
+ cancel();
2450
2331
  }
2451
- const conEvento = events.map((e) => e.start);
2332
+ const withEvent = events.map((e) => e.start);
2452
2333
  return /* @__PURE__ */ jsxs("div", { className: cn("gap-step-lg flex flex-col md:flex-row md:items-start", className), ...props, children: [
2453
2334
  /* @__PURE__ */ jsx(
2454
2335
  Calendar,
2455
2336
  {
2456
2337
  mode: "single",
2457
- selected: dia,
2458
- onSelect: elegirDia,
2459
- month: mes,
2460
- onMonthChange: setMes,
2461
- modifiers: { conEvento },
2338
+ selected: day,
2339
+ onSelect: pickDay,
2340
+ month,
2341
+ onMonthChange: setMonth,
2342
+ modifiers: { withEvent },
2462
2343
  modifiersClassNames: {
2463
- // El punto va bajo el número, no encima del fondo del día: sobre el
2464
- // seleccionado —que es bioluz sólido— un punto de acento desaparece.
2465
- // `after:` en Tailwind v4 ya trae `content: ""`, así que no hace falta
2466
- // declararlo con un valor arbitrario.
2467
- conEvento: cn(
2344
+ // The dot goes under the number, not on top of the day's background:
2345
+ // over the selected one — which is solid biolume — an accent dot
2346
+ // disappears. `after:` in Tailwind v4 already ships `content: ""`, so
2347
+ // there is no need to declare it with an arbitrary value.
2348
+ withEvent: cn(
2468
2349
  "after:bg-accent after:absolute after:bottom-1 after:left-1/2",
2469
2350
  "after:size-1 after:-translate-x-1/2 after:rounded-pill",
2470
2351
  "[&[data-selected=true]]:after:bg-accent-on"
@@ -2479,8 +2360,8 @@ function EventCalendar({
2479
2360
  "aria-labelledby": `${id}-dia`,
2480
2361
  className: "border-hairline rounded-card p-step-md gap-step-md flex min-w-0 flex-1 flex-col border",
2481
2362
  children: [
2482
- /* @__PURE__ */ jsx(Text, { as: "h3", variant: "h3", id: `${id}-dia`, className: "first-letter:uppercase", children: formatDay(dia) }),
2483
- delDia.length > 0 ? /* @__PURE__ */ jsx("ul", { className: "gap-step-xs flex flex-col", children: delDia.map((evento) => /* @__PURE__ */ jsxs(
2363
+ /* @__PURE__ */ jsx(Text, { as: "h3", variant: "h3", id: `${id}-dia`, className: "first-letter:uppercase", children: formatDay(day) }),
2364
+ ofTheDay.length > 0 ? /* @__PURE__ */ jsx("ul", { className: "gap-step-xs flex flex-col", children: ofTheDay.map((event) => /* @__PURE__ */ jsxs(
2484
2365
  "li",
2485
2366
  {
2486
2367
  className: "border-hairline gap-step-sm py-step-xs flex items-center border-b last:border-b-0",
@@ -2490,85 +2371,85 @@ function EventCalendar({
2490
2371
  {
2491
2372
  as: "span",
2492
2373
  variant: "meta",
2493
- tone: evento.tone === "warm" ? "warm" : "accent",
2374
+ tone: event.tone === "warm" ? "warm" : "accent",
2494
2375
  className: "shrink-0 tabular-nums",
2495
- children: /* @__PURE__ */ jsx("time", { dateTime: evento.start.toISOString(), children: formatTime2(evento.start) })
2376
+ children: /* @__PURE__ */ jsx("time", { dateTime: event.start.toISOString(), children: formatTime2(event.start) })
2496
2377
  }
2497
2378
  ),
2498
- /* @__PURE__ */ jsx(Text, { as: "span", variant: "ui", className: "min-w-0 flex-1 truncate", children: evento.title }),
2379
+ /* @__PURE__ */ jsx(Text, { as: "span", variant: "ui", className: "min-w-0 flex-1 truncate", children: event.title }),
2499
2380
  onUpdateEvent ? /* @__PURE__ */ jsx(
2500
2381
  Button,
2501
2382
  {
2502
2383
  variant: "tertiary",
2503
2384
  size: "sm",
2504
- onClick: () => editar(evento),
2505
- "aria-label": `Editar \xAB${evento.title}\xBB`,
2506
- children: "./editar"
2385
+ onClick: () => edit(event),
2386
+ "aria-label": `Editar \xAB${event.title}\xBB`,
2387
+ children: "./edit"
2507
2388
  }
2508
2389
  ) : null,
2509
2390
  onDeleteEvent ? /* @__PURE__ */ jsxs(AlertDialog, { children: [
2510
- /* @__PURE__ */ jsx(AlertDialogTrigger, { asChild: true, children: /* @__PURE__ */ jsx(Button, { variant: "tertiary", size: "sm", "aria-label": `Borrar \xAB${evento.title}\xBB`, children: "./borrar" }) }),
2391
+ /* @__PURE__ */ jsx(AlertDialogTrigger, { asChild: true, children: /* @__PURE__ */ jsx(Button, { variant: "tertiary", size: "sm", "aria-label": `Borrar \xAB${event.title}\xBB`, children: "./borrar" }) }),
2511
2392
  /* @__PURE__ */ jsxs(AlertDialogContent, { children: [
2512
2393
  /* @__PURE__ */ jsxs(AlertDialogHeader, { children: [
2513
2394
  /* @__PURE__ */ jsxs(AlertDialogTitle, { children: [
2514
2395
  "Borrar \xAB",
2515
- evento.title,
2396
+ event.title,
2516
2397
  "\xBB"
2517
2398
  ] }),
2518
2399
  /* @__PURE__ */ jsxs(AlertDialogDescription, { children: [
2519
2400
  "Se borra del ",
2520
- formatDay(evento.start),
2401
+ formatDay(event.start),
2521
2402
  " a las ",
2522
- formatTime2(evento.start),
2403
+ formatTime2(event.start),
2523
2404
  ". No se puede deshacer."
2524
2405
  ] })
2525
2406
  ] }),
2526
2407
  /* @__PURE__ */ jsxs(AlertDialogFooter, { children: [
2527
2408
  /* @__PURE__ */ jsx(AlertDialogCancel, { children: "Mejor no" }),
2528
- /* @__PURE__ */ jsx(AlertDialogAction, { onClick: () => onDeleteEvent(evento.id), children: "Borrar el evento" })
2409
+ /* @__PURE__ */ jsx(AlertDialogAction, { onClick: () => onDeleteEvent(event.id), children: "Borrar el event" })
2529
2410
  ] })
2530
2411
  ] })
2531
2412
  ] }) : null
2532
2413
  ]
2533
2414
  },
2534
- evento.id
2415
+ event.id
2535
2416
  )) }) : (
2536
- // `EmptyState` no: lleva una cara de la mascota, y la mascota tiene
2537
- // siete sitios contados donde puede aparecer. Un día vacío de una
2538
- // agenda no es uno de ellos — y en un mes de treinta días, la mitad lo
2539
- // serían.
2417
+ // `EmptyState` is not used: it carries a mascot face, and the mascot
2418
+ // has seven counted places where it may appear. An empty day in a
2419
+ // schedule is not one of them — and in a thirty-day month, half of them
2420
+ // would be.
2540
2421
  /* @__PURE__ */ jsx(Text, { as: "p", variant: "ui", tone: "muted", children: emptyMessage })
2541
2422
  ),
2542
- editable ? /* @__PURE__ */ jsxs("form", { onSubmit: enviar, className: "gap-step-sm border-hairline pt-step-md flex flex-col border-t", children: [
2423
+ editable ? /* @__PURE__ */ jsxs("form", { onSubmit: submit, className: "gap-step-sm border-hairline pt-step-md flex flex-col border-t", children: [
2543
2424
  /* @__PURE__ */ jsxs("div", { className: "gap-step-xs flex flex-col", children: [
2544
- /* @__PURE__ */ jsx(Label, { htmlFor: `${id}-titulo`, children: "T\xEDtulo" }),
2425
+ /* @__PURE__ */ jsx(Label, { htmlFor: `${id}-title`, children: "T\xEDtulo" }),
2545
2426
  /* @__PURE__ */ jsx(
2546
2427
  Input,
2547
2428
  {
2548
- id: `${id}-titulo`,
2549
- value: titulo,
2550
- onChange: (e) => setTitulo(e.target.value),
2429
+ id: `${id}-title`,
2430
+ value: title,
2431
+ onChange: (e) => setTitle(e.target.value),
2551
2432
  placeholder: "Publicar el art\xEDculo",
2552
2433
  required: true
2553
2434
  }
2554
2435
  )
2555
2436
  ] }),
2556
2437
  /* @__PURE__ */ jsxs("div", { className: "gap-step-xs flex flex-col", children: [
2557
- /* @__PURE__ */ jsx(Label, { htmlFor: `${id}-cuando`, children: "Cu\xE1ndo" }),
2438
+ /* @__PURE__ */ jsx(Label, { htmlFor: `${id}-when`, children: "Cu\xE1ndo" }),
2558
2439
  /* @__PURE__ */ jsx(
2559
2440
  DateField,
2560
2441
  {
2561
- id: `${id}-cuando`,
2442
+ id: `${id}-when`,
2562
2443
  withTime: true,
2563
- value: cuando,
2564
- onChange: (e) => setCuando(e.target.value),
2444
+ value: when,
2445
+ onChange: (e) => setWhen(e.target.value),
2565
2446
  required: true
2566
2447
  }
2567
2448
  )
2568
2449
  ] }),
2569
2450
  /* @__PURE__ */ jsxs("div", { className: "gap-step-sm flex flex-wrap items-center", children: [
2570
- /* @__PURE__ */ jsx(Button, { type: "submit", size: "sm", children: editando ? "Guardar" : "A\xF1adir" }),
2571
- editando ? /* @__PURE__ */ jsx(Button, { type: "button", variant: "tertiary", size: "sm", onClick: cancelar, children: "./cancelar" }) : null
2451
+ /* @__PURE__ */ jsx(Button, { type: "submit", size: "sm", children: editing ? "Guardar" : "A\xF1adir" }),
2452
+ editing ? /* @__PURE__ */ jsx(Button, { type: "button", variant: "tertiary", size: "sm", onClick: cancel, children: "./cancel" }) : null
2572
2453
  ] })
2573
2454
  ] }) : null
2574
2455
  ]
@@ -2584,43 +2465,56 @@ function Footer({
2584
2465
  className,
2585
2466
  ...props
2586
2467
  }) {
2468
+ const signature = /* @__PURE__ */ jsxs(Text, { variant: "meta", tone: "muted", as: "p", className: "ml-auto shrink-0", children: [
2469
+ /* @__PURE__ */ jsxs("span", { "aria-hidden": "true", className: "text-accent", children: [
2470
+ "$",
2471
+ " "
2472
+ ] }),
2473
+ "cd ~/",
2474
+ naming.domain,
2475
+ "/",
2476
+ year,
2477
+ /* @__PURE__ */ jsx(
2478
+ "span",
2479
+ {
2480
+ "aria-hidden": "true",
2481
+ className: "bg-accent motion-safe:caret ml-[0.2em] inline-block h-[1em] w-[0.5em] translate-y-[0.15em]"
2482
+ }
2483
+ )
2484
+ ] });
2485
+ const rows = [
2486
+ brand2 ? /* @__PURE__ */ jsx("div", { className: "flex items-center", children: brand2 }, "marca") : null,
2487
+ children ? /* @__PURE__ */ jsx("div", { className: "gap-step-md flex flex-wrap items-center", children }, "enlaces") : null,
2488
+ social && social.length > 0 ? (
2489
+ // 18px of separation, from the document. It is not a `spacing` step: it is
2490
+ // the rhythm of a row of icons, not that of a page.
2491
+ /* @__PURE__ */ jsx("ul", { className: "flex items-center gap-[18px]", children: social.map((socialLink) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx(
2492
+ "a",
2493
+ {
2494
+ href: socialLink.href,
2495
+ "aria-label": socialLink.label,
2496
+ className: cn(
2497
+ "text-text-muted hover:text-accent transition-standard block cursor-pointer text-[19px]",
2498
+ "rounded-chip focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent"
2499
+ ),
2500
+ children: socialLink.icon
2501
+ }
2502
+ ) }, socialLink.href)) }, "socialLinks")
2503
+ ) : null
2504
+ ].filter(Boolean);
2505
+ const [first, ...rest] = rows;
2587
2506
  return /* @__PURE__ */ jsx("footer", { className: cn("border-hairline w-full border-t", className), ...props, children: /* @__PURE__ */ jsxs("div", { className: "max-w-wide px-step-md py-step-xl gap-step-lg mx-auto flex flex-col", children: [
2588
- brand2 ? /* @__PURE__ */ jsx("div", { className: "flex items-center", children: brand2 }) : null,
2589
- children ? /* @__PURE__ */ jsx("div", { className: "gap-step-md flex flex-wrap items-center", children }) : null,
2590
2507
  /* @__PURE__ */ jsxs("div", { className: "gap-step-md flex flex-wrap items-center", children: [
2591
- social && social.length > 0 ? (
2592
- // 18px de separación, del documento. No es un escalón de `spacing`:
2593
- // es el ritmo de una fila de iconos, no el de una página.
2594
- /* @__PURE__ */ jsx("ul", { className: "flex items-center gap-[18px]", children: social.map((red) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx(
2595
- "a",
2596
- {
2597
- href: red.href,
2598
- "aria-label": red.label,
2599
- className: cn(
2600
- "text-text-muted hover:text-accent transition-standard block cursor-pointer text-[19px]",
2601
- "rounded-chip focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent"
2602
- ),
2603
- children: red.icon
2604
- }
2605
- ) }, red.href)) })
2606
- ) : null,
2607
- /* @__PURE__ */ jsxs(Text, { variant: "meta", tone: "muted", as: "p", className: "ml-auto", children: [
2608
- /* @__PURE__ */ jsxs("span", { "aria-hidden": "true", className: "text-accent", children: [
2609
- "$",
2610
- " "
2611
- ] }),
2612
- "cd ~/",
2613
- naming.domain,
2614
- "/",
2615
- year
2616
- ] })
2617
- ] })
2508
+ first ?? null,
2509
+ signature
2510
+ ] }),
2511
+ rest
2618
2512
  ] }) });
2619
2513
  }
2620
2514
  function FooterLink({ asChild = false, className, ...props }) {
2621
- const Raiz = asChild ? Slot : "a";
2515
+ const Root17 = asChild ? Slot : "a";
2622
2516
  return /* @__PURE__ */ jsx(
2623
- Raiz,
2517
+ Root17,
2624
2518
  {
2625
2519
  className: cn(
2626
2520
  "font-mono text-meta text-text-secondary hover:text-accent transition-standard cursor-pointer",
@@ -2638,24 +2532,24 @@ function Hero({
2638
2532
  action,
2639
2533
  pose,
2640
2534
  basePath,
2641
- variant = "cabecera",
2535
+ variant = "header",
2642
2536
  className,
2643
2537
  ...props
2644
2538
  }) {
2645
- const centrado = variant === "centrado";
2539
+ const centered = variant === "centered";
2646
2540
  return /* @__PURE__ */ jsxs(
2647
2541
  "section",
2648
2542
  {
2649
2543
  className: cn(
2650
- "degradado-hero rounded-panel border-hairline relative overflow-hidden border",
2651
- // 44 arriba, 40 a los lados y abajo. Del documento.
2544
+ "gradient-hero rounded-panel border-hairline relative overflow-hidden border",
2545
+ // 44 top, 40 on the sides and bottom. From the document.
2652
2546
  "px-step-xl pt-[44px] pb-step-xl",
2653
2547
  className
2654
2548
  ),
2655
2549
  ...props,
2656
2550
  children: [
2657
- centrado && pose ? /* @__PURE__ */ jsx(
2658
- Mascota,
2551
+ centered && pose ? /* @__PURE__ */ jsx(
2552
+ Mascot,
2659
2553
  {
2660
2554
  pose,
2661
2555
  basePath,
@@ -2667,7 +2561,7 @@ function Hero({
2667
2561
  {
2668
2562
  className: cn(
2669
2563
  "gap-step-md flex flex-col",
2670
- centrado ? "items-center text-center" : "md:max-w-[62%]"
2564
+ centered ? "items-center text-center" : "md:max-w-[62%]"
2671
2565
  ),
2672
2566
  children: [
2673
2567
  eyebrow ? /* @__PURE__ */ jsx(Text, { variant: "eyebrow", tone: "accent", as: "p", children: eyebrow }) : null,
@@ -2678,7 +2572,7 @@ function Hero({
2678
2572
  {
2679
2573
  className: cn(
2680
2574
  "gap-step-sm mt-step-xs flex flex-wrap items-center",
2681
- centrado && "justify-center"
2575
+ centered && "justify-center"
2682
2576
  ),
2683
2577
  children: action
2684
2578
  }
@@ -2686,14 +2580,14 @@ function Hero({
2686
2580
  ]
2687
2581
  }
2688
2582
  ),
2689
- !centrado && pose ? /* @__PURE__ */ jsx(
2690
- Mascota,
2583
+ !centered && pose ? /* @__PURE__ */ jsx(
2584
+ Mascot,
2691
2585
  {
2692
2586
  pose,
2693
2587
  basePath,
2694
2588
  className: cn(
2695
- // En móvil, en el flujo y bajo los botones. Desde md, sangrando por
2696
- // la esquina inferior derecha.
2589
+ // On mobile, in the flow and below the buttons. From md up, bleeding
2590
+ // off the bottom-right corner.
2697
2591
  "mt-step-lg mx-auto w-40",
2698
2592
  "md:mt-0 md:absolute md:right-0 md:-bottom-4 md:mx-0 md:w-64"
2699
2593
  )
@@ -2714,7 +2608,7 @@ function LinkRow({
2714
2608
  const rel = external ? "noopener noreferrer" : props.rel;
2715
2609
  const target = external ? "_blank" : props.target;
2716
2610
  return /* @__PURE__ */ jsx(
2717
- Tarjeta,
2611
+ CardShell,
2718
2612
  {
2719
2613
  className: cn("px-step-md py-step-sm", className),
2720
2614
  ...props,
@@ -2743,8 +2637,8 @@ function Nav({ brand: brand2, children, actions, className, ...props }) {
2743
2637
  {
2744
2638
  className: cn(
2745
2639
  "sticky top-0 z-50 w-full",
2746
- // abismo al 86 % con 14px de desenfoque detrás. El alfa va sobre el
2747
- // token, así que sigue el modo: en claro es papel al 86 %.
2640
+ // Abyss at 86 % with 14px of blur behind. The alpha rides on the token,
2641
+ // so it follows the mode: in light it is paper at 86 %.
2748
2642
  "bg-background/86 backdrop-blur-[14px]",
2749
2643
  "border-hairline border-b",
2750
2644
  className
@@ -2762,9 +2656,9 @@ function Nav({ brand: brand2, children, actions, className, ...props }) {
2762
2656
  );
2763
2657
  }
2764
2658
  function NavItem({ active = false, asChild = false, className, children, ...props }) {
2765
- const Raiz = asChild ? Slot : "a";
2659
+ const Root17 = asChild ? Slot : "a";
2766
2660
  return /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsxs(
2767
- Raiz,
2661
+ Root17,
2768
2662
  {
2769
2663
  "aria-current": active ? "page" : void 0,
2770
2664
  className: cn(
@@ -2786,39 +2680,49 @@ function NavItem({ active = false, asChild = false, className, children, ...prop
2786
2680
  function NewsletterForm({
2787
2681
  title,
2788
2682
  description,
2789
- state = "reposo",
2683
+ state = "idle",
2790
2684
  onSubmitEmail,
2791
- successMessage = "Ya est\xE1s dentro. Te llega un correo cada dos semanas, y nada m\xE1s.",
2792
- errorMessage = "No se pudo suscribir ese correo. Rev\xEDsalo y vuelve a intentar.",
2685
+ successMessage = "Ya est\xE1s dentro. Te llega un email cada dos semanas, y nada m\xE1s.",
2686
+ errorMessage = "No se pudo suscribir ese email. Rev\xEDsalo y vuelve a intentar.",
2793
2687
  disclaimer,
2794
- expresion,
2688
+ expression,
2795
2689
  basePath,
2796
2690
  submitLabel = "Suscribirme",
2797
- placeholder = "tu@correo.dev",
2798
- fieldLabel = "Correo electr\xF3nico",
2691
+ placeholder = "tu@email.dev",
2692
+ fieldLabel = "Email electr\xF3nico",
2799
2693
  nameField = false,
2800
2694
  nameLabel = "Nombre",
2801
2695
  namePlaceholder = "C\xF3mo te llamas",
2802
2696
  nameInputProps,
2697
+ aside,
2698
+ resetOnSuccess = true,
2699
+ onFieldChange,
2700
+ fieldErrors,
2803
2701
  className,
2804
2702
  ...props
2805
2703
  }) {
2806
2704
  const id = useId();
2807
- const enviando = state === "enviando";
2705
+ const form = useRef(null);
2706
+ const sending = state === "sending";
2808
2707
  const error = state === "error";
2809
- function enviar(evento) {
2810
- evento.preventDefault();
2811
- const datos = new FormData(evento.currentTarget);
2812
- const correo = String(datos.get("email") ?? "");
2813
- const nombre = nameField ? String(datos.get("name") ?? "") : void 0;
2814
- onSubmitEmail?.(correo, nombre);
2708
+ const nameError = fieldErrors?.name;
2709
+ const emailError = fieldErrors?.email;
2710
+ useEffect(() => {
2711
+ if (state === "success" && resetOnSuccess) form.current?.reset();
2712
+ }, [state, resetOnSuccess]);
2713
+ function submit(event) {
2714
+ event.preventDefault();
2715
+ const data = new FormData(event.currentTarget);
2716
+ const email = String(data.get("email") ?? "");
2717
+ const name = nameField ? String(data.get("name") ?? "") : void 0;
2718
+ onSubmitEmail?.(email, name);
2815
2719
  }
2816
- const boton = /* @__PURE__ */ jsx(
2720
+ const button2 = /* @__PURE__ */ jsx(
2817
2721
  Button,
2818
2722
  {
2819
2723
  type: "submit",
2820
2724
  variant: "conversion",
2821
- loading: enviando,
2725
+ loading: sending,
2822
2726
  className: cn("disabled:opacity-60", nameField && "sm:self-start"),
2823
2727
  children: submitLabel
2824
2728
  }
@@ -2827,65 +2731,79 @@ function NewsletterForm({
2827
2731
  "section",
2828
2732
  {
2829
2733
  className: cn(
2830
- "degradado-seccion rounded-panel border-hairline p-step-lg gap-step-md flex flex-col border",
2734
+ "gradient-section rounded-panel border-hairline p-step-lg border",
2735
+ // Two columns from `md` up when there is an illustration, one otherwise.
2736
+ // `items-center` centres the pose against the block of text and form
2737
+ // rather than against the panel, which is what the blog was doing by
2738
+ // hand with an absolute position and a reserved `pr`.
2739
+ aside ? "gap-step-lg flex flex-col md:flex-row md:items-center" : "gap-step-md flex flex-col",
2831
2740
  className
2832
2741
  ),
2833
2742
  ...props,
2834
2743
  children: [
2835
- /* @__PURE__ */ jsxs("div", { className: "gap-step-xs flex flex-col", children: [
2836
- /* @__PURE__ */ jsx(Text, { as: "h2", variant: "h3", children: title }),
2837
- description ? /* @__PURE__ */ jsx(Text, { variant: "ui", tone: "secondary", children: description }) : null
2838
- ] }),
2839
- /* @__PURE__ */ jsxs("form", { onSubmit: enviar, className: "gap-step-sm flex flex-col", noValidate: true, children: [
2840
- /* @__PURE__ */ jsxs("div", { className: "gap-step-sm flex flex-col sm:flex-row sm:items-end", children: [
2841
- nameField ? /* @__PURE__ */ jsxs("div", { className: "gap-step-xs flex flex-1 flex-col", children: [
2842
- /* @__PURE__ */ jsx(Label, { htmlFor: `${id}-nombre`, children: nameLabel }),
2843
- /* @__PURE__ */ jsx(
2844
- Input,
2845
- {
2846
- id: `${id}-nombre`,
2847
- name: "name",
2848
- type: "text",
2849
- autoComplete: "name",
2850
- required: true,
2851
- placeholder: namePlaceholder,
2852
- disabled: enviando,
2853
- ...nameInputProps
2854
- }
2855
- )
2856
- ] }) : null,
2857
- /* @__PURE__ */ jsxs("div", { className: "gap-step-xs flex flex-1 flex-col", children: [
2858
- /* @__PURE__ */ jsx(Label, { htmlFor: id, children: fieldLabel }),
2859
- /* @__PURE__ */ jsx(
2860
- Input,
2861
- {
2862
- id,
2863
- name: "email",
2864
- type: "email",
2865
- autoComplete: "email",
2866
- required: true,
2867
- placeholder,
2868
- disabled: enviando,
2869
- invalid: error,
2870
- "aria-describedby": state === "exito" || error ? `${id}-aviso` : void 0
2871
- }
2872
- )
2744
+ /* @__PURE__ */ jsxs("div", { className: cn("gap-step-md flex min-w-0 flex-1 flex-col"), children: [
2745
+ /* @__PURE__ */ jsxs("div", { className: "gap-step-xs flex flex-col", children: [
2746
+ /* @__PURE__ */ jsx(Text, { as: "h2", variant: "h3", children: title }),
2747
+ description ? /* @__PURE__ */ jsx(Text, { variant: "ui", tone: "secondary", children: description }) : null
2748
+ ] }),
2749
+ /* @__PURE__ */ jsxs("form", { ref: form, onSubmit: submit, className: "gap-step-sm flex flex-col", noValidate: true, children: [
2750
+ /* @__PURE__ */ jsxs("div", { className: "gap-step-sm flex flex-col sm:flex-row sm:items-start", children: [
2751
+ nameField ? /* @__PURE__ */ jsxs("div", { className: "gap-step-xs flex flex-1 flex-col", children: [
2752
+ /* @__PURE__ */ jsx(Label, { htmlFor: `${id}-name`, children: nameLabel }),
2753
+ /* @__PURE__ */ jsx(
2754
+ Input,
2755
+ {
2756
+ id: `${id}-name`,
2757
+ name: "name",
2758
+ type: "text",
2759
+ autoComplete: "name",
2760
+ required: true,
2761
+ placeholder: namePlaceholder,
2762
+ disabled: sending,
2763
+ invalid: Boolean(nameError),
2764
+ "aria-describedby": nameError ? `${id}-name-error` : void 0,
2765
+ onChange: (e) => onFieldChange?.("name", e.currentTarget.value),
2766
+ ...nameInputProps
2767
+ }
2768
+ ),
2769
+ nameError ? /* @__PURE__ */ jsx(Text, { id: `${id}-name-error`, variant: "label", tone: "error", as: "p", role: "alert", children: nameError }) : null
2770
+ ] }) : null,
2771
+ /* @__PURE__ */ jsxs("div", { className: "gap-step-xs flex flex-1 flex-col", children: [
2772
+ /* @__PURE__ */ jsx(Label, { htmlFor: id, children: fieldLabel }),
2773
+ /* @__PURE__ */ jsx(
2774
+ Input,
2775
+ {
2776
+ id,
2777
+ name: "email",
2778
+ type: "email",
2779
+ autoComplete: "email",
2780
+ required: true,
2781
+ placeholder,
2782
+ disabled: sending,
2783
+ invalid: error || Boolean(emailError),
2784
+ onChange: (e) => onFieldChange?.("email", e.currentTarget.value),
2785
+ "aria-describedby": emailError ? `${id}-email-error` : state === "success" || error ? `${id}-notice` : void 0
2786
+ }
2787
+ ),
2788
+ emailError ? /* @__PURE__ */ jsx(Text, { id: `${id}-email-error`, variant: "label", tone: "error", as: "p", role: "alert", children: emailError }) : null
2789
+ ] }),
2790
+ nameField ? null : /* @__PURE__ */ jsx("div", { className: "sm:mt-[26px]", children: button2 })
2873
2791
  ] }),
2874
- nameField ? null : boton
2792
+ nameField ? button2 : null
2875
2793
  ] }),
2876
- nameField ? boton : null
2794
+ state === "success" ? /* @__PURE__ */ jsx(Alert, { id: `${id}-notice`, variant: "success", emphasis: "strong", children: successMessage }) : null,
2795
+ error ? /* @__PURE__ */ jsx(Alert, { id: `${id}-notice`, variant: "error", emphasis: "strong", children: errorMessage }) : null,
2796
+ disclaimer ? /* @__PURE__ */ jsxs("div", { className: "gap-step-sm flex items-center", children: [
2797
+ expression ? /* @__PURE__ */ jsx(MascotFace, { expression, basePath, className: "w-10 max-w-none" }) : null,
2798
+ /* @__PURE__ */ jsx(Text, { variant: "label", tone: "muted", as: "p", className: "font-normal", children: disclaimer })
2799
+ ] }) : null
2877
2800
  ] }),
2878
- state === "exito" ? /* @__PURE__ */ jsx(Alert, { id: `${id}-aviso`, variant: "success", enfasis: "fuerte", children: successMessage }) : null,
2879
- error ? /* @__PURE__ */ jsx(Alert, { id: `${id}-aviso`, variant: "error", enfasis: "fuerte", children: errorMessage }) : null,
2880
- disclaimer ? /* @__PURE__ */ jsxs("div", { className: "gap-step-sm flex items-center", children: [
2881
- expresion ? /* @__PURE__ */ jsx(CaraDeMascota, { expresion, basePath, className: "w-10 max-w-none" }) : null,
2882
- /* @__PURE__ */ jsx(Text, { variant: "label", tone: "muted", as: "p", className: "font-normal", children: disclaimer })
2883
- ] }) : null
2801
+ aside ? /* @__PURE__ */ jsx("div", { className: "shrink-0 md:max-w-[42%]", children: aside }) : null
2884
2802
  ]
2885
2803
  }
2886
2804
  );
2887
2805
  }
2888
- var cabecera = cva("gap-step-sm flex flex-col", {
2806
+ var header = cva("gap-step-sm flex flex-col", {
2889
2807
  variants: {
2890
2808
  size: {
2891
2809
  display: "py-section",
@@ -2904,7 +2822,7 @@ function PageHeader({
2904
2822
  className,
2905
2823
  ...props
2906
2824
  }) {
2907
- return /* @__PURE__ */ jsxs("header", { className: cn(cabecera({ size: size2 }), className), ...props, children: [
2825
+ return /* @__PURE__ */ jsxs("header", { className: cn(header({ size: size2 }), className), ...props, children: [
2908
2826
  eyebrow ? /* @__PURE__ */ jsx(Text, { variant: "eyebrow", tone: "accent", as: "p", children: eyebrow }) : null,
2909
2827
  /* @__PURE__ */ jsx(Text, { as, variant: size2 === "display" ? "display" : "h1", className: "max-w-measure", children: title }),
2910
2828
  description ? /* @__PURE__ */ jsx(Text, { variant: "body", tone: "secondary", children: description }) : null,
@@ -2918,33 +2836,33 @@ function ScrollingProgressBar({
2918
2836
  className,
2919
2837
  ...props
2920
2838
  }) {
2921
- const [avance, setAvance] = useState(0);
2922
- const pendiente = useRef(0);
2839
+ const [seek, setAvance] = useState(0);
2840
+ const pendingOne = useRef(0);
2923
2841
  useEffect(() => {
2924
- const medir = () => {
2925
- pendiente.current = 0;
2926
- const elemento = target?.current;
2927
- const inicio = elemento ? elemento.getBoundingClientRect().top + scrollY : 0;
2928
- const alto = elemento ? elemento.offsetHeight : document.documentElement.scrollHeight;
2929
- const recorrible = alto - innerHeight;
2930
- if (recorrible <= 0) {
2931
- setAvance(scrollY >= inicio ? 100 : 0);
2842
+ const measure = () => {
2843
+ pendingOne.current = 0;
2844
+ const element = target?.current;
2845
+ const start = element ? element.getBoundingClientRect().top + scrollY : 0;
2846
+ const height = element ? element.offsetHeight : document.documentElement.scrollHeight;
2847
+ const walkable = height - innerHeight;
2848
+ if (walkable <= 0) {
2849
+ setAvance(scrollY >= start ? 100 : 0);
2932
2850
  return;
2933
2851
  }
2934
- const recorrido = scrollY - inicio;
2935
- setAvance(Math.min(100, Math.max(0, recorrido / recorrible * 100)));
2852
+ const walk = scrollY - start;
2853
+ setAvance(Math.min(100, Math.max(0, walk / walkable * 100)));
2936
2854
  };
2937
- const alMoverse = () => {
2938
- if (pendiente.current) return;
2939
- pendiente.current = requestAnimationFrame(medir);
2855
+ const onMove = () => {
2856
+ if (pendingOne.current) return;
2857
+ pendingOne.current = requestAnimationFrame(measure);
2940
2858
  };
2941
- medir();
2942
- addEventListener("scroll", alMoverse, { passive: true });
2943
- addEventListener("resize", alMoverse);
2859
+ measure();
2860
+ addEventListener("scroll", onMove, { passive: true });
2861
+ addEventListener("resize", onMove);
2944
2862
  return () => {
2945
- if (pendiente.current) cancelAnimationFrame(pendiente.current);
2946
- removeEventListener("scroll", alMoverse);
2947
- removeEventListener("resize", alMoverse);
2863
+ if (pendingOne.current) cancelAnimationFrame(pendingOne.current);
2864
+ removeEventListener("scroll", onMove);
2865
+ removeEventListener("resize", onMove);
2948
2866
  };
2949
2867
  }, [target]);
2950
2868
  return /* @__PURE__ */ jsx(
@@ -2961,7 +2879,7 @@ function ScrollingProgressBar({
2961
2879
  "div",
2962
2880
  {
2963
2881
  className: cn("h-full", tone === "warm" ? "bg-warm" : "bg-accent"),
2964
- style: { width: `${avance}%` }
2882
+ style: { width: `${seek}%` }
2965
2883
  }
2966
2884
  )
2967
2885
  }
@@ -2975,20 +2893,21 @@ function SidebarItem({
2975
2893
  children,
2976
2894
  ...props
2977
2895
  }) {
2978
- const Raiz = asChild ? Slot : "a";
2896
+ const Root17 = asChild ? Slot : "a";
2979
2897
  return /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsxs(
2980
- Raiz,
2898
+ Root17,
2981
2899
  {
2982
2900
  "aria-current": active ? "page" : void 0,
2983
2901
  className: cn(
2984
2902
  "rounded-chip px-step-sm gap-step-xs flex cursor-pointer items-center py-1.5",
2985
2903
  "font-mono text-meta transition-standard",
2986
2904
  "focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent",
2987
- // El activo es fondo `surfaceRaised` y tinta primaria, igual que
2988
- // `TabsTrigger`. NO bioluz: `tokens.ts` lo dice explícito — acento
2989
- // claro pasa sobre background y sobre surface, pero sobre
2990
- // surfaceRaised mide 4.2 y no es color de texto ahí. El acento se
2991
- // queda en el `▸`, que es decorativo y le aplica el umbral de 3:1.
2905
+ // The active item is `surfaceRaised` with primary ink, same as
2906
+ // `TabsTrigger`. NOT biolume: `tokens.ts` says so explicitly — light
2907
+ // accent passes over background and over surface, but over
2908
+ // surfaceRaised it measures 4.2 and is not a text color there. The
2909
+ // accent stays on the `▸`, which is decorative and gets the 3:1
2910
+ // threshold.
2992
2911
  active ? "bg-surface-raised text-text-primary" : "text-text-secondary hover:text-text-primary hover:bg-surface-raised",
2993
2912
  className
2994
2913
  ),
@@ -3009,7 +2928,7 @@ function SidebarNav({
3009
2928
  className,
3010
2929
  ...props
3011
2930
  }) {
3012
- const pie = [version, branch].filter(Boolean);
2931
+ const footer = [version, branch].filter(Boolean);
3013
2932
  return /* @__PURE__ */ jsxs(
3014
2933
  "nav",
3015
2934
  {
@@ -3022,7 +2941,7 @@ function SidebarNav({
3022
2941
  children: [
3023
2942
  title ? /* @__PURE__ */ jsx(Text, { variant: "eyebrow", tone: "muted", as: "p", className: "px-step-sm", children: title }) : null,
3024
2943
  /* @__PURE__ */ jsx("ul", { className: "gap-0.5 flex flex-1 flex-col", children }),
3025
- pie.length > 0 ? /* @__PURE__ */ jsx(Text, { variant: "meta", tone: "muted", as: "p", className: "border-hairline px-step-sm pt-step-sm border-t", children: pie.map((p, i) => /* @__PURE__ */ jsxs("span", { children: [
2944
+ footer.length > 0 ? /* @__PURE__ */ jsx(Text, { variant: "meta", tone: "muted", as: "p", className: "border-hairline px-step-sm pt-step-sm border-t", children: footer.map((p, i) => /* @__PURE__ */ jsxs("span", { children: [
3026
2945
  i > 0 ? /* @__PURE__ */ jsx("span", { "aria-hidden": "true", children: " \xB7 " }) : null,
3027
2946
  p
3028
2947
  ] }, i)) }) : null
@@ -3040,12 +2959,12 @@ function Stat({
3040
2959
  className,
3041
2960
  ...props
3042
2961
  }) {
3043
- return /* @__PURE__ */ jsxs("div", { className: cn(SUPERFICIE_TARJETA, "p-step-lg gap-step-xs flex flex-col", className), ...props, children: [
2962
+ return /* @__PURE__ */ jsxs("div", { className: cn(CARD_SURFACE, "p-step-lg gap-step-xs flex flex-col", className), ...props, children: [
3044
2963
  /* @__PURE__ */ jsxs(Text, { variant: "eyebrow", tone: "muted", as: "p", className: "gap-step-xs flex items-center", children: [
3045
2964
  icon ? (
3046
- // `aria-hidden` no hace falta: los glifos del sistema ya lo traen
3047
- // puesto. Lo que sí hace falta es que no encoja al lado de un título
3048
- // largo, porque un icono aplastado se lee como otro icono.
2965
+ // `aria-hidden` is not needed: the system's glyphs already carry it.
2966
+ // What IS needed is that it does not shrink next to a long title,
2967
+ // because a squashed icon reads as a different icon.
3049
2968
  /* @__PURE__ */ jsx("span", { className: "shrink-0", children: icon })
3050
2969
  ) : null,
3051
2970
  label
@@ -3071,28 +2990,58 @@ function TalkCard({
3071
2990
  location,
3072
2991
  status,
3073
2992
  description,
2993
+ resources,
3074
2994
  className,
3075
2995
  ...props
3076
2996
  }) {
3077
- const pie = [
3078
- date ? /* @__PURE__ */ jsx("time", { dateTime, children: date }, "fecha") : null,
3079
- location ? /* @__PURE__ */ jsx("span", { children: location }, "lugar") : null
2997
+ const footer = [
2998
+ date ? /* @__PURE__ */ jsx("time", { dateTime, children: date }, "date") : null,
2999
+ location ? /* @__PURE__ */ jsx("span", { children: location }, "location") : null
3080
3000
  ].filter(Boolean);
3081
- return /* @__PURE__ */ jsx(Tarjeta, { className: cn("p-step-lg", className), ...props, children: /* @__PURE__ */ jsxs("article", { className: "gap-step-sm flex h-full flex-col", children: [
3001
+ const body = /* @__PURE__ */ jsxs(Fragment, { children: [
3082
3002
  /* @__PURE__ */ jsxs("div", { className: "gap-step-sm flex items-start justify-between", children: [
3083
3003
  /* @__PURE__ */ jsx(Text, { variant: "eyebrow", tone: "accent", as: "p", children: event }),
3084
3004
  status ? /* @__PURE__ */ jsx(Badge, { variant: "neutral", children: status }) : null
3085
3005
  ] }),
3086
- /* @__PURE__ */ jsx(Text, { as: "h3", variant: "h3", className: "group-hover:text-accent transition-standard", children: title }),
3006
+ /* @__PURE__ */ jsx(
3007
+ Text,
3008
+ {
3009
+ as: "h3",
3010
+ variant: "h3",
3011
+ className: cn(!resources && "group-hover:text-accent transition-standard"),
3012
+ children: title
3013
+ }
3014
+ ),
3087
3015
  description ? /* @__PURE__ */ jsx(Text, { variant: "ui", tone: "secondary", className: "line-clamp-2", children: description }) : null,
3088
- pie.length > 0 ? /* @__PURE__ */ jsx(Text, { variant: "label", tone: "muted", as: "p", className: "gap-step-xs mt-auto flex items-center pt-step-sm", children: pie.map((m, i) => /* @__PURE__ */ jsxs("span", { className: "gap-step-xs flex items-center", children: [
3089
- i > 0 ? /* @__PURE__ */ jsx("span", { "aria-hidden": "true", children: "\xB7" }) : null,
3090
- m
3091
- ] }, i)) }) : null
3092
- ] }) });
3016
+ footer.length > 0 ? /* @__PURE__ */ jsx(
3017
+ Text,
3018
+ {
3019
+ variant: "label",
3020
+ tone: "muted",
3021
+ as: "p",
3022
+ className: cn("gap-step-xs flex items-center pt-step-sm", !resources && "mt-auto"),
3023
+ children: footer.map((m, i) => /* @__PURE__ */ jsxs("span", { className: "gap-step-xs flex items-center", children: [
3024
+ i > 0 ? /* @__PURE__ */ jsx("span", { "aria-hidden": "true", children: "\xB7" }) : null,
3025
+ m
3026
+ ] }, i))
3027
+ }
3028
+ ) : null,
3029
+ resources ? /* @__PURE__ */ jsx("div", { className: "gap-step-md mt-auto flex flex-wrap items-center pt-step-sm", children: resources }) : null
3030
+ ] });
3031
+ if (resources) {
3032
+ return /* @__PURE__ */ jsx(
3033
+ "article",
3034
+ {
3035
+ className: cn(CARD_SURFACE, "p-step-lg gap-step-sm flex h-full flex-col", className),
3036
+ ...props,
3037
+ children: body
3038
+ }
3039
+ );
3040
+ }
3041
+ return /* @__PURE__ */ jsx(CardShell, { className: cn("p-step-lg", className), ...props, children: /* @__PURE__ */ jsx("article", { className: "gap-step-sm flex h-full flex-col", children: body }) });
3093
3042
  }
3094
3043
  function ThemeToggle({
3095
- label = "Cambiar de tema",
3044
+ label = "Cambiar de theme",
3096
3045
  onThemeChange,
3097
3046
  variant = "secondary",
3098
3047
  size: size2 = "icon",
@@ -3107,20 +3056,20 @@ function ThemeToggle({
3107
3056
  size: size2,
3108
3057
  "aria-label": label,
3109
3058
  className: cn("[&_svg]:size-[19px]", className),
3110
- onClick: () => onThemeChange?.(alternarTema()),
3059
+ onClick: () => onThemeChange?.(toggleTheme()),
3111
3060
  ...props,
3112
3061
  children: [
3113
- /* @__PURE__ */ jsx(Sol, { className: "light:hidden" }),
3114
- /* @__PURE__ */ jsx(Luna, { className: "hidden light:block" })
3062
+ /* @__PURE__ */ jsx(Sun, { className: "light:hidden" }),
3063
+ /* @__PURE__ */ jsx(Moon, { className: "hidden light:block" })
3115
3064
  ]
3116
3065
  }
3117
3066
  );
3118
3067
  }
3119
- function useTema() {
3120
- return useSyncExternalStore(suscribirse2, temaActual, servidor);
3068
+ function useTheme() {
3069
+ return useSyncExternalStore(subscribe2, currentTheme, server);
3121
3070
  }
3122
- var suscribirse2 = (avisar) => escucharTema(() => avisar());
3123
- var servidor = () => "dark";
3071
+ var subscribe2 = (warn) => watchTheme(() => warn());
3072
+ var server = () => "dark";
3124
3073
  function TableOfContents({
3125
3074
  items,
3126
3075
  title = "En esta p\xE1gina",
@@ -3132,20 +3081,20 @@ function TableOfContents({
3132
3081
  return /* @__PURE__ */ jsxs("nav", { "aria-label": typeof title === "string" ? title : "En esta p\xE1gina", className: cn("gap-step-sm flex flex-col", className), ...props, children: [
3133
3082
  /* @__PURE__ */ jsx(Text, { variant: "eyebrow", tone: "muted", as: "p", children: title }),
3134
3083
  /* @__PURE__ */ jsx("ul", { className: "border-hairline gap-step-xs flex flex-col border-l", children: items.map((item2) => {
3135
- const activo = item2.href === activeHref;
3136
- const clases = cn(
3084
+ const active = item2.href === activeHref;
3085
+ const classes = cn(
3137
3086
  "px-step-sm -ml-px block border-l",
3138
3087
  "font-sans text-label transition-standard",
3139
3088
  "focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent",
3140
3089
  "cursor-pointer",
3141
3090
  item2.nested && "pl-step-lg",
3142
3091
  "border-transparent text-text-secondary hover:text-text-primary",
3143
- // El hover del activo se declara con las dos variantes juntas para
3144
- // que gane al `hover:` de arriba por especificidad y no por el orden
3145
- // en que Tailwind decida emitir las reglas.
3092
+ // The active hover is declared with both variants together so it
3093
+ // beats the `hover:` above by specificity and not by the order
3094
+ // Tailwind happens to emit the rules in.
3146
3095
  "aria-[current]:border-accent aria-[current]:text-accent aria-[current]:hover:text-accent"
3147
3096
  );
3148
- 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);
3097
+ return /* @__PURE__ */ jsx("li", { children: linkAsChild ? /* @__PURE__ */ jsx(Slot, { className: classes, "aria-current": active ? "location" : void 0, children: linkAsChild({ href: item2.href, children: item2.label }) }) : /* @__PURE__ */ jsx("a", { href: item2.href, className: classes, "aria-current": active ? "location" : void 0, children: item2.label }) }, item2.href);
3149
3098
  }) })
3150
3099
  ] });
3151
3100
  }
@@ -3153,16 +3102,17 @@ function TableOfContents({
3153
3102
  // src/lib/social.tsx
3154
3103
  var social_exports = {};
3155
3104
  __export(social_exports, {
3156
- Correo: () => Correo,
3157
3105
  Discord: () => Discord,
3106
+ Email: () => Email,
3158
3107
  GitHub: () => GitHub,
3159
3108
  Instagram: () => Instagram,
3160
3109
  LinkedIn: () => LinkedIn,
3110
+ Newsletter: () => Newsletter,
3161
3111
  Rss: () => Rss,
3162
3112
  X: () => X,
3163
3113
  YouTube: () => YouTube
3164
3114
  });
3165
- function Marca({ children, ...props }) {
3115
+ function Brand({ children, ...props }) {
3166
3116
  return /* @__PURE__ */ jsx(
3167
3117
  "svg",
3168
3118
  {
@@ -3177,7 +3127,7 @@ function Marca({ children, ...props }) {
3177
3127
  }
3178
3128
  );
3179
3129
  }
3180
- function Funcional({ children, ...props }) {
3130
+ function Functional({ children, ...props }) {
3181
3131
  return /* @__PURE__ */ jsx(
3182
3132
  "svg",
3183
3133
  {
@@ -3196,19 +3146,23 @@ function Funcional({ children, ...props }) {
3196
3146
  }
3197
3147
  );
3198
3148
  }
3199
- 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" }) });
3200
- 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" }) });
3201
- 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" }) });
3202
- 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" }) });
3203
- 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" }) });
3204
- 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" }) });
3205
- var Rss = (props) => /* @__PURE__ */ jsxs(Funcional, { ...props, children: [
3149
+ var GitHub = (props) => /* @__PURE__ */ jsx(Brand, { ...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" }) });
3150
+ var LinkedIn = (props) => /* @__PURE__ */ jsx(Brand, { ...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" }) });
3151
+ var X = (props) => /* @__PURE__ */ jsx(Brand, { ...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" }) });
3152
+ var Instagram = (props) => /* @__PURE__ */ jsx(Brand, { ...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" }) });
3153
+ var Discord = (props) => /* @__PURE__ */ jsx(Brand, { ...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" }) });
3154
+ var YouTube = (props) => /* @__PURE__ */ jsx(Brand, { ...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" }) });
3155
+ var Rss = (props) => /* @__PURE__ */ jsxs(Functional, { ...props, children: [
3206
3156
  /* @__PURE__ */ jsx("path", { d: "M4 11a9 9 0 0 1 9 9M4 4a16 16 0 0 1 16 16" }),
3207
3157
  /* @__PURE__ */ jsx("circle", { cx: "5", cy: "19", r: "1.6", fill: "currentColor", stroke: "none" })
3208
3158
  ] });
3209
- var Correo = (props) => /* @__PURE__ */ jsxs(Funcional, { ...props, children: [
3159
+ var Email = (props) => /* @__PURE__ */ jsxs(Functional, { ...props, children: [
3210
3160
  /* @__PURE__ */ jsx("rect", { x: "2.75", y: "4.75", width: "18.5", height: "14.5", rx: "2" }),
3211
3161
  /* @__PURE__ */ jsx("path", { d: "m3.5 7.5 7.4 5.2a2 2 0 0 0 2.2 0l7.4-5.2" })
3212
3162
  ] });
3163
+ var Newsletter = (props) => /* @__PURE__ */ jsxs(Functional, { ...props, children: [
3164
+ /* @__PURE__ */ jsx("path", { d: "M18 8.5a6 6 0 1 0-12 0c0 5-2 6.5-2 6.5h16s-2-1.5-2-6.5" }),
3165
+ /* @__PURE__ */ jsx("path", { d: "M13.7 19a2 2 0 0 1-3.4 0" })
3166
+ ] });
3213
3167
 
3214
- export { Accordion, AccordionContent, AccordionItem, AccordionTrigger, Alert, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogOverlay, AlertDialogTitle, AlertDialogTrigger, ArticleCard, AudioPlayer, AuthorCard, Avatar, AvatarFallback, AvatarImage, AvatarUpload, 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, EventCalendar, Footer, FooterLink, HOVER_TARJETA, Hero, Input, LinkRow, MetricBadge, Nav, NavItem, NewsletterForm, PageHeader, Pagination, PaginationContent, PaginationEllipsis, PaginationItem, PaginationLink, PaginationNext, PaginationPrevious, Popover, PopoverAnchor, PopoverContent, PopoverTrigger, Progress, RadioGroup2 as RadioGroup, RadioGroupItem, SUPERFICIE_TARJETA, ScrollingProgressBar, 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, Textarea, ThemeToggle, ToastAction, Toaster, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, alert as alertVariants, avatar as avatarVariants, badge as badgeVariants, button as buttonVariants, categoria as categoryBadgeVariants, social_exports as social, toast2 as toast, useTema };
3168
+ export { Accordion, AccordionContent, AccordionItem, AccordionTrigger, Alert, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogOverlay, AlertDialogTitle, AlertDialogTrigger, ArticleCard, AudioPlayer, AuthorCard, Avatar, AvatarFallback, AvatarImage, AvatarUpload, 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, EventCalendar, Footer, FooterLink, Hero, Input, LinkRow, MetricBadge, Nav, NavItem, NewsletterForm, PageHeader, Pagination, PaginationContent, PaginationEllipsis, PaginationItem, PaginationLink, PaginationNext, PaginationPrevious, Popover, PopoverAnchor, PopoverContent, PopoverTrigger, Progress, RadioGroup2 as RadioGroup, RadioGroupItem, ScrollingProgressBar, 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, Textarea, ThemeToggle, ToastAction, Toaster, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, social_exports as social, toast2 as toast, useTheme };