@eduardoalvarez/arrecife 0.6.0 → 0.7.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 (42) hide show
  1. package/CHANGELOG.md +69 -0
  2. package/README.md +185 -20
  3. package/dist/brand/index.js +3 -3
  4. package/dist/chart/index.js +3 -3
  5. package/dist/{chunk-XKYHTOUJ.js → chunk-2WPWEIMD.js} +1 -1
  6. package/dist/chunk-45HVCTB7.js +70 -0
  7. package/dist/{chunk-DKCN7BAL.js → chunk-727HCBD4.js} +1 -1
  8. package/dist/{chunk-25YNFCIF.js → chunk-E6KFUSKB.js} +6 -3
  9. package/dist/{chunk-6O3KWB6P.js → chunk-JN3IS5OS.js} +2 -2
  10. package/dist/{chunk-O4TAH7YJ.js → chunk-OMKSESQB.js} +27 -3
  11. package/dist/{chunk-PMN7NR3G.js → chunk-TA7TLWW4.js} +1 -1
  12. package/dist/{chunk-JMOOFZ3B.js → chunk-WGNIRIN7.js} +1 -1
  13. package/dist/doctor.mjs +166 -0
  14. package/dist/form/index.js +4 -4
  15. package/dist/icons/index.cjs +149 -0
  16. package/dist/icons/index.d.cts +94 -0
  17. package/dist/icons/index.d.ts +94 -0
  18. package/dist/icons/index.js +28 -0
  19. package/dist/index-DlAO2JZs.d.cts +47 -0
  20. package/dist/index-DlAO2JZs.d.ts +47 -0
  21. package/dist/index.cjs +279 -103
  22. package/dist/index.d.cts +186 -57
  23. package/dist/index.d.ts +186 -57
  24. package/dist/index.js +262 -179
  25. package/dist/og/index.cjs +3 -2
  26. package/dist/og/index.js +1 -1
  27. package/dist/shiki/index.js +1 -1
  28. package/dist/social/index.cjs +67 -0
  29. package/dist/social/index.d.cts +2 -0
  30. package/dist/social/index.d.ts +2 -0
  31. package/dist/social/index.js +2 -0
  32. package/dist/tokens/index.cjs +27 -3
  33. package/dist/tokens/index.d.cts +33 -6
  34. package/dist/tokens/index.d.ts +33 -6
  35. package/dist/tokens/index.js +2 -2
  36. package/dist/tokens/theme.css +33 -3
  37. package/dist/variants/index.cjs +6 -3
  38. package/dist/variants/index.d.cts +4 -1
  39. package/dist/variants/index.d.ts +4 -1
  40. package/dist/variants/index.js +1 -1
  41. package/llms.txt +363 -30
  42. package/package.json +24 -2
package/dist/index.cjs CHANGED
@@ -283,6 +283,30 @@ var spacing = {
283
283
  var size = {
284
284
  /** Navigation bar height. */
285
285
  nav: 64,
286
+ /**
287
+ * The bar when it shares the screen with a sidebar.
288
+ *
289
+ * It is not «a smaller bar because it looks better». At 64 the header of an
290
+ * app shell competes with the rail beside it for the same corner, and the two
291
+ * together eat the top of the content area. 56 is what `cursos` had arrived at
292
+ * on its own, and it is the same reasoning as `control.iconSm`: the one admin
293
+ * app of the five is denser than the four reading sites. See
294
+ * `docs/decisions.md` § 30.
295
+ */
296
+ navCompact: 56,
297
+ /**
298
+ * The admin sidebar, and the rail it collapses to.
299
+ *
300
+ * They are tokens and not the consumer's `w-*` because a collapsible sidebar
301
+ * has to know BOTH: the layout beside it reserves one of the two, and two
302
+ * numbers written by hand in two files drift the first time one of them moves.
303
+ * A sidebar that never collapses is still just a box the layout sizes.
304
+ *
305
+ * 56 is the rail: `navCompact`'s height, so a panel's bar and its rail meet in
306
+ * a square corner instead of a step.
307
+ */
308
+ sidebar: 256,
309
+ sidebarRail: 56,
286
310
  /** Reading column width. */
287
311
  content: 760,
288
312
  /** Maximum page width. */
@@ -315,9 +339,9 @@ var gradient = {
315
339
  og: `linear-gradient(145deg, ${dark.background} 55%, ${deep} 100%)`
316
340
  },
317
341
  light: {
318
- hero: `linear-gradient(160deg, ${light.background} 60%, ${light.surfaceRaised} 100%)`,
319
- section: `linear-gradient(150deg, ${light.surface} 0%, ${light.surfaceRaised} 100%)`,
320
- og: `linear-gradient(145deg, ${light.background} 55%, ${light.surfaceRaised} 100%)`
342
+ hero: `linear-gradient(160deg, ${light.background} 60%, ${light.surface} 100%)`,
343
+ section: `linear-gradient(150deg, ${light.surface} 0%, ${light.background} 100%)`,
344
+ og: `linear-gradient(145deg, ${light.background} 55%, ${light.surface} 100%)`
321
345
  }
322
346
  };
323
347
  var shadow = {
@@ -452,7 +476,7 @@ var button = classVarianceAuthority.cva(
452
476
  "inline-flex cursor-pointer items-center justify-center gap-step-xs whitespace-nowrap select-none",
453
477
  "rounded-control font-sans font-medium",
454
478
  "transition-standard",
455
- "focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent",
479
+ "focus-ring",
456
480
  "disabled:pointer-events-none disabled:opacity-50",
457
481
  "[&_svg]:shrink-0"
458
482
  ],
@@ -463,7 +487,10 @@ var button = classVarianceAuthority.cva(
463
487
  "bg-accent text-accent-on hover:bg-accent-hover",
464
488
  "light:bg-brand-hull light:text-accent-on light:hover:bg-text-secondary"
465
489
  ],
466
- conversion: "bg-warm text-warm-on hover:bg-warm-hover",
490
+ // The one control whose focus ring is not biolume. It is the system's
491
+ // only sand fill, and a biolume ring three pixels off a sand button puts
492
+ // both of the brand's accents in the same glance. See `decisions.md` § 37.
493
+ conversion: "bg-warm text-warm-on hover:bg-warm-hover focus-ring-warm",
467
494
  secondary: [
468
495
  "border-hairline-hover border bg-transparent text-text-primary",
469
496
  "hover:border-accent hover:text-accent"
@@ -621,7 +648,7 @@ var CARD = [
621
648
  "group block cursor-pointer",
622
649
  CARD_SURFACE,
623
650
  CARD_HOVER,
624
- "focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent"
651
+ "focus-ring"
625
652
  ];
626
653
  var kebab = (name) => name.replace(/[A-Z]/g, (c) => `-${c.toLowerCase()}`);
627
654
  var scales = Object.keys(typeScale);
@@ -786,7 +813,7 @@ function AccordionTrigger({
786
813
  "font-sans text-lead font-medium text-text-primary",
787
814
  "transition-standard",
788
815
  "hover:text-accent",
789
- "focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent",
816
+ "focus-ring",
790
817
  "disabled:pointer-events-none disabled:opacity-50",
791
818
  "[&[data-state=open]>svg]:rotate-180",
792
819
  className
@@ -1022,7 +1049,7 @@ function AvatarUpload({
1022
1049
  "transition-standard hover:text-accent hover:border-accent",
1023
1050
  // Focus lives on the input, which is hidden: without this, tabbing to
1024
1051
  // the control shows up nowhere.
1025
- "has-[:focus-visible]:outline-2 has-[:focus-visible]:outline-offset-2 has-[:focus-visible]:outline-accent",
1052
+ "has-[:focus-visible]:outline-2 has-[:focus-visible]:outline-offset-3 has-[:focus-visible]:outline-accent",
1026
1053
  disabled && "pointer-events-none opacity-50"
1027
1054
  ),
1028
1055
  children: [
@@ -1111,14 +1138,14 @@ function Calendar({
1111
1138
  "rounded-chip inline-flex items-center justify-center",
1112
1139
  "transition-standard cursor-pointer",
1113
1140
  "hover:bg-surface-raised",
1114
- "focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent",
1141
+ "focus-ring",
1115
1142
  "disabled:pointer-events-none disabled:opacity-50"
1116
1143
  ].join(" ");
1117
1144
  const navigation = [
1118
1145
  "size-8 rounded-chip inline-flex items-center justify-center",
1119
1146
  "text-text-secondary transition-standard cursor-pointer",
1120
1147
  "hover:bg-surface-raised hover:text-text-primary",
1121
- "focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent",
1148
+ "focus-ring",
1122
1149
  "disabled:pointer-events-none disabled:opacity-50"
1123
1150
  ].join(" ");
1124
1151
  return /* @__PURE__ */ jsxRuntime.jsx(
@@ -1237,7 +1264,7 @@ function Checkbox({ className, ...props }) {
1237
1264
  "rounded-chip border-border bg-surface size-5 shrink-0 cursor-pointer border",
1238
1265
  "text-accent-on transition-standard",
1239
1266
  "hover:border-hairline-hover",
1240
- "focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent",
1267
+ "focus-ring",
1241
1268
  "disabled:pointer-events-none disabled:opacity-50",
1242
1269
  "data-[state=checked]:border-accent data-[state=checked]:bg-accent",
1243
1270
  "data-[state=indeterminate]:border-accent data-[state=indeterminate]:bg-accent",
@@ -1280,7 +1307,7 @@ function DateField({
1280
1307
  "font-mono text-ui text-text-primary",
1281
1308
  "transition-standard",
1282
1309
  "hover:border-hairline-hover",
1283
- "focus-visible:border-accent focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent",
1310
+ "focus-visible:border-accent focus-ring",
1284
1311
  "disabled:pointer-events-none disabled:opacity-50",
1285
1312
  "data-[invalid]:border-error data-[invalid]:focus-visible:outline-error",
1286
1313
  // The native indicator inherits the active theme's scheme.
@@ -1334,7 +1361,7 @@ function DialogContent({
1334
1361
  "rounded-chip text-text-muted absolute top-4 right-4 flex size-8 cursor-pointer items-center justify-center",
1335
1362
  "transition-standard",
1336
1363
  "hover:bg-surface-raised hover:text-text-primary",
1337
- "focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent"
1364
+ "focus-ring"
1338
1365
  ),
1339
1366
  children: /* @__PURE__ */ jsxRuntime.jsx(Close, {})
1340
1367
  }
@@ -1483,7 +1510,7 @@ function Input({ className, invalid = false, ...props }) {
1483
1510
  "font-sans text-ui text-text-primary placeholder:text-text-muted",
1484
1511
  "transition-standard",
1485
1512
  "hover:border-hairline-hover",
1486
- "focus-visible:border-accent focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent",
1513
+ "focus-visible:border-accent focus-ring",
1487
1514
  "disabled:pointer-events-none disabled:opacity-50",
1488
1515
  "data-[invalid]:border-error data-[invalid]:focus-visible:outline-error",
1489
1516
  "file:mr-step-sm file:border-0 file:bg-transparent file:font-sans file:text-label file:text-text-secondary",
@@ -1533,7 +1560,7 @@ function PaginationLink({ className, isActive = false, ...props }) {
1533
1560
  "font-sans text-ui text-text-secondary",
1534
1561
  "transition-standard",
1535
1562
  "hover:bg-surface hover:text-text-primary",
1536
- "focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent",
1563
+ "focus-ring",
1537
1564
  isActive && "bg-surface-raised text-text-primary",
1538
1565
  className
1539
1566
  ),
@@ -1548,7 +1575,7 @@ function PaginationPrevious({ className, ...props }) {
1548
1575
  ] });
1549
1576
  }
1550
1577
  function PaginationNext({ className, ...props }) {
1551
- return /* @__PURE__ */ jsxRuntime.jsxs(PaginationLink, { "aria-label": "P\xE1gina next", className: cn("gap-step-xs", className), ...props, children: [
1578
+ return /* @__PURE__ */ jsxRuntime.jsxs(PaginationLink, { "aria-label": "P\xE1gina siguiente", className: cn("gap-step-xs", className), ...props, children: [
1552
1579
  "Siguiente",
1553
1580
  /* @__PURE__ */ jsxRuntime.jsx(ChevronRight, {})
1554
1581
  ] });
@@ -1618,7 +1645,7 @@ function RadioGroupItem({ className, ...props }) {
1618
1645
  "rounded-pill border-border bg-surface size-5 shrink-0 cursor-pointer border",
1619
1646
  "transition-standard",
1620
1647
  "hover:border-hairline-hover",
1621
- "focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent",
1648
+ "focus-ring",
1622
1649
  "disabled:pointer-events-none disabled:opacity-50",
1623
1650
  "data-[state=checked]:border-accent",
1624
1651
  className
@@ -1645,7 +1672,7 @@ function SelectTrigger({
1645
1672
  "font-sans text-ui text-text-primary",
1646
1673
  "transition-standard",
1647
1674
  "hover:border-hairline-hover",
1648
- "focus-visible:border-accent focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent",
1675
+ "focus-visible:border-accent focus-ring",
1649
1676
  "disabled:pointer-events-none disabled:opacity-50",
1650
1677
  "data-[placeholder]:text-text-muted",
1651
1678
  className
@@ -1795,7 +1822,7 @@ function SheetContent({ className, side, children, ...props }) {
1795
1822
  "rounded-chip text-text-muted absolute top-4 right-4 flex size-8 cursor-pointer items-center justify-center",
1796
1823
  "transition-standard",
1797
1824
  "hover:bg-surface-raised hover:text-text-primary",
1798
- "focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent"
1825
+ "focus-ring"
1799
1826
  ),
1800
1827
  children: /* @__PURE__ */ jsxRuntime.jsx(Close, {})
1801
1828
  }
@@ -1870,7 +1897,7 @@ function Switch({ className, ...props }) {
1870
1897
  "rounded-pill border-border bg-surface-raised inline-flex h-6 w-11 shrink-0 cursor-pointer items-center border",
1871
1898
  "transition-standard",
1872
1899
  "hover:border-hairline-hover",
1873
- "focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent",
1900
+ "focus-ring",
1874
1901
  "disabled:pointer-events-none disabled:opacity-50",
1875
1902
  "data-[state=checked]:border-accent data-[state=checked]:bg-accent",
1876
1903
  className
@@ -1971,7 +1998,7 @@ function TabsTrigger({
1971
1998
  "font-sans text-label text-text-secondary",
1972
1999
  "transition-standard",
1973
2000
  "hover:text-text-primary",
1974
- "focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent",
2001
+ "focus-ring",
1975
2002
  "disabled:pointer-events-none disabled:opacity-50",
1976
2003
  "data-[state=active]:bg-surface-raised data-[state=active]:text-text-primary",
1977
2004
  className
@@ -1988,7 +2015,7 @@ function TabsContent({
1988
2015
  TabsPrimitive__namespace.Content,
1989
2016
  {
1990
2017
  className: cn(
1991
- "focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent",
2018
+ "focus-ring",
1992
2019
  className
1993
2020
  ),
1994
2021
  ...props
@@ -2007,7 +2034,7 @@ function Textarea({ className, invalid = false, ...props }) {
2007
2034
  "font-sans text-ui text-text-primary placeholder:text-text-muted",
2008
2035
  "transition-standard",
2009
2036
  "hover:border-hairline-hover",
2010
- "focus-visible:border-accent focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent",
2037
+ "focus-visible:border-accent focus-ring",
2011
2038
  "disabled:pointer-events-none disabled:opacity-50",
2012
2039
  "data-[invalid]:border-error data-[invalid]:focus-visible:outline-error",
2013
2040
  className
@@ -2062,7 +2089,7 @@ function Toast({ className, variant, children, ...props }) {
2062
2089
  "rounded-chip text-text-muted absolute top-3 right-3 flex size-7 cursor-pointer items-center justify-center",
2063
2090
  "transition-standard",
2064
2091
  "hover:bg-surface-raised hover:text-text-primary",
2065
- "focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent"
2092
+ "focus-ring"
2066
2093
  ),
2067
2094
  children: /* @__PURE__ */ jsxRuntime.jsx(Close, {})
2068
2095
  }
@@ -2304,21 +2331,21 @@ function ProgressBar({
2304
2331
  }
2305
2332
  );
2306
2333
  }
2307
- var CONTROL = "rounded-chip transition-standard cursor-pointer focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent";
2334
+ var CONTROL = "rounded-chip transition-standard cursor-pointer focus-ring";
2308
2335
  function SkipButton({
2309
- segundos,
2336
+ seconds,
2310
2337
  className,
2311
2338
  size: size2,
2312
- onSaltar
2339
+ onSkip
2313
2340
  }) {
2314
2341
  return /* @__PURE__ */ jsxRuntime.jsx(
2315
2342
  "button",
2316
2343
  {
2317
2344
  type: "button",
2318
- onClick: () => onSaltar(segundos),
2345
+ onClick: () => onSkip(seconds),
2319
2346
  className: cn("text-text-muted hover:text-text-primary", CONTROL, className),
2320
- "aria-label": segundos < 0 ? "Retroceder 15 segundos" : "Adelantar 15 segundos",
2321
- children: segundos < 0 ? /* @__PURE__ */ jsxRuntime.jsx(GoBackSeconds, { className: size2 }) : /* @__PURE__ */ jsxRuntime.jsx(AdvanceSeconds, { className: size2 })
2347
+ "aria-label": seconds < 0 ? "Retroceder 15 segundos" : "Adelantar 15 segundos",
2348
+ children: seconds < 0 ? /* @__PURE__ */ jsxRuntime.jsx(GoBackSeconds, { className: size2 }) : /* @__PURE__ */ jsxRuntime.jsx(AdvanceSeconds, { className: size2 })
2322
2349
  }
2323
2350
  );
2324
2351
  }
@@ -2350,8 +2377,8 @@ function SpeedButton({
2350
2377
  function Volume({
2351
2378
  size: size2,
2352
2379
  width,
2353
- silenciado,
2354
- volumen,
2380
+ muted,
2381
+ volume,
2355
2382
  onMute,
2356
2383
  onVolumeChange
2357
2384
  }) {
@@ -2362,8 +2389,8 @@ function Volume({
2362
2389
  type: "button",
2363
2390
  onClick: onMute,
2364
2391
  className: cn("text-text-muted hover:text-text-primary p-1", CONTROL),
2365
- "aria-label": silenciado ? "Activar sonido" : "Silenciar",
2366
- children: silenciado || volumen === 0 ? /* @__PURE__ */ jsxRuntime.jsx(VolumeMuted, { className: size2 }) : /* @__PURE__ */ jsxRuntime.jsx(VolumeOn, { className: size2 })
2392
+ "aria-label": muted ? "Activar sonido" : "Silenciar",
2393
+ children: muted || volume === 0 ? /* @__PURE__ */ jsxRuntime.jsx(VolumeMuted, { className: size2 }) : /* @__PURE__ */ jsxRuntime.jsx(VolumeOn, { className: size2 })
2367
2394
  }
2368
2395
  ),
2369
2396
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -2373,20 +2400,20 @@ function Volume({
2373
2400
  min: "0",
2374
2401
  max: "1",
2375
2402
  step: "0.1",
2376
- value: silenciado ? 0 : volumen,
2403
+ value: muted ? 0 : volume,
2377
2404
  onChange: onVolumeChange,
2378
2405
  className: cn(
2379
2406
  "bg-surface-raised rounded-pill h-1 cursor-pointer appearance-none",
2380
2407
  "[accent-color:var(--color-accent)]",
2381
2408
  width
2382
2409
  ),
2383
- "aria-label": "Volume"
2410
+ "aria-label": "Volumen"
2384
2411
  }
2385
2412
  )
2386
2413
  ] });
2387
2414
  }
2388
- function PlayIcon({ className, cargando, error, playing }) {
2389
- if (cargando) return /* @__PURE__ */ jsxRuntime.jsx(Spinner, { className: cn("motion-safe:animate-spin", className) });
2415
+ function PlayIcon({ className, loading, error, playing }) {
2416
+ if (loading) return /* @__PURE__ */ jsxRuntime.jsx(Spinner, { className: cn("motion-safe:animate-spin", className) });
2390
2417
  if (error) return /* @__PURE__ */ jsxRuntime.jsx(Retry, { className });
2391
2418
  if (playing) return /* @__PURE__ */ jsxRuntime.jsx(Pause, { className });
2392
2419
  return /* @__PURE__ */ jsxRuntime.jsx(Play, { className });
@@ -2406,7 +2433,7 @@ function PlayButton({
2406
2433
  onClick: onToggle,
2407
2434
  className: cn(
2408
2435
  "text-accent-on transition-standard cursor-pointer",
2409
- "focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent",
2436
+ "focus-ring",
2410
2437
  state.error ? "bg-error hover:bg-error/80" : "bg-accent hover:bg-accent-hover",
2411
2438
  className
2412
2439
  ),
@@ -2575,7 +2602,7 @@ function AudioPlayer({ src, title, mode = "full", onFirstPlay }) {
2575
2602
  );
2576
2603
  const progress = duration > 0 ? currentTime / duration * 100 : 0;
2577
2604
  const playLabel = hasError ? "Reintentar" : isPlaying ? "Pausar" : "Reproducir";
2578
- const playState = { cargando: isLoading, error: hasError, playing: isPlaying };
2605
+ const playState = { loading: isLoading, error: hasError, playing: isPlaying };
2579
2606
  const pointer = {
2580
2607
  onPointerDown: handlePointerDown,
2581
2608
  onPointerMove: handlePointerMove,
@@ -2616,7 +2643,7 @@ function AudioPlayer({ src, title, mode = "full", onFirstPlay }) {
2616
2643
  ] })
2617
2644
  ] }),
2618
2645
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex shrink-0 items-center gap-1", children: [
2619
- /* @__PURE__ */ jsxRuntime.jsx(SkipButton, { segundos: -15, className: "p-1.5", size: "w-5 h-5", onSaltar: skip }),
2646
+ /* @__PURE__ */ jsxRuntime.jsx(SkipButton, { seconds: -15, className: "p-1.5", size: "w-5 h-5", onSkip: skip }),
2620
2647
  /* @__PURE__ */ jsxRuntime.jsx(
2621
2648
  PlayButton,
2622
2649
  {
@@ -2627,7 +2654,7 @@ function AudioPlayer({ src, title, mode = "full", onFirstPlay }) {
2627
2654
  ...playState
2628
2655
  }
2629
2656
  ),
2630
- /* @__PURE__ */ jsxRuntime.jsx(SkipButton, { segundos: 15, className: "p-1.5", size: "w-5 h-5", onSaltar: skip }),
2657
+ /* @__PURE__ */ jsxRuntime.jsx(SkipButton, { seconds: 15, className: "p-1.5", size: "w-5 h-5", onSkip: skip }),
2631
2658
  /* @__PURE__ */ jsxRuntime.jsx(
2632
2659
  SpeedButton,
2633
2660
  {
@@ -2656,7 +2683,7 @@ function AudioPlayer({ src, title, mode = "full", onFirstPlay }) {
2656
2683
  ] }),
2657
2684
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mb-step-md", children: /* @__PURE__ */ jsxRuntime.jsx(ProgressBar, { height: "h-1.5", knob: 14, progress, ...pointer }) }),
2658
2685
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "gap-step-sm flex items-center", children: [
2659
- /* @__PURE__ */ jsxRuntime.jsx(SkipButton, { segundos: -15, className: "p-2", size: "w-6 h-6", onSaltar: skip }),
2686
+ /* @__PURE__ */ jsxRuntime.jsx(SkipButton, { seconds: -15, className: "p-2", size: "w-6 h-6", onSkip: skip }),
2660
2687
  /* @__PURE__ */ jsxRuntime.jsx(
2661
2688
  PlayButton,
2662
2689
  {
@@ -2668,7 +2695,7 @@ function AudioPlayer({ src, title, mode = "full", onFirstPlay }) {
2668
2695
  ...playState
2669
2696
  }
2670
2697
  ),
2671
- /* @__PURE__ */ jsxRuntime.jsx(SkipButton, { segundos: 15, className: "p-2", size: "w-6 h-6", onSaltar: skip }),
2698
+ /* @__PURE__ */ jsxRuntime.jsx(SkipButton, { seconds: 15, className: "p-2", size: "w-6 h-6", onSkip: skip }),
2672
2699
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "gap-step-sm ml-auto flex items-center", children: [
2673
2700
  /* @__PURE__ */ jsxRuntime.jsx(
2674
2701
  SpeedButton,
@@ -2683,8 +2710,8 @@ function AudioPlayer({ src, title, mode = "full", onFirstPlay }) {
2683
2710
  {
2684
2711
  size: "w-4 h-4",
2685
2712
  width: "w-16",
2686
- silenciado: isMuted,
2687
- volumen: volume,
2713
+ muted: isMuted,
2714
+ volume,
2688
2715
  onMute: toggleMute,
2689
2716
  onVolumeChange: handleVolumeChange
2690
2717
  }
@@ -2706,7 +2733,7 @@ function AudioPlayer({ src, title, mode = "full", onFirstPlay }) {
2706
2733
  ] }),
2707
2734
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [
2708
2735
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1", children: [
2709
- /* @__PURE__ */ jsxRuntime.jsx(SkipButton, { segundos: -15, className: "p-1.5", size: "w-5 h-5", onSaltar: skip }),
2736
+ /* @__PURE__ */ jsxRuntime.jsx(SkipButton, { seconds: -15, className: "p-1.5", size: "w-5 h-5", onSkip: skip }),
2710
2737
  /* @__PURE__ */ jsxRuntime.jsx(
2711
2738
  PlayButton,
2712
2739
  {
@@ -2717,7 +2744,7 @@ function AudioPlayer({ src, title, mode = "full", onFirstPlay }) {
2717
2744
  ...playState
2718
2745
  }
2719
2746
  ),
2720
- /* @__PURE__ */ jsxRuntime.jsx(SkipButton, { segundos: 15, className: "p-1.5", size: "w-5 h-5", onSaltar: skip })
2747
+ /* @__PURE__ */ jsxRuntime.jsx(SkipButton, { seconds: 15, className: "p-1.5", size: "w-5 h-5", onSkip: skip })
2721
2748
  ] }),
2722
2749
  /* @__PURE__ */ jsxRuntime.jsx(
2723
2750
  SpeedButton,
@@ -2742,7 +2769,7 @@ function AudioPlayer({ src, title, mode = "full", onFirstPlay }) {
2742
2769
  ] }),
2743
2770
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [
2744
2771
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "gap-step-xs flex items-center", children: [
2745
- /* @__PURE__ */ jsxRuntime.jsx(SkipButton, { segundos: -15, className: "p-2", size: "w-5 h-5", onSaltar: skip }),
2772
+ /* @__PURE__ */ jsxRuntime.jsx(SkipButton, { seconds: -15, className: "p-2", size: "w-5 h-5", onSkip: skip }),
2746
2773
  /* @__PURE__ */ jsxRuntime.jsx(
2747
2774
  PlayButton,
2748
2775
  {
@@ -2753,7 +2780,7 @@ function AudioPlayer({ src, title, mode = "full", onFirstPlay }) {
2753
2780
  ...playState
2754
2781
  }
2755
2782
  ),
2756
- /* @__PURE__ */ jsxRuntime.jsx(SkipButton, { segundos: 15, className: "p-2", size: "w-5 h-5", onSaltar: skip })
2783
+ /* @__PURE__ */ jsxRuntime.jsx(SkipButton, { seconds: 15, className: "p-2", size: "w-5 h-5", onSkip: skip })
2757
2784
  ] }),
2758
2785
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "gap-step-sm flex items-center", children: [
2759
2786
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -2769,8 +2796,8 @@ function AudioPlayer({ src, title, mode = "full", onFirstPlay }) {
2769
2796
  {
2770
2797
  size: "w-5 h-5",
2771
2798
  width: "w-20",
2772
- silenciado: isMuted,
2773
- volumen: volume,
2799
+ muted: isMuted,
2800
+ volume,
2774
2801
  onMute: toggleMute,
2775
2802
  onVolumeChange: handleVolumeChange
2776
2803
  }
@@ -2796,7 +2823,7 @@ function Blockquote({ children, author, source, className, ...props }) {
2796
2823
  }
2797
2824
  );
2798
2825
  }
2799
- var LINK = "transition-standard hover:text-accent focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent rounded-chip cursor-pointer";
2826
+ var LINK = "transition-standard hover:text-accent focus-ring rounded-chip cursor-pointer";
2800
2827
  function Breadcrumb({
2801
2828
  items,
2802
2829
  homeHref = "/",
@@ -2857,7 +2884,7 @@ function CodeBlock({ children, language, copyText, className, ...props }) {
2857
2884
  "gap-step-xs rounded-chip flex items-center px-2 py-1",
2858
2885
  "text-label font-mono text-text-muted cursor-pointer",
2859
2886
  "transition-standard hover:bg-surface hover:text-text-primary",
2860
- "focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent"
2887
+ "focus-ring"
2861
2888
  ),
2862
2889
  children: [
2863
2890
  copiado ? /* @__PURE__ */ jsxRuntime.jsx(Check, { className: "text-accent" }) : /* @__PURE__ */ jsxRuntime.jsx(Copy, {}),
@@ -2967,20 +2994,32 @@ function MascotFace({
2967
2994
  );
2968
2995
  }
2969
2996
  var FACE = "w-[66px] max-w-none";
2970
- function EmptyState({
2971
- expression,
2972
- title,
2973
- description,
2974
- action,
2975
- basePath,
2976
- className,
2977
- ...props
2978
- }) {
2997
+ function EmptyState(props) {
2998
+ if (props.variant === "inline") {
2999
+ const { variant: variant2, title: title2, description: description2, action: action2, icon, className: className2, ...rest2 } = props;
3000
+ return /* @__PURE__ */ jsxRuntime.jsxs(
3001
+ "div",
3002
+ {
3003
+ className: cn(
3004
+ "py-step-lg px-step-md gap-step-xs flex flex-col items-center text-center",
3005
+ className2
3006
+ ),
3007
+ ...rest2,
3008
+ children: [
3009
+ icon ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-text-muted shrink-0", children: icon }) : null,
3010
+ /* @__PURE__ */ jsxRuntime.jsx(Text, { variant: "ui", tone: "muted", as: "p", className: "max-w-measure", children: title2 }),
3011
+ description2 ? /* @__PURE__ */ jsxRuntime.jsx(Text, { variant: "label", tone: "muted", as: "p", className: "max-w-measure font-normal", children: description2 }) : null,
3012
+ action2 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-step-xs", children: action2 }) : null
3013
+ ]
3014
+ }
3015
+ );
3016
+ }
3017
+ const { variant, title, description, action, expression, basePath, className, ...rest } = props;
2979
3018
  return /* @__PURE__ */ jsxRuntime.jsxs(
2980
3019
  "div",
2981
3020
  {
2982
3021
  className: cn(CARD_SURFACE, "p-step-lg gap-step-sm flex flex-col items-center text-center", className),
2983
- ...props,
3022
+ ...rest,
2984
3023
  children: [
2985
3024
  /* @__PURE__ */ jsxRuntime.jsx(MascotFace, { expression, className: FACE, basePath }),
2986
3025
  /* @__PURE__ */ jsxRuntime.jsx(Text, { variant: "ui", as: "p", className: "font-medium", children: title }),
@@ -3169,7 +3208,7 @@ function EventCalendar({
3169
3208
  ] }),
3170
3209
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "gap-step-sm flex flex-wrap items-center", children: [
3171
3210
  /* @__PURE__ */ jsxRuntime.jsx(Button, { type: "submit", size: "sm", children: editing ? "Guardar" : "A\xF1adir" }),
3172
- editing ? /* @__PURE__ */ jsxRuntime.jsx(Button, { type: "button", variant: "tertiary", size: "sm", onClick: cancel, children: "./cancel" }) : null
3211
+ editing ? /* @__PURE__ */ jsxRuntime.jsx(Button, { type: "button", variant: "tertiary", size: "sm", onClick: cancel, children: "./cancelar" }) : null
3173
3212
  ] })
3174
3213
  ] }) : null
3175
3214
  ]
@@ -3215,7 +3254,7 @@ function Footer({
3215
3254
  "aria-label": socialLink.label,
3216
3255
  className: cn(
3217
3256
  "text-text-muted hover:text-accent transition-standard block cursor-pointer text-[19px]",
3218
- "rounded-chip focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent"
3257
+ "rounded-chip focus-ring"
3219
3258
  ),
3220
3259
  children: socialLink.icon
3221
3260
  }
@@ -3238,7 +3277,7 @@ function FooterLink({ asChild = false, className, ...props }) {
3238
3277
  {
3239
3278
  className: cn(
3240
3279
  "font-mono text-meta text-text-secondary hover:text-accent transition-standard cursor-pointer",
3241
- "rounded-chip focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent",
3280
+ "rounded-chip focus-ring",
3242
3281
  className
3243
3282
  ),
3244
3283
  ...props
@@ -3351,7 +3390,7 @@ function LinkRow({
3351
3390
  }
3352
3391
  );
3353
3392
  }
3354
- function Nav({ brand: brand2, children, actions, className, ...props }) {
3393
+ function Nav({ brand: brand2, children, actions, size: size2 = "default", className, ...props }) {
3355
3394
  return /* @__PURE__ */ jsxRuntime.jsx(
3356
3395
  "header",
3357
3396
  {
@@ -3364,14 +3403,23 @@ function Nav({ brand: brand2, children, actions, className, ...props }) {
3364
3403
  className
3365
3404
  ),
3366
3405
  ...props,
3367
- children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "max-w-wide px-step-md h-nav gap-step-lg mx-auto flex items-center", children: [
3368
- brand2 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "shrink-0", children: brand2 }) : null,
3369
- children ? /* @__PURE__ */ jsxRuntime.jsx("nav", { "aria-label": "Principal", className: "ml-auto min-w-0", children: /* @__PURE__ */ jsxRuntime.jsxs("ul", { className: "gap-step-md flex items-center", children: [
3370
- /* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": "true", className: "text-text-muted font-mono text-meta select-none", children: "~/" }),
3371
- children
3372
- ] }) }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1" }),
3373
- actions ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "gap-step-sm flex shrink-0 items-center", children: actions }) : null
3374
- ] })
3406
+ children: /* @__PURE__ */ jsxRuntime.jsxs(
3407
+ "div",
3408
+ {
3409
+ className: cn(
3410
+ "max-w-wide px-step-md gap-step-lg mx-auto flex items-center",
3411
+ size2 === "compact" ? "h-nav-compact" : "h-nav"
3412
+ ),
3413
+ children: [
3414
+ brand2 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "shrink-0", children: brand2 }) : null,
3415
+ children ? /* @__PURE__ */ jsxRuntime.jsx("nav", { "aria-label": "Principal", className: "ml-auto min-w-0", children: /* @__PURE__ */ jsxRuntime.jsxs("ul", { className: "gap-step-md flex items-center", children: [
3416
+ /* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": "true", className: "text-text-muted font-mono text-meta select-none", children: "~/" }),
3417
+ children
3418
+ ] }) }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1" }),
3419
+ actions ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "gap-step-sm flex shrink-0 items-center", children: actions }) : null
3420
+ ]
3421
+ }
3422
+ )
3375
3423
  }
3376
3424
  );
3377
3425
  }
@@ -3383,7 +3431,7 @@ function NavItem({ active = false, asChild = false, className, children, ...prop
3383
3431
  "aria-current": active ? "page" : void 0,
3384
3432
  className: cn(
3385
3433
  "font-mono text-meta transition-standard cursor-pointer",
3386
- "rounded-chip focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent",
3434
+ "rounded-chip focus-ring",
3387
3435
  active ? "text-accent underline decoration-1 underline-offset-4" : "text-text-secondary hover:text-accent",
3388
3436
  className
3389
3437
  ),
@@ -3402,14 +3450,14 @@ function NewsletterForm({
3402
3450
  description,
3403
3451
  state = "idle",
3404
3452
  onSubmitEmail,
3405
- successMessage = "Ya est\xE1s dentro. Te llega un email cada dos semanas, y nada m\xE1s.",
3406
- errorMessage = "No se pudo suscribir ese email. Rev\xEDsalo y vuelve a intentar.",
3453
+ successMessage = "Ya est\xE1s dentro. Te llega un correo cada dos semanas, y nada m\xE1s.",
3454
+ errorMessage = "No se pudo suscribir ese correo. Rev\xEDsalo y vuelve a intentar.",
3407
3455
  disclaimer,
3408
3456
  expression,
3409
3457
  basePath,
3410
3458
  submitLabel = "Suscribirme",
3411
3459
  placeholder = "tu@email.dev",
3412
- fieldLabel = "Email electr\xF3nico",
3460
+ fieldLabel = "Correo electr\xF3nico",
3413
3461
  nameField = false,
3414
3462
  nameLabel = "Nombre",
3415
3463
  namePlaceholder = "C\xF3mo te llamas",
@@ -3605,23 +3653,27 @@ function ScrollingProgressBar({
3605
3653
  }
3606
3654
  );
3607
3655
  }
3656
+ var Collapsed = react.createContext(false);
3608
3657
  function SidebarItem({
3609
3658
  active = false,
3610
3659
  asChild = false,
3611
3660
  badge: badge2,
3661
+ icon,
3612
3662
  className,
3613
3663
  children,
3614
3664
  ...props
3615
3665
  }) {
3616
3666
  const Root18 = asChild ? reactSlot.Slot : "a";
3667
+ const collapsed = react.useContext(Collapsed);
3617
3668
  return /* @__PURE__ */ jsxRuntime.jsx("li", { children: /* @__PURE__ */ jsxRuntime.jsxs(
3618
3669
  Root18,
3619
3670
  {
3620
3671
  "aria-current": active ? "page" : void 0,
3621
3672
  className: cn(
3622
3673
  "rounded-chip px-step-sm gap-step-xs flex cursor-pointer items-center py-1.5",
3674
+ collapsed && "justify-center",
3623
3675
  "font-mono text-meta transition-standard",
3624
- "focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent",
3676
+ "focus-ring",
3625
3677
  // The active item is `surfaceRaised` with primary ink, same as
3626
3678
  // `TabsTrigger`. NOT biolume: `tokens.ts` says so explicitly — light
3627
3679
  // accent passes over background and over surface, but over
@@ -3633,15 +3685,57 @@ function SidebarItem({
3633
3685
  ),
3634
3686
  ...props,
3635
3687
  children: [
3636
- /* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": "true", className: active ? "text-accent" : "text-text-muted", children: "\u25B8" }),
3637
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "min-w-0 flex-1 truncate", children }),
3638
- badge2 ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-text-muted shrink-0", children: badge2 }) : null
3688
+ icon ? (
3689
+ // A shade bigger than the 13px mono label, which is what keeps it
3690
+ // reading as a glyph rather than as a character in the word.
3691
+ /* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": "true", className: "text-body shrink-0", children: icon })
3692
+ ) : /* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": "true", className: active ? "text-accent" : "text-text-muted", children: "\u25B8" }),
3693
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: collapsed ? "sr-only" : "min-w-0 flex-1 truncate", children }),
3694
+ badge2 ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn("text-text-muted", collapsed ? "sr-only" : "shrink-0"), children: badge2 }) : null
3639
3695
  ]
3640
3696
  }
3641
3697
  ) });
3642
3698
  }
3699
+ function SidebarGroup({ label, children, className, ...props }) {
3700
+ const id = react.useId();
3701
+ const collapsed = react.useContext(Collapsed);
3702
+ return /* @__PURE__ */ jsxRuntime.jsxs(
3703
+ "li",
3704
+ {
3705
+ className: cn(
3706
+ "mt-step-md first:mt-0",
3707
+ // In a rail the label has nowhere to go, so the block becomes a rule.
3708
+ // The label itself stays in the accessibility tree naming the list.
3709
+ collapsed && "border-hairline pt-step-md mt-step-sm border-t first:border-t-0",
3710
+ className
3711
+ ),
3712
+ ...props,
3713
+ children: [
3714
+ /* @__PURE__ */ jsxRuntime.jsx(
3715
+ Text,
3716
+ {
3717
+ variant: "meta",
3718
+ tone: "muted",
3719
+ as: "p",
3720
+ id,
3721
+ className: collapsed ? "sr-only" : "px-step-sm pb-step-xs",
3722
+ children: label
3723
+ }
3724
+ ),
3725
+ /* @__PURE__ */ jsxRuntime.jsx("ul", { "aria-labelledby": id, className: "gap-0.5 flex flex-col", children })
3726
+ ]
3727
+ }
3728
+ );
3729
+ }
3643
3730
  function SidebarNav({
3644
3731
  title,
3732
+ brand: brand2,
3733
+ mark,
3734
+ user,
3735
+ collapsed = false,
3736
+ onCollapsedChange,
3737
+ collapseLabel = "Plegar el panel",
3738
+ expandLabel = "Desplegar el panel",
3645
3739
  version,
3646
3740
  branch,
3647
3741
  children,
@@ -3649,26 +3743,85 @@ function SidebarNav({
3649
3743
  ...props
3650
3744
  }) {
3651
3745
  const footer = [version, branch].filter(Boolean);
3652
- return /* @__PURE__ */ jsxRuntime.jsxs(
3746
+ const top = collapsed ? mark : brand2;
3747
+ return /* @__PURE__ */ jsxRuntime.jsx(Collapsed.Provider, { value: collapsed, children: /* @__PURE__ */ jsxRuntime.jsxs(
3653
3748
  "nav",
3654
3749
  {
3655
3750
  "aria-label": typeof title === "string" ? title : "Administraci\xF3n",
3656
3751
  className: cn(
3657
3752
  "border-hairline bg-surface p-step-sm gap-step-sm flex h-full flex-col border-r",
3753
+ // The width is the component's only when it can collapse: the layout
3754
+ // beside it has to reserve one of the two, and it cannot know which.
3755
+ // It does NOT transition. The system's only transition animates colour
3756
+ // and border, and a rail that slides is the entrance animation this
3757
+ // library does not have — same call as the `Switch` knob, which changes
3758
+ // position without moving.
3759
+ onCollapsedChange && (collapsed ? "w-sidebar-rail" : "w-sidebar"),
3658
3760
  className
3659
3761
  ),
3660
3762
  ...props,
3661
3763
  children: [
3662
- title ? /* @__PURE__ */ jsxRuntime.jsx(Text, { variant: "eyebrow", tone: "muted", as: "p", className: "px-step-sm", children: title }) : null,
3764
+ top || onCollapsedChange ? /* @__PURE__ */ jsxRuntime.jsxs(
3765
+ "div",
3766
+ {
3767
+ className: cn(
3768
+ "border-hairline px-step-sm pb-step-sm mb-step-xs gap-step-xs flex items-center border-b",
3769
+ collapsed ? "justify-center" : "justify-between"
3770
+ ),
3771
+ children: [
3772
+ top ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "min-w-0", children: top }) : null,
3773
+ onCollapsedChange ? /* @__PURE__ */ jsxRuntime.jsx(
3774
+ "button",
3775
+ {
3776
+ type: "button",
3777
+ onClick: () => onCollapsedChange(!collapsed),
3778
+ "aria-expanded": !collapsed,
3779
+ "aria-label": collapsed ? expandLabel : collapseLabel,
3780
+ className: cn(
3781
+ "rounded-chip transition-standard shrink-0 cursor-pointer p-1",
3782
+ "text-text-muted hover:text-text-primary hover:bg-surface-raised",
3783
+ "focus-ring"
3784
+ ),
3785
+ children: collapsed ? /* @__PURE__ */ jsxRuntime.jsx(ChevronRight, {}) : /* @__PURE__ */ jsxRuntime.jsx(ChevronLeft, {})
3786
+ }
3787
+ ) : null
3788
+ ]
3789
+ }
3790
+ ) : null,
3791
+ title && !collapsed ? /* @__PURE__ */ jsxRuntime.jsx(Text, { variant: "eyebrow", tone: "muted", as: "p", className: "px-step-sm", children: title }) : null,
3663
3792
  /* @__PURE__ */ jsxRuntime.jsx("ul", { className: "gap-0.5 flex flex-1 flex-col", children }),
3664
- footer.length > 0 ? /* @__PURE__ */ jsxRuntime.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__ */ jsxRuntime.jsxs("span", { children: [
3665
- i > 0 ? /* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": "true", children: " \xB7 " }) : null,
3666
- p
3667
- ] }, i)) }) : null
3793
+ user ? /* @__PURE__ */ jsxRuntime.jsx(
3794
+ "div",
3795
+ {
3796
+ className: cn(
3797
+ "border-hairline px-step-sm pt-step-sm border-t",
3798
+ collapsed && "flex justify-center"
3799
+ ),
3800
+ children: user
3801
+ }
3802
+ ) : null,
3803
+ footer.length > 0 && !collapsed ? /* @__PURE__ */ jsxRuntime.jsx(
3804
+ Text,
3805
+ {
3806
+ variant: "meta",
3807
+ tone: "muted",
3808
+ as: "p",
3809
+ className: cn("px-step-sm", user ? "" : "border-hairline pt-step-sm border-t"),
3810
+ children: footer.map((p, i) => /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
3811
+ i > 0 ? /* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": "true", children: " \xB7 " }) : null,
3812
+ p
3813
+ ] }, i))
3814
+ }
3815
+ ) : null
3668
3816
  ]
3669
3817
  }
3670
- );
3818
+ ) });
3671
3819
  }
3820
+ var DELTA = {
3821
+ up: { glyph: ChevronUp, label: "sube" },
3822
+ down: { glyph: ChevronDown, label: "baja" },
3823
+ flat: { glyph: Minus, label: "sin cambio" }
3824
+ };
3672
3825
  function Stat({
3673
3826
  value,
3674
3827
  label,
@@ -3676,30 +3829,52 @@ function Stat({
3676
3829
  progress,
3677
3830
  icon,
3678
3831
  description,
3832
+ delta,
3833
+ spark,
3679
3834
  className,
3680
3835
  ...props
3681
3836
  }) {
3837
+ const DeltaGlyph = delta ? DELTA[delta.direction].glyph : null;
3682
3838
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn(CARD_SURFACE, "p-step-lg gap-step-xs flex flex-col", className), ...props, children: [
3683
- /* @__PURE__ */ jsxRuntime.jsxs(Text, { variant: "eyebrow", tone: "muted", as: "p", className: "gap-step-xs flex items-center", children: [
3839
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "gap-step-sm flex items-start justify-between", children: [
3840
+ /* @__PURE__ */ jsxRuntime.jsx(Text, { variant: "eyebrow", tone: "muted", as: "p", className: "min-w-0", children: label }),
3684
3841
  icon ? (
3685
3842
  // `aria-hidden` is not needed: the system's glyphs already carry it.
3686
- // What IS needed is that it does not shrink next to a long title,
3687
- // because a squashed icon reads as a different icon.
3688
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "shrink-0", children: icon })
3689
- ) : null,
3690
- label
3843
+ // The circle is a SURFACE — the tint at 10 %, same as an alert's — and
3844
+ // the colour stays on the glyph, which is § 4b and also what keeps it
3845
+ // on the 3:1 graphical threshold instead of text's 4.5.
3846
+ /* @__PURE__ */ jsxRuntime.jsx(
3847
+ "span",
3848
+ {
3849
+ className: cn(
3850
+ "size-control-icon-sm text-ui flex shrink-0 items-center justify-center rounded-full",
3851
+ tone === "neutral" ? "bg-accent/10 text-accent" : "bg-warm/10 text-warm"
3852
+ ),
3853
+ children: icon
3854
+ }
3855
+ )
3856
+ ) : null
3691
3857
  ] }),
3692
- /* @__PURE__ */ jsxRuntime.jsx(Text, { variant: "stat", as: "p", tone: tone === "alerta" ? "warm" : "accent", children: value }),
3858
+ /* @__PURE__ */ jsxRuntime.jsx(Text, { variant: "stat", as: "p", tone: tone === "neutral" ? "primary" : "warm", children: value }),
3859
+ delta && DeltaGlyph ? /* @__PURE__ */ jsxRuntime.jsxs(Text, { variant: "label", tone: "secondary", as: "p", className: "gap-step-xs flex items-center", children: [
3860
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "sr-only", children: [
3861
+ DELTA[delta.direction].label,
3862
+ " "
3863
+ ] }),
3864
+ /* @__PURE__ */ jsxRuntime.jsx(DeltaGlyph, { className: "shrink-0" }),
3865
+ delta.value
3866
+ ] }) : null,
3693
3867
  description ? /* @__PURE__ */ jsxRuntime.jsx(Text, { variant: "ui", tone: "secondary", as: "p", children: description }) : null,
3694
3868
  typeof progress === "number" ? /* @__PURE__ */ jsxRuntime.jsx(
3695
3869
  Progress,
3696
3870
  {
3697
3871
  value: progress,
3698
- tone: tone === "alerta" ? "warm" : "accent",
3872
+ tone: tone === "neutral" ? "accent" : "warm",
3699
3873
  label: `${label}: ${progress}%`,
3700
3874
  className: "mt-step-sm"
3701
3875
  }
3702
- ) : null
3876
+ ) : null,
3877
+ spark ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-auto pt-step-md", children: spark }) : null
3703
3878
  ] });
3704
3879
  }
3705
3880
  function TalkCard({
@@ -3761,7 +3936,7 @@ function TalkCard({
3761
3936
  return /* @__PURE__ */ jsxRuntime.jsx(CardShell, { className: cn("p-step-lg", className), ...props, children: /* @__PURE__ */ jsxRuntime.jsx("article", { className: "gap-step-sm flex h-full flex-col", children: body }) });
3762
3937
  }
3763
3938
  function ThemeToggle({
3764
- label = "Cambiar de theme",
3939
+ label = "Cambiar de tema",
3765
3940
  onThemeChange,
3766
3941
  variant = "secondary",
3767
3942
  size: size2 = "icon",
@@ -3805,7 +3980,7 @@ function TableOfContents({
3805
3980
  const classes = cn(
3806
3981
  "px-step-sm -ml-px block border-l",
3807
3982
  "font-sans text-label transition-standard",
3808
- "focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent",
3983
+ "focus-ring",
3809
3984
  "cursor-pointer",
3810
3985
  item2.nested && "pl-step-lg",
3811
3986
  "border-transparent text-text-secondary hover:text-text-primary",
@@ -3875,7 +4050,7 @@ function Logo({
3875
4050
  ] });
3876
4051
  }
3877
4052
 
3878
- // src/lib/social.tsx
4053
+ // src/social/index.tsx
3879
4054
  var social_exports = {};
3880
4055
  __export(social_exports, {
3881
4056
  Discord: () => Discord,
@@ -4056,6 +4231,7 @@ exports.SheetFooter = SheetFooter;
4056
4231
  exports.SheetHeader = SheetHeader;
4057
4232
  exports.SheetTitle = SheetTitle;
4058
4233
  exports.SheetTrigger = SheetTrigger;
4234
+ exports.SidebarGroup = SidebarGroup;
4059
4235
  exports.SidebarItem = SidebarItem;
4060
4236
  exports.SidebarNav = SidebarNav;
4061
4237
  exports.Skeleton = Skeleton;