Veintiocho reglas de estructura y comportamiento, cada una con su verificación. Ninguna nombra un negocio. Este documento no describe un producto: describe el sistema sobre el que se montan los productos. RetiCash es el primero, y es el que las puso a prueba.
De dos fuentes y una asimetría.
Interactive Brokers puso el marco: cinco franjas, tres columnas, un panel de contexto permanente que no cambia al cambiar de pestaña, cifras en dos niveles, barra de estado, vistas con nombre. Carbon puso las superficies y el aire: la rejilla de 16 columnas, la escala tipográfica, las piezas, la densidad. Las dos son sistemas de container-row-column con cortes de mínimo; la lógica es la misma máquina.
La asimetría es ésta: ninguna de las dos documenta el armazón de terminal. El «Ratio» de IB —que es Bootstrap— cubre sus sitios de marketing, su registro y sus portales; su sección de componentes de portal tiene tres piezas. TWS, que es lo que uno admira, no está en el sistema. Carbon cubre la barra y el riel, no la división del espacio de trabajo.
Lo que faltaba no era elegir entre dos sistemas: era escribir el que ninguno de los dos escribió. Y escribirlo con la disciplina que impide que se desvanezca — cada regla con su verificación, y cada verificación diciendo si hoy pasa o falla.
IB deja que el operador arme su escritorio: divisores arrastrables, pestañas que se abren y cierran, disposiciones guardadas. Aquí no. El que usa esto tiene a alguien enfrente, no una estación de trabajo que configurar.
Ontikos fracasó cuatro veces como sistema de diseño, y siempre por la misma razón: se escribió como ideal antes de que nada hubiera operado. Éste se escribe al revés — sale de algo que operó. Para que no vuelva a pasar, cada regla lleva su marca, y la marca es dura:
Pasó la operación real en un producto, y su verificación corre y da verde. Es la única marca que autoriza a copiar la regla a otro producto sin volver a pensarla.
Se leyó de la referencia o se dedujo del sistema, pero todavía no la probó nadie operando. Vale como plano; no vale como evidencia.
La regla es correcta y el producto hoy no la cumple. No se borra la regla: se deja en rojo hasta que el producto la alcance.
Nada entra a Ontikos sin verificación que corra. Una regla sin comprobación es una opinión con número, y de eso ya hubo cuatro versiones.
Cuatro piezas de vocabulario. Todo lo demás del sistema se dice con estas cuatro palabras.
El marco fijo: barra, riel, estado. Vive fuera de la rejilla y nunca se mueve.
Una división del viewport restante. Declara su ancho en columnas y es dueña de su scroll.
Lo visible de una región: barra de título más cuerpo. Es la unidad que puede llevar pestañas.
Lo que va dentro del cuerpo. Ahí manda la rejilla de documento, con su aire.
Barra, riel y estado quedan. El scroll ocurre dentro de la región, y se ve dónde.
La barra se fue hacia arriba y el estado desapareció: un documento estirado.
scrollingElement.scrollTop === 0 en todo momento, y la barra de estado visible a cualquier alto de contenido.3 · 8 · 5 de las 16. Cada borde coincide con una línea de la rejilla.
296 px cae entre dos columnas. Ese resto es el que después obliga a inventar márgenes para taparlo.
px en la declaración de regiones; y medido, cada borde de región coincide con un borde de columna con tolerancia 0.Corte vertical arriba, horizontal adentro. Los bordes siguen alineados de arriba abajo.
Vertical dentro de vertical: cuatro bandas y ninguna jerarquía.
profundidad 1 · profundidad 2
profundidad 3
Nadie puede decir de un vistazo dónde termina una cosa y empieza la otra.
≤ 2, contada sobre el archivo.El título está dentro del borde: nombra un recinto, no una zona vaga.
Rótulos flotando sobre bloques sin recinto. Al segundo ya no se sabe si el rótulo abre o cierra.
Tres pestañas, un mismo rectángulo de contexto. La acción está siempre en el mismo lugar.
El contexto se encoge y en la tercera desaparece. Hay que volver atrás para poder actuar.
getBoundingClientRect() de la región de contexto no cambia en ningún valor.Cuatro tarjetas, dos bloques, una tabla. Todo cae en las mismas líneas.
Cada fila arranca en un sitio distinto. Prolijo por bloque, desordenado por columna.
ancho máximo · medio · mínimo de terminal
La lista se pliega primero y pasa a pestaña. El contexto —y por lo tanto la acción— se queda.
Se salvó la lista y se perdió la acción. Ya no se puede cerrar una operación sin abrir otra cosa.
Todo lo que se abre le quita al usuario una parte de lo que estaba viendo. Elegir la superficie es elegir cuánto se le quita. La pregunta no es «¿qué se ve mejor?», sino ¿qué pierde de vista mientras esto está abierto, y lo necesitaba?
no cobra nada
Ya está en pantalla. Seleccionar la llena. No aparece nada nuevo.
no cobra nada
La fila crece donde está. Nada se corre salvo lo que viene debajo.
cobra poco
Pegada a lo que la abrió. Efímera: se va al elegir o al tocar afuera.
cobra su región
Entra por el borde de su región, no de la pantalla.
cobra todo
Impide todo lo demás. Vale sólo cuando seguir sin decidir sería un error.
No hay que discutirlo cada vez. Lo que se abre determina la superficie.
| Lo que se abre | Superficie | Por qué |
|---|---|---|
| El detalle de algo seleccionado | Región de contexto | ya está en pantalla y no cuesta nada |
| Un menú de opciones de un elemento | Anclada | efímera, y hay que ver de qué elemento es |
| Filtros de una lista | En sitio, sobre la lista | pertenecen a la región y hay que ver el efecto |
| Un formulario de varios campos | Cajón en su región | necesita espacio, no necesita bloquear |
| Confirmar algo irreversible | Modal | seguir sin decidir sería el error |
| Un aviso que no exige acción | En línea, en la región | informa sin interrumpir |
| Una condición que impide operar | Compuerta sobre la región | cubre y ofrece el acto que desbloquea · no un banner con los controles vivos debajo |
| El resultado de una acción ya hecha | Aviso pasajero sobre el armazón | no hay nada que decidir; se va solo |
Esta fila decía «banner de la región». El documento del primer producto ya tenía la regla mejor resuelta y ganada: el bloqueo no es un aviso, es una compuerta. Un banner deja los controles vivos debajo, y un control que no va a funcionar no debe poder tocarse. La compuerta cubre su región y ofrece el acto que desbloquea. Se corrigió aquí, no allá — es la disciplina funcionando en la dirección que importa: lo que operó gana sobre lo que se dedujo.
La lista no se movió, el rectángulo de contexto tampoco. Sólo cambió lo que hay dentro.
Mirar un registro cobra la pantalla entera. Es lo que hace hoy el producto.
getBoundingClientRect() de la región de contexto no cambia.El cajón entra por el borde de su región. La lista y el contexto siguen a la vista.
Salió de su región, tapó el contexto y hasta la barra. Ya no se sabe para quién se está llenando el formulario.
modal en la disposición.Una pregunta y dos salidas. Detrás no hay nada que el usuario pueda seguir haciendo, y así debe ser.
Ver, filtrar y editar también bloquean. Cuando todo bloquea, bloquear no significa nada y se confirma sin leer.
El formulario y el dato que lo justifica están en pantalla al mismo tiempo.
Cayó justo sobre la cifra que hay que copiar. El usuario cierra, mira, vuelve a abrir.
Un nivel. Para llegar a otra decisión, primero se resuelve ésta.
Modal sobre modal. Ya no se sabe qué cierra qué, ni qué queda a medio hacer si se cancela.
La fila que abrió el cajón queda marcada y a la vista. Esc o volver a ella lo cierran.
El disparador quedó tapado. Sin marca ni hilo de vuelta, cerrar es adivinar.
Esc y el propio disparador la cierran.240 ms.GanadaSale del borde donde va a quedarse. El ojo ya sabe dónde mirar antes de que termine.
Nace en un lugar y termina en otro. El usuario persigue la superficie en vez de leerla.
≤ 240 ms, desplazamiento en un solo eje, y el origen del movimiento sobre el borde donde la superficie queda. Cero apariciones instantáneas y cero traslados.Las dos acciones están en pantalla desde que la vista abre. Cero clics para poder actuar.
Menú, después cajón, y recién ahí el botón. Dos aperturas para hacer lo único que la pantalla existe para hacer.
0 para llegar a ella.Los otros cortes refluyen contenido dentro de un mismo sistema —tres columnas pasan a dos, una tarjeta se angosta—. Éste no reordena nada. Antes de él manda el sistema de una región; después, el de varias. Por eso es uno solo y por eso hay que declararlo.
Cuatro cortes, una sola frontera. Los demás refluyen dentro de su sistema; sólo uno cambia de sistema.
Un solo umbral. De un lado un sistema entero; del otro, el otro entero. No hay estado intermedio que probar.
La del medio no es ninguna de las dos: riel y barra de estado del sistema de varias regiones, encima de un contenido que baja.
a3f1 → … → a3f1
a3f1 → … → c0b9
Volvió con un bloque menos. Un plegado automático se comió un aviso al cruzar.
Cada regla se puede probar en un solo lado. Tocar un sistema no puede mover el otro, y se sabe sin leer el código.
Arriba, una regla sin sistema: al tocarla se movió el ritmo del otro lado. Abajo, una regla declarada que no aplica a nada.
0.Los fichas de color · la escala tipográfica · el vocabulario de estados · las palabras de la interfaz · los datos y la capa de servicio · la ontología: qué entidad, qué acción, qué pregunta responde la pantalla.
Las regiones · las superficies y su costo · el orden de plegado · el riel · la barra de estado · el cajón · la profundidad de división. Nada de esto significa lo mismo del otro lado, y varias cosas ni siquiera existen ahí.
La medición sin resultado se distingue de la medición chica. Son cosas distintas y se tratan distinto.
Costó un desbordamiento inexistente y unos gráficos dibujados en blanco: el panel oculto informaba ancho 0 y cero cuadros de animación.
0; y la decisión no consulta el agente de usuario en ningún punto — se busca la cadena y tiene que dar cero apariciones.No es el otro sistema con menos columnas. Es otro sistema, y tratarlo como una degradación es el error que produce interfaces estiradas.
Es el hallazgo que reordenó este documento: la regla 01 no pertenece al sistema de varias regiones. Un armazón fijo con una región que baja ya la cumplía, y la cumplía antes de que existieran estos pliegos. La regla 01 es del tronco común.
Y el costo se mide distinto. En varias regiones lo caro es tapar el dato. Aquí tapar es normal y barato: lo caro es perder el lugar. Se mide en gestos para volver, no en superficie cubierta.
El área segura contemplada arriba y abajo es lo que evita que la barra de alcance quede debajo del indicador del aparato.
scrollingElement.scrollTop === 0 a cualquier alto de contenido; las dos barras visibles siempre.La salida suele estar —una cruz arriba a la derecha, y el velo que se toca—. Lo que casi nunca está garantizado es la vuelta al mismo punto: la región se repinta y el usuario aterriza arriba, en una lista por la que ya había bajado.
scrollTop de la región, con tolerancia 0 px.Los destinos se reparten el ancho en partes iguales: ninguno queda más difícil de acertar que otro.
La regla estaba bien pensada desde el principio. Lo que se fue de norma es dónde cambia: en dos umbrales, y ninguno es la frontera.
Es la regla más inusual del sistema y la más firme. Al lado ancho no le aplica: allá el ancho es el material de trabajo.
Diecisiete radios distintos medidos en el producto de referencia, contra dos del otro lado. Eso no es una escala redonda: es una acumulación de decisiones sueltas tomadas en momentos distintos.
Y corrige a quien verifica. Medir un lado contra la norma del otro produce falsos rojos. Cada sistema declara la suya, y sólo dentro de ella se juzga.
4.Las vistas se encienden y se apagan; no entran en la historia. Y lo que sí entra son dos marcadores de guarda, puestos para que el gesto de atrás pregunte si uno quiere salir. O sea: el gesto no está sin implementar — está implementado al revés de esta regla, y cuesta un diálogo cada vez.
La guarda resuelve un problema real —salirse sin querer— pero lo resuelve interceptando en vez de navegando. Con vistas apiladas, el mismo gesto haría lo que el usuario espera y la guarda sólo haría falta en la primera.
Es la única pieza que entra a Ontikos por ahora, y entra porque los dos sistemas de referencia le guardan sitio por separado: Carbon la tiene como Progress Indicator; «Ratio» de IB tiene Progress Steps entre los tres únicos componentes de su sección de portal.
Cuando dos sistemas que no se hablan reservan lugar para la misma pieza, la pieza no es de un negocio. Lo que sigue son tres negocios distintos con la misma pieza, sin una línea de CSS de diferencia entre ellos.
Hitos y palabras del producto. Forma, estados y plazo del sistema.
Cuatro hitos, sin plazo: no todo compromiso lo tiene, y el que no lo tiene no lo muestra.
Tres hitos. Los mismos estados, la misma marca, el mismo plazo — y el negocio no aparece en ninguna clase.
Fallido no es un color más: es un estado del compromiso, y el mensaje sigue terminando en verbo.
La versión que operó en RetiCash hace tres cosas que no viajan, y conviene tenerlas escritas para que no vuelvan a entrar:
| Lo que hacía | Por qué se queda en el producto |
|---|---|
| El hito actual pulsa | El pulso pide una atención que el hito no necesita. Ninguno de los dos sistemas de referencia anima su indicador de proceso. |
| Conector de 3 px redondeado | Carbon usa 1 px recto. El grosor era peso visual sin información. |
| El hito activo se tiñe según compra o venta | Es vocabulario del cambio de divisa. Una póliza no tiene lado. |
La pieza vive en proceso.css, un solo archivo. Este documento la importa y la muestra; el documento del producto la importa y sólo declara sus hitos y sus palabras. Ninguno de los dos la redacta dos veces — que es exactamente lo que permitió que la compuerta fuera falsa en un documento y verdadera en el otro durante media tarde.
proceso.css · cero clases de negocio · cero colores literales fuera del bloque de fichas · un solo umbral, en la frontera · cero animaciones. Sin medir: la geometría y el cambio de orientación en navegador — el panel no ejecuta scripts sobre archivos locales, así que queda declarado, no comprobado.
| Una región | Varias regiones | |
|---|---|---|
| Armazón | fijo, no baja nunca · tronco común · regla 01 | |
| Regiones | una | declaradas, de 2 a 4 |
| Quién manda el alto | el viewport, de los dos lados | |
| Navegación | barra de alcance, abajo | riel con rótulo, al costado |
| Superficies | en sitio · hoja · pantalla empujada · modal | contexto · en sitio · anclada · cajón · modal |
| Lo caro | perder el lugar · se mide en gestos | tapar el dato · se mide en superficie |
| Esquina | su propia escala | su propia escala |
| Reglas | 01 · 22 – 28 | 01 – 16 |
| La frontera | 17 – 21 | |
Corrido contra el código que sirve producción del primer producto. Esta tabla la reescribe verificar.py; si envejece, es porque nadie la corrió — y eso también se ve.
| Regla | Comprobación | Fecha | Resultado |
|---|---|---|---|
| 17 | Hay una frontera, y una sola | 4 sep 2026 | ✗ 2 umbrales de terminal · 1056 · 1312 |
| 17 | Ancho de la tierra de nadie | 4 sep 2026 | ✗ 256 px en total · 1056–1311 px (256) |
| 19 | Ninguna regla cruza · reglas inertes | 4 sep 2026 | ✗ 5 regla(s) declaradas antes de que exista la región · nace en 1312 px |
| — | Umbrales que deciden algo en la plataforma | 4 sep 2026 | ✗ 12 umbrales distintos · 400 · 430 · 520 · 560 · 561 · 600 · 671 · 860 · 900 · 1055 · 1056 · 1312 |
| 02 | Regiones declaradas en columnas, no en píxeles | 4 sep 2026 | ✗ 4 en píxeles · #rc-menu → 78px · .bnav.cds--side-nav--rail: → 74px · .bnav.cds--side-nav.cds--s → 78px |
| 21 | La gramática no consulta el agente de usuario | 4 sep 2026 | ✓ cero en el compositor · 2 en core.js, ajenos a la disposición |
| 21 | Un ancho de cero no decide nada | 4 sep 2026 | ✓ guarda presente en el compositor |
| 27 | Escala de esquina por sistema | 4 sep 2026 | ✗ una región: 17 valores (meta 4) · varias regiones: 0 |
| 28 | Cambiar de vista es navegar | 4 sep 2026 | ✗ el gesto atrás está interceptado para preguntar si salir, no para volver a la vista anterior |
| — | Pieza · proceso: de sistema, no de negocio | 4 sep 2026 | ✓ sin literales · sin negocio · 1 umbral (1055 px) · sin animación |
| — | Pieza · proceso: una sola implementación | 4 sep 2026 | ✗ dos implementaciones · carbon/linea.css aún dibuja: marca · conector · estados · animación |
| 01 | El armazón nunca baja · navegador | 4 sep 2026 | Cumple en una región; en varias, sin medir |
| 06 | Las pestañas no mueven la región · navegador | — | No aplica todavía: no hay pestañas de región |
| 16 | La acción primaria no se abre · navegador | 4 sep 2026 | No cumple: registrar orden exige abrir un panel |
| 18 | El cruce es reversible · navegador | 4 sep 2026 | Huella de ida y vuelta sin comparar |
| 23 | Vuelta al mismo punto de scroll · navegador | — | Sin medir |
| — | Pieza · proceso: geometría y orientación · navegador | — | Sin medir · el panel no ejecuta scripts sobre archivos locales |
Ontikos no trae colores, ni tipografía, ni componentes. Trae la casa; cada producto pone los muebles.
| Lo pone Ontikos | Lo pone el producto |
|---|---|
| El armazón y las regiones | Qué va en cada región |
| Las cinco superficies y su costo | Qué se abre en cada una |
| La frontera y su reversibilidad | En qué ancho cae, y por qué |
| Que haya escala de esquina, de color y de tipografía | Los valores de cada escala |
| Que cada pantalla responda una pregunta y habilite una acción | Cuál es la pregunta y cuál la acción |
| Que toda regla traiga verificación | Que la verificación corra en su tubería |
Este sistema existe porque los cuatro intentos anteriores se escribieron como ideal antes de que nada operara. Éste sale al revés: de un producto que operó. Para que no se repita, la regla de entrada es dura y no admite excepción —
Nada entra a Ontikos sin una verificación que corra y un producto donde haya pasado. Una regla sin comprobación es una opinión con número. De las veintiocho, hoy sólo siete están ganadas; las otras veintiuna llevan su marca a la vista, y no se pueden citar como evidencia hasta que la pierdan.