astra
alpha-0.1-background
alpha-0.1-dir-prefs
alpha-0.1-sec-dom
menubar-v4-safe
active-uix
morfo-runtime
morfo-driven-soma
semantuix
glm-5
main
sium-v1.0
${ noResults }
26 Commits (bf90fc62b14e98b7913f0ffdc8411779937089e7)
| Author | SHA1 | Message | Date |
|---|---|---|---|
|
|
ad26922d29 |
uix(foundation): data-ink, el contexto de tinta para marcas ajenas
El hermano de data-on, para un problema distinto: uno re-entinta un subárbol porque cambió su lienzo, este porque el contenido son marcas de otros y se pelean entre sí. Un muro de logos de clientes es el caso que todas las referencias shippean y ninguna resuelve a nivel de sistema: veinte marcas en veinte paletas gritan sobre la página, así que los catálogos retocan cada asset a mano — y por eso venden el modo oscuro como un segundo artefacto, porque un asset retocado no puede seguir a un tema. Va a la fundación y no a un componente, y eso se midió antes de elegir. Image no tiene eje de tinta, ni prop ni regla, y tampoco era su casa: es un componente con máquina de estados de carga para fotos, mientras que un logo suele ser un svg en línea. Y el mecanismo es doble — un vectorial toma la tinta por currentColor y un raster por filtro —, así que un solo eje tiene que cubrir los dos. Un primitivo Logo nuevo se descartó por lo mismo: no habría cargado más que el contexto. Sin tokens nuevos: el reposo y el realce son los que el tier semántico de la escala de opacidad ya tenía. Y el opt-out por marca vale anidado, porque hay marcas registradas que no se pueden alterar y el bloque no puede saber cuáles. Dos medias querys que importan: la transición se anula con la preferencia de movimiento reducido, y bajo colores forzados se retira el desaturado entero, porque ahí la paleta es del sistema y desaturar pelearía contra el contraste que ese modo existe para garantizar. Verificado sobre ocho marcas de anchos y colores dispares: en mono, gris al sesenta y cinco por ciento con la tinta del tema, y otra distinta en oscuro; en brand, el color propio de cada una; al pasar el puntero, color entero. Queda anotada en el generador la trampa que me costó una vuelta: renderBlock une declaraciones con un salto de línea y no añade punto y coma, así que cada entrada trae el suyo salvo la última. Escritas sin ellos, las reglas llegan a la hoja de estilo y no pintan nada. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
2 months ago |
|
|
93d18c90df |
uix(table): una tabla ancha vuelve a tener por dónde salir, y expone los tipos que exige
Dos cosas que salieron al componer la tabla de comparación de pricing, y que no son del block. La primera se ve y se mide: a 375 la tabla ocupaba 420 dentro de un contenedor de 327, y esos 93 píxeles eran inalcanzables. Sin barra, sin indicio, columnas desaparecidas. Fijar la primera columna —que funciona— no sirve de nada si no hay nada que desplazar. El envoltorio recortaba en los dos ejes: el recorte existe por el radio de las esquinas y el eje de bloque lo necesita, pero el eje en línea no, y ahí se comía contenido. Ahora el eje en línea desplaza y el de bloque sigue recortando, así que el radio se conserva y nada scrollea en vertical salvo que se pida con maxHeight, que es otra cosa. Medido después: cuatrocientos veinte sobre trescientos veinticinco, desplazable; al mover noventa y cinco la columna fijada se queda donde estaba y la última columna entra en pantalla. La demo del propio componente no cambia. La segunda es de tipos: el componente exige una instancia del motor y no la exportaba, así que cualquiera fuera de libs tenía que cruzar una frontera para tipar su propia envoltura. El guard del tier blocks lo rechazó por nombre y tenía razón: lo que se corrige es que el componente exponga lo que demanda, no que la frontera se ensanche. El guard afirma la forma con su porqué escrito y está probado por mutación: devolviendo el recorte de siempre, falla. Que sea guard y no nota importa porque el fallo era silencioso — nada peta, el contenido desaparece por el borde. Quedan registradas dos filas abiertas que no toco: la columna fijada se ancla con una propiedad física, así que en dirección derecha-izquierda se mueve con el contenido en vez de quedarse —medido, su borde se sale de la pantalla—, y eso es del eje de dirección; y el prop de la tabla no lleva parámetro de tipo, así que todo consumidor tipado castea, empezando por la demo de este mismo componente. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
2 months ago |
|
|
b92dc3bdb2 |
uix(card): el estado deshabilitado deja de pelearse con la animación por la opacidad
Salió midiendo el plan actual de pricing: la tarjeta no se atenuaba. La regla estaba escrita, el token resolvía a 0.4 sobre la propia tarjeta y el cursor de esa misma regla sí aplicaba — pero la opacidad computada seguía en uno. La culpable es su propia animación de entrada. Corre con relleno en los dos extremos y su último fotograma es opacidad uno; una animación gana a una declaración normal en la cascada, así que fijaba la propiedad para siempre. Aislado en el mismo nodo desactivando la entrada, atenúa correctamente. Llevaba ahí desde que el componente existe, invisible porque el cursor hacía parecer que el estado estaba cableado, y alcanzaba a toda Card deshabilitada del ecosistema. El arreglo es dejar de compartir la propiedad: el estado atenúa por filter, que la animación no posee. Mismo token, misma escala, ninguno nuevo, y el bloqueo del puntero en la tarjeta interactiva no se toca. El guard afirma la FORMA con su porqué escrito —que la regla usa filter y no opacity, más el bloqueo del puntero y la presencia de la animación que obliga a esa forma— y está probado por mutación: devolviendo la regla a opacity, falla; restaurada, verde. Verificado con la animación presente: la deshabilitada computa filter opacity a 0.4 y sus hermanas ninguno; en píxeles, su tinta más oscura sube a 164 frente a 139 de la normal sobre el mismo lienzo, que es justo lo que da un 0.4 sobre el fondo de página. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
2 months ago |
|
|
d61515027a |
docs(theming): el changelog vuelve a su formato — mi entrada no traía 400 líneas
Al escribir la §49 pasé prettier por el fichero y reformateó los ejemplos de código de entradas ajenas: 237 inserciones y 185 borrados de los que apenas veinte eran míos. Es justo lo que el handoff del tier advierte de los ficheros que ya venían con otro formato — formatearlos produce un diff del documento entero y sepulta el cambio real. El fichero vuelve al formato que tenía y la entrada se re-aplica sin pasar prettier. Efecto neto contra el estado anterior al commit: 43 líneas, todas de la §49. No reescribo el commit porque la rama es compartida. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
2 months ago |
|
|
d38c54fdf8 |
uix(card): el realce al puntero deja de ser rehén de `interactive`
El usuario preguntó por qué una tarjeta de plan de precios no responde al puntero. Le dije que Card no exponía estado de puntero y era falso: el realce existe desde siempre —los dos tokens están en la fundación, con reglas para ghost, outline y solid, composición con el anillo de selección para que no desaparezca al pasar el ratón, y anulación bajo reduced-motion—, pero todo colgaba de un solo attr. Y ese attr empaqueta cinco cosas: el elemento button, el evento commit-select, el cursor, la escala de pulsación, el anillo de foco y la elevación. Una tarjeta que ya contiene su propia llamada a la acción no puede tomar ese paquete: un button dentro de otro es marcado inválido y las dos activaciones se pelean por el mismo gesto. Así que la elevación era inalcanzable justo donde más se pide — planes de precio, teasers de artículo, tarjetas de testimonio. La elevación pasa a su propio eje. `interactive` lo implica, así que una tarjeta clicable no cambia en nada. Lo que el eje NO trae, a propósito: ni cursor de puntero —un puntero sobre algo que al pulsarlo no hace nada es una promesa falsa—, ni escala de pulsación, ni anillo de foco. Eso es lo que un CONTROL le debe al visitante. Sin tokens nuevos: los dos que hacían falta ya estaban. Y el attr es de envoltorio visual, no contrato — lo estampa el componente de eidos y lo guarda la mitad de presencia, que gana su primera fila de card; no el morfo, porque declarar ahí lo que sólo lee una capa es justo lo que la doctrina del 15 de agosto dejó dicho. El eidos-lint lo clasifica como eidos-only, 0 inválidos. Medido en navegador sobre estilos computados y posición real: apagado, el hover no mueve nada ni pinta sombra —cero regresión—; puesto, translateY de −2px y sombra de 18/48, con la tarjeta todavía div, cursor auto y su CTA intacto dentro, sin un solo botón anidado en botón; bajo reduced-motion el desplazamiento se anula y la sombra se queda, que es suprimir el movimiento sin perder la señal de profundidad; y una Card interactive de verdad —cinco en la demo del canon— sigue siendo button, con cursor de puntero y los mismos dos píxeles de elevación. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
2 months ago |
|
|
79a90e6283 |
fix(eidos): las variables de `Flex` y `Grid` dejan de heredarse
Dentro de un `Mockup`, un `<Grid columns={7}>` colapsaba a columnas de `0px`: el
grid medía 72px, exactamente los 6 huecos de 12px, sin nada para las 7 pistas.
La §46 registró `inherits: false` para las 44 variables de `Box`, pero `--flex-*`
y `--grid-*` se quedaron fuera. Como una custom property hereda por defecto, el
`align="center"` de un `Stack` exterior escribía `--flex-align: center` y CADA
descendiente lo heredaba: un `Stack` anidado que no pide alineación ninguna
acababa con `align-items: center`, su hijo `Grid` encogía a contenido, el ancho
quedaba indefinido y `1fr` no tenía nada que repartir.
Las 7 variables de `flex.css` y las 13 de `grid.css` se registran ahora con
`@property { syntax: '*'; inherits: false }` y sin valor inicial, igual que Box.
Un layout anidado vuelve a decidir su propia alineación.
Verificado: `vitest src/uix/eidos` 361/361 · el grid del mockup pasa de `0px` a
`103.71px` por columna, que es exactamente `(798 − 6×12) / 7` —el reparto real—
· demos de hero, pricing, feature-split, testimonials, button, accordion y table
sin regresión. Doctrina en theming/changelog §48.
Lección registrada: al arreglar la herencia de un recipe hay que barrer TODOS los
hermanos que escriben variables para sí mismos. El «pon `justify` explícito en
los clusters anidados» que yo había anotado en el handoff era este bug sin
diagnosticar.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
2 months ago |
|
|
cd399f7c7c |
fix(eidos): el `align`/`justify`/`alignContent` de `Grid` sí aplican
`<Grid align="center">` no tenía efecto: `align-items` computaba `normal`. Los atajos `place-items`/`place-content` del recipe se emiten DESPUÉS de los longhands, y su fallback `revert-layer` —cuando el prop `placeItems`/ `placeContent` no está puesto— revertía el longhand anterior a su valor inicial, pisando en silencio lo que `align`/`justify`/`alignContent` escribían (un atajo posterior gana sobre el longhand que expande). Ahora el fallback de los atajos COMPONE los vars de los longhands en vez de revertir; si el prop del atajo sí está puesto, sigue ganando (va el último). Los grids por defecto no cambian (para ítems de grid, `align-items: normal` ≡ `stretch`). Encontrado al alinear las filas de `feature-split`. Verificado: `vitest src/uix/eidos` 353/353 · en el navegador, feature-split (filas centradas), el chart del Mockup (`align="end"` = barras a la base) y feature-grid (AutoGrid, sin cambio). Doctrina en theming/changelog §47. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
3 months ago |
|
|
d38bd63faa |
docs(blocks): registro de F2.1, doctrina de demo del tier y handoff
Documentación al día de lo que se cerró hoy y handoff para retomar mañana.
- `PLAN-blocks.md` §7: **F2.1 `site-header` HECHA** con sus siete commits, la
fase 0 contra el dossier §P1, el landmark que le faltaba a `NavigationMenu`
(arreglado en el canon, no parcheado en el block), el hueco del CTA que
navega y parece botón (registrado, no falseado) y el defecto de framework
que destapó la demo.
- `theming/changelog.md` §46: las 44 variables de cascada de `Box` dejan de
heredarse. Un `Section` regalaba su padding a cada descendiente —la galería
arrastraba ~300px de aire desde F0— y los hijos heredaban anchos y `display`
ajenos. `@property { inherits: false }`, radio verificado sin regresiones.
Lección: una variable que un componente escribe para SÍ MISMO debe declararse
`inherits: false`; si no, deja de ser un prop y se vuelve un contagio.
- `architecture/blocks.md` B-9: la demo de un block se construye sobre el
harness compartido y el block se enseña A SANGRE — nunca dentro de un marco
con relleno ni de una caja con scroll, porque eso cambia lo que el block
hace.
- `src/uix/blocks/README.md`: anatomía de la demo (harness, `{Name}Site`, ruta
`preview`, `DocRow`, catálogo único, ejes en el shell).
- `CONTINUE-blocks.md` (nuevo): handoff — qué toca (F2.2 `hero`), la plantilla
de ficheros para copiar, las reglas que ya costaron sangre (a sangre, iframe
solo para anchos de dispositivo, cada prop un control, nada de backticks en
`<Text>`, ojo con las variables que heredan), la deuda declarada que es
decisión del usuario y el estado exacto de los gates.
Gates al parar: `blocks:check` verde · `svelte-check` 73 errores, todos deuda
ajena (0 propios) · `vitest src/uix/eidos` 353/353 · `contracts.test` con los
3 fallos ajenos conocidos.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
3 months ago |
|
|
5aa8090bad |
color: contraste Stage 2 — contrato §40 como datos + guard CI; solver descartado
La ejecución refutó la premisa del plan: el morph HEREDA el contraste del texto (steps 11/12 = curva-L del donante verbatim; ~invariante al croma bajo gamut-mapping), así que toda escala desde donantes §40-compliant cumple por construcción. Medido en 3 bancos (base, leave-one-out, 45 semillas OOD): 0 fallos del gate duro text-strong·12, min WCAG 9.7:1. El solver de luminancia no tenía nada que resolver → descartado por especulativo. D2 = base verbatim (sin migración base→seeds). - $color: CONTRAST_PAIRS (arts/color/contrast-contract.ts) — tabla §40 como datos compartidos: floor duro text-strong·12, banda text·11 (tope relacional, sin nº mágico), border·7 exento - scripts/contrast-audit.ts: muere la PAIRS pre-veredicto (4.5 duro contra §40), consume CONTRAST_PAIRS + banco de regresión morph-generado - eidos/lib/contrast-invariant.test.ts: guard de CI (4 tests) que bloquea la herencia - docs: reference.md §40, next-features.md §1, changelog.md §45, plan (OUTCOME) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
3 months ago |
|
|
b2f0a7f2bf |
docs(theming): ratifica la doctrina de contraste tonal — Stage 1 (paridad)
Cierra Stage 1 de la iniciativa next-features §1 con los veredictos del usuario: - reference.md §40 (doctrina standing): contrato de contraste por pares de slots. Texto = dos tiers (text·11 secundario ≈APCA 60 / text-strong·12 AA garantizado). Bordes = dos tiers WCAG 1.4.11 (decorativo exento: accent·7, subtle·4/default·6, reposo-sobre-fondo · portador 3:1: solid·9 lo cumple, el resto con señal redundante). Foco = eje de config (primitives.focusRing + color.focus, un solo `outline` por §32); default suave, endurecer = valores por config, no código. - changelog.md §44: el chronicle datado (drift medido + veredictos + la herramienta scripts/contrast-audit.ts). - next-features.md §1: Stage 1 marcado DONE; Stage 2 (generador by-construction) sigue abierto, gated en la migración base→seeds. Sin cambios de código (el hallazgo del foco es una decisión de valores-por- defecto vía config; defaults mantenidos por decisión del usuario). El script de auditoría (commiteado antes) queda como herramienta de medición. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
3 months ago |
|
|
f0de4faf75 |
docs(color): handoff de cierre definitivo de la jaula del color
Actualiza el handoff y el changelog §43 al estado FINAL de la iniciativa (cerrada, cuarta sesión): - open-color-cage-2026-07.md: añade las 2 fugas transitivas cerradas (card-group-item · s-text) + el guard runtime, el fix del bug de Card/Avatar (`b93cc6c5c`), la lista completa de commits (sesiones 3–4), y una sección «Follow-ups» con lo menor que queda (override docs-chrome sobre `<Code>`, ringColor roles-only, límites de los 2 guards, comentarios históricos) + nota del estado del working tree (WIP de chat/palabras sin commitear, ajeno). - changelog.md §43: el bug de Card/Avatar pasa de «flageado, NO arreglado» a ARREGLADO con el resumen del fix (migración a resolveComponentColor + compose del seed + canales ring/badge separados intactos). Sin cambios de código. La iniciativa queda CERRADA sin huecos abiertos (qr-code excluido por diseño). Contract 30/30. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
3 months ago |
|
|
72a6569c3e |
uix(color): abre `color` en la familia chart (resolver SVG rol/escala/crudo)
Chart era el último hueco de la iniciativa. Su `color` NO tinta labels/ejes:
tinta la MARCA de datos (stroke de línea, fill de área/barra/burbuja, hue de
heatmap, arco de gauge, porción de pie/funnel/bar-list/polar, punto de smith).
Es SVG con resolución JS, así que NO usa el `data-color` + capa de paleta
compartida (eso es para cascadas CSS en HTML) — el mecanismo es propio.
Resolver central en `chart/context.ts`:
- `seriesColor` / `seriesSurface` reescritos + `seriesContrast` nuevo, todos
`number | ComponentColorProp`. Un índice cicla `SERIES_ROLES` (multi-serie,
sin cambios). Un valor explícito pasa por `resolveChartColor`:
· rol/intent → `var(--color-{role}-{solid,surface,contrast})`
· una de las 33 escalas → `var(--scale-{name}-{9,a2})` (steps solid /
surface-alpha del `PALETTE_SLOT_STEP`); contrast → white (no hay token)
· valor CSS crudo → verbatim (surface = `color-mix 15%`, contrast = white;
sin contraste garantizado, el trade-off de cualquier custom).
- `ChartContext.color` widenado a `number | ComponentColorProp`.
Todos los props `color?: ColorRole` (~14: ChartSeriesProps, Bubble, Sparkline,
ChartCategory, BarList, Funnel, Calendar/Heatmap, Smith×2, Gauge) →
`ComponentColorProp`. Los 3 builders que armaban el fill inline (funnel:
solid+contrast, heatmap:56, calendar-heatmap:118) refactorizados para pasar
por el helper — funnel pierde su `roleOf` local.
qr-code queda FUERA por decisión de diseño (color = tinta de módulos del QR,
contraste con el fondo, no encaja escalas).
Verificado en Chrome: las 3 ramas del resolver resuelven a color real
(--scale-teal-9→oklch, --scale-teal-a2→rgba translúcido, #3b82f6→verbatim,
mix translúcido ok); marcas existentes = primary-solid (roles behavior-
preserving). check chart limpio; contract 30/30. Docs: changelog §43 +
handoff actualizados (hueco chart cerrado, qr-code excluido por diseño).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
3 months ago |
|
|
0b2170d626 |
uix(color): Fase 5 — guard estructural + docs (CIERRA la iniciativa)
Guard: test nuevo "keeps every component `*Color` prop open (THM-2 — the
cage stays open)" en recipe-css-contract.test.ts — escanea los alias
`export type XColor = …` de components/*/types.ts y FALLA si alguno se
estrecha por debajo de ComponentColorProp. Uniones aditivas ('muted',
'inherit', 'absent'…) pasan; alias resuelven transitivamente
(DatePickerColor = CalendarColor); WIP_TRACKS (chronos) re-entra con su
track; exento comentado: OnionColor = string (MAS ancho que la jaula,
normalizacion pendiente). Verde con el inventario real: 60+ alias abiertos.
Docs (todo lo aplazado del track):
- reference.md §25: reversion de los subconjuntos THM-2 registrada como
doctrina (color = sistema completo en TODOS; identidad ≠ evaluacion;
enforcement = el guard).
- Tracker clean-room §THM-2: nota de reversion (los narrows que THM-2 dejo
"por diseño" quedan abiertos, Avatar.Badge incluido).
- changelog.md §43: cronica de la iniciativa completa (mecanica, fases,
huecos señalados).
- Handoff open-color-cage-2026-07.md → CERRADO con el resumen de la tercera
sesion (cola completa, F4, F5, commits) y los 2 huecos pendientes de
decision: chart (11 props ColorRole) y qr-code (color inline semi-abierto,
invisible para el guard). El cuerpo queda como referencia de patrones A–E.
- 13 READMEs con afirmaciones ya falsas corregidos (roles-only, subsets,
"Locking to ColorRole", tablas de props): badge, css-field, field-langs,
float-panel, link, listbox, mark, metrics (solo el icon; Chart delega en
chart y queda como esta), password-field, proof-of-human (incl. la fila de
decision "descartar" → "hecho (reversion)"), range-calendar, textarea,
timeline. banner NO se toca (su ColorRole es del eje intent, otra cosa).
Contract test: 29/29 verde.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
3 months ago |
|
|
d990fe42f9 |
eidos(gradient-finish): auditoria final - tinta named determinista via --_{c}-finish-ink (D7)
Re-auditoria completa del ciclo (batteria entera de guards + bordes
discriminantes medidos en navegador). Dos hallazgos, dos cierres:
1. El override directo de --_{c}-fg del named finish EMPATABA (0,3,0) con el
slice solid de Surface y dejaba el ganador al orden de hojas de estilo -
no es un contrato (el caso discriminante aurora-sobre-amber lo destapo:
la primera verificacion usaba primary, cuya contrast blanca coincidia con
la tinta de aurora y enmascaraba el empate). Fix por la doctrina D7: el
generador emite la var --_{c}-finish-ink y el slice solid de cada recipe
la consume con su contrast de fallback - gana por existir, nunca por
especificidad; las variantes no-solid quedan inertes por no leerla.
Verificado por valores: aurora-amber blanco (autorada) en Button/Badge/
Surface; flat/rampa amber oscuros (heredada); outline inerte.
2. Nombre no declarado (gradient="foo") degrada a la rampa - medido y
documentado en D11 como fallback gracioso.
Atribucion corregida de paso: el crash de morfo:vocabulary/morfo:check es el
morfo de text-blur (deuda preexistente ajena, chip de tarea creado) - NO
palabras como se asumio antes; surface/box/palabras validan OK.
Bateria final: eidos entero 331/333 (2 = proof-of-human preexistentes),
config 72/72, guard 5/5, audit 145/145, eidos-lint invalid:0 en los tres
consumidores, typecheck limpio.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
3 months ago |
|
|
77ef3b0b3d |
eidos(gradient-finish): v2.2 named finishes + on/data-on - EL PLAN COMPLETO
D11 - Named finishes (el diseno A rescatado como opt-in explicito):
- gradientFinish.named opta gradientes del open cage como acabado, cada uno
con su tinta AUTORADA obligatoria (--gradient-{name}-ink, override de la
convencion --_{c}-fg a especificidad (0,3,0) sobre el slice de variante).
- La base sigue siendo el solid de la identidad (fill por capas, D2) -> el
aurora shipped son blobs de rol con alfa SIN color base final:
background-image-valido POR ARQUITECTURA (el caveat del mesh disuelto, no
exceptuado), y re-tine por tema y modo via referencias de rol.
- Honestidad documentada: la validacion numerica al peor stop de un string
CSS arbitrario no es implementable (stops desconocidos); posible solo para
gradientes de modelo (buildGradient) - diferida. El guard clava la sanidad
del config (named subconjunto de gradients + ink presente).
D12 - on/data-on minimo (Surface on="light|dark"):
- La foundation re-vincula --color-content-*/--color-border-default para el
subarbol (dark -> tinta on-solid; light -> on-solid-contrast; mixes oklch
82/64/32%). Verificado EN VIVO: un parrafo muted dentro del aurora computa
la tinta del contexto al 64%.
- Limites POR CONSTRUCCION y documentados en cada consumidor: componentes
anidados con tokens propios y contenido portaleado NO se re-entintan (la
inversion completa sigue siendo iniciativa independiente). forced-colors:
el contexto resuelve a CanvasText/GrayText (bloque extendido). Sin
color-scheme a proposito (solo chrome UA).
Ademas: prop gradient ampliada a (string & {}) para named en Button/Badge/
Surface; poda del orphan-guard (border/text de Surface: 3 slots x 8 colores,
lo que las variantes consumen); guard 5/5; audit 145/145; lab CASO 07 con el
aurora REAL (<Surface gradient="aurora" on="dark">) verificado por valores.
Docs: capitulo D11+D12 + registro D1-D12 + roadmap COMPLETO; reference p39;
changelog p42; plan cerrado (quedan declaradas: inversion completa, demo
propia de Surface, validacion de modelo para tintas named).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
3 months ago |
|
|
58076cadfe |
eidos(surface): primitiva Surface - el lienzo temable (Box + tratamiento), v2.1
Box es layout-only por doctrina y rechaza background/color; Surface es la primitiva que posee el lado del tratamiento: el caso hero / banda decorativa / bgGradient como primitiva de primera clase, no como escape-hatch style=. - Composicion sobre <Box> (patron Section): hereda TODA la API de caja y estampa data-surface + color/variant/gradient/rounded (attrs eidos-only de wrapper, doctrina D8). - Recipe palette-tint espejo de Card SIN chrome: _palette-* 5 slots x 8 colores -> el forward THM-2 ruta roles + 33 escalas donantes gratis (verificado: color="teal" resuelve sin cableado extra). - Variantes soft (tinte track, tinta global) y solid (lienzo saturado, texto plano hereda contrast); gradient en el gate del acabado (rampa anclada + spread; sin solid-hover -> extremo profundo cae a solid). - Morfo declarativo patron Box (scope eidos, 1 parte, 0 eventos justificados); eidos-lint invalid:0; audit 145/145 PASS (ficha completa: Baseline/Decisiones/Gaps con disposiciones/Passive justification). - Lab temas/gradientes CASO 07: heroes REALES con Surface (rampa primary, spread plum, banda soft teal) verificados por valores computados; el aurora nombrado queda como preview del siguiente paso. Cola v2 restante: named finishes con tinta autorada + on/data-on. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
3 months ago |
|
|
63f6209e5f |
eidos(gradient-finish): v1.5 kind spread - rotacion de matiz anclada, medida antes de implementar
Esta vez en el orden de la doctrina D6b: las dos puertas se midieron ANTES
de escribir la implementacion.
- Puerta 1 (sonda, 84 combos): la rotacion pura a L constante rompia grass
(+-4 grados) y gold (+-27) - L de OKLCH no es luminancia relativa. Rescate =
la propia doctrina aplicada suave: ambos stops rotados toman la mezcla
DEBIL del ancla (lift/3) -> 0 regresiones hasta +-45 grados.
- Puerta 2 (RCS en Chromium, por valores computados): el canal h de
relative color es <number> - calc(h +- 30deg) computa none -> el token
--gradient-finish-spread es SIN unidad ('30').
Shipped: gradient="spread" en Button+Badge (boolean | 'ramp' | 'spread';
data-gradient='spread' overridea la var del acabado - cero cambios de CSS de
recipe); token + override por tema (gradientFinish.spread); guard 4/4 con el
invariante del spread anclado; lab con especimenes reales (threat cruza el
360, gris C=0 queda ~plano - documentado, no caso especial); docs D10 en
theming/gradient-finish.md + reference p39 + changelog p42 + plan v1.5
completa.
Una doctrina, dos kinds: la rampa huye de la tinta con fuerza; el spread
huye suave mientras juega con el matiz.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
3 months ago |
|
|
a63d806b66 |
eidos(gradient-finish): override del dial por tema/modo - v1.x COMPLETA + capitulo del libro
- ThemeDefinition.gradientFinish.lift: el tema re-emite --gradient-finish-lift
en su bloque (misma especificidad, despues en cascada -> el tema gana);
claro y oscuro pueden llevar intensidades distintas, 0% apaga por tema.
Test: active-eidos-config.test.ts ("per-theme gradient-finish dial override").
- Capitulo de nivel libro docs/theming/gradient-finish.md: registro de
decisiones D1-D9 con el porque de cada una, las alternativas rechazadas con
evidencia (color-value/variante/bg-prop; pasos 7/11 con valores reales;
lift-up global medido y tumbado 52/84), la rectificacion documentada y la
leccion de proceso (medir antes de fijar defaults). Indexado en docs/README.
- reference.md paragrafo 39 enlaza el capitulo; changelog paragrafo 42 y el plan
marcan la v1.x completa (guard + Badge + override por tema).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
3 months ago |
|
|
322a1939a8 |
eidos(gradient-finish): acabado anclado a la sombra de la tinta - v1 Button+Badge + dial temable + guard
El gradiente entra al sistema como ACABADO (material) del fill, jamas como
valor del eje de color: prop `gradient` -> attr eidos-only `data-gradient`
(familia data-variant; NO morfo - el runtime lo resolveria desde props de
soma y mergeProps clobberea el stamp del wrapper).
- Fill por capas: background-color = base solida (degrada sola en
forced-colors) + background-image = rampa derivada de los slots de LA
instancia (roles + 33 escalas + custom gratis, tinta heredada).
- Dial unico de tema: primitives.gradientFinish.lift (26%) ->
--gradient-finish-lift (0% = apagado; override por instancia via cascada).
- RAMPA ANCLADA a la sombra de la tinta ("la rampa huye de la tinta"):
tinta blanca -> #000 fuerte abajo (CTA sombreado); tinta oscura -> #fff
fuerte arriba (glossy). Ancla+angulo por color x modo con el MISMO flip
del slot contrast. Rectificacion MEDIDA: el lift global hacia blanco
rompia la tinta heredada en 52/84 combos a 26% (techo global 0%) - el
contraste ahora solo puede mejorar: dial sin topes.
- Guard ejecutable gradient-finish-guard.test.ts (3/3): no-regresion <=40%
sobre 84 combos + set flat-fail clavado (cyan/orange, deuda on-solid
preexistente).
- Generador emite la VAR (--_{c}-fill-finish); el recipe pinta (solid +
re-assert en hover: su shorthand background resetea el longhand).
- Lab temas/gradientes: 9 casos con componentes reales sobre el token real
(dial en vivo, polaridad observable, evidencia de pasos 7/11, forced-colors).
- Docs: capitulo theming/gradient-finish.md (registro de decisiones D1-D9,
alternativas rechazadas con evidencia, leccion de proceso: medir ANTES de
fijar defaults) + reference.md paragrafo 39 + changelog paragrafo 42 + plan
docs/process/gradient-finish-plan-2026-07.md.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
3 months ago |
|
|
a52f80ceab |
refactor(eidos): prune the depth `scrim` cue (F4-D scrim decision)
`--depth-{plane}-scrim` was declared (DepthPlane field, DEPTH_CUES, validation,
applyDepth) but never seeded, emitted or read — a write-surface with no reader
(applyDepth({p:{scrim}}) silently no-op'd; never present in generated base.css).
Analyzed via workflow (state map + 4 dispositions + adversarial stress). The
four collapse to prune vs promote-to-z-parity: wire-and-unify SINKS (contradicts
the test-locked z open-cage precedent + the MD3/Radix/Vaul consensus that the
veil is component-owned, not an elevation cue), relocate flips its verb to
retain, and complete-to-z-parity would mint a third alias of the --color-overlay
backdrop role. Unlike z (kept as an exposed open cage — it varies per plane and
is unpaintable-forever), scrim has no per-plane variance and no value to seed.
Prune: remove scrim from DepthPlane / DEPTH_CUES / validation / emitter +
applyDepth doc. Amend rfc-depth.md (token contract + Phase-4 note + atmosphere
rows), reference.md cue list, changelog, pendiente. The modal veil stays where
MD3/Radix/Vaul + the standing decision put it: --{component}-overlay-* tinted by
--color-overlay.
Zero observable change (never emitted). Tests 71/71; npm run check src/ = 9
baseline, 0 new; base.css unchanged.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
3 months ago |
|
|
b55ca6eecb |
fix(cleanroom): F2+F3+F4-C+SEM-4s1 — lote mecánico, censos con guard, corpus documental y el close polimórfico de los pickers VIVO
F2 — lote mecánico (13 ítems): - DEP-2 ogl eliminado (0 imports) · DEP-1 clsx inlineado como toClassString propio + suite de contrato (props.test.ts; soma.md §12 cerrado). - THM-7: los 5 selectores manuales de sema.md reescritos con semaSelector (los ejemplos [data-toast-root] apuntaban a un part INEXISTENTE — la deriva que el builder previene, demostrada en el propio doc). - MOR-1 escape isomorfo + validación de attr-names en semaSelector + 9 tests (selectors.test.ts, matches() real con comillas/corchetes) · MOR-2 partMarkerAttr = única fuente compilador↔builder + test de paridad · MOR-3 _resetCompileCache borrado (0 usos). - SOM-2 keydown continue en match sin handler + keyboardFixtureMorfo · SOM-1 no-await de handlers (censo async = 0; contrato V1 cumplido) + pin. - SEM-2 trigger pre-attacha catch con logger (void trigger sin unhandled rejection; throw intacto para awaiters) + pin · SEM-3 fallback muerto de applyDominance → skip defensivo + timer tope de awaitExpression cancelado · SEC-1 adjudicado YA implementado (assertCssVariableValue desde 2026-05-11) + pin del path de VALOR. - accordion → outline (§32; su outline:none dejaba CERO anillo en HCM) — verificado en vivo · THM-6 radius-full 9999px · EID-4 recuentos 33. F3 — censos con guard: - SOM-3 cerrado: announcer + image-provider migrados a scheduler-preferred (consumidores cableados: date/time-field vía soma.uix.timers; avatar/image vía eidos.timers — verificado en vivo); guard de timers ENSANCHADO de soma/components a TODO soma y pasado a EVIDENCIA (setTimeout exige .schedule( en el fichero — layers/ y datetime/ escapaban del ámbito viejo). - THM-5: R-4.7 nueva (válvula same-line /* important: <razón> */, escaneo comment-blanked) + las 15 declaraciones anotadas con su razón + canon recipe-contract §3/§4. - SOM-4 adjudicado: el censo/guard YA existían (49 pins); knob/mask-field/ timeline pinneados (overrides documentados en call-site); media-player Batch-4 (35 hits, cero renderProps) = único batch restante, registrado. - THM-4 doctrinado en eidos.md §unused (comportamiento/composición = legítimo; deuda = eje visual sin consumidor; hotspots por lotes). F4-C — corpus documental (decisiones de usuario aplicadas): - DOC-3: los 15 enlaces muertos resueltos (repoint a la edición FINAL trackeada / des-link históricos) · docs:check I6-links WARN→ERROR. - DOC-1: tabla «Build contract» MIGRADA a component-guide con estados modernizados (A3–A5 → LIVE + guards de hoy); banners reapuntados; citas de CANON/sema.md historificadas; lápida-redirect en el §13 del fósil. - DOC-4: hold chain → holds.ts · FAQ event:* SUPERSEDED por signatures · gradient añadido a los DOS capstones (sextet real) · nota de paleta de demo-authoring corregida (universalPaletteDecls + decisión THM-2 = mecanismo universal como sucesor del tracker borrado). - DOC-5/6: recuentos anti-frágiles datados · §4.11 dup → §4.12 · Known gaps historificado · N-6/N-7 recuperadas de git (d68d2c45^) y canonizadas en eidos.md §pickers · authoring E2 → canon/tsc.md · air-old des-linkado · EID-3 (placement) en la fila RTL · AUX-2 disabledDom documentado. SEM-4 sesión 1 — el close polimórfico de los pickers, VIVO (D.11): - Reconciliación: los morfos ya no declaran close (delegated al Popover, de-dialoged 06-27); el agujero real era el cierre programático bypaseando dismissWith → save/cancel/select eran perceptualmente SILENCIOSOS. - Fix: PickerShellHandle.setPopoverDismiss + closeWith(cause) en los 5 providers (14 sitios; select/commit → 'save' = commit.save+fulfill, cancel → 'cancel' = emerge; fallback raw para headless) + UN inyector en el eidos PickerShell root (norma N-8). Picker genérico fuera a propósito (ya suena commit-set/cancel por diseño S9). - Verificado en vivo (date-picker): Done → close·commit·fulfill·active · Cancel → close·emerge · cierre real. Gates: matriz 141/141 (los 6 morfos nuevos de la pista de texto paralela también PASS) · contracts 38/38 · eidos 314 · sema 178 · morfo 94 · docs:check 0/0 con I6 en error · baseline propio 57. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
3 months ago |
|
|
4addfd7dbf |
fix(cleanroom): P1s ejecutados (EID-1/EID-2/SEM-1/MOR-4/THM-1/THM-3) + auditoría + plan scene/ambient
Clean-room fixes (2026-07-11, sobre los P1 de la auditoría):
- EID-1: el anillo de foco de la fundación migra a `outline` (§32) — el último
box-shadow del catálogo; :where()-wrapped para que las recetas siempre ganen;
doctrina actualizada en theming/reference + changelog.
- EID-2: opacidades literales de archetypes.css → var(--opacity-disabled/hover).
- SEM-1: política de live-region unificada — la urgencia va SOLO por intent
(threat/loss → assertive), runtime y AnnounceChannel ya coinciden.
- MOR-4: card-group con morfo propio (scope eidos) + guard de enumeración.
- THM-1: component-audit + recipe-css-contract escanean los *.css hermanos
(calendar-select, color-picker-spectrum, date-range-picker-time…); R-2.1
caza también hsl()/oklch(); violaciones de los secundarios corregidas.
- THM-3: canario de censo de toggle volteado (lint.test); commit-block promovido
a firma global block-shake; regen de generated/base.css.
Docs nuevos:
- docs/audit-new-10-july/audit-active-uix.md — auditoría clean-room 2026-07-10
del ecosistema (hallazgos P1–P3 con evidencia ruta:línea, matriz y gap analysis).
- docs/process/PLAN-scene-ambient-pack.md — plan por fases: motor arts/scene +
pack Ambient (45 animaciones de demos) + vía de promoción agéntica (Aura);
gate de decisiones D1–D9.
- docs/Disenando_lo_que_ocurre_FINAL.{docx,pdf} — edición FINAL del libro.
- README.md raíz (esqueleto de paquete).
Excluidos deliberadamente de este commit: words/palabras/chronos (pista
separada), web/routes/alpha (terminado, sin commitear por decisión), rt.css
(volcado de referencia Radix Themes).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
3 months ago |
|
|
bf573430b8 |
docs(theming): close the touch-rows/§37 reconciliation — pseudo hit-slop CONFIRMED (user decision)
Option (a) with riders: the ::before slop stands for bare markers (the Material mdc-touch-target / Android touch-delegate / iOS hit-inset lineage). Rider 1: dense coarse stacks must keep pitch >= --touch-target (WCAG excludes overlapped area; bare boxes still hold AA via 2.5.8 Spacing worst-case). Rider 2: the Field labeled-row task stays open as the ADDITIVE improvement — the row becomes the real AAA target (2.5.5 Equivalent) and the slop remains a harmless net. Chronicle updated in changelog §37; standing in reference §37; handoff block resolved. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
3 months ago |
|
|
53b6f629f2 |
feat(audit): component re-audit + fixes P0–P5 (P4 complete, P5 in progress)
Re-audit of the whole component catalog at pilot depth (91 fichas + the checkpoint verdicts in docs/audit/components/) and the executed fix packages. - P0–P3: doctrine (sema participation, CANON §3 intent, component-guide §5 + API naming, §32 outline), guards (morfo-vocabulary-check S10/S11d, component-audit A-3.1/A-1.4/S9, eidos-lint classHooks), morfo contracts (role=application removed ×4, aria-selected off the Day, drp translationRef, field data-state prune, pin-input commit-set, media-player renames), 13 new sema packs + 12 morfos family-default → pack. - P4 (N1–N10) COMPLETE: selectionMode (select/combobox/toggle-group/calendar); onValueCommit terminal-callback norm (pin-input/search/password/textarea + date/time/color-field add); typed validation reason + onInvalid (tags-input, css-field); index/onIndexChange (carousel); deselectable; openDelay/ groupSkipDelay; allowCustomValue; defaultValue prune. - P5 (in progress): S1 class-hooks codemod (22 hooks → data-attrs across cropper/button/image-picker/toggle/image-adjustments); S5 outline remnant in field.css; depth pass (data-depth=overlay on tooltip/toast/float-panel); touch-rows (--touch-target token, decoupled ::before hit-slop, area-not-visual, 44 AAA). S6 (Field composition) + S8 (calendar-surface) pending. Verification: errors-outside-(alpha|words|palabras|chronos) == 59 (baseline); morfo-vocabulary-check exit 0; eidos-lint class-hooks/invalid 0 on touched components; per-component vitest suites green. Handoff + remaining plan: docs/process/continue-audit-fixes-2026-07.md Excluded (broken by the N1 rename, left broken per user decision, not staged): words/**, palabras/**, chronos, web/routes/alpha/**. Reconciliation pending: the touch-rows ::before for checkbox/switch reverses changelog §37's earlier pseudo-element rejection (WCAG-overlap) that had routed markers to a labeled-row/Field task — flagged for the user in the handoff. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
3 months ago |
|
|
aa05532e9f |
docs(book): F7.3 (8/9) — eidos-motion translated to docs/theming/motion.md
src/uix/eidos/eidos-motion.md (698 L, Spanish) translated to English, same s1-s19 numbering: the two-moment thesis, the closed cascade model (D.11-D.13), motion across the 4 layers, the two-surface registry, types, the EngineMotion API + cleanup policy, the 5 drivers, the DOM contract (data-animation-style), Presence integration, reduced motion, primitives/ keyframes, built-in content, per-component defaults, code map, s15 (the events.css -> signatures migration — cited from events.css), Chakra comparison, naming, phases F1-F7, deferred. Stub with the full s-map at the old path; corpus links swept (comparison, eidos chapter, changelog, motion-guide). docs:check 0 errors. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
3 months ago |
|
|
060f7f1572 |
docs(book): F7.3 (2/3) — theming/ satellites: guide + notes + channels + motion-guide + changelog
Five theming docs into the book tree: - docs/theming/guide.md — THEMING_GUIDE (241 L, Spanish -> English): add a component's recipe step-by-step + the three theme-definition modes. - docs/theming/notes.md — THEMING_NOTES (168 L, Spanish -> English): the bundle/feature comparison + the controversial-decisions FAQ (in-page anchor to s1.bis fixed to a real THEMING link). - docs/theming/channels.md — CHANNELS_SYNTHESIS (115 L, Spanish -> English): the per-channel-RFC capstone (two moments, 8 expression vs 3 runtime channels, the builder sextet + applyTheme). - docs/theming/motion-guide.md — MOTION_GUIDE (213 L, already English): moved with frontmatter + links repointed. - docs/theming/changelog.md — THEMING_CHANGELOG (1310 L): chronicle, moved VERBATIM (recorded history is not translated), links repointed. Thin stubs at all five old paths; corpus links swept (docs map E3/E4 rows, building-a-component phase 5, decisions umbrella, getting-started, eidos chapter). docs:check 0 errors (258 docs). Remaining in F7.3: THEMING.md itself (1499 L) + eidos-motion.md (698 L). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
3 months ago |