@eduardoalvarez/arrecife 0.3.0 → 0.4.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.
package/dist/index.cjs CHANGED
@@ -1,11 +1,13 @@
1
1
  'use strict';
2
2
 
3
- var classVarianceAuthority = require('class-variance-authority');
3
+ var AccordionPrimitive = require('@radix-ui/react-accordion');
4
4
  var clsx = require('clsx');
5
5
  var tailwindMerge = require('tailwind-merge');
6
6
  var jsxRuntime = require('react/jsx-runtime');
7
- var AvatarPrimitive = require('@radix-ui/react-avatar');
7
+ var classVarianceAuthority = require('class-variance-authority');
8
+ var AlertDialogPrimitive = require('@radix-ui/react-alert-dialog');
8
9
  var reactSlot = require('@radix-ui/react-slot');
10
+ var AvatarPrimitive = require('@radix-ui/react-avatar');
9
11
  var locale = require('date-fns/locale');
10
12
  var reactDayPicker = require('react-day-picker');
11
13
  var CheckboxPrimitive = require('@radix-ui/react-checkbox');
@@ -20,8 +22,8 @@ var SeparatorPrimitive = require('@radix-ui/react-separator');
20
22
  var SwitchPrimitive = require('@radix-ui/react-switch');
21
23
  var TabsPrimitive = require('@radix-ui/react-tabs');
22
24
  var ToastPrimitive = require('@radix-ui/react-toast');
23
- var TooltipPrimitive = require('@radix-ui/react-tooltip');
24
25
  var react = require('react');
26
+ var TooltipPrimitive = require('@radix-ui/react-tooltip');
25
27
 
26
28
  function _interopNamespace(e) {
27
29
  if (e && e.__esModule) return e;
@@ -41,6 +43,8 @@ function _interopNamespace(e) {
41
43
  return Object.freeze(n);
42
44
  }
43
45
 
46
+ var AccordionPrimitive__namespace = /*#__PURE__*/_interopNamespace(AccordionPrimitive);
47
+ var AlertDialogPrimitive__namespace = /*#__PURE__*/_interopNamespace(AlertDialogPrimitive);
44
48
  var AvatarPrimitive__namespace = /*#__PURE__*/_interopNamespace(AvatarPrimitive);
45
49
  var CheckboxPrimitive__namespace = /*#__PURE__*/_interopNamespace(CheckboxPrimitive);
46
50
  var DialogPrimitive__namespace = /*#__PURE__*/_interopNamespace(DialogPrimitive);
@@ -249,6 +253,10 @@ var sintaxis = {
249
253
  /** `markup.deleted`, `invalid`. */
250
254
  invalido: dark.error
251
255
  };
256
+ var series = {
257
+ dark: [dark.accent, dark.warm, brand.body, dark.textMuted],
258
+ light: [light.accent, light.warm, brand.body, light.textMuted]
259
+ };
252
260
  var profundo = "#0D2129";
253
261
  var gradient = {
254
262
  dark: {
@@ -299,11 +307,94 @@ var tokens = {
299
307
  size,
300
308
  gradient,
301
309
  sintaxis,
310
+ series,
302
311
  shadow,
303
312
  motion,
304
313
  tagline,
305
314
  naming
306
315
  };
316
+
317
+ // src/tema/index.ts
318
+ var TEMA_CLAVE = "arrecife-tema";
319
+ var TEMA_ATRIBUTO = "data-theme";
320
+ var TEMA_EVENTO = "arrecife:tema";
321
+ var esTema = (valor) => valor === "dark" || valor === "light";
322
+ function temaActual() {
323
+ if (typeof document === "undefined") return "dark";
324
+ const puesto = document.documentElement.getAttribute(TEMA_ATRIBUTO);
325
+ return esTema(puesto) ? puesto : "dark";
326
+ }
327
+ function temaGuardado() {
328
+ if (typeof localStorage === "undefined") return null;
329
+ try {
330
+ const valor = localStorage.getItem(TEMA_CLAVE);
331
+ return esTema(valor) ? valor : null;
332
+ } catch {
333
+ return null;
334
+ }
335
+ }
336
+ function temaPreferido() {
337
+ const guardado = temaGuardado();
338
+ if (guardado) return guardado;
339
+ if (typeof matchMedia === "undefined") return "dark";
340
+ return matchMedia("(prefers-color-scheme: light)").matches ? "light" : "dark";
341
+ }
342
+ function aplicarTema(tema, persistir = true) {
343
+ if (typeof document === "undefined") return;
344
+ document.documentElement.setAttribute(TEMA_ATRIBUTO, tema);
345
+ document.documentElement.style.colorScheme = tema;
346
+ if (persistir) {
347
+ try {
348
+ localStorage.setItem(TEMA_CLAVE, tema);
349
+ } catch {
350
+ }
351
+ }
352
+ dispatchEvent(new CustomEvent(TEMA_EVENTO, { detail: tema }));
353
+ }
354
+ function alternarTema() {
355
+ const siguiente = temaActual() === "dark" ? "light" : "dark";
356
+ aplicarTema(siguiente);
357
+ return siguiente;
358
+ }
359
+ function escucharTema(alCambiar) {
360
+ if (typeof window === "undefined") return () => {
361
+ };
362
+ const propio = (evento) => {
363
+ const detalle = evento.detail;
364
+ if (esTema(detalle)) alCambiar(detalle);
365
+ };
366
+ const otraPestana = (evento) => {
367
+ if (evento.key !== TEMA_CLAVE) return;
368
+ const tema = esTema(evento.newValue) ? evento.newValue : temaPreferido();
369
+ aplicarTema(tema, false);
370
+ alCambiar(tema);
371
+ };
372
+ addEventListener(TEMA_EVENTO, propio);
373
+ addEventListener("storage", otraPestana);
374
+ return () => {
375
+ removeEventListener(TEMA_EVENTO, propio);
376
+ removeEventListener("storage", otraPestana);
377
+ };
378
+ }
379
+ var scriptTema = [
380
+ "(function () {",
381
+ " var CLAVE = " + JSON.stringify(TEMA_CLAVE) + ";",
382
+ " function resolver() {",
383
+ " try {",
384
+ " var guardado = localStorage.getItem(CLAVE);",
385
+ ' if (guardado === "dark" || guardado === "light") return guardado;',
386
+ " } catch (e) {}",
387
+ ' return matchMedia("(prefers-color-scheme: light)").matches ? "light" : "dark";',
388
+ " }",
389
+ " function aplicar() {",
390
+ " var tema = resolver();",
391
+ " document.documentElement.setAttribute(" + JSON.stringify(TEMA_ATRIBUTO) + ", tema);",
392
+ " document.documentElement.style.colorScheme = tema;",
393
+ " }",
394
+ " aplicar();",
395
+ ' document.addEventListener("astro:after-swap", aplicar);',
396
+ "})();"
397
+ ].join("\n");
307
398
  var kebab = (nombre) => nombre.replace(/[A-Z]/g, (c) => `-${c.toLowerCase()}`);
308
399
  var escalas = Object.keys(typeScale);
309
400
  var radios = Object.keys(radius);
@@ -325,6 +416,164 @@ var twMerge = tailwindMerge.extendTailwindMerge({
325
416
  function cn(...inputs) {
326
417
  return twMerge(clsx.clsx(inputs));
327
418
  }
419
+ function Glyph({ children, ...props }) {
420
+ return /* @__PURE__ */ jsxRuntime.jsx(
421
+ "svg",
422
+ {
423
+ viewBox: "0 0 16 16",
424
+ width: "1em",
425
+ height: "1em",
426
+ fill: "none",
427
+ stroke: "currentColor",
428
+ strokeWidth: 1.75,
429
+ strokeLinecap: "round",
430
+ strokeLinejoin: "round",
431
+ "aria-hidden": "true",
432
+ focusable: "false",
433
+ ...props,
434
+ children
435
+ }
436
+ );
437
+ }
438
+ var Check = (props) => /* @__PURE__ */ jsxRuntime.jsx(Glyph, { ...props, children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M3 8.5 6.5 12 13 4.5" }) });
439
+ var Minus = (props) => /* @__PURE__ */ jsxRuntime.jsx(Glyph, { ...props, children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M3.5 8h9" }) });
440
+ var ChevronDown = (props) => /* @__PURE__ */ jsxRuntime.jsx(Glyph, { ...props, children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M4 6l4 4 4-4" }) });
441
+ var ChevronUp = (props) => /* @__PURE__ */ jsxRuntime.jsx(Glyph, { ...props, children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M4 10l4-4 4 4" }) });
442
+ var ChevronLeft = (props) => /* @__PURE__ */ jsxRuntime.jsx(Glyph, { ...props, children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M10 4L6 8l4 4" }) });
443
+ var ChevronRight = (props) => /* @__PURE__ */ jsxRuntime.jsx(Glyph, { ...props, children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M6 4l4 4-4 4" }) });
444
+ var Close = (props) => /* @__PURE__ */ jsxRuntime.jsx(Glyph, { ...props, children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M4 4l8 8M12 4l-8 8" }) });
445
+ var Copy = (props) => /* @__PURE__ */ jsxRuntime.jsxs(Glyph, { ...props, children: [
446
+ /* @__PURE__ */ jsxRuntime.jsx("rect", { x: "5.5", y: "5.5", width: "8", height: "8", rx: "1.5" }),
447
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M10.5 3.5h-7a1.5 1.5 0 0 0-1.5 1.5v7" })
448
+ ] });
449
+ var ArrowUpRight = (props) => /* @__PURE__ */ jsxRuntime.jsx(Glyph, { ...props, children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M5 11l6-6M5.5 5h5.5v5.5" }) });
450
+ var Ellipsis = (props) => /* @__PURE__ */ jsxRuntime.jsx(Glyph, { ...props, strokeWidth: 2.25, children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M4 8h.01M8 8h.01M12 8h.01" }) });
451
+ var Spinner = (props) => /* @__PURE__ */ jsxRuntime.jsxs(
452
+ "svg",
453
+ {
454
+ viewBox: "0 0 16 16",
455
+ width: "1em",
456
+ height: "1em",
457
+ fill: "none",
458
+ stroke: "currentColor",
459
+ strokeWidth: 2,
460
+ strokeLinecap: "round",
461
+ "aria-hidden": "true",
462
+ focusable: "false",
463
+ className: "motion-safe:animate-spin",
464
+ ...props,
465
+ children: [
466
+ /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "8", cy: "8", r: "6", opacity: 0.3 }),
467
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M8 2a6 6 0 0 1 6 6" })
468
+ ]
469
+ }
470
+ );
471
+ var Sol = (props) => /* @__PURE__ */ jsxRuntime.jsxs(Glyph, { ...props, children: [
472
+ /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "8", cy: "8", r: "3" }),
473
+ /* @__PURE__ */ jsxRuntime.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" })
474
+ ] });
475
+ var Luna = (props) => /* @__PURE__ */ jsxRuntime.jsx(Glyph, { ...props, children: /* @__PURE__ */ jsxRuntime.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" }) });
476
+ function GlifoMedia({ children, ...props }) {
477
+ return /* @__PURE__ */ jsxRuntime.jsx(
478
+ "svg",
479
+ {
480
+ xmlns: "http://www.w3.org/2000/svg",
481
+ viewBox: "0 0 24 24",
482
+ fill: "none",
483
+ "aria-hidden": "true",
484
+ focusable: "false",
485
+ ...props,
486
+ children
487
+ }
488
+ );
489
+ }
490
+ var Play = (props) => /* @__PURE__ */ jsxRuntime.jsx(GlifoMedia, { fill: "currentColor", ...props, children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M8 5v14l11-7z" }) });
491
+ var Pause = (props) => /* @__PURE__ */ jsxRuntime.jsx(GlifoMedia, { fill: "currentColor", ...props, children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M6 4h4v16H6V4zm8 0h4v16h-4V4z" }) });
492
+ var Retry = (props) => /* @__PURE__ */ jsxRuntime.jsx(
493
+ GlifoMedia,
494
+ {
495
+ stroke: "currentColor",
496
+ strokeWidth: 2,
497
+ strokeLinecap: "round",
498
+ strokeLinejoin: "round",
499
+ ...props,
500
+ children: /* @__PURE__ */ jsxRuntime.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" })
501
+ }
502
+ );
503
+ var GoBackSeconds = (props) => /* @__PURE__ */ jsxRuntime.jsxs(GlifoMedia, { stroke: "currentColor", strokeWidth: 1.5, strokeLinecap: "round", ...props, children: [
504
+ /* @__PURE__ */ jsxRuntime.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" }),
505
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M7.5 10.5L10 8.5V15.5", strokeLinejoin: "round" }),
506
+ /* @__PURE__ */ jsxRuntime.jsx(
507
+ "path",
508
+ {
509
+ d: "M14 4.5L12 2C17.5228 2 22 6.47715 22 12C22 17.5228 17.5228 22 12 22C8.7288 22 5.82446 20.4293 4 18.001M8 2.83209C6.87754 3.32251 5.86251 4.01303 5 4.85857C3.14864 6.67349 2 9.20261 2 12C2 12.6849 2.06886 13.3538 2.20004 14",
510
+ strokeLinejoin: "round"
511
+ }
512
+ )
513
+ ] });
514
+ var AdvanceSeconds = (props) => /* @__PURE__ */ jsxRuntime.jsxs(GlifoMedia, { stroke: "currentColor", strokeWidth: 1.5, strokeLinecap: "round", ...props, children: [
515
+ /* @__PURE__ */ jsxRuntime.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" }),
516
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M7.5 10.5L10 8.5V15.5", strokeLinejoin: "round" }),
517
+ /* @__PURE__ */ jsxRuntime.jsx(
518
+ "path",
519
+ {
520
+ d: "M10 4.5L12 2C6.47715 2 2 6.47715 2 12C2 12.6849 2.06886 13.3538 2.20004 14M16 2.83209C19.5318 4.3752 22 7.89936 22 12C22 17.5228 17.5228 22 12 22C8.72852 22 5.82443 20.4287 4 18",
521
+ strokeLinejoin: "round"
522
+ }
523
+ )
524
+ ] });
525
+ var VolumeOn = (props) => /* @__PURE__ */ jsxRuntime.jsx(GlifoMedia, { fill: "currentColor", ...props, children: /* @__PURE__ */ jsxRuntime.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" }) });
526
+ var VolumeMuted = (props) => /* @__PURE__ */ jsxRuntime.jsx(GlifoMedia, { fill: "currentColor", ...props, children: /* @__PURE__ */ jsxRuntime.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" }) });
527
+ function Accordion({ className, ...props }) {
528
+ return /* @__PURE__ */ jsxRuntime.jsx(
529
+ AccordionPrimitive__namespace.Root,
530
+ {
531
+ className: cn("border-hairline w-full border-t", className),
532
+ ...props
533
+ }
534
+ );
535
+ }
536
+ function AccordionItem({
537
+ className,
538
+ ...props
539
+ }) {
540
+ return /* @__PURE__ */ jsxRuntime.jsx(AccordionPrimitive__namespace.Item, { className: cn("border-hairline border-b", className), ...props });
541
+ }
542
+ function AccordionTrigger({
543
+ className,
544
+ children,
545
+ headingLevel = 3,
546
+ ...props
547
+ }) {
548
+ const Encabezado = `h${headingLevel}`;
549
+ return /* @__PURE__ */ jsxRuntime.jsx(AccordionPrimitive__namespace.Header, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(Encabezado, { children: /* @__PURE__ */ jsxRuntime.jsxs(
550
+ AccordionPrimitive__namespace.Trigger,
551
+ {
552
+ className: cn(
553
+ "gap-step-sm py-step-sm flex w-full cursor-pointer items-center justify-between text-left",
554
+ "font-sans text-lead font-medium text-text-primary",
555
+ "transition-standard",
556
+ "hover:text-accent",
557
+ "focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent",
558
+ "disabled:pointer-events-none disabled:opacity-50",
559
+ "[&[data-state=open]>svg]:rotate-180",
560
+ className
561
+ ),
562
+ ...props,
563
+ children: [
564
+ children,
565
+ /* @__PURE__ */ jsxRuntime.jsx(ChevronDown, { className: "text-text-muted shrink-0" })
566
+ ]
567
+ }
568
+ ) }) });
569
+ }
570
+ function AccordionContent({
571
+ className,
572
+ children,
573
+ ...props
574
+ }) {
575
+ return /* @__PURE__ */ jsxRuntime.jsx(AccordionPrimitive__namespace.Content, { className: "overflow-hidden", ...props, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("pb-step-md font-sans text-ui text-text-secondary max-w-measure", className), children }) });
576
+ }
328
577
  var alert = classVarianceAuthority.cva("w-full rounded-card border p-step-md font-sans text-ui", {
329
578
  variants: {
330
579
  variant: {
@@ -395,6 +644,176 @@ function Alert({
395
644
  }
396
645
  );
397
646
  }
647
+ var button = classVarianceAuthority.cva(
648
+ [
649
+ "inline-flex cursor-pointer items-center justify-center gap-step-xs whitespace-nowrap select-none",
650
+ "rounded-control font-sans font-medium",
651
+ "transition-standard",
652
+ "focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent",
653
+ "disabled:pointer-events-none disabled:opacity-50",
654
+ "[&_svg]:shrink-0"
655
+ ],
656
+ {
657
+ variants: {
658
+ variant: {
659
+ primary: [
660
+ "bg-accent text-accent-on hover:bg-accent-hover",
661
+ "light:bg-brand-hull light:text-accent-on light:hover:bg-text-secondary"
662
+ ],
663
+ conversion: "bg-warm text-warm-on hover:bg-warm-hover",
664
+ secondary: [
665
+ "border-hairline-hover border bg-transparent text-text-primary",
666
+ "hover:border-accent hover:text-accent"
667
+ ],
668
+ tertiary: [
669
+ "bg-transparent font-mono font-normal text-text-secondary",
670
+ "hover:text-accent hover:underline hover:underline-offset-4"
671
+ ]
672
+ },
673
+ size: {
674
+ sm: "h-8 px-control-sm text-label",
675
+ md: "h-10 px-control-md text-ui",
676
+ lg: "h-12 px-control-lg text-lead",
677
+ /** Cuadrado 42×42, sin texto. Lleva `aria-label` obligatorio. */
678
+ icon: "size-control-icon p-0"
679
+ }
680
+ },
681
+ compoundVariants: [
682
+ /**
683
+ * El terciario no tiene caja: ni padding horizontal ni alto de control.
684
+ * Va aquí y no como `px-0` en la variante para que gane al `px-*` del
685
+ * tamaño sin depender del orden en que cva concatena las clases.
686
+ */
687
+ { variant: "tertiary", size: ["sm", "md", "lg"], class: "h-auto px-0" }
688
+ ],
689
+ defaultVariants: { variant: "primary", size: "md" }
690
+ }
691
+ );
692
+ function Button({
693
+ className,
694
+ variant,
695
+ size: size2,
696
+ asChild = false,
697
+ loading = false,
698
+ icon,
699
+ children,
700
+ disabled,
701
+ ...props
702
+ }) {
703
+ if (asChild) {
704
+ return /* @__PURE__ */ jsxRuntime.jsx(reactSlot.Slot, { className: cn(button({ variant, size: size2 }), className), ...props, children });
705
+ }
706
+ return /* @__PURE__ */ jsxRuntime.jsxs(
707
+ "button",
708
+ {
709
+ className: cn(button({ variant, size: size2 }), className),
710
+ disabled: disabled === true || loading,
711
+ "aria-busy": loading || void 0,
712
+ ...props,
713
+ children: [
714
+ loading ? /* @__PURE__ */ jsxRuntime.jsx(Spinner, {}) : icon,
715
+ children
716
+ ]
717
+ }
718
+ );
719
+ }
720
+ var AlertDialog = AlertDialogPrimitive__namespace.Root;
721
+ var AlertDialogTrigger = AlertDialogPrimitive__namespace.Trigger;
722
+ function AlertDialogOverlay({
723
+ className,
724
+ ...props
725
+ }) {
726
+ return /* @__PURE__ */ jsxRuntime.jsx(
727
+ AlertDialogPrimitive__namespace.Overlay,
728
+ {
729
+ className: cn("bg-brand-hull/70 fixed inset-0 z-50", className),
730
+ ...props
731
+ }
732
+ );
733
+ }
734
+ function AlertDialogContent({
735
+ className,
736
+ children,
737
+ ...props
738
+ }) {
739
+ return /* @__PURE__ */ jsxRuntime.jsxs(AlertDialogPrimitive__namespace.Portal, { children: [
740
+ /* @__PURE__ */ jsxRuntime.jsx(AlertDialogOverlay, {}),
741
+ /* @__PURE__ */ jsxRuntime.jsx(
742
+ AlertDialogPrimitive__namespace.Content,
743
+ {
744
+ className: cn(
745
+ "fixed top-1/2 left-1/2 z-50 w-full max-w-content -translate-x-1/2 -translate-y-1/2",
746
+ "gap-step-md p-step-lg flex flex-col",
747
+ "rounded-panel border-border bg-surface shadow-standard border",
748
+ "text-text-primary font-sans",
749
+ className
750
+ ),
751
+ ...props,
752
+ children
753
+ }
754
+ )
755
+ ] });
756
+ }
757
+ function AlertDialogHeader({ className, ...props }) {
758
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("gap-step-xs flex flex-col", className), ...props });
759
+ }
760
+ function AlertDialogFooter({ className, ...props }) {
761
+ return /* @__PURE__ */ jsxRuntime.jsx(
762
+ "div",
763
+ {
764
+ className: cn("gap-step-sm flex flex-col-reverse sm:flex-row sm:justify-end", className),
765
+ ...props
766
+ }
767
+ );
768
+ }
769
+ function AlertDialogTitle({
770
+ className,
771
+ ...props
772
+ }) {
773
+ return /* @__PURE__ */ jsxRuntime.jsx(
774
+ AlertDialogPrimitive__namespace.Title,
775
+ {
776
+ className: cn("text-h3 font-display text-text-primary", className),
777
+ ...props
778
+ }
779
+ );
780
+ }
781
+ function AlertDialogDescription({
782
+ className,
783
+ ...props
784
+ }) {
785
+ return /* @__PURE__ */ jsxRuntime.jsx(
786
+ AlertDialogPrimitive__namespace.Description,
787
+ {
788
+ className: cn("text-ui text-text-secondary max-w-measure", className),
789
+ ...props
790
+ }
791
+ );
792
+ }
793
+ function AlertDialogCancel({
794
+ className,
795
+ ...props
796
+ }) {
797
+ return /* @__PURE__ */ jsxRuntime.jsx(
798
+ AlertDialogPrimitive__namespace.Cancel,
799
+ {
800
+ className: cn(button({ variant: "secondary" }), className),
801
+ ...props
802
+ }
803
+ );
804
+ }
805
+ function AlertDialogAction({
806
+ className,
807
+ ...props
808
+ }) {
809
+ return /* @__PURE__ */ jsxRuntime.jsx(
810
+ AlertDialogPrimitive__namespace.Action,
811
+ {
812
+ className: cn(button({ variant: "primary" }), className),
813
+ ...props
814
+ }
815
+ );
816
+ }
398
817
  var avatar = classVarianceAuthority.cva(
399
818
  "relative flex shrink-0 overflow-hidden rounded-pill bg-surface-raised border border-hairline",
400
819
  {
@@ -489,182 +908,6 @@ function MetricBadge({ className, boxed = false, ...props }) {
489
908
  }
490
909
  );
491
910
  }
492
- function Glyph({ children, ...props }) {
493
- return /* @__PURE__ */ jsxRuntime.jsx(
494
- "svg",
495
- {
496
- viewBox: "0 0 16 16",
497
- width: "1em",
498
- height: "1em",
499
- fill: "none",
500
- stroke: "currentColor",
501
- strokeWidth: 1.75,
502
- strokeLinecap: "round",
503
- strokeLinejoin: "round",
504
- "aria-hidden": "true",
505
- focusable: "false",
506
- ...props,
507
- children
508
- }
509
- );
510
- }
511
- var Check = (props) => /* @__PURE__ */ jsxRuntime.jsx(Glyph, { ...props, children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M3 8.5 6.5 12 13 4.5" }) });
512
- var Minus = (props) => /* @__PURE__ */ jsxRuntime.jsx(Glyph, { ...props, children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M3.5 8h9" }) });
513
- var ChevronDown = (props) => /* @__PURE__ */ jsxRuntime.jsx(Glyph, { ...props, children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M4 6l4 4 4-4" }) });
514
- var ChevronUp = (props) => /* @__PURE__ */ jsxRuntime.jsx(Glyph, { ...props, children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M4 10l4-4 4 4" }) });
515
- var ChevronLeft = (props) => /* @__PURE__ */ jsxRuntime.jsx(Glyph, { ...props, children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M10 4L6 8l4 4" }) });
516
- var ChevronRight = (props) => /* @__PURE__ */ jsxRuntime.jsx(Glyph, { ...props, children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M6 4l4 4-4 4" }) });
517
- var Close = (props) => /* @__PURE__ */ jsxRuntime.jsx(Glyph, { ...props, children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M4 4l8 8M12 4l-8 8" }) });
518
- var Copy = (props) => /* @__PURE__ */ jsxRuntime.jsxs(Glyph, { ...props, children: [
519
- /* @__PURE__ */ jsxRuntime.jsx("rect", { x: "5.5", y: "5.5", width: "8", height: "8", rx: "1.5" }),
520
- /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M10.5 3.5h-7a1.5 1.5 0 0 0-1.5 1.5v7" })
521
- ] });
522
- var ArrowUpRight = (props) => /* @__PURE__ */ jsxRuntime.jsx(Glyph, { ...props, children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M5 11l6-6M5.5 5h5.5v5.5" }) });
523
- var Ellipsis = (props) => /* @__PURE__ */ jsxRuntime.jsx(Glyph, { ...props, strokeWidth: 2.25, children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M4 8h.01M8 8h.01M12 8h.01" }) });
524
- var Spinner = (props) => /* @__PURE__ */ jsxRuntime.jsxs(
525
- "svg",
526
- {
527
- viewBox: "0 0 16 16",
528
- width: "1em",
529
- height: "1em",
530
- fill: "none",
531
- stroke: "currentColor",
532
- strokeWidth: 2,
533
- strokeLinecap: "round",
534
- "aria-hidden": "true",
535
- focusable: "false",
536
- className: "motion-safe:animate-spin",
537
- ...props,
538
- children: [
539
- /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "8", cy: "8", r: "6", opacity: 0.3 }),
540
- /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M8 2a6 6 0 0 1 6 6" })
541
- ]
542
- }
543
- );
544
- function GlifoMedia({ children, ...props }) {
545
- return /* @__PURE__ */ jsxRuntime.jsx(
546
- "svg",
547
- {
548
- xmlns: "http://www.w3.org/2000/svg",
549
- viewBox: "0 0 24 24",
550
- fill: "none",
551
- "aria-hidden": "true",
552
- focusable: "false",
553
- ...props,
554
- children
555
- }
556
- );
557
- }
558
- var Play = (props) => /* @__PURE__ */ jsxRuntime.jsx(GlifoMedia, { fill: "currentColor", ...props, children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M8 5v14l11-7z" }) });
559
- var Pause = (props) => /* @__PURE__ */ jsxRuntime.jsx(GlifoMedia, { fill: "currentColor", ...props, children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M6 4h4v16H6V4zm8 0h4v16h-4V4z" }) });
560
- var Retry = (props) => /* @__PURE__ */ jsxRuntime.jsx(
561
- GlifoMedia,
562
- {
563
- stroke: "currentColor",
564
- strokeWidth: 2,
565
- strokeLinecap: "round",
566
- strokeLinejoin: "round",
567
- ...props,
568
- children: /* @__PURE__ */ jsxRuntime.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" })
569
- }
570
- );
571
- var GoBackSeconds = (props) => /* @__PURE__ */ jsxRuntime.jsxs(GlifoMedia, { stroke: "currentColor", strokeWidth: 1.5, strokeLinecap: "round", ...props, children: [
572
- /* @__PURE__ */ jsxRuntime.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" }),
573
- /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M7.5 10.5L10 8.5V15.5", strokeLinejoin: "round" }),
574
- /* @__PURE__ */ jsxRuntime.jsx(
575
- "path",
576
- {
577
- d: "M14 4.5L12 2C17.5228 2 22 6.47715 22 12C22 17.5228 17.5228 22 12 22C8.7288 22 5.82446 20.4293 4 18.001M8 2.83209C6.87754 3.32251 5.86251 4.01303 5 4.85857C3.14864 6.67349 2 9.20261 2 12C2 12.6849 2.06886 13.3538 2.20004 14",
578
- strokeLinejoin: "round"
579
- }
580
- )
581
- ] });
582
- var AdvanceSeconds = (props) => /* @__PURE__ */ jsxRuntime.jsxs(GlifoMedia, { stroke: "currentColor", strokeWidth: 1.5, strokeLinecap: "round", ...props, children: [
583
- /* @__PURE__ */ jsxRuntime.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" }),
584
- /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M7.5 10.5L10 8.5V15.5", strokeLinejoin: "round" }),
585
- /* @__PURE__ */ jsxRuntime.jsx(
586
- "path",
587
- {
588
- d: "M10 4.5L12 2C6.47715 2 2 6.47715 2 12C2 12.6849 2.06886 13.3538 2.20004 14M16 2.83209C19.5318 4.3752 22 7.89936 22 12C22 17.5228 17.5228 22 12 22C8.72852 22 5.82443 20.4287 4 18",
589
- strokeLinejoin: "round"
590
- }
591
- )
592
- ] });
593
- var VolumeOn = (props) => /* @__PURE__ */ jsxRuntime.jsx(GlifoMedia, { fill: "currentColor", ...props, children: /* @__PURE__ */ jsxRuntime.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" }) });
594
- var VolumeMuted = (props) => /* @__PURE__ */ jsxRuntime.jsx(GlifoMedia, { fill: "currentColor", ...props, children: /* @__PURE__ */ jsxRuntime.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" }) });
595
- var button = classVarianceAuthority.cva(
596
- [
597
- "inline-flex cursor-pointer items-center justify-center gap-step-xs whitespace-nowrap select-none",
598
- "rounded-control font-sans font-medium",
599
- "transition-standard",
600
- "focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent",
601
- "disabled:pointer-events-none disabled:opacity-50",
602
- "[&_svg]:shrink-0"
603
- ],
604
- {
605
- variants: {
606
- variant: {
607
- primary: [
608
- "bg-accent text-accent-on hover:bg-accent-hover",
609
- "light:bg-brand-hull light:text-accent-on light:hover:bg-text-secondary"
610
- ],
611
- conversion: "bg-warm text-warm-on hover:bg-warm-hover",
612
- secondary: [
613
- "border-hairline-hover border bg-transparent text-text-primary",
614
- "hover:border-accent hover:text-accent"
615
- ],
616
- tertiary: [
617
- "bg-transparent font-mono font-normal text-text-secondary",
618
- "hover:text-accent hover:underline hover:underline-offset-4"
619
- ]
620
- },
621
- size: {
622
- sm: "h-8 px-control-sm text-label",
623
- md: "h-10 px-control-md text-ui",
624
- lg: "h-12 px-control-lg text-lead",
625
- /** Cuadrado 42×42, sin texto. Lleva `aria-label` obligatorio. */
626
- icon: "size-control-icon p-0"
627
- }
628
- },
629
- compoundVariants: [
630
- /**
631
- * El terciario no tiene caja: ni padding horizontal ni alto de control.
632
- * Va aquí y no como `px-0` en la variante para que gane al `px-*` del
633
- * tamaño sin depender del orden en que cva concatena las clases.
634
- */
635
- { variant: "tertiary", size: ["sm", "md", "lg"], class: "h-auto px-0" }
636
- ],
637
- defaultVariants: { variant: "primary", size: "md" }
638
- }
639
- );
640
- function Button({
641
- className,
642
- variant,
643
- size: size2,
644
- asChild = false,
645
- loading = false,
646
- icon,
647
- children,
648
- disabled,
649
- ...props
650
- }) {
651
- if (asChild) {
652
- return /* @__PURE__ */ jsxRuntime.jsx(reactSlot.Slot, { className: cn(button({ variant, size: size2 }), className), ...props, children });
653
- }
654
- return /* @__PURE__ */ jsxRuntime.jsxs(
655
- "button",
656
- {
657
- className: cn(button({ variant, size: size2 }), className),
658
- disabled: disabled === true || loading,
659
- "aria-busy": loading || void 0,
660
- ...props,
661
- children: [
662
- loading ? /* @__PURE__ */ jsxRuntime.jsx(Spinner, {}) : icon,
663
- children
664
- ]
665
- }
666
- );
667
- }
668
911
  function Calendar({
669
912
  className,
670
913
  classNames,
@@ -1700,6 +1943,76 @@ function ToastDescription({
1700
1943
  }) {
1701
1944
  return /* @__PURE__ */ jsxRuntime.jsx(ToastPrimitive__namespace.Description, { className: cn("max-w-measure", className), ...props });
1702
1945
  }
1946
+ var avisos = [];
1947
+ var suscriptores = /* @__PURE__ */ new Set();
1948
+ var contador = 0;
1949
+ function emitir(siguientes) {
1950
+ avisos = siguientes;
1951
+ for (const avisar of suscriptores) avisar();
1952
+ }
1953
+ var suscribirse = (avisar) => {
1954
+ suscriptores.add(avisar);
1955
+ return () => {
1956
+ suscriptores.delete(avisar);
1957
+ };
1958
+ };
1959
+ var leer = () => avisos;
1960
+ var VACIO = [];
1961
+ var enServidor = () => VACIO;
1962
+ function crear(mensaje, opciones = {}) {
1963
+ contador += 1;
1964
+ const id = `arrecife-toast-${contador}`;
1965
+ const { description, ...resto } = opciones;
1966
+ emitir([
1967
+ ...avisos,
1968
+ {
1969
+ ...resto,
1970
+ // El primer argumento es la línea principal. Si además llega `title`, el
1971
+ // mensaje pasa a ser la descripción: así `toast('Guardado')` y
1972
+ // `toast('No se pudo guardar', { title: 'Error' })` se leen igual de bien.
1973
+ ...opciones.title ? { description: description ?? mensaje } : { title: mensaje, ...description === void 0 ? {} : { description } },
1974
+ id,
1975
+ abierto: true
1976
+ }
1977
+ ]);
1978
+ return id;
1979
+ }
1980
+ function descartar(id) {
1981
+ emitir(avisos.map((a) => id === void 0 || a.id === id ? { ...a, abierto: false } : a));
1982
+ }
1983
+ function retirar(id) {
1984
+ emitir(avisos.filter((a) => a.id !== id));
1985
+ }
1986
+ var toast2 = Object.assign(crear, {
1987
+ success: (mensaje, opciones = {}) => crear(mensaje, { ...opciones, variant: "success" }),
1988
+ error: (mensaje, opciones = {}) => crear(mensaje, { ...opciones, variant: "error" }),
1989
+ dismiss: descartar
1990
+ });
1991
+ function Toaster({ duration = 5e3, label = "Avisos" }) {
1992
+ const lista = react.useSyncExternalStore(suscribirse, leer, enServidor);
1993
+ return /* @__PURE__ */ jsxRuntime.jsxs(ToastProvider, { duration, label, children: [
1994
+ lista.map(({ id, title, description, variant, duration: propio, action, abierto }) => /* @__PURE__ */ jsxRuntime.jsxs(
1995
+ Toast,
1996
+ {
1997
+ open: abierto,
1998
+ variant: variant ?? "neutral",
1999
+ ...propio === void 0 ? {} : { duration: propio },
2000
+ onOpenChange: (sigue) => {
2001
+ if (!sigue) retirar(id);
2002
+ },
2003
+ children: [
2004
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0 flex-1", children: [
2005
+ title ? /* @__PURE__ */ jsxRuntime.jsx(ToastTitle, { children: title }) : null,
2006
+ description ? /* @__PURE__ */ jsxRuntime.jsx(ToastDescription, { children: description }) : null
2007
+ ] }),
2008
+ action
2009
+ ]
2010
+ },
2011
+ id
2012
+ )),
2013
+ /* @__PURE__ */ jsxRuntime.jsx(ToastViewport, {})
2014
+ ] });
2015
+ }
1703
2016
  var TooltipProvider = TooltipPrimitive__namespace.Provider;
1704
2017
  var Tooltip = TooltipPrimitive__namespace.Root;
1705
2018
  var TooltipTrigger = TooltipPrimitive__namespace.Trigger;
@@ -1739,6 +2052,7 @@ function ArticleCard({
1739
2052
  dateTime,
1740
2053
  readingMinutes,
1741
2054
  tags,
2055
+ headingLevel = 3,
1742
2056
  className,
1743
2057
  ...props
1744
2058
  }) {
@@ -1754,7 +2068,15 @@ function ArticleCard({
1754
2068
  i > 0 ? /* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": "true", children: "\xB7" }) : null,
1755
2069
  m
1756
2070
  ] }, i)) }) : null,
1757
- /* @__PURE__ */ jsxRuntime.jsx(Text, { as: "h3", variant: "h3", className: "group-hover:text-accent transition-standard", children: title }),
2071
+ /* @__PURE__ */ jsxRuntime.jsx(
2072
+ Text,
2073
+ {
2074
+ as: headingLevel === 2 ? "h2" : "h3",
2075
+ variant: "h3",
2076
+ className: "group-hover:text-accent transition-standard",
2077
+ children: title
2078
+ }
2079
+ ),
1758
2080
  excerpt ? /* @__PURE__ */ jsxRuntime.jsx(Text, { variant: "ui", tone: "secondary", className: "line-clamp-2", children: excerpt }) : null,
1759
2081
  tags && tags.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "gap-step-xs mt-auto flex flex-wrap pt-step-sm", children: tags.map((t) => /* @__PURE__ */ jsxRuntime.jsx(CategoryBadge, { children: t }, t)) }) : null
1760
2082
  ] }) });
@@ -2531,10 +2853,12 @@ function Footer({
2531
2853
  social,
2532
2854
  year = (/* @__PURE__ */ new Date()).getFullYear(),
2533
2855
  children,
2856
+ brand: brand2,
2534
2857
  className,
2535
2858
  ...props
2536
2859
  }) {
2537
2860
  return /* @__PURE__ */ jsxRuntime.jsx("footer", { className: cn("border-hairline w-full border-t", className), ...props, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "max-w-wide px-step-md py-step-xl gap-step-lg mx-auto flex flex-col", children: [
2861
+ brand2 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center", children: brand2 }) : null,
2538
2862
  children ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "gap-step-md flex flex-wrap items-center", children }) : null,
2539
2863
  social && social.length > 0 ? (
2540
2864
  // 18px de separación, del documento. No es un escalón de `spacing`:
@@ -2585,9 +2909,11 @@ function Hero({
2585
2909
  action,
2586
2910
  pose,
2587
2911
  basePath,
2912
+ variant = "cabecera",
2588
2913
  className,
2589
2914
  ...props
2590
2915
  }) {
2916
+ const centrado = variant === "centrado";
2591
2917
  return /* @__PURE__ */ jsxRuntime.jsxs(
2592
2918
  "section",
2593
2919
  {
@@ -2599,13 +2925,39 @@ function Hero({
2599
2925
  ),
2600
2926
  ...props,
2601
2927
  children: [
2602
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "gap-step-md flex flex-col md:max-w-[62%]", children: [
2603
- eyebrow ? /* @__PURE__ */ jsxRuntime.jsx(Text, { variant: "eyebrow", tone: "accent", as: "p", children: eyebrow }) : null,
2604
- /* @__PURE__ */ jsxRuntime.jsx(Text, { as: "h1", variant: "display", children: title }),
2605
- description ? /* @__PURE__ */ jsxRuntime.jsx(Text, { variant: "body", tone: "secondary", children: description }) : null,
2606
- action ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "gap-step-sm mt-step-xs flex flex-wrap items-center", children: action }) : null
2607
- ] }),
2608
- pose ? /* @__PURE__ */ jsxRuntime.jsx(
2928
+ centrado && pose ? /* @__PURE__ */ jsxRuntime.jsx(
2929
+ Mascota,
2930
+ {
2931
+ pose,
2932
+ basePath,
2933
+ className: "mb-step-md mx-auto w-48 md:w-56"
2934
+ }
2935
+ ) : null,
2936
+ /* @__PURE__ */ jsxRuntime.jsxs(
2937
+ "div",
2938
+ {
2939
+ className: cn(
2940
+ "gap-step-md flex flex-col",
2941
+ centrado ? "items-center text-center" : "md:max-w-[62%]"
2942
+ ),
2943
+ children: [
2944
+ eyebrow ? /* @__PURE__ */ jsxRuntime.jsx(Text, { variant: "eyebrow", tone: "accent", as: "p", children: eyebrow }) : null,
2945
+ /* @__PURE__ */ jsxRuntime.jsx(Text, { as: "h1", variant: "display", children: title }),
2946
+ description ? /* @__PURE__ */ jsxRuntime.jsx(Text, { variant: "body", tone: "secondary", children: description }) : null,
2947
+ action ? /* @__PURE__ */ jsxRuntime.jsx(
2948
+ "div",
2949
+ {
2950
+ className: cn(
2951
+ "gap-step-sm mt-step-xs flex flex-wrap items-center",
2952
+ centrado && "justify-center"
2953
+ ),
2954
+ children: action
2955
+ }
2956
+ ) : null
2957
+ ]
2958
+ }
2959
+ ),
2960
+ !centrado && pose ? /* @__PURE__ */ jsxRuntime.jsx(
2609
2961
  Mascota,
2610
2962
  {
2611
2963
  pose,
@@ -2710,6 +3062,10 @@ function NewsletterForm({
2710
3062
  submitLabel = "Suscribirme",
2711
3063
  placeholder = "tu@correo.dev",
2712
3064
  fieldLabel = "Correo electr\xF3nico",
3065
+ nameField = false,
3066
+ nameLabel = "Nombre",
3067
+ namePlaceholder = "C\xF3mo te llamas",
3068
+ nameInputProps,
2713
3069
  className,
2714
3070
  ...props
2715
3071
  }) {
@@ -2720,8 +3076,19 @@ function NewsletterForm({
2720
3076
  evento.preventDefault();
2721
3077
  const datos = new FormData(evento.currentTarget);
2722
3078
  const correo = String(datos.get("email") ?? "");
2723
- onSubmitEmail?.(correo);
3079
+ const nombre = nameField ? String(datos.get("name") ?? "") : void 0;
3080
+ onSubmitEmail?.(correo, nombre);
2724
3081
  }
3082
+ const boton = /* @__PURE__ */ jsxRuntime.jsx(
3083
+ Button,
3084
+ {
3085
+ type: "submit",
3086
+ variant: "conversion",
3087
+ loading: enviando,
3088
+ className: cn("disabled:opacity-60", nameField && "sm:self-start"),
3089
+ children: submitLabel
3090
+ }
3091
+ );
2725
3092
  return /* @__PURE__ */ jsxRuntime.jsxs(
2726
3093
  "section",
2727
3094
  {
@@ -2735,34 +3102,44 @@ function NewsletterForm({
2735
3102
  /* @__PURE__ */ jsxRuntime.jsx(Text, { as: "h2", variant: "h3", children: title }),
2736
3103
  description ? /* @__PURE__ */ jsxRuntime.jsx(Text, { variant: "ui", tone: "secondary", children: description }) : null
2737
3104
  ] }),
2738
- /* @__PURE__ */ jsxRuntime.jsxs("form", { onSubmit: enviar, className: "gap-step-sm flex flex-col sm:flex-row sm:items-end", noValidate: true, children: [
2739
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "gap-step-xs flex flex-1 flex-col", children: [
2740
- /* @__PURE__ */ jsxRuntime.jsx(Label2, { htmlFor: id, children: fieldLabel }),
2741
- /* @__PURE__ */ jsxRuntime.jsx(
2742
- Input,
2743
- {
2744
- id,
2745
- name: "email",
2746
- type: "email",
2747
- autoComplete: "email",
2748
- required: true,
2749
- placeholder,
2750
- disabled: enviando,
2751
- invalid: error,
2752
- "aria-describedby": state === "exito" || error ? `${id}-aviso` : void 0
2753
- }
2754
- )
3105
+ /* @__PURE__ */ jsxRuntime.jsxs("form", { onSubmit: enviar, className: "gap-step-sm flex flex-col", noValidate: true, children: [
3106
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "gap-step-sm flex flex-col sm:flex-row sm:items-end", children: [
3107
+ nameField ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "gap-step-xs flex flex-1 flex-col", children: [
3108
+ /* @__PURE__ */ jsxRuntime.jsx(Label2, { htmlFor: `${id}-nombre`, children: nameLabel }),
3109
+ /* @__PURE__ */ jsxRuntime.jsx(
3110
+ Input,
3111
+ {
3112
+ id: `${id}-nombre`,
3113
+ name: "name",
3114
+ type: "text",
3115
+ autoComplete: "name",
3116
+ required: true,
3117
+ placeholder: namePlaceholder,
3118
+ disabled: enviando,
3119
+ ...nameInputProps
3120
+ }
3121
+ )
3122
+ ] }) : null,
3123
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "gap-step-xs flex flex-1 flex-col", children: [
3124
+ /* @__PURE__ */ jsxRuntime.jsx(Label2, { htmlFor: id, children: fieldLabel }),
3125
+ /* @__PURE__ */ jsxRuntime.jsx(
3126
+ Input,
3127
+ {
3128
+ id,
3129
+ name: "email",
3130
+ type: "email",
3131
+ autoComplete: "email",
3132
+ required: true,
3133
+ placeholder,
3134
+ disabled: enviando,
3135
+ invalid: error,
3136
+ "aria-describedby": state === "exito" || error ? `${id}-aviso` : void 0
3137
+ }
3138
+ )
3139
+ ] }),
3140
+ nameField ? null : boton
2755
3141
  ] }),
2756
- /* @__PURE__ */ jsxRuntime.jsx(
2757
- Button,
2758
- {
2759
- type: "submit",
2760
- variant: "conversion",
2761
- loading: enviando,
2762
- className: "disabled:opacity-60",
2763
- children: submitLabel
2764
- }
2765
- )
3142
+ nameField ? boton : null
2766
3143
  ] }),
2767
3144
  state === "exito" ? /* @__PURE__ */ jsxRuntime.jsx(Alert, { id: `${id}-aviso`, variant: "success", enfasis: "fuerte", children: successMessage }) : null,
2768
3145
  error ? /* @__PURE__ */ jsxRuntime.jsx(Alert, { id: `${id}-aviso`, variant: "error", enfasis: "fuerte", children: errorMessage }) : null,
@@ -2800,6 +3177,62 @@ function PageHeader({
2800
3177
  action ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "gap-step-sm mt-step-sm flex flex-wrap items-center", children: action }) : null
2801
3178
  ] });
2802
3179
  }
3180
+ function ScrollingProgressBar({
3181
+ target,
3182
+ tone = "accent",
3183
+ sticky = true,
3184
+ className,
3185
+ ...props
3186
+ }) {
3187
+ const [avance, setAvance] = react.useState(0);
3188
+ const pendiente = react.useRef(0);
3189
+ react.useEffect(() => {
3190
+ const medir = () => {
3191
+ pendiente.current = 0;
3192
+ const elemento = target?.current;
3193
+ const inicio = elemento ? elemento.getBoundingClientRect().top + scrollY : 0;
3194
+ const alto = elemento ? elemento.offsetHeight : document.documentElement.scrollHeight;
3195
+ const recorrible = alto - innerHeight;
3196
+ if (recorrible <= 0) {
3197
+ setAvance(scrollY >= inicio ? 100 : 0);
3198
+ return;
3199
+ }
3200
+ const recorrido = scrollY - inicio;
3201
+ setAvance(Math.min(100, Math.max(0, recorrido / recorrible * 100)));
3202
+ };
3203
+ const alMoverse = () => {
3204
+ if (pendiente.current) return;
3205
+ pendiente.current = requestAnimationFrame(medir);
3206
+ };
3207
+ medir();
3208
+ addEventListener("scroll", alMoverse, { passive: true });
3209
+ addEventListener("resize", alMoverse);
3210
+ return () => {
3211
+ if (pendiente.current) cancelAnimationFrame(pendiente.current);
3212
+ removeEventListener("scroll", alMoverse);
3213
+ removeEventListener("resize", alMoverse);
3214
+ };
3215
+ }, [target]);
3216
+ return /* @__PURE__ */ jsxRuntime.jsx(
3217
+ "div",
3218
+ {
3219
+ "aria-hidden": "true",
3220
+ className: cn(
3221
+ "h-1 w-full overflow-hidden",
3222
+ sticky && "sticky top-0 z-40",
3223
+ className
3224
+ ),
3225
+ ...props,
3226
+ children: /* @__PURE__ */ jsxRuntime.jsx(
3227
+ "div",
3228
+ {
3229
+ className: cn("h-full", tone === "warm" ? "bg-warm" : "bg-accent"),
3230
+ style: { width: `${avance}%` }
3231
+ }
3232
+ )
3233
+ }
3234
+ );
3235
+ }
2803
3236
  function SidebarItem({
2804
3237
  active = false,
2805
3238
  asChild = false,
@@ -2885,6 +3318,7 @@ function TalkCard({
2885
3318
  dateTime,
2886
3319
  location,
2887
3320
  status,
3321
+ description,
2888
3322
  className,
2889
3323
  ...props
2890
3324
  }) {
@@ -2898,12 +3332,43 @@ function TalkCard({
2898
3332
  status ? /* @__PURE__ */ jsxRuntime.jsx(Badge, { variant: "neutral", children: status }) : null
2899
3333
  ] }),
2900
3334
  /* @__PURE__ */ jsxRuntime.jsx(Text, { as: "h3", variant: "h3", className: "group-hover:text-accent transition-standard", children: title }),
3335
+ description ? /* @__PURE__ */ jsxRuntime.jsx(Text, { variant: "ui", tone: "secondary", className: "line-clamp-2", children: description }) : null,
2901
3336
  pie.length > 0 ? /* @__PURE__ */ jsxRuntime.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__ */ jsxRuntime.jsxs("span", { className: "gap-step-xs flex items-center", children: [
2902
3337
  i > 0 ? /* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": "true", children: "\xB7" }) : null,
2903
3338
  m
2904
3339
  ] }, i)) }) : null
2905
3340
  ] }) });
2906
3341
  }
3342
+ function ThemeToggle({
3343
+ label = "Cambiar de tema",
3344
+ onThemeChange,
3345
+ variant = "secondary",
3346
+ size: size2 = "icon",
3347
+ className,
3348
+ ...props
3349
+ }) {
3350
+ return /* @__PURE__ */ jsxRuntime.jsxs(
3351
+ Button,
3352
+ {
3353
+ type: "button",
3354
+ variant,
3355
+ size: size2,
3356
+ "aria-label": label,
3357
+ className: cn("[&_svg]:size-[19px]", className),
3358
+ onClick: () => onThemeChange?.(alternarTema()),
3359
+ ...props,
3360
+ children: [
3361
+ /* @__PURE__ */ jsxRuntime.jsx(Sol, { className: "light:hidden" }),
3362
+ /* @__PURE__ */ jsxRuntime.jsx(Luna, { className: "hidden light:block" })
3363
+ ]
3364
+ }
3365
+ );
3366
+ }
3367
+ function useTema() {
3368
+ return react.useSyncExternalStore(suscribirse2, temaActual, servidor);
3369
+ }
3370
+ var suscribirse2 = (avisar) => escucharTema(() => avisar());
3371
+ var servidor = () => "dark";
2907
3372
  function TableOfContents({
2908
3373
  items,
2909
3374
  title = "En esta p\xE1gina",
@@ -2922,7 +3387,11 @@ function TableOfContents({
2922
3387
  "focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent",
2923
3388
  "cursor-pointer",
2924
3389
  item2.nested && "pl-step-lg",
2925
- activo ? "border-accent text-accent" : "border-transparent text-text-secondary hover:text-text-primary"
3390
+ "border-transparent text-text-secondary hover:text-text-primary",
3391
+ // El hover del activo se declara con las dos variantes juntas para
3392
+ // que gane al `hover:` de arriba por especificidad y no por el orden
3393
+ // en que Tailwind decida emitir las reglas.
3394
+ "aria-[current]:border-accent aria-[current]:text-accent aria-[current]:hover:text-accent"
2926
3395
  );
2927
3396
  return /* @__PURE__ */ jsxRuntime.jsx("li", { children: linkAsChild ? /* @__PURE__ */ jsxRuntime.jsx(reactSlot.Slot, { className: clases, "aria-current": activo ? "location" : void 0, children: linkAsChild({ href: item2.href, children: item2.label }) }) : /* @__PURE__ */ jsxRuntime.jsx("a", { href: item2.href, className: clases, "aria-current": activo ? "location" : void 0, children: item2.label }) }, item2.href);
2928
3397
  }) })
@@ -3030,7 +3499,21 @@ var Correo = (props) => /* @__PURE__ */ jsxRuntime.jsxs(Funcional, { ...props, c
3030
3499
  /* @__PURE__ */ jsxRuntime.jsx("path", { d: "m3.5 7.5 7.4 5.2a2 2 0 0 0 2.2 0l7.4-5.2" })
3031
3500
  ] });
3032
3501
 
3502
+ exports.Accordion = Accordion;
3503
+ exports.AccordionContent = AccordionContent;
3504
+ exports.AccordionItem = AccordionItem;
3505
+ exports.AccordionTrigger = AccordionTrigger;
3033
3506
  exports.Alert = Alert;
3507
+ exports.AlertDialog = AlertDialog;
3508
+ exports.AlertDialogAction = AlertDialogAction;
3509
+ exports.AlertDialogCancel = AlertDialogCancel;
3510
+ exports.AlertDialogContent = AlertDialogContent;
3511
+ exports.AlertDialogDescription = AlertDialogDescription;
3512
+ exports.AlertDialogFooter = AlertDialogFooter;
3513
+ exports.AlertDialogHeader = AlertDialogHeader;
3514
+ exports.AlertDialogOverlay = AlertDialogOverlay;
3515
+ exports.AlertDialogTitle = AlertDialogTitle;
3516
+ exports.AlertDialogTrigger = AlertDialogTrigger;
3034
3517
  exports.ArticleCard = ArticleCard;
3035
3518
  exports.AudioPlayer = AudioPlayer;
3036
3519
  exports.AuthorCard = AuthorCard;
@@ -3109,6 +3592,7 @@ exports.RUTA_ASSETS = RUTA_ASSETS;
3109
3592
  exports.RadioGroup = RadioGroup2;
3110
3593
  exports.RadioGroupItem = RadioGroupItem;
3111
3594
  exports.SUPERFICIE_TARJETA = SUPERFICIE_TARJETA;
3595
+ exports.ScrollingProgressBar = ScrollingProgressBar;
3112
3596
  exports.Select = Select;
3113
3597
  exports.SelectContent = SelectContent;
3114
3598
  exports.SelectGroup = SelectGroup;
@@ -3132,6 +3616,9 @@ exports.SidebarNav = SidebarNav;
3132
3616
  exports.Skeleton = Skeleton;
3133
3617
  exports.Stat = Stat;
3134
3618
  exports.Switch = Switch;
3619
+ exports.TEMA_ATRIBUTO = TEMA_ATRIBUTO;
3620
+ exports.TEMA_CLAVE = TEMA_CLAVE;
3621
+ exports.TEMA_EVENTO = TEMA_EVENTO;
3135
3622
  exports.Table = Table;
3136
3623
  exports.TableBody = TableBody;
3137
3624
  exports.TableCaption = TableCaption;
@@ -3148,18 +3635,22 @@ exports.TabsTrigger = TabsTrigger;
3148
3635
  exports.TalkCard = TalkCard;
3149
3636
  exports.Text = Text;
3150
3637
  exports.Textarea = Textarea;
3638
+ exports.ThemeToggle = ThemeToggle;
3151
3639
  exports.Toast = Toast;
3152
3640
  exports.ToastAction = ToastAction;
3153
3641
  exports.ToastDescription = ToastDescription;
3154
3642
  exports.ToastProvider = ToastProvider;
3155
3643
  exports.ToastTitle = ToastTitle;
3156
3644
  exports.ToastViewport = ToastViewport;
3645
+ exports.Toaster = Toaster;
3157
3646
  exports.Tooltip = Tooltip;
3158
3647
  exports.TooltipContent = TooltipContent;
3159
3648
  exports.TooltipProvider = TooltipProvider;
3160
3649
  exports.TooltipTrigger = TooltipTrigger;
3161
3650
  exports.alertVariants = alert;
3162
3651
  exports.aletas = aletas;
3652
+ exports.alternarTema = alternarTema;
3653
+ exports.aplicarTema = aplicarTema;
3163
3654
  exports.avatarVariants = avatar;
3164
3655
  exports.badgeVariants = badge;
3165
3656
  exports.brand = brand;
@@ -3170,6 +3661,7 @@ exports.cn = cn;
3170
3661
  exports.colors = colors;
3171
3662
  exports.control = control;
3172
3663
  exports.dark = dark;
3664
+ exports.escucharTema = escucharTema;
3173
3665
  exports.fonts = fonts;
3174
3666
  exports.gradient = gradient;
3175
3667
  exports.light = light;
@@ -3180,13 +3672,20 @@ exports.motion = motion;
3180
3672
  exports.naming = naming;
3181
3673
  exports.poses = poses;
3182
3674
  exports.radius = radius;
3675
+ exports.scriptTema = scriptTema;
3676
+ exports.series = series;
3183
3677
  exports.shadow = shadow;
3184
3678
  exports.sintaxis = sintaxis;
3185
3679
  exports.size = size;
3186
3680
  exports.social = social_exports;
3187
3681
  exports.spacing = spacing;
3188
3682
  exports.tagline = tagline;
3683
+ exports.temaActual = temaActual;
3684
+ exports.temaGuardado = temaGuardado;
3685
+ exports.temaPreferido = temaPreferido;
3189
3686
  exports.textVariants = texto;
3687
+ exports.toast = toast2;
3190
3688
  exports.tokens = tokens;
3191
3689
  exports.typeScale = typeScale;
3690
+ exports.useTema = useTema;
3192
3691
  exports.usoDeCara = usoDeCara;