@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.
- package/CHANGELOG.md +55 -0
- package/LICENSE +21 -0
- package/README.md +520 -0
- package/assets/brand/face-annoyed.png +0 -0
- package/assets/brand/face-confused.png +0 -0
- package/assets/brand/face-hearts.png +0 -0
- package/assets/brand/face-laughing.png +0 -0
- package/assets/brand/face-shades.png +0 -0
- package/assets/brand/face-waiting.png +0 -0
- package/assets/brand/face-wink.png +0 -0
- package/assets/brand/fin-foam.png +0 -0
- package/assets/brand/fin.png +0 -0
- package/assets/brand/pose-desk.png +0 -0
- package/assets/brand/pose-laptop-coffee.png +0 -0
- package/assets/brand/pose-peek.png +0 -0
- package/assets/brand/pose-surf.png +0 -0
- package/dist/brand/index.cjs +228 -0
- package/dist/brand/index.d.cts +63 -0
- package/dist/brand/index.d.ts +63 -0
- package/dist/brand/index.js +3 -0
- package/dist/catalogo-Du5ID-Hi.d.cts +77 -0
- package/dist/catalogo-Du5ID-Hi.d.ts +77 -0
- package/dist/chunk-22OXRTAL.js +22 -0
- package/dist/chunk-DHF63QNM.js +231 -0
- package/dist/chunk-E3OMP2DL.js +36 -0
- package/dist/chunk-ZL5X6XO7.js +102 -0
- package/dist/index.cjs +3191 -0
- package/dist/index.d.cts +1024 -0
- package/dist/index.d.ts +1024 -0
- package/dist/index.js +2624 -0
- package/dist/og/index.cjs +322 -0
- package/dist/og/index.d.cts +164 -0
- package/dist/og/index.d.ts +164 -0
- package/dist/og/index.js +242 -0
- package/dist/shiki/index.cjs +127 -0
- package/dist/shiki/index.d.cts +16 -0
- package/dist/shiki/index.d.ts +16 -0
- package/dist/shiki/index.js +95 -0
- package/dist/tokens/index.cjs +263 -0
- package/dist/tokens/index.d.cts +623 -0
- package/dist/tokens/index.d.ts +623 -0
- package/dist/tokens/index.js +2 -0
- package/dist/tokens/theme.css +266 -0
- package/package.json +128 -0
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __export = (target, all) => {
|
|
3
|
+
for (var name in all)
|
|
4
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
5
|
+
};
|
|
6
|
+
|
|
7
|
+
// src/tokens/tokens.ts
|
|
8
|
+
var dark = {
|
|
9
|
+
background: "#091319",
|
|
10
|
+
// abismo · fondo de página
|
|
11
|
+
surface: "#10202B",
|
|
12
|
+
// fosa · tarjetas y paneles
|
|
13
|
+
surfaceRaised: "#17303E",
|
|
14
|
+
// corriente · menús, tabs activos
|
|
15
|
+
border: "#22414F",
|
|
16
|
+
// bordes de control
|
|
17
|
+
hairline: "#1E3441",
|
|
18
|
+
// divisiones sutiles
|
|
19
|
+
hairlineHover: "#2C4D5D",
|
|
20
|
+
// hairline en hover de tarjeta
|
|
21
|
+
textPrimary: "#EDF4F3",
|
|
22
|
+
// espuma 16.84:1
|
|
23
|
+
textSecondary: "#A7BCC4",
|
|
24
|
+
// bruma 9.50:1
|
|
25
|
+
textMuted: "#71919C",
|
|
26
|
+
// plancton 5.57:1 nunca bajo 13px
|
|
27
|
+
accent: "#35D6C0",
|
|
28
|
+
// bioluz 10.31:1 interactivo
|
|
29
|
+
accentHover: "#5FE3D1",
|
|
30
|
+
accentOn: "#06171A",
|
|
31
|
+
// tinta sobre bioluz
|
|
32
|
+
warm: "#F2A65A",
|
|
33
|
+
// arena 9.28:1 humano y conversión
|
|
34
|
+
warmHover: "#F7BB7D",
|
|
35
|
+
warmOn: "#2A1605",
|
|
36
|
+
// tinta sobre arena
|
|
37
|
+
success: "#4FB477",
|
|
38
|
+
warning: "#E8A33D",
|
|
39
|
+
error: "#E15757"
|
|
40
|
+
// 4.51:1 sobre surface
|
|
41
|
+
};
|
|
42
|
+
var light = {
|
|
43
|
+
background: "#F6F2EA",
|
|
44
|
+
// papel
|
|
45
|
+
surface: "#FFFFFF",
|
|
46
|
+
surfaceRaised: "#EFE9DE",
|
|
47
|
+
border: "#E6DFD2",
|
|
48
|
+
hairline: "#EBE6DC",
|
|
49
|
+
hairlineHover: "#D3C8B2",
|
|
50
|
+
// hairline en hover de tarjeta
|
|
51
|
+
textPrimary: "#0B1524",
|
|
52
|
+
// 16.40:1
|
|
53
|
+
textSecondary: "#3D4B58",
|
|
54
|
+
textMuted: "#626A75",
|
|
55
|
+
// 4.53:1 sobre surfaceRaised
|
|
56
|
+
accent: "#0D7C6F",
|
|
57
|
+
// bioluz oscura 4.55:1
|
|
58
|
+
accentHover: "#0C7466",
|
|
59
|
+
accentOn: "#FFFFFF",
|
|
60
|
+
warm: "#A65B27",
|
|
61
|
+
// arena oscura 4.54:1
|
|
62
|
+
warmHover: "#96511F",
|
|
63
|
+
warmOn: "#FFF7EE",
|
|
64
|
+
success: "#0F6B52",
|
|
65
|
+
warning: "#8D6111",
|
|
66
|
+
// 4.51:1 sobre surfaceRaised
|
|
67
|
+
error: "#C0392B"
|
|
68
|
+
};
|
|
69
|
+
var colors = { dark, light };
|
|
70
|
+
var brand = {
|
|
71
|
+
/** Cuerpo de la mascota. 4.22:1 → SOLO relleno, NUNCA texto. */
|
|
72
|
+
body: "#3E7CB1",
|
|
73
|
+
/** Patrón de manchas. */
|
|
74
|
+
spots: "#C2D7E7",
|
|
75
|
+
/** Casco · contorno y fondo de bloques de código. */
|
|
76
|
+
hull: "#0B1524"
|
|
77
|
+
};
|
|
78
|
+
var fonts = {
|
|
79
|
+
/** SOLO titulares y números grandes. Nunca cuerpo. */
|
|
80
|
+
display: '"Bricolage Grotesque", ui-sans-serif, system-ui, sans-serif',
|
|
81
|
+
/** Cuerpo e interfaz. */
|
|
82
|
+
sans: '"Geist", ui-sans-serif, system-ui, sans-serif',
|
|
83
|
+
/** Código, rutas, etiquetas, metadatos, firma CLI. */
|
|
84
|
+
mono: '"JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, monospace'
|
|
85
|
+
};
|
|
86
|
+
var typeScale = {
|
|
87
|
+
display: { family: "display", size: 76, lineHeight: 0.96, weight: 800, tracking: "-0.035em" },
|
|
88
|
+
/** Métricas grandes. Números, no prosa: interlineado 1 y sin descendentes. */
|
|
89
|
+
stat: { family: "display", size: 46, lineHeight: 1, weight: 800, tracking: "-0.035em" },
|
|
90
|
+
h1: { family: "display", size: 44, lineHeight: 1.05, weight: 700, tracking: "-0.03em" },
|
|
91
|
+
h2: { family: "display", size: 30, lineHeight: 1.1, weight: 600, tracking: "-0.02em" },
|
|
92
|
+
h3: { family: "display", size: 25, lineHeight: 1.15, weight: 600, tracking: "-0.02em" },
|
|
93
|
+
body: { family: "sans", size: 18, lineHeight: 1.75, weight: 400 },
|
|
94
|
+
/**
|
|
95
|
+
* 17px. El botón grande y la bajada de las páginas internas.
|
|
96
|
+
*
|
|
97
|
+
* Entra como escalón propio porque el documento lo usa DOS veces y en piezas
|
|
98
|
+
* distintas: «lg 15px 30px r12» con texto de 17, y «h1 44/700 · bajada 17px ·
|
|
99
|
+
* párrafo de contexto 15px». Un solo uso no habría justificado partir la
|
|
100
|
+
* distancia entre `ui` (15) y `body` (18); dos sí.
|
|
101
|
+
*/
|
|
102
|
+
lead: { family: "sans", size: 17, lineHeight: 1.5, weight: 400 },
|
|
103
|
+
ui: { family: "sans", size: 15, lineHeight: 1.6, weight: 400 },
|
|
104
|
+
label: { family: "sans", size: 13, lineHeight: 1.5, weight: 500 },
|
|
105
|
+
/**
|
|
106
|
+
* La escala de las etiquetas de estado: sans 12.5/500, cuadrada.
|
|
107
|
+
*
|
|
108
|
+
* Es medio píxel por debajo de `label`, y esta vez el medio píxel sí importa:
|
|
109
|
+
* una etiqueta de estado va dentro de una tabla o al lado de un título, y a 13
|
|
110
|
+
* competía con el texto que acompaña. El documento la da en 12.5 y se ve.
|
|
111
|
+
*/
|
|
112
|
+
tag: { family: "sans", size: 12.5, lineHeight: 1.4, weight: 500 },
|
|
113
|
+
/**
|
|
114
|
+
* La escala de categoría y métrica: mono 11.5.
|
|
115
|
+
*
|
|
116
|
+
* Rompe el suelo de `limits.minScreenPx`, y es a propósito. Ese suelo protege
|
|
117
|
+
* al TEXTO —lo que se lee en una frase—, y una píldora de una palabra no es
|
|
118
|
+
* texto corrido: es una marca. El contraste sigue medido y pasa AA (plancton
|
|
119
|
+
* 5.57:1 sobre abismo), que es la parte que no se negocia.
|
|
120
|
+
*
|
|
121
|
+
* A 13 las tres familias de etiqueta salían del tamaño de un botón pequeño y
|
|
122
|
+
* pesaban más que el título que acompañan. Ver `docs/decisiones.md`.
|
|
123
|
+
*/
|
|
124
|
+
chip: { family: "mono", size: 11.5, lineHeight: 1.4, weight: 400 },
|
|
125
|
+
/**
|
|
126
|
+
* Mono SIN transformar: fechas, rutas, versiones, nombres de archivo, la firma
|
|
127
|
+
* del footer y las métricas de etiqueta. Es la mayoría del mono del sistema.
|
|
128
|
+
*
|
|
129
|
+
* Existe porque `eyebrow` lleva `uppercase` de fábrica y no es una preferencia
|
|
130
|
+
* que se pueda apagar: es la escala del eyebrow. Un `18 ago 2026` en versalitas
|
|
131
|
+
* o un `pose-laptop-coffee.png` en mayúsculas están mal, y sin este escalón la
|
|
132
|
+
* única salida era un `normal-case` en cada sitio de uso.
|
|
133
|
+
*
|
|
134
|
+
* El documento dice 12.5. Son 13 por la misma razón por la que `textMuted` se
|
|
135
|
+
* corrigió: `limits.minScreenPx` es 13 y plancton «nunca bajo 13px». Esta
|
|
136
|
+
* escala es justo donde se escriben las metas en muted, así que ponerla en
|
|
137
|
+
* 12.5 habría dejado ilegible su uso más común por medio píxel.
|
|
138
|
+
*/
|
|
139
|
+
meta: { family: "mono", size: 13, lineHeight: 1.6, weight: 400 },
|
|
140
|
+
eyebrow: { family: "mono", size: 12, tracking: "0.12em", transform: "uppercase" }
|
|
141
|
+
};
|
|
142
|
+
var limits = {
|
|
143
|
+
/** Mínimo absoluto en pantalla. */
|
|
144
|
+
minScreenPx: 13,
|
|
145
|
+
/** Mínimo absoluto impreso. */
|
|
146
|
+
minPrintPt: 12,
|
|
147
|
+
/** Medida máxima de cuerpo. */
|
|
148
|
+
measure: "68ch"
|
|
149
|
+
};
|
|
150
|
+
var radius = {
|
|
151
|
+
chip: 6,
|
|
152
|
+
control: 10,
|
|
153
|
+
card: 14,
|
|
154
|
+
panel: 16,
|
|
155
|
+
pill: 999
|
|
156
|
+
};
|
|
157
|
+
var control = {
|
|
158
|
+
sm: 14,
|
|
159
|
+
md: 22,
|
|
160
|
+
lg: 30,
|
|
161
|
+
/** Botón de icono: cuadrado, sin texto. */
|
|
162
|
+
icon: 42
|
|
163
|
+
};
|
|
164
|
+
var spacing = {
|
|
165
|
+
xs: 8,
|
|
166
|
+
sm: 12,
|
|
167
|
+
md: 16,
|
|
168
|
+
lg: 26,
|
|
169
|
+
xl: 40,
|
|
170
|
+
section: 96
|
|
171
|
+
};
|
|
172
|
+
var size = {
|
|
173
|
+
/** Alto de la barra de navegación. */
|
|
174
|
+
nav: 64,
|
|
175
|
+
/** Ancho de columna de lectura. */
|
|
176
|
+
content: 760,
|
|
177
|
+
/** Ancho máximo de página. */
|
|
178
|
+
wide: 1180
|
|
179
|
+
};
|
|
180
|
+
var sintaxis = {
|
|
181
|
+
/** El casco. Es el fondo del bloque en los dos modos. */
|
|
182
|
+
fondo: brand.hull,
|
|
183
|
+
/** Identificadores, funciones, tipos, variables. */
|
|
184
|
+
identificador: dark.textPrimary,
|
|
185
|
+
/** Cadenas, números, booleanos, null. */
|
|
186
|
+
literal: dark.accent,
|
|
187
|
+
/** Palabras clave, control de flujo, `import`, `this`. */
|
|
188
|
+
palabraClave: dark.warm,
|
|
189
|
+
/** Comentarios y puntuación. */
|
|
190
|
+
comentario: dark.textMuted,
|
|
191
|
+
/** `markup.deleted`, `invalid`. */
|
|
192
|
+
invalido: dark.error
|
|
193
|
+
};
|
|
194
|
+
var profundo = "#0D2129";
|
|
195
|
+
var gradient = {
|
|
196
|
+
dark: {
|
|
197
|
+
hero: `linear-gradient(160deg, ${dark.background} 60%, ${profundo} 100%)`,
|
|
198
|
+
seccion: `linear-gradient(150deg, ${dark.surface} 0%, ${profundo} 100%)`,
|
|
199
|
+
/** El de la plantilla OG de artículo. 145°, del documento. */
|
|
200
|
+
og: `linear-gradient(145deg, ${dark.background} 55%, ${profundo} 100%)`
|
|
201
|
+
},
|
|
202
|
+
light: {
|
|
203
|
+
hero: `linear-gradient(160deg, ${light.background} 60%, ${light.surfaceRaised} 100%)`,
|
|
204
|
+
seccion: `linear-gradient(150deg, ${light.surface} 0%, ${light.surfaceRaised} 100%)`,
|
|
205
|
+
og: `linear-gradient(145deg, ${light.background} 55%, ${light.surfaceRaised} 100%)`
|
|
206
|
+
}
|
|
207
|
+
};
|
|
208
|
+
var shadow = {
|
|
209
|
+
standard: "0 1px 2px rgba(0, 0, 0, 0.35)"
|
|
210
|
+
};
|
|
211
|
+
var motion = {
|
|
212
|
+
duration: "150ms",
|
|
213
|
+
easing: "ease-out",
|
|
214
|
+
properties: "color, background-color, border-color, fill, stroke"
|
|
215
|
+
};
|
|
216
|
+
var tagline = {
|
|
217
|
+
/** Hero. */
|
|
218
|
+
largo: "Ayudo a equipos de ingenier\xEDa a escalar con criterio",
|
|
219
|
+
/** Header, una línea. */
|
|
220
|
+
corto: "Ayudo a equipos a escalar con criterio",
|
|
221
|
+
/** LinkedIn. */
|
|
222
|
+
en: "Helping engineering teams scale with judgment"
|
|
223
|
+
};
|
|
224
|
+
var naming = {
|
|
225
|
+
wordmark: "Eduardo \xC1lvarez",
|
|
226
|
+
mascot: "Tiburonc\xEDn",
|
|
227
|
+
/** El dominio, para la firma CLI del footer: `$ cd ~/eduardoalvarez.dev/2026`. */
|
|
228
|
+
domain: "eduardoalvarez.dev"
|
|
229
|
+
};
|
|
230
|
+
|
|
231
|
+
export { __export, brand, colors, control, dark, fonts, gradient, light, limits, motion, naming, radius, shadow, sintaxis, size, spacing, tagline, typeScale };
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
// src/brand/catalogo.ts
|
|
2
|
+
var caras = {
|
|
3
|
+
annoyed: "face-annoyed.png",
|
|
4
|
+
confused: "face-confused.png",
|
|
5
|
+
hearts: "face-hearts.png",
|
|
6
|
+
laughing: "face-laughing.png",
|
|
7
|
+
shades: "face-shades.png",
|
|
8
|
+
waiting: "face-waiting.png",
|
|
9
|
+
wink: "face-wink.png"
|
|
10
|
+
};
|
|
11
|
+
var poses = {
|
|
12
|
+
desk: "pose-desk.png",
|
|
13
|
+
"laptop-coffee": "pose-laptop-coffee.png",
|
|
14
|
+
peek: "pose-peek.png",
|
|
15
|
+
surf: "pose-surf.png"
|
|
16
|
+
};
|
|
17
|
+
var aletas = {
|
|
18
|
+
/** Dos azules. Para fondos claros. */
|
|
19
|
+
color: "fin.png",
|
|
20
|
+
/** Silueta a una tinta. Para fondos oscuros. */
|
|
21
|
+
espuma: "fin-foam.png"
|
|
22
|
+
};
|
|
23
|
+
var usoDeCara = {
|
|
24
|
+
wink: "Formularios, nota al pie amable",
|
|
25
|
+
waiting: "Sin resultados, estado de espera",
|
|
26
|
+
laughing: "\xC9xito, suscripci\xF3n confirmada",
|
|
27
|
+
shades: "M\xF3dulo o curso completado",
|
|
28
|
+
hearts: "Agradecimiento, OG de art\xEDculo",
|
|
29
|
+
confused: "404, p\xE1gina no encontrada",
|
|
30
|
+
annoyed: "Error del servidor, fallo de build"
|
|
31
|
+
};
|
|
32
|
+
var RUTA_ASSETS = "/brand";
|
|
33
|
+
var listaCaras = Object.keys(caras);
|
|
34
|
+
var listaPoses = Object.keys(poses);
|
|
35
|
+
|
|
36
|
+
export { RUTA_ASSETS, aletas, caras, listaCaras, listaPoses, poses, usoDeCara };
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { aletas, RUTA_ASSETS, poses, caras } from './chunk-E3OMP2DL.js';
|
|
2
|
+
import { control, spacing, radius, typeScale, naming } from './chunk-DHF63QNM.js';
|
|
3
|
+
import { clsx } from 'clsx';
|
|
4
|
+
import { extendTailwindMerge } from 'tailwind-merge';
|
|
5
|
+
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
6
|
+
|
|
7
|
+
var escalas = Object.keys(typeScale);
|
|
8
|
+
var radios = Object.keys(radius);
|
|
9
|
+
var espacios = Object.keys(spacing);
|
|
10
|
+
var controles = Object.keys(control).map((nombre) => `control-${nombre}`);
|
|
11
|
+
var twMerge = extendTailwindMerge({
|
|
12
|
+
extend: {
|
|
13
|
+
classGroups: {
|
|
14
|
+
"font-size": [{ text: escalas }],
|
|
15
|
+
rounded: [{ rounded: radios }],
|
|
16
|
+
p: [{ p: espacios }],
|
|
17
|
+
px: [{ px: [...espacios, ...controles] }],
|
|
18
|
+
py: [{ py: espacios }],
|
|
19
|
+
gap: [{ gap: espacios }],
|
|
20
|
+
size: [{ size: controles }]
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
function cn(...inputs) {
|
|
25
|
+
return twMerge(clsx(inputs));
|
|
26
|
+
}
|
|
27
|
+
function Isotipo({
|
|
28
|
+
sobre = "oscuro",
|
|
29
|
+
basePath = RUTA_ASSETS,
|
|
30
|
+
alt = "",
|
|
31
|
+
className,
|
|
32
|
+
...props
|
|
33
|
+
}) {
|
|
34
|
+
const archivo = sobre === "oscuro" ? aletas.espuma : aletas.color;
|
|
35
|
+
return /* @__PURE__ */ jsx(
|
|
36
|
+
"img",
|
|
37
|
+
{
|
|
38
|
+
src: `${basePath}/${archivo}`,
|
|
39
|
+
alt,
|
|
40
|
+
width: 147,
|
|
41
|
+
height: 111,
|
|
42
|
+
className: cn("h-8 w-auto select-none", className),
|
|
43
|
+
...props
|
|
44
|
+
}
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
function Logo({
|
|
48
|
+
sobre = "oscuro",
|
|
49
|
+
basePath = RUTA_ASSETS,
|
|
50
|
+
soloIsotipo = false,
|
|
51
|
+
className,
|
|
52
|
+
...props
|
|
53
|
+
}) {
|
|
54
|
+
return /* @__PURE__ */ jsxs("span", { className: cn("gap-xs inline-flex items-center", className), ...props, children: [
|
|
55
|
+
/* @__PURE__ */ jsx(
|
|
56
|
+
Isotipo,
|
|
57
|
+
{
|
|
58
|
+
sobre,
|
|
59
|
+
basePath,
|
|
60
|
+
alt: soloIsotipo ? naming.wordmark : "",
|
|
61
|
+
className: "h-7 w-auto"
|
|
62
|
+
}
|
|
63
|
+
),
|
|
64
|
+
soloIsotipo ? null : /* @__PURE__ */ jsx("span", { className: "text-ui font-display text-text-primary font-bold tracking-[-0.02em]", children: naming.wordmark })
|
|
65
|
+
] });
|
|
66
|
+
}
|
|
67
|
+
function Mascota({
|
|
68
|
+
pose,
|
|
69
|
+
basePath = RUTA_ASSETS,
|
|
70
|
+
alt = "",
|
|
71
|
+
className,
|
|
72
|
+
...props
|
|
73
|
+
}) {
|
|
74
|
+
return /* @__PURE__ */ jsx(
|
|
75
|
+
"img",
|
|
76
|
+
{
|
|
77
|
+
src: `${basePath}/${poses[pose]}`,
|
|
78
|
+
alt,
|
|
79
|
+
className: cn("h-auto w-full max-w-64 select-none", className),
|
|
80
|
+
...props
|
|
81
|
+
}
|
|
82
|
+
);
|
|
83
|
+
}
|
|
84
|
+
function CaraDeMascota({
|
|
85
|
+
expresion,
|
|
86
|
+
basePath = RUTA_ASSETS,
|
|
87
|
+
alt = "",
|
|
88
|
+
className,
|
|
89
|
+
...props
|
|
90
|
+
}) {
|
|
91
|
+
return /* @__PURE__ */ jsx(
|
|
92
|
+
"img",
|
|
93
|
+
{
|
|
94
|
+
src: `${basePath}/${caras[expresion]}`,
|
|
95
|
+
alt,
|
|
96
|
+
className: cn("h-auto w-full max-w-24 select-none", className),
|
|
97
|
+
...props
|
|
98
|
+
}
|
|
99
|
+
);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
export { CaraDeMascota, Isotipo, Logo, Mascota, cn };
|