@eduardoalvarez/arrecife 0.6.0 → 0.8.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 (56) hide show
  1. package/CHANGELOG.md +112 -0
  2. package/README.md +288 -49
  3. package/dist/brand/index.cjs +2 -2
  4. package/dist/brand/index.js +3 -3
  5. package/dist/chart/index.cjs +129 -2
  6. package/dist/chart/index.d.cts +114 -4
  7. package/dist/chart/index.d.ts +114 -4
  8. package/dist/chart/index.js +129 -5
  9. package/dist/{chunk-PMN7NR3G.js → chunk-5A5GH2PF.js} +1 -1
  10. package/dist/{chunk-DKCN7BAL.js → chunk-6IGD5REB.js} +1 -1
  11. package/dist/{chunk-XKYHTOUJ.js → chunk-FAAGZG7A.js} +1 -1
  12. package/dist/{chunk-O4TAH7YJ.js → chunk-FGFNK72B.js} +29 -5
  13. package/dist/chunk-HOADZ6GS.js +72 -0
  14. package/dist/chunk-LXRGQKMG.js +145 -0
  15. package/dist/{chunk-6O3KWB6P.js → chunk-MPZBF2TZ.js} +2 -2
  16. package/dist/{chunk-JMOOFZ3B.js → chunk-TRPBID2W.js} +1 -1
  17. package/dist/{chunk-25YNFCIF.js → chunk-XXDATT3A.js} +6 -3
  18. package/dist/doctor.mjs +248 -0
  19. package/dist/form/index.cjs +2 -2
  20. package/dist/form/index.d.cts +1 -1
  21. package/dist/form/index.d.ts +1 -1
  22. package/dist/form/index.js +4 -4
  23. package/dist/icons/index.cjs +149 -0
  24. package/dist/icons/index.d.cts +94 -0
  25. package/dist/icons/index.d.ts +94 -0
  26. package/dist/icons/index.js +28 -0
  27. package/dist/index-BbRplw_B.d.cts +58 -0
  28. package/dist/index-BbRplw_B.d.ts +58 -0
  29. package/dist/index.cjs +425 -251
  30. package/dist/index.d.cts +303 -104
  31. package/dist/index.d.ts +303 -104
  32. package/dist/index.js +283 -285
  33. package/dist/{label-MgHFKnFy.d.ts → label-DJ4HuD-R.d.cts} +3 -2
  34. package/dist/{label-MgHFKnFy.d.cts → label-DJ4HuD-R.d.ts} +3 -2
  35. package/dist/og/index.cjs +3 -2
  36. package/dist/og/index.js +1 -1
  37. package/dist/shiki/index.js +1 -1
  38. package/dist/social/data.cjs +161 -0
  39. package/dist/social/data.d.cts +161 -0
  40. package/dist/social/data.d.ts +161 -0
  41. package/dist/social/data.js +2 -0
  42. package/dist/social/index.cjs +153 -0
  43. package/dist/social/index.d.cts +2 -0
  44. package/dist/social/index.d.ts +2 -0
  45. package/dist/social/index.js +3 -0
  46. package/dist/tokens/index.cjs +29 -5
  47. package/dist/tokens/index.d.cts +37 -10
  48. package/dist/tokens/index.d.ts +37 -10
  49. package/dist/tokens/index.js +2 -2
  50. package/dist/tokens/theme.css +79 -22
  51. package/dist/variants/index.cjs +6 -3
  52. package/dist/variants/index.d.cts +6 -3
  53. package/dist/variants/index.d.ts +6 -3
  54. package/dist/variants/index.js +1 -1
  55. package/llms.txt +530 -80
  56. package/package.json +29 -2
@@ -0,0 +1,153 @@
1
+ 'use strict';
2
+
3
+ var jsxRuntime = require('react/jsx-runtime');
4
+
5
+ // src/social/data.ts
6
+ var SOCIAL_STROKE_WIDTH = 1.6;
7
+ var SOCIAL_VIEW_BOX = "0 0 24 24";
8
+ var gitHubGlyph = {
9
+ kind: "brand",
10
+ shapes: [
11
+ {
12
+ tag: "path",
13
+ d: "M12 .5C5.73.5.5 5.73.5 12a11.5 11.5 0 0 0 7.86 10.91c.58.1.79-.25.79-.55 0-.27-.01-1.18-.02-2.14-3.2.7-3.88-1.36-3.88-1.36-.52-1.33-1.28-1.68-1.28-1.68-1.05-.72.08-.7.08-.7 1.16.08 1.77 1.19 1.77 1.19 1.03 1.77 2.7 1.26 3.36.96.1-.75.4-1.26.73-1.55-2.55-.29-5.24-1.28-5.24-5.69 0-1.26.45-2.29 1.19-3.09-.12-.29-.52-1.46.11-3.05 0 0 .97-.31 3.18 1.18a11 11 0 0 1 5.79 0c2.2-1.49 3.17-1.18 3.17-1.18.63 1.59.23 2.76.12 3.05.74.8 1.18 1.83 1.18 3.09 0 4.42-2.69 5.39-5.25 5.68.41.36.78 1.06.78 2.14 0 1.55-.01 2.79-.01 3.17 0 .3.2.66.79.55A11.5 11.5 0 0 0 23.5 12C23.5 5.73 18.27.5 12 .5Z"
14
+ }
15
+ ]
16
+ };
17
+ var linkedInGlyph = {
18
+ kind: "brand",
19
+ shapes: [
20
+ {
21
+ tag: "path",
22
+ d: "M4.98 3.5a2.5 2.5 0 1 1 0 5 2.5 2.5 0 0 1 0-5ZM3 9h4v12H3V9Zm7 0h3.8v1.71h.05a4.17 4.17 0 0 1 3.75-2.06c4.01 0 4.75 2.64 4.75 6.07V21h-4v-5.4c0-1.29-.02-2.95-1.8-2.95-1.8 0-2.08 1.4-2.08 2.85V21h-3.97V9Z"
23
+ }
24
+ ]
25
+ };
26
+ var xGlyph = {
27
+ kind: "brand",
28
+ shapes: [
29
+ {
30
+ tag: "path",
31
+ d: "M17.53 3h3.06l-6.69 7.64L21.75 21h-6.16l-4.83-6.3L5.25 21H2.19l7.15-8.17L2.5 3h6.32l4.36 5.77L17.53 3Zm-1.07 16.17h1.7L7.62 4.74H5.8l10.66 14.43Z"
32
+ }
33
+ ]
34
+ };
35
+ var instagramGlyph = {
36
+ kind: "brand",
37
+ shapes: [
38
+ {
39
+ tag: "path",
40
+ d: "M12 2.16c3.2 0 3.58.01 4.85.07 1.17.05 1.8.25 2.23.41.56.22.96.48 1.38.9.42.42.68.82.9 1.38.16.42.36 1.06.41 2.23.06 1.27.07 1.65.07 4.85s-.01 3.58-.07 4.85c-.05 1.17-.25 1.8-.41 2.23-.22.56-.48.96-.9 1.38-.42.42-.82.68-1.38.9-.42.16-1.06.36-2.23.41-1.27.06-1.65.07-4.85.07s-3.58-.01-4.85-.07c-1.17-.05-1.8-.25-2.23-.41-.56-.22-.96-.48-1.38-.9-.42-.42-.68-.82-.9-1.38-.16-.42-.36-1.06-.41-2.23C2.17 15.58 2.16 15.2 2.16 12s.01-3.58.07-4.85c.05-1.17.25-1.8.41-2.23.22-.56.48-.96.9-1.38.42-.42.82-.68 1.38-.9.42-.16 1.06-.36 2.23-.41C8.42 2.17 8.8 2.16 12 2.16Zm0 3.68a6.16 6.16 0 1 0 0 12.32 6.16 6.16 0 0 0 0-12.32Zm0 10.16a4 4 0 1 1 0-8 4 4 0 0 1 0 8Zm7.85-10.4a1.44 1.44 0 1 1-2.88 0 1.44 1.44 0 0 1 2.88 0Z"
41
+ }
42
+ ]
43
+ };
44
+ var discordGlyph = {
45
+ kind: "brand",
46
+ shapes: [
47
+ {
48
+ tag: "path",
49
+ d: "M20.32 5.56A18.5 18.5 0 0 0 15.7 4.1a.07.07 0 0 0-.07.04c-.2.36-.42.82-.58 1.19a17 17 0 0 0-5.1 0c-.16-.38-.39-.83-.59-1.19a.07.07 0 0 0-.07-.04c-1.6.28-3.15.77-4.62 1.46a.06.06 0 0 0-.03.03C1.66 10 .9 14.28 1.28 18.5a.08.08 0 0 0 .03.05 18.6 18.6 0 0 0 5.6 2.84.07.07 0 0 0 .08-.03c.43-.59.81-1.21 1.14-1.86a.07.07 0 0 0-.04-.1c-.6-.23-1.18-.51-1.74-.83a.07.07 0 0 1-.01-.12l.35-.27a.07.07 0 0 1 .07-.01 13.3 13.3 0 0 0 11.3 0 .07.07 0 0 1 .08.01l.34.27c.04.04.04.1-.01.12-.55.33-1.13.6-1.74.83a.07.07 0 0 0-.04.1c.34.65.72 1.27 1.14 1.86a.07.07 0 0 0 .08.03 18.5 18.5 0 0 0 5.6-2.84.07.07 0 0 0 .04-.05c.45-4.88-.75-9.12-3.18-12.88a.06.06 0 0 0-.03-.03ZM8.4 15.93c-1.1 0-2.01-1.01-2.01-2.25 0-1.24.89-2.25 2.01-2.25 1.13 0 2.03 1.02 2.02 2.25 0 1.24-.9 2.25-2.02 2.25Zm7.22 0c-1.1 0-2.01-1.01-2.01-2.25 0-1.24.89-2.25 2.01-2.25 1.13 0 2.03 1.02 2.02 2.25 0 1.24-.89 2.25-2.02 2.25Z"
50
+ }
51
+ ]
52
+ };
53
+ var youTubeGlyph = {
54
+ kind: "brand",
55
+ shapes: [
56
+ {
57
+ tag: "path",
58
+ d: "M23.5 6.9a3 3 0 0 0-2.12-2.12C19.5 4.27 12 4.27 12 4.27s-7.5 0-9.38.51A3 3 0 0 0 .5 6.9 31.3 31.3 0 0 0 0 12a31.3 31.3 0 0 0 .5 5.1 3 3 0 0 0 2.12 2.12c1.88.51 9.38.51 9.38.51s7.5 0 9.38-.51a3 3 0 0 0 2.12-2.12A31.3 31.3 0 0 0 24 12a31.3 31.3 0 0 0-.5-5.1ZM9.6 15.6V8.4l6.24 3.6-6.24 3.6Z"
59
+ }
60
+ ]
61
+ };
62
+ var rssGlyph = {
63
+ kind: "functional",
64
+ shapes: [
65
+ { tag: "path", d: "M4 11a9 9 0 0 1 9 9M4 4a16 16 0 0 1 16 16" },
66
+ { tag: "circle", cx: 5, cy: 19, r: 1.6, solid: true }
67
+ ]
68
+ };
69
+ var emailGlyph = {
70
+ kind: "functional",
71
+ shapes: [
72
+ { tag: "rect", x: 2.75, y: 4.75, width: 18.5, height: 14.5, rx: 2 },
73
+ { tag: "path", d: "m3.5 7.5 7.4 5.2a2 2 0 0 0 2.2 0l7.4-5.2" }
74
+ ]
75
+ };
76
+ var newsletterGlyph = {
77
+ kind: "functional",
78
+ shapes: [
79
+ { tag: "path", d: "M18 8.5a6 6 0 1 0-12 0c0 5-2 6.5-2 6.5h16s-2-1.5-2-6.5" },
80
+ { tag: "path", d: "M13.7 19a2 2 0 0 1-3.4 0" }
81
+ ]
82
+ };
83
+ var websiteGlyph = {
84
+ kind: "functional",
85
+ shapes: [
86
+ { tag: "circle", cx: 12, cy: 12, r: 9.25 },
87
+ { tag: "path", d: "M2.75 12h18.5" },
88
+ { tag: "path", d: "M12 2.75a14 14 0 0 1 0 18.5a14 14 0 0 1 0-18.5" }
89
+ ]
90
+ };
91
+ var SOLID = { fill: "currentColor", stroke: "none" };
92
+ function drawShape(shape, index) {
93
+ if (shape.tag === "path") {
94
+ return /* @__PURE__ */ jsxRuntime.jsx("path", { d: shape.d, ...shape.solid ? SOLID : {} }, index);
95
+ }
96
+ if (shape.tag === "circle") {
97
+ return /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: shape.cx, cy: shape.cy, r: shape.r, ...shape.solid ? SOLID : {} }, index);
98
+ }
99
+ return /* @__PURE__ */ jsxRuntime.jsx(
100
+ "rect",
101
+ {
102
+ x: shape.x,
103
+ y: shape.y,
104
+ width: shape.width,
105
+ height: shape.height,
106
+ rx: shape.rx
107
+ },
108
+ index
109
+ );
110
+ }
111
+ function Glyph({ glyph, ...props }) {
112
+ const brand = glyph.kind === "brand";
113
+ return /* @__PURE__ */ jsxRuntime.jsx(
114
+ "svg",
115
+ {
116
+ viewBox: SOCIAL_VIEW_BOX,
117
+ width: "1em",
118
+ height: "1em",
119
+ fill: brand ? "currentColor" : "none",
120
+ ...brand ? {} : {
121
+ stroke: "currentColor",
122
+ strokeWidth: SOCIAL_STROKE_WIDTH,
123
+ strokeLinecap: "round",
124
+ strokeLinejoin: "round"
125
+ },
126
+ "aria-hidden": "true",
127
+ focusable: "false",
128
+ ...props,
129
+ children: glyph.shapes.map(drawShape)
130
+ }
131
+ );
132
+ }
133
+ var GitHub = (props) => /* @__PURE__ */ jsxRuntime.jsx(Glyph, { glyph: gitHubGlyph, ...props });
134
+ var LinkedIn = (props) => /* @__PURE__ */ jsxRuntime.jsx(Glyph, { glyph: linkedInGlyph, ...props });
135
+ var X = (props) => /* @__PURE__ */ jsxRuntime.jsx(Glyph, { glyph: xGlyph, ...props });
136
+ var Instagram = (props) => /* @__PURE__ */ jsxRuntime.jsx(Glyph, { glyph: instagramGlyph, ...props });
137
+ var Discord = (props) => /* @__PURE__ */ jsxRuntime.jsx(Glyph, { glyph: discordGlyph, ...props });
138
+ var YouTube = (props) => /* @__PURE__ */ jsxRuntime.jsx(Glyph, { glyph: youTubeGlyph, ...props });
139
+ var Rss = (props) => /* @__PURE__ */ jsxRuntime.jsx(Glyph, { glyph: rssGlyph, ...props });
140
+ var Email = (props) => /* @__PURE__ */ jsxRuntime.jsx(Glyph, { glyph: emailGlyph, ...props });
141
+ var Newsletter = (props) => /* @__PURE__ */ jsxRuntime.jsx(Glyph, { glyph: newsletterGlyph, ...props });
142
+ var Website = (props) => /* @__PURE__ */ jsxRuntime.jsx(Glyph, { glyph: websiteGlyph, ...props });
143
+
144
+ exports.Discord = Discord;
145
+ exports.Email = Email;
146
+ exports.GitHub = GitHub;
147
+ exports.Instagram = Instagram;
148
+ exports.LinkedIn = LinkedIn;
149
+ exports.Newsletter = Newsletter;
150
+ exports.Rss = Rss;
151
+ exports.Website = Website;
152
+ exports.X = X;
153
+ exports.YouTube = YouTube;
@@ -0,0 +1,2 @@
1
+ import 'react';
2
+ export { D as Discord, E as Email, G as GitHub, I as Instagram, L as LinkedIn, N as Newsletter, R as Rss, S as SocialIconProps, W as Website, X, Y as YouTube } from '../index-BbRplw_B.cjs';
@@ -0,0 +1,2 @@
1
+ import 'react';
2
+ export { D as Discord, E as Email, G as GitHub, I as Instagram, L as LinkedIn, N as Newsletter, R as Rss, S as SocialIconProps, W as Website, X, Y as YouTube } from '../index-BbRplw_B.js';
@@ -0,0 +1,3 @@
1
+ export { Discord, Email, GitHub, Instagram, LinkedIn, Newsletter, Rss, Website, X, YouTube } from '../chunk-HOADZ6GS.js';
2
+ import '../chunk-LXRGQKMG.js';
3
+ import '../chunk-MLKGABMK.js';
@@ -146,7 +146,7 @@ var typeScale = {
146
146
  * (plankton 5.57:1 over abyss), which is the part that is not negotiable.
147
147
  *
148
148
  * At 13 the three badge families grew past the size of a small button and
149
- * outweighed the title they accompany. See `docs/decisions.md`.
149
+ * outweighed the title they accompany. See `docs/decisions/`.
150
150
  */
151
151
  chip: { family: "mono", size: 11.5, lineHeight: 1.4, weight: 400 },
152
152
  /**
@@ -200,7 +200,7 @@ var control = {
200
200
  * baseline; 28 would have been a fifth height that matches nothing.
201
201
  *
202
202
  * It does not replace `icon`. A page's primary action stays at 42; this is for
203
- * a row of a table. See `docs/decisions.md` § 22.
203
+ * a row of a table. See `docs/decisions/0.6.md` § 22.
204
204
  */
205
205
  iconSm: 32
206
206
  };
@@ -215,6 +215,30 @@ var spacing = {
215
215
  var size = {
216
216
  /** Navigation bar height. */
217
217
  nav: 64,
218
+ /**
219
+ * The bar when it shares the screen with a sidebar.
220
+ *
221
+ * It is not «a smaller bar because it looks better». At 64 the header of an
222
+ * app shell competes with the rail beside it for the same corner, and the two
223
+ * together eat the top of the content area. 56 is what `cursos` had arrived at
224
+ * on its own, and it is the same reasoning as `control.iconSm`: the one admin
225
+ * app of the five is denser than the four reading sites. See
226
+ * `docs/decisions/0.7.md` § 30.
227
+ */
228
+ navCompact: 56,
229
+ /**
230
+ * The admin sidebar, and the rail it collapses to.
231
+ *
232
+ * They are tokens and not the consumer's `w-*` because a collapsible sidebar
233
+ * has to know BOTH: the layout beside it reserves one of the two, and two
234
+ * numbers written by hand in two files drift the first time one of them moves.
235
+ * A sidebar that never collapses is still just a box the layout sizes.
236
+ *
237
+ * 56 is the rail: `navCompact`'s height, so a panel's bar and its rail meet in
238
+ * a square corner instead of a step.
239
+ */
240
+ sidebar: 256,
241
+ sidebarRail: 56,
218
242
  /** Reading column width. */
219
243
  content: 760,
220
244
  /** Maximum page width. */
@@ -247,9 +271,9 @@ var gradient = {
247
271
  og: `linear-gradient(145deg, ${dark.background} 55%, ${deep} 100%)`
248
272
  },
249
273
  light: {
250
- hero: `linear-gradient(160deg, ${light.background} 60%, ${light.surfaceRaised} 100%)`,
251
- section: `linear-gradient(150deg, ${light.surface} 0%, ${light.surfaceRaised} 100%)`,
252
- og: `linear-gradient(145deg, ${light.background} 55%, ${light.surfaceRaised} 100%)`
274
+ hero: `linear-gradient(160deg, ${light.background} 60%, ${light.surface} 100%)`,
275
+ section: `linear-gradient(150deg, ${light.surface} 0%, ${light.background} 100%)`,
276
+ og: `linear-gradient(145deg, ${light.background} 55%, ${light.surface} 100%)`
253
277
  }
254
278
  };
255
279
  var shadow = {
@@ -280,7 +280,7 @@ declare const typeScale: {
280
280
  * (plankton 5.57:1 over abyss), which is the part that is not negotiable.
281
281
  *
282
282
  * At 13 the three badge families grew past the size of a small button and
283
- * outweighed the title they accompany. See `docs/decisions.md`.
283
+ * outweighed the title they accompany. See `docs/decisions/`.
284
284
  */
285
285
  readonly chip: {
286
286
  readonly family: "mono";
@@ -336,7 +336,7 @@ declare const radius: {
336
336
  *
337
337
  * Only the horizontal padding and the icon button's square. Height comes from
338
338
  * the type scale, and there is a single radius for all three sizes: see
339
- * `docs/decisions.md`.
339
+ * `docs/decisions/`.
340
340
  *
341
341
  * They are not in `spacing` because they are not page rhythm: 14, 22 and 30 do
342
342
  * not compose with 8/12/16/26/40 and must not be offered as margins.
@@ -360,7 +360,7 @@ declare const control: {
360
360
  * baseline; 28 would have been a fifth height that matches nothing.
361
361
  *
362
362
  * It does not replace `icon`. A page's primary action stays at 42; this is for
363
- * a row of a table. See `docs/decisions.md` § 22.
363
+ * a row of a table. See `docs/decisions/0.6.md` § 22.
364
364
  */
365
365
  readonly iconSm: 32;
366
366
  };
@@ -397,6 +397,30 @@ declare const spacing: {
397
397
  declare const size: {
398
398
  /** Navigation bar height. */
399
399
  readonly nav: 64;
400
+ /**
401
+ * The bar when it shares the screen with a sidebar.
402
+ *
403
+ * It is not «a smaller bar because it looks better». At 64 the header of an
404
+ * app shell competes with the rail beside it for the same corner, and the two
405
+ * together eat the top of the content area. 56 is what `cursos` had arrived at
406
+ * on its own, and it is the same reasoning as `control.iconSm`: the one admin
407
+ * app of the five is denser than the four reading sites. See
408
+ * `docs/decisions/0.7.md` § 30.
409
+ */
410
+ readonly navCompact: 56;
411
+ /**
412
+ * The admin sidebar, and the rail it collapses to.
413
+ *
414
+ * They are tokens and not the consumer's `w-*` because a collapsible sidebar
415
+ * has to know BOTH: the layout beside it reserves one of the two, and two
416
+ * numbers written by hand in two files drift the first time one of them moves.
417
+ * A sidebar that never collapses is still just a box the layout sizes.
418
+ *
419
+ * 56 is the rail: `navCompact`'s height, so a panel's bar and its rail meet in
420
+ * a square corner instead of a step.
421
+ */
422
+ readonly sidebar: 256;
423
+ readonly sidebarRail: 56;
400
424
  /** Reading column width. */
401
425
  readonly content: 760;
402
426
  /** Maximum page width. */
@@ -464,7 +488,7 @@ declare const syntax: {
464
488
  *
465
489
  * A fifth series is not added by inventing a hue. If a chart needs five
466
490
  * categories, either there are too many categories or they need an «other»
467
- * bucket: see `docs/decisions.md`.
491
+ * bucket: see `docs/decisions/`.
468
492
  */
469
493
  declare const series: {
470
494
  readonly dark: readonly ["#35D6C0", "#F2A65A", "#3E7CB1", "#71919C"];
@@ -478,9 +502,9 @@ declare const gradient: {
478
502
  readonly og: "linear-gradient(145deg, #091319 55%, #0D2129 100%)";
479
503
  };
480
504
  readonly light: {
481
- readonly hero: "linear-gradient(160deg, #F6F2EA 60%, #EFE9DE 100%)";
482
- readonly section: "linear-gradient(150deg, #FFFFFF 0%, #EFE9DE 100%)";
483
- readonly og: "linear-gradient(145deg, #F6F2EA 55%, #EFE9DE 100%)";
505
+ readonly hero: "linear-gradient(160deg, #F6F2EA 60%, #FFFFFF 100%)";
506
+ readonly section: "linear-gradient(150deg, #FFFFFF 0%, #F6F2EA 100%)";
507
+ readonly og: "linear-gradient(145deg, #F6F2EA 55%, #FFFFFF 100%)";
484
508
  };
485
509
  };
486
510
  /** A single level. There is no elevation scale. */
@@ -711,6 +735,9 @@ declare const tokens: {
711
735
  };
712
736
  readonly size: {
713
737
  readonly nav: 64;
738
+ readonly navCompact: 56;
739
+ readonly sidebar: 256;
740
+ readonly sidebarRail: 56;
714
741
  readonly content: 760;
715
742
  readonly wide: 1180;
716
743
  };
@@ -721,9 +748,9 @@ declare const tokens: {
721
748
  readonly og: "linear-gradient(145deg, #091319 55%, #0D2129 100%)";
722
749
  };
723
750
  readonly light: {
724
- readonly hero: "linear-gradient(160deg, #F6F2EA 60%, #EFE9DE 100%)";
725
- readonly section: "linear-gradient(150deg, #FFFFFF 0%, #EFE9DE 100%)";
726
- readonly og: "linear-gradient(145deg, #F6F2EA 55%, #EFE9DE 100%)";
751
+ readonly hero: "linear-gradient(160deg, #F6F2EA 60%, #FFFFFF 100%)";
752
+ readonly section: "linear-gradient(150deg, #FFFFFF 0%, #F6F2EA 100%)";
753
+ readonly og: "linear-gradient(145deg, #F6F2EA 55%, #FFFFFF 100%)";
727
754
  };
728
755
  };
729
756
  readonly syntax: {
@@ -280,7 +280,7 @@ declare const typeScale: {
280
280
  * (plankton 5.57:1 over abyss), which is the part that is not negotiable.
281
281
  *
282
282
  * At 13 the three badge families grew past the size of a small button and
283
- * outweighed the title they accompany. See `docs/decisions.md`.
283
+ * outweighed the title they accompany. See `docs/decisions/`.
284
284
  */
285
285
  readonly chip: {
286
286
  readonly family: "mono";
@@ -336,7 +336,7 @@ declare const radius: {
336
336
  *
337
337
  * Only the horizontal padding and the icon button's square. Height comes from
338
338
  * the type scale, and there is a single radius for all three sizes: see
339
- * `docs/decisions.md`.
339
+ * `docs/decisions/`.
340
340
  *
341
341
  * They are not in `spacing` because they are not page rhythm: 14, 22 and 30 do
342
342
  * not compose with 8/12/16/26/40 and must not be offered as margins.
@@ -360,7 +360,7 @@ declare const control: {
360
360
  * baseline; 28 would have been a fifth height that matches nothing.
361
361
  *
362
362
  * It does not replace `icon`. A page's primary action stays at 42; this is for
363
- * a row of a table. See `docs/decisions.md` § 22.
363
+ * a row of a table. See `docs/decisions/0.6.md` § 22.
364
364
  */
365
365
  readonly iconSm: 32;
366
366
  };
@@ -397,6 +397,30 @@ declare const spacing: {
397
397
  declare const size: {
398
398
  /** Navigation bar height. */
399
399
  readonly nav: 64;
400
+ /**
401
+ * The bar when it shares the screen with a sidebar.
402
+ *
403
+ * It is not «a smaller bar because it looks better». At 64 the header of an
404
+ * app shell competes with the rail beside it for the same corner, and the two
405
+ * together eat the top of the content area. 56 is what `cursos` had arrived at
406
+ * on its own, and it is the same reasoning as `control.iconSm`: the one admin
407
+ * app of the five is denser than the four reading sites. See
408
+ * `docs/decisions/0.7.md` § 30.
409
+ */
410
+ readonly navCompact: 56;
411
+ /**
412
+ * The admin sidebar, and the rail it collapses to.
413
+ *
414
+ * They are tokens and not the consumer's `w-*` because a collapsible sidebar
415
+ * has to know BOTH: the layout beside it reserves one of the two, and two
416
+ * numbers written by hand in two files drift the first time one of them moves.
417
+ * A sidebar that never collapses is still just a box the layout sizes.
418
+ *
419
+ * 56 is the rail: `navCompact`'s height, so a panel's bar and its rail meet in
420
+ * a square corner instead of a step.
421
+ */
422
+ readonly sidebar: 256;
423
+ readonly sidebarRail: 56;
400
424
  /** Reading column width. */
401
425
  readonly content: 760;
402
426
  /** Maximum page width. */
@@ -464,7 +488,7 @@ declare const syntax: {
464
488
  *
465
489
  * A fifth series is not added by inventing a hue. If a chart needs five
466
490
  * categories, either there are too many categories or they need an «other»
467
- * bucket: see `docs/decisions.md`.
491
+ * bucket: see `docs/decisions/`.
468
492
  */
469
493
  declare const series: {
470
494
  readonly dark: readonly ["#35D6C0", "#F2A65A", "#3E7CB1", "#71919C"];
@@ -478,9 +502,9 @@ declare const gradient: {
478
502
  readonly og: "linear-gradient(145deg, #091319 55%, #0D2129 100%)";
479
503
  };
480
504
  readonly light: {
481
- readonly hero: "linear-gradient(160deg, #F6F2EA 60%, #EFE9DE 100%)";
482
- readonly section: "linear-gradient(150deg, #FFFFFF 0%, #EFE9DE 100%)";
483
- readonly og: "linear-gradient(145deg, #F6F2EA 55%, #EFE9DE 100%)";
505
+ readonly hero: "linear-gradient(160deg, #F6F2EA 60%, #FFFFFF 100%)";
506
+ readonly section: "linear-gradient(150deg, #FFFFFF 0%, #F6F2EA 100%)";
507
+ readonly og: "linear-gradient(145deg, #F6F2EA 55%, #FFFFFF 100%)";
484
508
  };
485
509
  };
486
510
  /** A single level. There is no elevation scale. */
@@ -711,6 +735,9 @@ declare const tokens: {
711
735
  };
712
736
  readonly size: {
713
737
  readonly nav: 64;
738
+ readonly navCompact: 56;
739
+ readonly sidebar: 256;
740
+ readonly sidebarRail: 56;
714
741
  readonly content: 760;
715
742
  readonly wide: 1180;
716
743
  };
@@ -721,9 +748,9 @@ declare const tokens: {
721
748
  readonly og: "linear-gradient(145deg, #091319 55%, #0D2129 100%)";
722
749
  };
723
750
  readonly light: {
724
- readonly hero: "linear-gradient(160deg, #F6F2EA 60%, #EFE9DE 100%)";
725
- readonly section: "linear-gradient(150deg, #FFFFFF 0%, #EFE9DE 100%)";
726
- readonly og: "linear-gradient(145deg, #F6F2EA 55%, #EFE9DE 100%)";
751
+ readonly hero: "linear-gradient(160deg, #F6F2EA 60%, #FFFFFF 100%)";
752
+ readonly section: "linear-gradient(150deg, #FFFFFF 0%, #F6F2EA 100%)";
753
+ readonly og: "linear-gradient(145deg, #F6F2EA 55%, #FFFFFF 100%)";
727
754
  };
728
755
  };
729
756
  readonly syntax: {
@@ -1,3 +1,3 @@
1
- export { tokens } from '../chunk-PMN7NR3G.js';
2
- export { brand, colors, control, dark, fonts, gradient, light, limits, motion, naming, radius, series, shadow, size, spacing, syntax, tagline, typeScale } from '../chunk-O4TAH7YJ.js';
1
+ export { tokens } from '../chunk-5A5GH2PF.js';
2
+ export { brand, colors, control, dark, fonts, gradient, light, limits, motion, naming, radius, series, shadow, size, spacing, syntax, tagline, typeScale } from '../chunk-FGFNK72B.js';
3
3
  import '../chunk-MLKGABMK.js';
@@ -123,6 +123,9 @@
123
123
  --spacing-control-icon-sm: 32px;
124
124
 
125
125
  --spacing-nav: 64px;
126
+ --spacing-nav-compact: 56px;
127
+ --spacing-sidebar: 256px;
128
+ --spacing-sidebar-rail: 56px;
126
129
  --container-content: 760px;
127
130
  --container-wide: 1180px;
128
131
  --container-measure: 68ch;
@@ -204,9 +207,9 @@
204
207
  --color-series-3: #3E7CB1;
205
208
  --color-series-4: #626A75;
206
209
 
207
- --gradient-hero: linear-gradient(160deg, #F6F2EA 60%, #EFE9DE 100%);
208
- --gradient-section: linear-gradient(150deg, #FFFFFF 0%, #EFE9DE 100%);
209
- --gradient-og: linear-gradient(145deg, #F6F2EA 55%, #EFE9DE 100%);
210
+ --gradient-hero: linear-gradient(160deg, #F6F2EA 60%, #FFFFFF 100%);
211
+ --gradient-section: linear-gradient(150deg, #FFFFFF 0%, #F6F2EA 100%);
212
+ --gradient-og: linear-gradient(145deg, #F6F2EA 55%, #FFFFFF 100%);
210
213
  }
211
214
 
212
215
  /* --- the system's two gradients, as utilities -------------------------------
@@ -244,27 +247,54 @@
244
247
  animation: arrecife-shimmer 1.4s linear infinite;
245
248
  }
246
249
 
247
- /* --- the fifth exception: the caret of the CLI signature --------------------
248
- A terminal prompt with a caret that does not blink is a terminal that has
249
- hung. The caret is the one piece of the footer that says the signature is a
250
- prompt and not a decorative string, and a still block reads as a typo.
251
-
252
- step-end and not a fade: a real caret is on or off, and easing it turns a
253
- terminal into a pulsing dot. 1.06s is the cadence of a VT100 and of the site
254
- this comes from.
255
-
256
- It is the only exception that is not feedback about progress, and it earns its
257
- place on the other half of the criterion the other four share: it is not
258
- decoration, it is what makes the piece legible as what it is. Behind
259
- motion-safe, where the caret stays solid — which is a caret at rest, not a
260
- missing one. See docs/decisions.md § 23. */
261
- @keyframes arrecife-caret {
262
- 0%, 50% { opacity: 1; }
263
- 50.01%, 100% { opacity: 0; }
250
+ /* --- the fifth exception: the halo the CLI signature ends in ----------------
251
+ The mark stays solid and RADIATES: a ring grows out of it to 5px and fades.
252
+ It never turns off, and nothing about it is on-or-off.
253
+
254
+ THIS IS WHAT THE CLI SIGNATURE ENDS IN. Both sites that draw that signature
255
+ had it — cursos in app/globals.css, eduardoalvarez.dev in base.css — under
256
+ the name cursor-ping, and the blog's copy sat there with nothing rendering
257
+ it, because adopting the library's Footer had replaced its mark with a blink.
258
+ The library had overruled the identity in the one direction it is not allowed
259
+ to: it invented.
260
+
261
+ That blink shipped in 0.6.0 as a caret utility and it is GONE. It was kept
262
+ for one release on the grounds that a terminal caret is a real thing to want,
263
+ which is true and is not a reason: nothing in the library drew it, no
264
+ consumer had ever asked for it, and the argument that justified it had been
265
+ written from first principles about terminals rather than read off the two
266
+ sites that already had a signature. A utility with no consumer and no origin
267
+ is not a feature, it is the invention still sitting there under a new label.
268
+ See docs/decisions/0.8.md § 45.
269
+
270
+ Its reason is the one the other four exceptions share: it is feedback about
271
+ PROGRESS. A prompt that radiates says the terminal is live, which is the same
272
+ thing the button spinner says and the same thing a still mark cannot say.
273
+ With the caret gone the criterion is ONE again — progress or spatial
274
+ continuity — and the legibility half § 23 opened turns out to have had
275
+ exactly one member for its whole life.
276
+
277
+ The color comes from --color-accent and not from a hex, so it follows the
278
+ mode. cursos wrote it against its own --primary, which freezes to whichever
279
+ mode was active; the blog hardcoded rgba(53, 214, 192, 0.7), which is this
280
+ accent at 70 % and goes stale the day the accent moves. 1.5s ease-in-out,
281
+ which is the cadence both arrived at.
282
+
283
+ Behind motion-safe at the call site — the half NOT copied from cursos, whose
284
+ span animates regardless. The blog guarded it, every other exception here is
285
+ guarded, and at rest the bar is simply solid.
286
+ See docs/decisions/0.8.md § 45. */
287
+ @keyframes arrecife-pulse {
288
+ 0%, 100% {
289
+ box-shadow: 0 0 0 0 color-mix(in oklab, var(--color-accent) 70%, transparent);
290
+ }
291
+ 50% {
292
+ box-shadow: 0 0 0 5px transparent;
293
+ }
264
294
  }
265
295
 
266
- @utility caret {
267
- animation: arrecife-caret 1.06s step-end infinite;
296
+ @utility pulse-accent {
297
+ animation: arrecife-pulse 1.5s ease-in-out infinite;
268
298
  }
269
299
 
270
300
  /* --- the accordion exception -----------------------------------------------
@@ -335,6 +365,33 @@
335
365
  animation: arrecife-slide-out-bottom var(--duration-standard) var(--ease-standard);
336
366
  }
337
367
 
368
+ /* --- the focus ring ---------------------------------------------------------
369
+ The document gives it once, on the primary button: «focus ring 2px #35D6C0 +
370
+ offset 3px». The code had it as three classes copied to twenty-nine call
371
+ sites in twenty-four files, all of them at offset 2, and three audits in a row
372
+ said so — the value was never argued down to 2, it was copied from the first
373
+ component and inherited by the next twenty-eight.
374
+
375
+ It is one utility for the reason § 15 gives: a list kept in sync by hand with
376
+ another list ends up out of sync. Twenty-nine copies is twenty-nine chances to
377
+ write the next one at offset 2 again, and nothing was checking.
378
+
379
+ focus-ring-warm exists for the ONE control the ring cannot be biolume on:
380
+ the conversion button is the system's only sand fill, and a biolume ring
381
+ around it puts both of the brand's accents in the same three pixels. It sets
382
+ only the color, so the width and the offset stay in one place. */
383
+ @utility focus-ring {
384
+ &:focus-visible {
385
+ outline: 2px solid var(--color-accent);
386
+ outline-offset: 3px;
387
+ }
388
+ }
389
+ @utility focus-ring-warm {
390
+ &:focus-visible {
391
+ outline-color: var(--color-warm);
392
+ }
393
+ }
394
+
338
395
  /* The system's only transition, as a utility. States are communicated with
339
396
  border and color, not with movement: this class cannot animate anything else. */
340
397
  @utility transition-standard {
@@ -8,7 +8,7 @@ var button = classVarianceAuthority.cva(
8
8
  "inline-flex cursor-pointer items-center justify-center gap-step-xs whitespace-nowrap select-none",
9
9
  "rounded-control font-sans font-medium",
10
10
  "transition-standard",
11
- "focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent",
11
+ "focus-ring",
12
12
  "disabled:pointer-events-none disabled:opacity-50",
13
13
  "[&_svg]:shrink-0"
14
14
  ],
@@ -19,7 +19,10 @@ var button = classVarianceAuthority.cva(
19
19
  "bg-accent text-accent-on hover:bg-accent-hover",
20
20
  "light:bg-brand-hull light:text-accent-on light:hover:bg-text-secondary"
21
21
  ],
22
- conversion: "bg-warm text-warm-on hover:bg-warm-hover",
22
+ // The one control whose focus ring is not biolume. It is the system's
23
+ // only sand fill, and a biolume ring three pixels off a sand button puts
24
+ // both of the brand's accents in the same glance. See `docs/decisions/0.7.md` § 37.
25
+ conversion: "bg-warm text-warm-on hover:bg-warm-hover focus-ring-warm",
23
26
  secondary: [
24
27
  "border-hairline-hover border bg-transparent text-text-primary",
25
28
  "hover:border-accent hover:text-accent"
@@ -177,7 +180,7 @@ var CARD = [
177
180
  "group block cursor-pointer",
178
181
  CARD_SURFACE,
179
182
  CARD_HOVER,
180
- "focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent"
183
+ "focus-ring"
181
184
  ];
182
185
 
183
186
  exports.CARD = CARD;
@@ -32,7 +32,7 @@ import * as class_variance_authority_types from 'class-variance-authority/types'
32
32
  * actions and toolbars, next to «Editar» and «Duplicar», with no context to tell
33
33
  * them apart: with every one rendered as `secondary`, «Eliminar curso» looked
34
34
  * exactly like «Cancelar» and only the word separated them. See
35
- * `docs/decisions.md` § 21.
35
+ * `docs/decisions/0.6.md` § 21.
36
36
  *
37
37
  * `destructiveOutline` fills on hover, and that IS an exception to «secondary is
38
38
  * never filled» — declared here rather than discovered later. A destructive
@@ -151,7 +151,7 @@ declare const text: (props?: ({
151
151
  *
152
152
  * The radius: the document says 12, which is none of the system's five radii. It
153
153
  * uses the card radius rather than introducing a sixth — see
154
- * `docs/decisions.md`.
154
+ * `docs/decisions/`.
155
155
  */
156
156
  declare const alert: (props?: ({
157
157
  variant?: "error" | "accent" | "success" | "warning" | null | undefined;
@@ -174,7 +174,10 @@ declare const avatar: (props?: ({
174
174
  * hand: that project ships no framework JavaScript and cannot import a
175
175
  * component, so until now it copied the class list into its Astro. The copy had
176
176
  * already drifted once — the hero gradient sat at `55%` and `#e9eeea` against
177
- * the token's `60%` and `#EFE9DE`, and nothing compared them.
177
+ * the token's `60%` and, at the time, `#EFE9DE`. Nothing compared them. The
178
+ * light gradient's second stop is `#FFFFFF` since § 9 was measured, which is the
179
+ * same lesson from the other side: a copied value goes stale when the original
180
+ * moves, and only the original is ever right.
178
181
  */
179
182
  declare const CARD_SURFACE = "rounded-card border-hairline bg-surface border";
180
183
  /** Rule 6's hover: the border only. Applied where the card is clickable. */
@@ -32,7 +32,7 @@ import * as class_variance_authority_types from 'class-variance-authority/types'
32
32
  * actions and toolbars, next to «Editar» and «Duplicar», with no context to tell
33
33
  * them apart: with every one rendered as `secondary`, «Eliminar curso» looked
34
34
  * exactly like «Cancelar» and only the word separated them. See
35
- * `docs/decisions.md` § 21.
35
+ * `docs/decisions/0.6.md` § 21.
36
36
  *
37
37
  * `destructiveOutline` fills on hover, and that IS an exception to «secondary is
38
38
  * never filled» — declared here rather than discovered later. A destructive
@@ -151,7 +151,7 @@ declare const text: (props?: ({
151
151
  *
152
152
  * The radius: the document says 12, which is none of the system's five radii. It
153
153
  * uses the card radius rather than introducing a sixth — see
154
- * `docs/decisions.md`.
154
+ * `docs/decisions/`.
155
155
  */
156
156
  declare const alert: (props?: ({
157
157
  variant?: "error" | "accent" | "success" | "warning" | null | undefined;
@@ -174,7 +174,10 @@ declare const avatar: (props?: ({
174
174
  * hand: that project ships no framework JavaScript and cannot import a
175
175
  * component, so until now it copied the class list into its Astro. The copy had
176
176
  * already drifted once — the hero gradient sat at `55%` and `#e9eeea` against
177
- * the token's `60%` and `#EFE9DE`, and nothing compared them.
177
+ * the token's `60%` and, at the time, `#EFE9DE`. Nothing compared them. The
178
+ * light gradient's second stop is `#FFFFFF` since § 9 was measured, which is the
179
+ * same lesson from the other side: a copied value goes stale when the original
180
+ * moves, and only the original is ever right.
178
181
  */
179
182
  declare const CARD_SURFACE = "rounded-card border-hairline bg-surface border";
180
183
  /** Rule 6's hover: the border only. Applied where the card is clickable. */