@eduardoalvarez/arrecife 0.11.0 → 0.12.1

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 +33 -0
  2. package/README.md +34 -14
  3. package/dist/brand/index.cjs +2 -2
  4. package/dist/brand/index.d.cts +1 -1
  5. package/dist/brand/index.d.ts +1 -1
  6. package/dist/brand/index.js +3 -3
  7. package/dist/chart/index.cjs +2 -2
  8. package/dist/chart/index.d.cts +3 -3
  9. package/dist/chart/index.d.ts +3 -3
  10. package/dist/chart/index.js +3 -3
  11. package/dist/{chunk-FGFNK72B.js → chunk-5YWGOFDX.js} +17 -4
  12. package/dist/{chunk-5A5GH2PF.js → chunk-6QJQ6K7J.js} +1 -1
  13. package/dist/{chunk-TRPBID2W.js → chunk-BFYNBIVJ.js} +1 -1
  14. package/dist/{chunk-RKGKO2TW.js → chunk-BRDTB44R.js} +2 -2
  15. package/dist/{chunk-XXDATT3A.js → chunk-FF33ARRA.js} +1 -1
  16. package/dist/{chunk-FAAGZG7A.js → chunk-TMUGT3Y3.js} +1 -1
  17. package/dist/{chunk-6IGD5REB.js → chunk-W75O3Z77.js} +1 -1
  18. package/dist/{chunk-ZSCSKCTY.js → chunk-WU66TPJT.js} +1 -1
  19. package/dist/form/index.cjs +2 -2
  20. package/dist/form/index.js +4 -4
  21. package/dist/icons/index.cjs +2 -2
  22. package/dist/icons/index.d.cts +2 -2
  23. package/dist/icons/index.d.ts +2 -2
  24. package/dist/icons/index.js +3 -3
  25. package/dist/index.cjs +86 -18
  26. package/dist/index.d.cts +31 -16
  27. package/dist/index.d.ts +31 -16
  28. package/dist/index.js +83 -28
  29. package/dist/og/index.cjs +1 -2
  30. package/dist/og/index.js +1 -1
  31. package/dist/shiki/index.js +1 -1
  32. package/dist/tokens/index.cjs +17 -4
  33. package/dist/tokens/index.d.cts +20 -5
  34. package/dist/tokens/index.d.ts +20 -5
  35. package/dist/tokens/index.js +2 -2
  36. package/dist/tokens/theme.css +20 -3
  37. package/dist/variants/index.cjs +1 -1
  38. package/dist/variants/index.d.cts +2 -2
  39. package/dist/variants/index.d.ts +2 -2
  40. package/dist/variants/index.js +1 -1
  41. package/llms.txt +39 -13
  42. package/package.json +1 -1
package/dist/index.cjs CHANGED
@@ -209,7 +209,7 @@ var typeScale = {
209
209
  * (plankton 5.57:1 over abyss), which is the part that is not negotiable.
210
210
  *
211
211
  * At 13 the three badge families grew past the size of a small button and
212
- * outweighed the title they accompany. See `docs/decisions/`.
212
+ * outweighed the title they accompany. See `docs/decisions/` § 10.
213
213
  */
214
214
  chip: { family: "mono", size: 11.5, lineHeight: 1.4, weight: 400 },
215
215
  /**
@@ -263,7 +263,7 @@ var control = {
263
263
  * baseline; 28 would have been a fifth height that matches nothing.
264
264
  *
265
265
  * It does not replace `icon`. A page's primary action stays at 42; this is for
266
- * a row of a table. See `docs/decisions/0.6.md` § 22.
266
+ * a row of a table. See `docs/decisions/` § 22.
267
267
  */
268
268
  iconSm: 32
269
269
  };
@@ -286,7 +286,7 @@ var size = {
286
286
  * together eat the top of the content area. 56 is what `cursos` had arrived at
287
287
  * on its own, and it is the same reasoning as `control.iconSm`: the one admin
288
288
  * app of the five is denser than the four reading sites. See
289
- * `docs/decisions/0.7.md` § 30.
289
+ * `docs/decisions/` § 30.
290
290
  */
291
291
  navCompact: 56,
292
292
  /**
@@ -359,7 +359,20 @@ var naming = {
359
359
  wordmark: "Eduardo \xC1lvarez",
360
360
  mascot: "Tiburonc\xEDn",
361
361
  /** The domain, for the footer CLI signature: `$ cd ~/eduardoalvarez.dev/2026`. */
362
- domain: "eduardoalvarez.dev"
362
+ domain: "eduardoalvarez.dev",
363
+ /** The library's own name, for a footer that credits it. */
364
+ library: "Arrecife",
365
+ /**
366
+ * Where the library is published, for `Footer builtWith`.
367
+ *
368
+ * It is here and not written into the component for the reason the domain is:
369
+ * one string, five projects. It is the same URL as `homepage` in
370
+ * `package.json` and it cannot be derived from it — this file imports nothing
371
+ * — so `check:exports` compares the two on every build. Without that, moving
372
+ * the Storybook would update what npm prints and leave five production
373
+ * footers linking at the old address.
374
+ */
375
+ libraryUrl: "https://arrecife.eduardoalvarez.dev"
363
376
  };
364
377
 
365
378
  // src/tokens/index.ts
@@ -484,7 +497,7 @@ var button = classVarianceAuthority.cva(
484
497
  ],
485
498
  // The one control whose focus ring is not biolume. It is the system's
486
499
  // only sand fill, and a biolume ring three pixels off a sand button puts
487
- // both of the brand's accents in the same glance. See `docs/decisions/0.7.md` § 37.
500
+ // both of the brand's accents in the same glance. See `docs/decisions/` § 37.
488
501
  conversion: "bg-warm text-warm-on hover:bg-warm-hover focus-ring-warm",
489
502
  secondary: [
490
503
  "border-hairline-hover border bg-transparent text-text-primary",
@@ -3240,8 +3253,7 @@ function SocialRow({ social }) {
3240
3253
  function Signature({
3241
3254
  year,
3242
3255
  href,
3243
- domain: domainName = naming.domain,
3244
- className
3256
+ domain: domainName = naming.domain
3245
3257
  }) {
3246
3258
  const domain = href ? /* @__PURE__ */ jsxRuntime.jsx(
3247
3259
  "a",
@@ -3251,7 +3263,7 @@ function Signature({
3251
3263
  children: domainName
3252
3264
  }
3253
3265
  ) : domainName;
3254
- return /* @__PURE__ */ jsxRuntime.jsxs(Text, { variant: "meta", tone: "muted", as: "p", className: cn("shrink-0", className), children: [
3266
+ return /* @__PURE__ */ jsxRuntime.jsxs(Text, { variant: "meta", tone: "muted", as: "p", children: [
3255
3267
  /* @__PURE__ */ jsxRuntime.jsxs("span", { "aria-hidden": "true", className: "text-accent", children: [
3256
3268
  "$",
3257
3269
  " "
@@ -3269,6 +3281,40 @@ function Signature({
3269
3281
  )
3270
3282
  ] });
3271
3283
  }
3284
+ function BuiltWith() {
3285
+ return /* @__PURE__ */ jsxRuntime.jsxs(Text, { variant: "meta", tone: "muted", as: "p", children: [
3286
+ "Creado con",
3287
+ " ",
3288
+ /* @__PURE__ */ jsxRuntime.jsx(
3289
+ "a",
3290
+ {
3291
+ href: naming.libraryUrl,
3292
+ target: "_blank",
3293
+ rel: "noopener noreferrer",
3294
+ className: cn(
3295
+ "text-accent hover:text-text-primary transition-standard cursor-pointer",
3296
+ "underline decoration-1 underline-offset-4",
3297
+ "rounded-chip focus-ring"
3298
+ ),
3299
+ children: naming.library
3300
+ }
3301
+ ),
3302
+ " ",
3303
+ /* @__PURE__ */ jsxRuntime.jsx(Icon, { as: react.Heart, tone: "current", className: "text-accent inline align-middle" })
3304
+ ] });
3305
+ }
3306
+ function SignatureBlock({
3307
+ year,
3308
+ href,
3309
+ domain,
3310
+ builtWith,
3311
+ className
3312
+ }) {
3313
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("flex shrink-0 flex-col items-center sm:items-end", className), children: [
3314
+ /* @__PURE__ */ jsxRuntime.jsx(Signature, { year, href, domain }),
3315
+ builtWith ? /* @__PURE__ */ jsxRuntime.jsx(BuiltWith, {}) : null
3316
+ ] });
3317
+ }
3272
3318
  function Shell({
3273
3319
  className,
3274
3320
  contentClassName,
@@ -3291,6 +3337,7 @@ function Footer({
3291
3337
  linkAsChild,
3292
3338
  social,
3293
3339
  brand: brand2,
3340
+ builtWith,
3294
3341
  year = (/* @__PURE__ */ new Date()).getFullYear(),
3295
3342
  signatureHref,
3296
3343
  domain,
@@ -3340,21 +3387,42 @@ function Footer({
3340
3387
  column.title
3341
3388
  )) })
3342
3389
  ] }),
3343
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "border-hairline mt-step-xl pt-step-lg border-t", children: /* @__PURE__ */ jsxRuntime.jsx(Signature, { year, href: signatureHref, domain, className: "text-center sm:text-right" }) })
3390
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "border-hairline mt-step-xl pt-step-lg border-t", children: /* @__PURE__ */ jsxRuntime.jsx(
3391
+ SignatureBlock,
3392
+ {
3393
+ year,
3394
+ href: signatureHref,
3395
+ domain,
3396
+ builtWith
3397
+ }
3398
+ ) })
3344
3399
  ] });
3345
3400
  }
3346
3401
  const rows = [
3347
3402
  brand2 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center", children: brand2 }, "brand") : null,
3348
3403
  social && social.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx(SocialRow, { social }, "social") : null
3349
3404
  ].filter(Boolean);
3350
- const [first, ...others] = rows;
3351
- return /* @__PURE__ */ jsxRuntime.jsxs(Shell, { className, contentClassName: "gap-step-lg", ...rest, children: [
3352
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "gap-step-md flex flex-col items-center sm:flex-row sm:flex-wrap", children: [
3353
- first ?? null,
3354
- /* @__PURE__ */ jsxRuntime.jsx(Signature, { year, href: signatureHref, domain, className: "sm:ml-auto" })
3355
- ] }),
3356
- others
3357
- ] });
3405
+ return /* @__PURE__ */ jsxRuntime.jsxs(
3406
+ Shell,
3407
+ {
3408
+ className,
3409
+ contentClassName: "gap-step-lg items-center sm:flex-row sm:items-start",
3410
+ ...rest,
3411
+ children: [
3412
+ rows.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "gap-step-lg flex flex-col items-center sm:items-start", children: rows }) : null,
3413
+ /* @__PURE__ */ jsxRuntime.jsx(
3414
+ SignatureBlock,
3415
+ {
3416
+ year,
3417
+ href: signatureHref,
3418
+ domain,
3419
+ builtWith,
3420
+ className: "sm:ml-auto"
3421
+ }
3422
+ )
3423
+ ]
3424
+ }
3425
+ );
3358
3426
  }
3359
3427
  function Hero({
3360
3428
  title,
@@ -3502,7 +3570,7 @@ function Nav({ brand: brand2, children, actions, size: size2 = "default", classN
3502
3570
  puts it in `actions`. A `Nav` that hid its own items would leave every
3503
3571
  consumer without a drawer with no navigation at all, silently.
3504
3572
 
3505
- See `docs/decisions/0.10.md` § 54.
3573
+ See `docs/decisions/` § 54.
3506
3574
  */
3507
3575
  /* @__PURE__ */ jsxRuntime.jsx("nav", { "aria-label": "Principal", className: "ml-auto min-w-0 overflow-x-auto", children: /* @__PURE__ */ jsxRuntime.jsxs("ul", { className: "gap-step-md flex w-max items-center", children: [
3508
3576
  /* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": "true", className: "text-text-muted font-mono text-meta select-none", children: "~/" }),
package/dist/index.d.cts CHANGED
@@ -48,7 +48,7 @@ import '@radix-ui/react-label';
48
48
  * `--ease-standard`, so it introduces neither a new timing nor a new curve.
49
49
  * Whoever asked for less motion still sees the panel appear where it will stay.
50
50
  *
51
- * See `docs/decisions/0.6.md` § 20.
51
+ * See `docs/decisions/` § 20.
52
52
  *
53
53
  * The chevron, by contrast, rotates with no transition: `transition-standard`
54
54
  * only covers color and border, so `rotate` snaps even with the class in place.
@@ -111,7 +111,7 @@ declare function Alert({ className, variant, emphasis, title, icon, children, ..
111
111
  * «Borrar el artículo», not «Aceptar».
112
112
  *
113
113
  * `destructive` is for the destructive button that has none of that around it:
114
- * a table row, a toolbar. See `docs/decisions/0.6.md` § 21.
114
+ * a table row, a toolbar. See `docs/decisions/` § 21.
115
115
  */
116
116
  declare const AlertDialog: react.FC<AlertDialogPrimitive.AlertDialogProps>;
117
117
  declare const AlertDialogTrigger: react.ForwardRefExoticComponent<AlertDialogPrimitive.AlertDialogTriggerProps & react.RefAttributes<HTMLButtonElement>>;
@@ -497,7 +497,7 @@ declare function Switch({ className, ...props }: SwitchProps): react.JSX.Element
497
497
  * `Nav`'s `size` documents: a `rounded-none` passed from the call site does
498
498
  * nothing, silently. There is one shape on purpose — fourteen call sites wanted
499
499
  * the same one — and a second gets a prop when a second consumer exists, not
500
- * before. See `docs/decisions/0.8.md` § 39.
500
+ * before. See `docs/decisions/` § 39.
501
501
  *
502
502
  * THE `tabIndex` IS NOT DECORATION and it is not new behaviour dressed up as
503
503
  * markup. A region you can pan with a mouse has to be reachable with a keyboard
@@ -771,7 +771,7 @@ declare function AuthorCard({ name, role, src, bio, action, className, ...props
771
771
  * paths this file used to carry verbatim from the portfolio are gone with
772
772
  * `lib/glyphs.tsx`; `Play`, `Pause`, `SpeakerHigh` and `SpeakerSlash` are the
773
773
  * same symbols in Phosphor's hand, and the ±15s skips are `ArrowCounterClockwise`
774
- * and `ArrowClockwise`. See `docs/decisions/0.10.md` § 51.
774
+ * and `ArrowClockwise`. See `docs/decisions/` § 51.
775
775
  * - analytics' `trackEvent` → the `onFirstPlay` prop, which the consumer wires
776
776
  * to whatever they use. It still fires exactly once per load.
777
777
  *
@@ -912,7 +912,7 @@ type CourseCardProps = Omit<CardShellProps, 'children' | 'title' | 'media'> & {
912
912
  * formatted in a currency the library does not know, the rating is drawn by a
913
913
  * component the project already has, and the cover is an image pipeline. What
914
914
  * IS the identity's stays here: the title's scale and its hover, the sand bar,
915
- * the status badge. See `docs/decisions/0.11.md` § 59.
915
+ * the status badge. See `docs/decisions/` § 59.
916
916
  *
917
917
  * The title does NOT go over the cover. It stays in the body at `h3`, with the
918
918
  * hover every other card has. Text on a photograph needs a scrim, and a scrim's
@@ -941,7 +941,7 @@ declare function CourseCard({ title, summary, meta, status, progress, media, foo
941
941
  * smaller one: the hole inside a table page or a dashboard widget, competing with
942
942
  * a dozen elements around it. An admin panel has twenty of those on one screen,
943
943
  * and twenty faces is not the humour contract, it is a zoo. The variant carries
944
- * no face, and the type does not let one through. See `docs/decisions/0.7.md` § 27.
944
+ * no face, and the type does not let one through. See `docs/decisions/` § 27.
945
945
  */
946
946
  type EmptyStateBase = Omit<ComponentPropsWithoutRef<'div'>, 'title'> & {
947
947
  title: ReactNode;
@@ -1030,7 +1030,7 @@ declare function EventCalendar({ events, onCreateEvent, onUpdateEvent, onDeleteE
1030
1030
  * The domain defaults to `naming.domain` and not to a hand-written string, for
1031
1031
  * the same reason as the wordmark: if it changes, it changes in all five
1032
1032
  * projects at once. A project that lives on its OWN domain passes `domain` —
1033
- * see `docs/decisions/0.9.md` § 49.
1033
+ * see `docs/decisions/` § 49.
1034
1034
  *
1035
1035
  * The social links are icons with NO visible text, so `aria-label` is not an
1036
1036
  * improvement: it is the only thing that makes them legible. Which is why it is
@@ -1046,7 +1046,7 @@ declare function EventCalendar({ events, onCreateEvent, onUpdateEvent, onDeleteE
1046
1046
  * answer has not moved: `EmptyState` is a discriminated union where `page` is
1047
1047
  * the default and `inline` cannot be handed a face; `Nav` takes a `size` where
1048
1048
  * `default` is the bar it always was. Both left what was written before exactly
1049
- * where it was. See `docs/decisions/0.8.md` § 44.
1049
+ * where it was. See `docs/decisions/` § 44.
1050
1050
  *
1051
1051
  * The union is what holds the rule up. `columns`, `description` and `action`
1052
1052
  * exist only on `full`, and the default form cannot be handed one. As loose
@@ -1094,7 +1094,7 @@ type FooterColumn = {
1094
1094
  * `./aviso-legal` — and that row is what `variant="full"`'s columns replace. A
1095
1095
  * flat row cannot say which block a link belongs to, cannot carry a heading a
1096
1096
  * screen reader can jump to, and made whoever wrote the label type the `./`
1097
- * themselves, which the columns put there. See docs/decisions/0.8.md § 47.
1097
+ * themselves, which the columns put there. See docs/decisions/ § 47.
1098
1098
  */
1099
1099
  type FooterBase = Omit<ComponentPropsWithoutRef<'footer'>, 'children'> & {
1100
1100
  social?: readonly SocialLink[];
@@ -1129,10 +1129,25 @@ type FooterBase = Omit<ComponentPropsWithoutRef<'footer'>, 'children'> & {
1129
1129
  * have warned about.
1130
1130
  *
1131
1131
  * It is a domain and not a whole signature: the `$`, the `cd ~/` and the year
1132
- * are the identity's and stay the component's. See `docs/decisions/0.9.md`
1132
+ * are the identity's and stay the component's. See `docs/decisions/`
1133
1133
  * § 49.
1134
1134
  */
1135
1135
  domain?: string | undefined;
1136
+ /**
1137
+ * Adds «Creado con Arrecife ♥», linking to the library's Storybook.
1138
+ *
1139
+ * OFF BY DEFAULT, and that is the decision rather than the default. No
1140
+ * consuming project credits the library today — the four were read before
1141
+ * this was written — so turning it on for everybody would be the library
1142
+ * putting a line into five production footers that none of them asked for.
1143
+ * That is the move § 45 is about, and it does not get made twice.
1144
+ *
1145
+ * A site that wants it passes `builtWith`. It is a boolean and not a slot: the
1146
+ * string and the destination are the library's, and a slot would be an
1147
+ * invitation to write «Hecho con Arrecife» on one site and «Creado con» on the
1148
+ * next, which is the drift this package exists to remove.
1149
+ */
1150
+ builtWith?: boolean | undefined;
1136
1151
  };
1137
1152
  type FooterProps = FooterBase & ({
1138
1153
  /** The shape the library has always had: stacked rows and the signature at the top right. */
@@ -1168,7 +1183,7 @@ type FooterProps = FooterBase & ({
1168
1183
  children: ReactNode;
1169
1184
  }) => ReactNode) | undefined;
1170
1185
  });
1171
- declare function Footer({ variant, columns, description, action, linkAsChild, social, brand, year, signatureHref, domain, className, ...rest }: FooterProps): react.JSX.Element;
1186
+ declare function Footer({ variant, columns, description, action, linkAsChild, social, brand, builtWith, year, signatureHref, domain, className, ...rest }: FooterProps): react.JSX.Element;
1172
1187
 
1173
1188
  /**
1174
1189
  * ONE per site. It is the only piece in the system that is spent like the
@@ -1302,7 +1317,7 @@ type NavItemProps = ComponentPropsWithoutRef<'a'> & {
1302
1317
  * impossible to call. It passed `tsc` and it passed the build, because the shape
1303
1318
  * of the children is not something either one looks at. `Slottable` is Radix's
1304
1319
  * answer to exactly this: it marks which child the router's `Link` replaces and
1305
- * leaves the decoration where it is. See `docs/decisions/0.8.md` § 40.
1320
+ * leaves the decoration where it is. See `docs/decisions/` § 40.
1306
1321
  */
1307
1322
  declare function NavItem({ active, asChild, className, children, ...props }: NavItemProps): react.JSX.Element;
1308
1323
 
@@ -1439,7 +1454,7 @@ declare function NewsletterForm({ title, description, state, onSubmitEmail, succ
1439
1454
  * at 24px, and `cursos` titles 29 of its 32 at `h3` — every one in the panel —
1440
1455
  * and the other three, the public catalog pages, at `h2`. Both are rungs the
1441
1456
  * scale already has, and a third `size` could only have named one of them. See
1442
- * `docs/decisions/0.11.md` § 57.
1457
+ * `docs/decisions/` § 57.
1443
1458
  *
1444
1459
  * It takes no mascot face, at either scale: faces go in empty states,
1445
1460
  * confirmations, errors, course progress and celebration.
@@ -1543,7 +1558,7 @@ declare function ScrollingProgressBar({ target, tone, sticky, className, ...prop
1543
1558
  * eyebrow is the same length in none of them, so an inline icon puts the only
1544
1559
  * coloured mark on a different x in every card; pinned to the corner it lands on
1545
1560
  * a grid. The circle is the tint pattern the system already has — `bg-accent/10`
1546
- * as a surface and the colour on the GLYPH, per `docs/decisions/0.6.md` § 4b — and a
1561
+ * as a surface and the colour on the GLYPH, per `docs/decisions/` § 4b — and a
1547
1562
  * glyph clears the 3:1 graphical threshold where text would not clear 4.5.
1548
1563
  *
1549
1564
  * WHICH IS WHY A NEUTRAL NUMBER IS PRIMARY INK AND NOT BIOLUME. With a biolume
@@ -1551,7 +1566,7 @@ declare function ScrollingProgressBar({ target, tone, sticky, className, ...prop
1551
1566
  * the size of a postcard, and the thing you came to read stops being the loudest
1552
1567
  * thing in it. `alert` and `achievement` DO still paint the number sand, so the
1553
1568
  * document's rule survives exactly where it matters: sand when the number is not
1554
- * just a number. See `docs/decisions/0.7.md` § 31.
1569
+ * just a number. See `docs/decisions/` § 31.
1555
1570
  */
1556
1571
  type StatProps = Omit<ComponentPropsWithoutRef<'div'>, 'title'> & {
1557
1572
  /** The number, already formatted. The library imposes no locale. */
@@ -1563,7 +1578,7 @@ type StatProps = Omit<ComponentPropsWithoutRef<'div'>, 'title'> & {
1563
1578
  * the opposite — the diplomas issued, the modules finished. The two paint the
1564
1579
  * same sand today and they are still two names: a system that names by meaning
1565
1580
  * cannot make «this is bad» the only way to say «this stands out». See
1566
- * `docs/decisions/0.7.md` § 28.
1581
+ * `docs/decisions/` § 28.
1567
1582
  */
1568
1583
  tone?: 'neutral' | 'alert' | 'achievement';
1569
1584
  /** With `progress`, the metric reads as progress and adds the bar. */
package/dist/index.d.ts CHANGED
@@ -48,7 +48,7 @@ import '@radix-ui/react-label';
48
48
  * `--ease-standard`, so it introduces neither a new timing nor a new curve.
49
49
  * Whoever asked for less motion still sees the panel appear where it will stay.
50
50
  *
51
- * See `docs/decisions/0.6.md` § 20.
51
+ * See `docs/decisions/` § 20.
52
52
  *
53
53
  * The chevron, by contrast, rotates with no transition: `transition-standard`
54
54
  * only covers color and border, so `rotate` snaps even with the class in place.
@@ -111,7 +111,7 @@ declare function Alert({ className, variant, emphasis, title, icon, children, ..
111
111
  * «Borrar el artículo», not «Aceptar».
112
112
  *
113
113
  * `destructive` is for the destructive button that has none of that around it:
114
- * a table row, a toolbar. See `docs/decisions/0.6.md` § 21.
114
+ * a table row, a toolbar. See `docs/decisions/` § 21.
115
115
  */
116
116
  declare const AlertDialog: react.FC<AlertDialogPrimitive.AlertDialogProps>;
117
117
  declare const AlertDialogTrigger: react.ForwardRefExoticComponent<AlertDialogPrimitive.AlertDialogTriggerProps & react.RefAttributes<HTMLButtonElement>>;
@@ -497,7 +497,7 @@ declare function Switch({ className, ...props }: SwitchProps): react.JSX.Element
497
497
  * `Nav`'s `size` documents: a `rounded-none` passed from the call site does
498
498
  * nothing, silently. There is one shape on purpose — fourteen call sites wanted
499
499
  * the same one — and a second gets a prop when a second consumer exists, not
500
- * before. See `docs/decisions/0.8.md` § 39.
500
+ * before. See `docs/decisions/` § 39.
501
501
  *
502
502
  * THE `tabIndex` IS NOT DECORATION and it is not new behaviour dressed up as
503
503
  * markup. A region you can pan with a mouse has to be reachable with a keyboard
@@ -771,7 +771,7 @@ declare function AuthorCard({ name, role, src, bio, action, className, ...props
771
771
  * paths this file used to carry verbatim from the portfolio are gone with
772
772
  * `lib/glyphs.tsx`; `Play`, `Pause`, `SpeakerHigh` and `SpeakerSlash` are the
773
773
  * same symbols in Phosphor's hand, and the ±15s skips are `ArrowCounterClockwise`
774
- * and `ArrowClockwise`. See `docs/decisions/0.10.md` § 51.
774
+ * and `ArrowClockwise`. See `docs/decisions/` § 51.
775
775
  * - analytics' `trackEvent` → the `onFirstPlay` prop, which the consumer wires
776
776
  * to whatever they use. It still fires exactly once per load.
777
777
  *
@@ -912,7 +912,7 @@ type CourseCardProps = Omit<CardShellProps, 'children' | 'title' | 'media'> & {
912
912
  * formatted in a currency the library does not know, the rating is drawn by a
913
913
  * component the project already has, and the cover is an image pipeline. What
914
914
  * IS the identity's stays here: the title's scale and its hover, the sand bar,
915
- * the status badge. See `docs/decisions/0.11.md` § 59.
915
+ * the status badge. See `docs/decisions/` § 59.
916
916
  *
917
917
  * The title does NOT go over the cover. It stays in the body at `h3`, with the
918
918
  * hover every other card has. Text on a photograph needs a scrim, and a scrim's
@@ -941,7 +941,7 @@ declare function CourseCard({ title, summary, meta, status, progress, media, foo
941
941
  * smaller one: the hole inside a table page or a dashboard widget, competing with
942
942
  * a dozen elements around it. An admin panel has twenty of those on one screen,
943
943
  * and twenty faces is not the humour contract, it is a zoo. The variant carries
944
- * no face, and the type does not let one through. See `docs/decisions/0.7.md` § 27.
944
+ * no face, and the type does not let one through. See `docs/decisions/` § 27.
945
945
  */
946
946
  type EmptyStateBase = Omit<ComponentPropsWithoutRef<'div'>, 'title'> & {
947
947
  title: ReactNode;
@@ -1030,7 +1030,7 @@ declare function EventCalendar({ events, onCreateEvent, onUpdateEvent, onDeleteE
1030
1030
  * The domain defaults to `naming.domain` and not to a hand-written string, for
1031
1031
  * the same reason as the wordmark: if it changes, it changes in all five
1032
1032
  * projects at once. A project that lives on its OWN domain passes `domain` —
1033
- * see `docs/decisions/0.9.md` § 49.
1033
+ * see `docs/decisions/` § 49.
1034
1034
  *
1035
1035
  * The social links are icons with NO visible text, so `aria-label` is not an
1036
1036
  * improvement: it is the only thing that makes them legible. Which is why it is
@@ -1046,7 +1046,7 @@ declare function EventCalendar({ events, onCreateEvent, onUpdateEvent, onDeleteE
1046
1046
  * answer has not moved: `EmptyState` is a discriminated union where `page` is
1047
1047
  * the default and `inline` cannot be handed a face; `Nav` takes a `size` where
1048
1048
  * `default` is the bar it always was. Both left what was written before exactly
1049
- * where it was. See `docs/decisions/0.8.md` § 44.
1049
+ * where it was. See `docs/decisions/` § 44.
1050
1050
  *
1051
1051
  * The union is what holds the rule up. `columns`, `description` and `action`
1052
1052
  * exist only on `full`, and the default form cannot be handed one. As loose
@@ -1094,7 +1094,7 @@ type FooterColumn = {
1094
1094
  * `./aviso-legal` — and that row is what `variant="full"`'s columns replace. A
1095
1095
  * flat row cannot say which block a link belongs to, cannot carry a heading a
1096
1096
  * screen reader can jump to, and made whoever wrote the label type the `./`
1097
- * themselves, which the columns put there. See docs/decisions/0.8.md § 47.
1097
+ * themselves, which the columns put there. See docs/decisions/ § 47.
1098
1098
  */
1099
1099
  type FooterBase = Omit<ComponentPropsWithoutRef<'footer'>, 'children'> & {
1100
1100
  social?: readonly SocialLink[];
@@ -1129,10 +1129,25 @@ type FooterBase = Omit<ComponentPropsWithoutRef<'footer'>, 'children'> & {
1129
1129
  * have warned about.
1130
1130
  *
1131
1131
  * It is a domain and not a whole signature: the `$`, the `cd ~/` and the year
1132
- * are the identity's and stay the component's. See `docs/decisions/0.9.md`
1132
+ * are the identity's and stay the component's. See `docs/decisions/`
1133
1133
  * § 49.
1134
1134
  */
1135
1135
  domain?: string | undefined;
1136
+ /**
1137
+ * Adds «Creado con Arrecife ♥», linking to the library's Storybook.
1138
+ *
1139
+ * OFF BY DEFAULT, and that is the decision rather than the default. No
1140
+ * consuming project credits the library today — the four were read before
1141
+ * this was written — so turning it on for everybody would be the library
1142
+ * putting a line into five production footers that none of them asked for.
1143
+ * That is the move § 45 is about, and it does not get made twice.
1144
+ *
1145
+ * A site that wants it passes `builtWith`. It is a boolean and not a slot: the
1146
+ * string and the destination are the library's, and a slot would be an
1147
+ * invitation to write «Hecho con Arrecife» on one site and «Creado con» on the
1148
+ * next, which is the drift this package exists to remove.
1149
+ */
1150
+ builtWith?: boolean | undefined;
1136
1151
  };
1137
1152
  type FooterProps = FooterBase & ({
1138
1153
  /** The shape the library has always had: stacked rows and the signature at the top right. */
@@ -1168,7 +1183,7 @@ type FooterProps = FooterBase & ({
1168
1183
  children: ReactNode;
1169
1184
  }) => ReactNode) | undefined;
1170
1185
  });
1171
- declare function Footer({ variant, columns, description, action, linkAsChild, social, brand, year, signatureHref, domain, className, ...rest }: FooterProps): react.JSX.Element;
1186
+ declare function Footer({ variant, columns, description, action, linkAsChild, social, brand, builtWith, year, signatureHref, domain, className, ...rest }: FooterProps): react.JSX.Element;
1172
1187
 
1173
1188
  /**
1174
1189
  * ONE per site. It is the only piece in the system that is spent like the
@@ -1302,7 +1317,7 @@ type NavItemProps = ComponentPropsWithoutRef<'a'> & {
1302
1317
  * impossible to call. It passed `tsc` and it passed the build, because the shape
1303
1318
  * of the children is not something either one looks at. `Slottable` is Radix's
1304
1319
  * answer to exactly this: it marks which child the router's `Link` replaces and
1305
- * leaves the decoration where it is. See `docs/decisions/0.8.md` § 40.
1320
+ * leaves the decoration where it is. See `docs/decisions/` § 40.
1306
1321
  */
1307
1322
  declare function NavItem({ active, asChild, className, children, ...props }: NavItemProps): react.JSX.Element;
1308
1323
 
@@ -1439,7 +1454,7 @@ declare function NewsletterForm({ title, description, state, onSubmitEmail, succ
1439
1454
  * at 24px, and `cursos` titles 29 of its 32 at `h3` — every one in the panel —
1440
1455
  * and the other three, the public catalog pages, at `h2`. Both are rungs the
1441
1456
  * scale already has, and a third `size` could only have named one of them. See
1442
- * `docs/decisions/0.11.md` § 57.
1457
+ * `docs/decisions/` § 57.
1443
1458
  *
1444
1459
  * It takes no mascot face, at either scale: faces go in empty states,
1445
1460
  * confirmations, errors, course progress and celebration.
@@ -1543,7 +1558,7 @@ declare function ScrollingProgressBar({ target, tone, sticky, className, ...prop
1543
1558
  * eyebrow is the same length in none of them, so an inline icon puts the only
1544
1559
  * coloured mark on a different x in every card; pinned to the corner it lands on
1545
1560
  * a grid. The circle is the tint pattern the system already has — `bg-accent/10`
1546
- * as a surface and the colour on the GLYPH, per `docs/decisions/0.6.md` § 4b — and a
1561
+ * as a surface and the colour on the GLYPH, per `docs/decisions/` § 4b — and a
1547
1562
  * glyph clears the 3:1 graphical threshold where text would not clear 4.5.
1548
1563
  *
1549
1564
  * WHICH IS WHY A NEUTRAL NUMBER IS PRIMARY INK AND NOT BIOLUME. With a biolume
@@ -1551,7 +1566,7 @@ declare function ScrollingProgressBar({ target, tone, sticky, className, ...prop
1551
1566
  * the size of a postcard, and the thing you came to read stops being the loudest
1552
1567
  * thing in it. `alert` and `achievement` DO still paint the number sand, so the
1553
1568
  * document's rule survives exactly where it matters: sand when the number is not
1554
- * just a number. See `docs/decisions/0.7.md` § 31.
1569
+ * just a number. See `docs/decisions/` § 31.
1555
1570
  */
1556
1571
  type StatProps = Omit<ComponentPropsWithoutRef<'div'>, 'title'> & {
1557
1572
  /** The number, already formatted. The library imposes no locale. */
@@ -1563,7 +1578,7 @@ type StatProps = Omit<ComponentPropsWithoutRef<'div'>, 'title'> & {
1563
1578
  * the opposite — the diplomas issued, the modules finished. The two paint the
1564
1579
  * same sand today and they are still two names: a system that names by meaning
1565
1580
  * cannot make «this is bad» the only way to say «this stands out». See
1566
- * `docs/decisions/0.7.md` § 28.
1581
+ * `docs/decisions/` § 28.
1567
1582
  */
1568
1583
  tone?: 'neutral' | 'alert' | 'achievement';
1569
1584
  /** With `progress`, the metric reads as progress and adds the bar. */