@eduardoalvarez/arrecife 0.1.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 (44) hide show
  1. package/CHANGELOG.md +55 -0
  2. package/LICENSE +21 -0
  3. package/README.md +520 -0
  4. package/assets/brand/face-annoyed.png +0 -0
  5. package/assets/brand/face-confused.png +0 -0
  6. package/assets/brand/face-hearts.png +0 -0
  7. package/assets/brand/face-laughing.png +0 -0
  8. package/assets/brand/face-shades.png +0 -0
  9. package/assets/brand/face-waiting.png +0 -0
  10. package/assets/brand/face-wink.png +0 -0
  11. package/assets/brand/fin-foam.png +0 -0
  12. package/assets/brand/fin.png +0 -0
  13. package/assets/brand/pose-desk.png +0 -0
  14. package/assets/brand/pose-laptop-coffee.png +0 -0
  15. package/assets/brand/pose-peek.png +0 -0
  16. package/assets/brand/pose-surf.png +0 -0
  17. package/dist/brand/index.cjs +228 -0
  18. package/dist/brand/index.d.cts +63 -0
  19. package/dist/brand/index.d.ts +63 -0
  20. package/dist/brand/index.js +3 -0
  21. package/dist/catalogo-Du5ID-Hi.d.cts +77 -0
  22. package/dist/catalogo-Du5ID-Hi.d.ts +77 -0
  23. package/dist/chunk-22OXRTAL.js +22 -0
  24. package/dist/chunk-DHF63QNM.js +231 -0
  25. package/dist/chunk-E3OMP2DL.js +36 -0
  26. package/dist/chunk-ZL5X6XO7.js +102 -0
  27. package/dist/index.cjs +3191 -0
  28. package/dist/index.d.cts +1024 -0
  29. package/dist/index.d.ts +1024 -0
  30. package/dist/index.js +2624 -0
  31. package/dist/og/index.cjs +322 -0
  32. package/dist/og/index.d.cts +164 -0
  33. package/dist/og/index.d.ts +164 -0
  34. package/dist/og/index.js +242 -0
  35. package/dist/shiki/index.cjs +127 -0
  36. package/dist/shiki/index.d.cts +16 -0
  37. package/dist/shiki/index.d.ts +16 -0
  38. package/dist/shiki/index.js +95 -0
  39. package/dist/tokens/index.cjs +263 -0
  40. package/dist/tokens/index.d.cts +623 -0
  41. package/dist/tokens/index.d.ts +623 -0
  42. package/dist/tokens/index.js +2 -0
  43. package/dist/tokens/theme.css +266 -0
  44. package/package.json +128 -0
@@ -0,0 +1,228 @@
1
+ 'use strict';
2
+
3
+ var clsx = require('clsx');
4
+ var tailwindMerge = require('tailwind-merge');
5
+ var jsxRuntime = require('react/jsx-runtime');
6
+
7
+ // src/brand/catalogo.ts
8
+ var caras = {
9
+ annoyed: "face-annoyed.png",
10
+ confused: "face-confused.png",
11
+ hearts: "face-hearts.png",
12
+ laughing: "face-laughing.png",
13
+ shades: "face-shades.png",
14
+ waiting: "face-waiting.png",
15
+ wink: "face-wink.png"
16
+ };
17
+ var poses = {
18
+ desk: "pose-desk.png",
19
+ "laptop-coffee": "pose-laptop-coffee.png",
20
+ peek: "pose-peek.png",
21
+ surf: "pose-surf.png"
22
+ };
23
+ var aletas = {
24
+ /** Dos azules. Para fondos claros. */
25
+ color: "fin.png",
26
+ /** Silueta a una tinta. Para fondos oscuros. */
27
+ espuma: "fin-foam.png"
28
+ };
29
+ var usoDeCara = {
30
+ wink: "Formularios, nota al pie amable",
31
+ waiting: "Sin resultados, estado de espera",
32
+ laughing: "\xC9xito, suscripci\xF3n confirmada",
33
+ shades: "M\xF3dulo o curso completado",
34
+ hearts: "Agradecimiento, OG de art\xEDculo",
35
+ confused: "404, p\xE1gina no encontrada",
36
+ annoyed: "Error del servidor, fallo de build"
37
+ };
38
+ var RUTA_ASSETS = "/brand";
39
+ var listaCaras = Object.keys(caras);
40
+ var listaPoses = Object.keys(poses);
41
+ var typeScale = {
42
+ display: { family: "display", size: 76, lineHeight: 0.96, weight: 800, tracking: "-0.035em" },
43
+ /** Métricas grandes. Números, no prosa: interlineado 1 y sin descendentes. */
44
+ stat: { family: "display", size: 46, lineHeight: 1, weight: 800, tracking: "-0.035em" },
45
+ h1: { family: "display", size: 44, lineHeight: 1.05, weight: 700, tracking: "-0.03em" },
46
+ h2: { family: "display", size: 30, lineHeight: 1.1, weight: 600, tracking: "-0.02em" },
47
+ h3: { family: "display", size: 25, lineHeight: 1.15, weight: 600, tracking: "-0.02em" },
48
+ body: { family: "sans", size: 18, lineHeight: 1.75, weight: 400 },
49
+ /**
50
+ * 17px. El botón grande y la bajada de las páginas internas.
51
+ *
52
+ * Entra como escalón propio porque el documento lo usa DOS veces y en piezas
53
+ * distintas: «lg 15px 30px r12» con texto de 17, y «h1 44/700 · bajada 17px ·
54
+ * párrafo de contexto 15px». Un solo uso no habría justificado partir la
55
+ * distancia entre `ui` (15) y `body` (18); dos sí.
56
+ */
57
+ lead: { family: "sans", size: 17, lineHeight: 1.5, weight: 400 },
58
+ ui: { family: "sans", size: 15, lineHeight: 1.6, weight: 400 },
59
+ label: { family: "sans", size: 13, lineHeight: 1.5, weight: 500 },
60
+ /**
61
+ * La escala de las etiquetas de estado: sans 12.5/500, cuadrada.
62
+ *
63
+ * Es medio píxel por debajo de `label`, y esta vez el medio píxel sí importa:
64
+ * una etiqueta de estado va dentro de una tabla o al lado de un título, y a 13
65
+ * competía con el texto que acompaña. El documento la da en 12.5 y se ve.
66
+ */
67
+ tag: { family: "sans", size: 12.5, lineHeight: 1.4, weight: 500 },
68
+ /**
69
+ * La escala de categoría y métrica: mono 11.5.
70
+ *
71
+ * Rompe el suelo de `limits.minScreenPx`, y es a propósito. Ese suelo protege
72
+ * al TEXTO —lo que se lee en una frase—, y una píldora de una palabra no es
73
+ * texto corrido: es una marca. El contraste sigue medido y pasa AA (plancton
74
+ * 5.57:1 sobre abismo), que es la parte que no se negocia.
75
+ *
76
+ * A 13 las tres familias de etiqueta salían del tamaño de un botón pequeño y
77
+ * pesaban más que el título que acompañan. Ver `docs/decisiones.md`.
78
+ */
79
+ chip: { family: "mono", size: 11.5, lineHeight: 1.4, weight: 400 },
80
+ /**
81
+ * Mono SIN transformar: fechas, rutas, versiones, nombres de archivo, la firma
82
+ * del footer y las métricas de etiqueta. Es la mayoría del mono del sistema.
83
+ *
84
+ * Existe porque `eyebrow` lleva `uppercase` de fábrica y no es una preferencia
85
+ * que se pueda apagar: es la escala del eyebrow. Un `18 ago 2026` en versalitas
86
+ * o un `pose-laptop-coffee.png` en mayúsculas están mal, y sin este escalón la
87
+ * única salida era un `normal-case` en cada sitio de uso.
88
+ *
89
+ * El documento dice 12.5. Son 13 por la misma razón por la que `textMuted` se
90
+ * corrigió: `limits.minScreenPx` es 13 y plancton «nunca bajo 13px». Esta
91
+ * escala es justo donde se escriben las metas en muted, así que ponerla en
92
+ * 12.5 habría dejado ilegible su uso más común por medio píxel.
93
+ */
94
+ meta: { family: "mono", size: 13, lineHeight: 1.6, weight: 400 },
95
+ eyebrow: { family: "mono", size: 12, tracking: "0.12em", transform: "uppercase" }
96
+ };
97
+ var radius = {
98
+ chip: 6,
99
+ control: 10,
100
+ card: 14,
101
+ panel: 16,
102
+ pill: 999
103
+ };
104
+ var control = {
105
+ sm: 14,
106
+ md: 22,
107
+ lg: 30,
108
+ /** Botón de icono: cuadrado, sin texto. */
109
+ icon: 42
110
+ };
111
+ var spacing = {
112
+ xs: 8,
113
+ sm: 12,
114
+ md: 16,
115
+ lg: 26,
116
+ xl: 40,
117
+ section: 96
118
+ };
119
+ var naming = {
120
+ wordmark: "Eduardo \xC1lvarez"};
121
+
122
+ // src/lib/cn.ts
123
+ var escalas = Object.keys(typeScale);
124
+ var radios = Object.keys(radius);
125
+ var espacios = Object.keys(spacing);
126
+ var controles = Object.keys(control).map((nombre) => `control-${nombre}`);
127
+ var twMerge = tailwindMerge.extendTailwindMerge({
128
+ extend: {
129
+ classGroups: {
130
+ "font-size": [{ text: escalas }],
131
+ rounded: [{ rounded: radios }],
132
+ p: [{ p: espacios }],
133
+ px: [{ px: [...espacios, ...controles] }],
134
+ py: [{ py: espacios }],
135
+ gap: [{ gap: espacios }],
136
+ size: [{ size: controles }]
137
+ }
138
+ }
139
+ });
140
+ function cn(...inputs) {
141
+ return twMerge(clsx.clsx(inputs));
142
+ }
143
+ function Isotipo({
144
+ sobre = "oscuro",
145
+ basePath = RUTA_ASSETS,
146
+ alt = "",
147
+ className,
148
+ ...props
149
+ }) {
150
+ const archivo = sobre === "oscuro" ? aletas.espuma : aletas.color;
151
+ return /* @__PURE__ */ jsxRuntime.jsx(
152
+ "img",
153
+ {
154
+ src: `${basePath}/${archivo}`,
155
+ alt,
156
+ width: 147,
157
+ height: 111,
158
+ className: cn("h-8 w-auto select-none", className),
159
+ ...props
160
+ }
161
+ );
162
+ }
163
+ function Logo({
164
+ sobre = "oscuro",
165
+ basePath = RUTA_ASSETS,
166
+ soloIsotipo = false,
167
+ className,
168
+ ...props
169
+ }) {
170
+ return /* @__PURE__ */ jsxRuntime.jsxs("span", { className: cn("gap-xs inline-flex items-center", className), ...props, children: [
171
+ /* @__PURE__ */ jsxRuntime.jsx(
172
+ Isotipo,
173
+ {
174
+ sobre,
175
+ basePath,
176
+ alt: soloIsotipo ? naming.wordmark : "",
177
+ className: "h-7 w-auto"
178
+ }
179
+ ),
180
+ soloIsotipo ? null : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-ui font-display text-text-primary font-bold tracking-[-0.02em]", children: naming.wordmark })
181
+ ] });
182
+ }
183
+ function Mascota({
184
+ pose,
185
+ basePath = RUTA_ASSETS,
186
+ alt = "",
187
+ className,
188
+ ...props
189
+ }) {
190
+ return /* @__PURE__ */ jsxRuntime.jsx(
191
+ "img",
192
+ {
193
+ src: `${basePath}/${poses[pose]}`,
194
+ alt,
195
+ className: cn("h-auto w-full max-w-64 select-none", className),
196
+ ...props
197
+ }
198
+ );
199
+ }
200
+ function CaraDeMascota({
201
+ expresion,
202
+ basePath = RUTA_ASSETS,
203
+ alt = "",
204
+ className,
205
+ ...props
206
+ }) {
207
+ return /* @__PURE__ */ jsxRuntime.jsx(
208
+ "img",
209
+ {
210
+ src: `${basePath}/${caras[expresion]}`,
211
+ alt,
212
+ className: cn("h-auto w-full max-w-24 select-none", className),
213
+ ...props
214
+ }
215
+ );
216
+ }
217
+
218
+ exports.CaraDeMascota = CaraDeMascota;
219
+ exports.Isotipo = Isotipo;
220
+ exports.Logo = Logo;
221
+ exports.Mascota = Mascota;
222
+ exports.RUTA_ASSETS = RUTA_ASSETS;
223
+ exports.aletas = aletas;
224
+ exports.caras = caras;
225
+ exports.listaCaras = listaCaras;
226
+ exports.listaPoses = listaPoses;
227
+ exports.poses = poses;
228
+ exports.usoDeCara = usoDeCara;
@@ -0,0 +1,63 @@
1
+ import { F as Fondo, C as Cara, P as Pose } from '../catalogo-Du5ID-Hi.cjs';
2
+ export { A as Aleta, R as RUTA_ASSETS, a as aletas, c as caras, l as listaCaras, b as listaPoses, p as poses, u as usoDeCara } from '../catalogo-Du5ID-Hi.cjs';
3
+ import * as react from 'react';
4
+ import { ComponentPropsWithoutRef } from 'react';
5
+
6
+ type IsotipoProps = Omit<ComponentPropsWithoutRef<'img'>, 'src' | 'alt'> & {
7
+ /**
8
+ * Sobre qué fondo se monta. Es obligatorio decidirlo, aunque tenga default:
9
+ * el cuerpo de la aleta es casi negro, así que la variante de dos azules
10
+ * desaparece sobre abismo. Al ser una prop, la regla deja de ser algo que
11
+ * recordar.
12
+ */
13
+ sobre?: Fondo | undefined;
14
+ basePath?: string | undefined;
15
+ /** Texto alternativo. Vacío cuando el isotipo acompaña a un texto que ya lo nombra. */
16
+ alt?: string | undefined;
17
+ };
18
+ declare function Isotipo({ sobre, basePath, alt, className, ...props }: IsotipoProps): react.JSX.Element;
19
+
20
+ type LogoProps = Omit<ComponentPropsWithoutRef<'span'>, 'children'> & {
21
+ sobre?: Fondo | undefined;
22
+ basePath?: string | undefined;
23
+ /** Oculta el wordmark y deja solo la aleta, para barras muy estrechas. */
24
+ soloIsotipo?: boolean | undefined;
25
+ };
26
+ /**
27
+ * El wordmark sale de `naming.wordmark`, no de una cadena escrita a mano, y
28
+ * siempre dice «Eduardo Álvarez». La mascota se llama Tiburoncín y no aparece
29
+ * escrita dentro del logo: no hay ninguna prop que permita cambiar el texto.
30
+ *
31
+ * Cuando se oculta el wordmark, el nombre sigue llegando al lector de pantalla
32
+ * por el `alt` del isotipo. Un logo sin nombre accesible es un logo invisible.
33
+ */
34
+ declare function Logo({ sobre, basePath, soloIsotipo, className, ...props }: LogoProps): react.JSX.Element;
35
+
36
+ type Base = Omit<ComponentPropsWithoutRef<'img'>, 'src' | 'alt'> & {
37
+ basePath?: string | undefined;
38
+ /**
39
+ * Texto alternativo. Vacío por defecto: la mascota es ilustración y el texto
40
+ * que la acompaña ya dice lo que hay que saber. Se rellena solo cuando la
41
+ * imagen aporta información que no está escrita al lado.
42
+ */
43
+ alt?: string | undefined;
44
+ };
45
+ type MascotaProps = Base & {
46
+ pose: Pose;
47
+ };
48
+ /** Tiburoncín de cuerpo entero. */
49
+ declare function Mascota({ pose, basePath, alt, className, ...props }: MascotaProps): react.JSX.Element;
50
+ type CaraDeMascotaProps = Base & {
51
+ expresion: Cara;
52
+ };
53
+ /**
54
+ * La cabeza de Tiburoncín, con expresión.
55
+ *
56
+ * Las caras van SOLO en estados vacíos, confirmaciones, errores, progreso de
57
+ * curso y celebración. Nunca en hero, precios, servicios, contacto ni CV. Por
58
+ * eso `EmptyState` recibe una cara y `PageHeader` no: la regla no está escrita
59
+ * en una guía que haya que recordar, está en qué componentes la aceptan.
60
+ */
61
+ declare function CaraDeMascota({ expresion, basePath, alt, className, ...props }: CaraDeMascotaProps): react.JSX.Element;
62
+
63
+ export { Cara, CaraDeMascota, type CaraDeMascotaProps, Fondo, Isotipo, type IsotipoProps, Logo, type LogoProps, Mascota, type MascotaProps, Pose };
@@ -0,0 +1,63 @@
1
+ import { F as Fondo, C as Cara, P as Pose } from '../catalogo-Du5ID-Hi.js';
2
+ export { A as Aleta, R as RUTA_ASSETS, a as aletas, c as caras, l as listaCaras, b as listaPoses, p as poses, u as usoDeCara } from '../catalogo-Du5ID-Hi.js';
3
+ import * as react from 'react';
4
+ import { ComponentPropsWithoutRef } from 'react';
5
+
6
+ type IsotipoProps = Omit<ComponentPropsWithoutRef<'img'>, 'src' | 'alt'> & {
7
+ /**
8
+ * Sobre qué fondo se monta. Es obligatorio decidirlo, aunque tenga default:
9
+ * el cuerpo de la aleta es casi negro, así que la variante de dos azules
10
+ * desaparece sobre abismo. Al ser una prop, la regla deja de ser algo que
11
+ * recordar.
12
+ */
13
+ sobre?: Fondo | undefined;
14
+ basePath?: string | undefined;
15
+ /** Texto alternativo. Vacío cuando el isotipo acompaña a un texto que ya lo nombra. */
16
+ alt?: string | undefined;
17
+ };
18
+ declare function Isotipo({ sobre, basePath, alt, className, ...props }: IsotipoProps): react.JSX.Element;
19
+
20
+ type LogoProps = Omit<ComponentPropsWithoutRef<'span'>, 'children'> & {
21
+ sobre?: Fondo | undefined;
22
+ basePath?: string | undefined;
23
+ /** Oculta el wordmark y deja solo la aleta, para barras muy estrechas. */
24
+ soloIsotipo?: boolean | undefined;
25
+ };
26
+ /**
27
+ * El wordmark sale de `naming.wordmark`, no de una cadena escrita a mano, y
28
+ * siempre dice «Eduardo Álvarez». La mascota se llama Tiburoncín y no aparece
29
+ * escrita dentro del logo: no hay ninguna prop que permita cambiar el texto.
30
+ *
31
+ * Cuando se oculta el wordmark, el nombre sigue llegando al lector de pantalla
32
+ * por el `alt` del isotipo. Un logo sin nombre accesible es un logo invisible.
33
+ */
34
+ declare function Logo({ sobre, basePath, soloIsotipo, className, ...props }: LogoProps): react.JSX.Element;
35
+
36
+ type Base = Omit<ComponentPropsWithoutRef<'img'>, 'src' | 'alt'> & {
37
+ basePath?: string | undefined;
38
+ /**
39
+ * Texto alternativo. Vacío por defecto: la mascota es ilustración y el texto
40
+ * que la acompaña ya dice lo que hay que saber. Se rellena solo cuando la
41
+ * imagen aporta información que no está escrita al lado.
42
+ */
43
+ alt?: string | undefined;
44
+ };
45
+ type MascotaProps = Base & {
46
+ pose: Pose;
47
+ };
48
+ /** Tiburoncín de cuerpo entero. */
49
+ declare function Mascota({ pose, basePath, alt, className, ...props }: MascotaProps): react.JSX.Element;
50
+ type CaraDeMascotaProps = Base & {
51
+ expresion: Cara;
52
+ };
53
+ /**
54
+ * La cabeza de Tiburoncín, con expresión.
55
+ *
56
+ * Las caras van SOLO en estados vacíos, confirmaciones, errores, progreso de
57
+ * curso y celebración. Nunca en hero, precios, servicios, contacto ni CV. Por
58
+ * eso `EmptyState` recibe una cara y `PageHeader` no: la regla no está escrita
59
+ * en una guía que haya que recordar, está en qué componentes la aceptan.
60
+ */
61
+ declare function CaraDeMascota({ expresion, basePath, alt, className, ...props }: CaraDeMascotaProps): react.JSX.Element;
62
+
63
+ export { Cara, CaraDeMascota, type CaraDeMascotaProps, Fondo, Isotipo, type IsotipoProps, Logo, type LogoProps, Mascota, type MascotaProps, Pose };
@@ -0,0 +1,3 @@
1
+ export { CaraDeMascota, Isotipo, Logo, Mascota } from '../chunk-ZL5X6XO7.js';
2
+ export { RUTA_ASSETS, aletas, caras, listaCaras, listaPoses, poses, usoDeCara } from '../chunk-E3OMP2DL.js';
3
+ import '../chunk-DHF63QNM.js';
@@ -0,0 +1,77 @@
1
+ /**
2
+ * El catálogo de la marca: qué piezas de Tiburoncín existen y cómo se llama su
3
+ * archivo. Datos puros, sin React, para que también lo puedan leer las
4
+ * plantillas de OG y cualquier script.
5
+ *
6
+ * Añadir una pieza nueva es soltar el PNG en `assets/brand/` y añadir una línea
7
+ * aquí. El tipo se actualiza solo y el autocompletado la ofrece de inmediato.
8
+ */
9
+ /**
10
+ * Las caras. Solo se usan en estados vacíos, confirmaciones, errores, progreso
11
+ * de curso y celebración — nunca en hero, precios, servicios, contacto ni CV.
12
+ * Por eso `EmptyState` recibe una cara y `PageHeader` no.
13
+ */
14
+ declare const caras: {
15
+ readonly annoyed: "face-annoyed.png";
16
+ readonly confused: "face-confused.png";
17
+ readonly hearts: "face-hearts.png";
18
+ readonly laughing: "face-laughing.png";
19
+ readonly shades: "face-shades.png";
20
+ readonly waiting: "face-waiting.png";
21
+ readonly wink: "face-wink.png";
22
+ };
23
+ /** Poses de cuerpo entero. */
24
+ declare const poses: {
25
+ readonly desk: "pose-desk.png";
26
+ readonly 'laptop-coffee': "pose-laptop-coffee.png";
27
+ readonly peek: "pose-peek.png";
28
+ readonly surf: "pose-surf.png";
29
+ };
30
+ /**
31
+ * La aleta, en sus dos variantes.
32
+ *
33
+ * El cuerpo de la aleta es casi negro, así que sobre fondo oscuro la variante de
34
+ * dos azules desaparece. `espuma` es la silueta a una tinta —el 94 % de sus
35
+ * píxeles son `#EDF4F3`, o sea el token espuma— y es la que se ve sobre abismo.
36
+ */
37
+ declare const aletas: {
38
+ /** Dos azules. Para fondos claros. */
39
+ readonly color: "fin.png";
40
+ /** Silueta a una tinta. Para fondos oscuros. */
41
+ readonly espuma: "fin-foam.png";
42
+ };
43
+ /**
44
+ * El uso asignado de cada cara, del inventario del manual.
45
+ *
46
+ * No es documentación suelta: es la parte del contrato de humor que se puede
47
+ * escribir como dato. El manual asigna una situación a cada cara, y sin esto la
48
+ * elección se hacía a ojo en cada sitio de uso — que es como `annoyed` termina
49
+ * en una confirmación y `hearts` en un error.
50
+ *
51
+ * Falta una: el manual lista ocho caras y `head-5` (sorpresa · confirmación
52
+ * destructiva) no tiene PNG en `assets/brand/`. Cuando llegue, entra aquí y en
53
+ * `caras` a la vez.
54
+ */
55
+ declare const usoDeCara: {
56
+ readonly wink: "Formularios, nota al pie amable";
57
+ readonly waiting: "Sin resultados, estado de espera";
58
+ readonly laughing: "Éxito, suscripción confirmada";
59
+ readonly shades: "Módulo o curso completado";
60
+ readonly hearts: "Agradecimiento, OG de artículo";
61
+ readonly confused: "404, página no encontrada";
62
+ readonly annoyed: "Error del servidor, fallo de build";
63
+ };
64
+ type Cara = keyof typeof caras;
65
+ type Pose = keyof typeof poses;
66
+ type Aleta = keyof typeof aletas;
67
+ /** Sobre qué fondo se va a montar la pieza. Decide qué aleta se usa. */
68
+ type Fondo = 'oscuro' | 'claro';
69
+ /**
70
+ * Dónde se sirven los PNG. Por defecto `/brand`, que es donde ya viven en los
71
+ * cinco proyectos (`public/brand/`), así que no hay nada que configurar.
72
+ */
73
+ declare const RUTA_ASSETS = "/brand";
74
+ declare const listaCaras: readonly Cara[];
75
+ declare const listaPoses: readonly Pose[];
76
+
77
+ export { type Aleta as A, type Cara as C, type Fondo as F, type Pose as P, RUTA_ASSETS as R, aletas as a, listaPoses as b, caras as c, listaCaras as l, poses as p, usoDeCara as u };
@@ -0,0 +1,77 @@
1
+ /**
2
+ * El catálogo de la marca: qué piezas de Tiburoncín existen y cómo se llama su
3
+ * archivo. Datos puros, sin React, para que también lo puedan leer las
4
+ * plantillas de OG y cualquier script.
5
+ *
6
+ * Añadir una pieza nueva es soltar el PNG en `assets/brand/` y añadir una línea
7
+ * aquí. El tipo se actualiza solo y el autocompletado la ofrece de inmediato.
8
+ */
9
+ /**
10
+ * Las caras. Solo se usan en estados vacíos, confirmaciones, errores, progreso
11
+ * de curso y celebración — nunca en hero, precios, servicios, contacto ni CV.
12
+ * Por eso `EmptyState` recibe una cara y `PageHeader` no.
13
+ */
14
+ declare const caras: {
15
+ readonly annoyed: "face-annoyed.png";
16
+ readonly confused: "face-confused.png";
17
+ readonly hearts: "face-hearts.png";
18
+ readonly laughing: "face-laughing.png";
19
+ readonly shades: "face-shades.png";
20
+ readonly waiting: "face-waiting.png";
21
+ readonly wink: "face-wink.png";
22
+ };
23
+ /** Poses de cuerpo entero. */
24
+ declare const poses: {
25
+ readonly desk: "pose-desk.png";
26
+ readonly 'laptop-coffee': "pose-laptop-coffee.png";
27
+ readonly peek: "pose-peek.png";
28
+ readonly surf: "pose-surf.png";
29
+ };
30
+ /**
31
+ * La aleta, en sus dos variantes.
32
+ *
33
+ * El cuerpo de la aleta es casi negro, así que sobre fondo oscuro la variante de
34
+ * dos azules desaparece. `espuma` es la silueta a una tinta —el 94 % de sus
35
+ * píxeles son `#EDF4F3`, o sea el token espuma— y es la que se ve sobre abismo.
36
+ */
37
+ declare const aletas: {
38
+ /** Dos azules. Para fondos claros. */
39
+ readonly color: "fin.png";
40
+ /** Silueta a una tinta. Para fondos oscuros. */
41
+ readonly espuma: "fin-foam.png";
42
+ };
43
+ /**
44
+ * El uso asignado de cada cara, del inventario del manual.
45
+ *
46
+ * No es documentación suelta: es la parte del contrato de humor que se puede
47
+ * escribir como dato. El manual asigna una situación a cada cara, y sin esto la
48
+ * elección se hacía a ojo en cada sitio de uso — que es como `annoyed` termina
49
+ * en una confirmación y `hearts` en un error.
50
+ *
51
+ * Falta una: el manual lista ocho caras y `head-5` (sorpresa · confirmación
52
+ * destructiva) no tiene PNG en `assets/brand/`. Cuando llegue, entra aquí y en
53
+ * `caras` a la vez.
54
+ */
55
+ declare const usoDeCara: {
56
+ readonly wink: "Formularios, nota al pie amable";
57
+ readonly waiting: "Sin resultados, estado de espera";
58
+ readonly laughing: "Éxito, suscripción confirmada";
59
+ readonly shades: "Módulo o curso completado";
60
+ readonly hearts: "Agradecimiento, OG de artículo";
61
+ readonly confused: "404, página no encontrada";
62
+ readonly annoyed: "Error del servidor, fallo de build";
63
+ };
64
+ type Cara = keyof typeof caras;
65
+ type Pose = keyof typeof poses;
66
+ type Aleta = keyof typeof aletas;
67
+ /** Sobre qué fondo se va a montar la pieza. Decide qué aleta se usa. */
68
+ type Fondo = 'oscuro' | 'claro';
69
+ /**
70
+ * Dónde se sirven los PNG. Por defecto `/brand`, que es donde ya viven en los
71
+ * cinco proyectos (`public/brand/`), así que no hay nada que configurar.
72
+ */
73
+ declare const RUTA_ASSETS = "/brand";
74
+ declare const listaCaras: readonly Cara[];
75
+ declare const listaPoses: readonly Pose[];
76
+
77
+ export { type Aleta as A, type Cara as C, type Fondo as F, type Pose as P, RUTA_ASSETS as R, aletas as a, listaPoses as b, caras as c, listaCaras as l, poses as p, usoDeCara as u };
@@ -0,0 +1,22 @@
1
+ import { naming, tagline, motion, shadow, sintaxis, gradient, size, spacing, control, radius, limits, typeScale, fonts, brand, colors } from './chunk-DHF63QNM.js';
2
+
3
+ // src/tokens/index.ts
4
+ var tokens = {
5
+ colors,
6
+ brand,
7
+ fonts,
8
+ typeScale,
9
+ limits,
10
+ radius,
11
+ control,
12
+ spacing,
13
+ size,
14
+ gradient,
15
+ sintaxis,
16
+ shadow,
17
+ motion,
18
+ tagline,
19
+ naming
20
+ };
21
+
22
+ export { tokens };