docs(blocks): el plan de ejecución de V1, con la fase 0 corregida

La ficha de Pricing.Compare reservaba dos decisiones y ahora las tiene, resueltas
por doctrina y no por gusto: los planes los declara el createTable del app y la
parte lo compone —B-5 admite datos sólo donde el canon compuesto ya es
data-driven, y Table lo es—, y en móvil la tabla scrollea con la columna de
características fijada, porque el canon ya da el pinning.

Eso último es una corrección de mi propia fase 0: el README de Table lo lista
como gap diferido y es falso a fecha de hoy — el engine, soma y el recipe lo
implementan los tres. Me apoyé en el README y di un dato equivocado; el primer
paso del plan lo corrige donde vive.

Seis pasos con su verificación cada uno, y los riesgos del árbol compartido
escritos para el agente que lo ejecute.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
alpha-0.1-background
dev 2 months ago
parent 70f45033fd
commit b36247944b

@ -736,6 +736,86 @@ términos, y el primero es el que más trabajo hace:
| **V5** | `cta` | split-with-media | tercer **`layout="split"`** + slot `media` (el nombre que ya usa `hero`); el `Mockup` existe. Es suelo: el dossier la lista | bajo |
| **V8** | `pricing` | single-price | ✅ **HECHA 2026-08-17 — y NO era gratis.** Medido: la fila es `auto-fill`, así que RESERVA las pistas que caben aunque nadie las ocupe → un plan solo daba 315px pegados al borde con 677px de vacío, y `columns={1}` lo cambiaba por una card de 992px. Resuelto con **`.Plans maxWidth`** (tope de fila, centrado, reenviado nombrado por A-94); el número lo pone el app. Detalle: README del block §«The row cap» | ~0 → bajo |
#### Plan de ejecución de V1 — `Pricing.Compare` (firmado 2026-08-17)
**Fase 0 hecha, y con una corrección propia**: el README de `Table` lista el
pinning de columnas como gap diferido, y **es falso a fecha de hoy** — el engine
tiene `enablePinning` por columna e `initialColumnPinning`, soma escribe
`position: sticky` con su offset (`buildColumnStyle`) y el recipe pinta
`[data-pinned]` con un borde que revela lo que hay detrás. La primera versión de
esta fase 0 se apoyó en el README y dio un dato equivocado; el paso 1 lo corrige.
**Las dos decisiones que la ficha reservaba, resueltas por doctrina:**
- **(a) Quién declara los planes → el `createTable` del app, y `.Compare` lo
COMPONE.** B-5 admite `items={…}` «sólo donde el canon compuesto ya es
data-driven», y `Table` lo es: exige la instancia de `createTable`. Así que
`.Compare` NO inventa un formato de matriz propio ni lo traduce por dentro: el
app crea la tabla como en cualquier otra del ecosistema y `.Compare` la recibe.
`.Plans` y `.Compare` CONVIVEN (las refs muestran ambos), alimentados por el
MISMO array del app — sin registro por contexto (acoplamiento por orden de
montaje) y sin sustitución. Descartadas: matriz propia (viola B-5 y duplica el
engine) · registro de `.Plan` en contexto (acopla dos partes que no se hablan).
- **(b) Móvil → scroll horizontal con la columna de características FIJADA.**
Es lo que hacen las referencias y el canon ya lo da (`enablePinning` +
`initialColumnPinning: { left: [...] }`); cero código nuevo, cero gap.
Descartado el colapso a lista por plan: el mismo contenido dos veces, y una
tabla que deja de ser tabla pierde la navegación por celdas que es la razón de
existir de una comparación.
**Qué es `.Compare` (y qué no):**
- **PARTE** de `pricing` (término 4 de la regla de forma): coordina con el
periodo — la fila de precio lee el contexto y muestra la cifra mensual o anual;
el app entrega ambas por snippet, como en `PlanPrice`.
- **Coloca**: fija la columna de características, y sobre las columnas de plan
aplica `featured` (acento) y `state` (`current` atenuado · `selected` con
anillo) — los mismos ejes que `.Plan`, así que **el estado se declara UNA vez
por plan y viaja a las dos vistas**.
- **Posee la semántica**: la tabla lleva su `label` (nombre accesible; el canon
`Table` lo tiene) y las celdas booleanas (✓ / —) el `aria-label` que sus glifos
no dan — palabras del block por idlangref con fallback inglés, como
`PRICING_PLAN_REASON`.
- **No traduce, no formatea, no inventa**: precios por snippet, palabras del app.
**Pasos, cada uno con su verificación:**
1. **Corregir el README de `Table`** (fila «Column pinning» → HECHO, con las tres
capas nombradas) → `docs:check`.
2. **`compare-langs`**: idlangrefs `#?blocks.pricing.compare.included|Included` ·
`.notIncluded|Not included` (para el `aria-label` de las celdas booleanas) →
fila en `blocks-langs.ts` del arnés y test que afirma prefijo + fallback.
3. **`.Compare`** (`pricing-compare.svelte` + tipos): recibe `table`
(`TableInstance`), `label`, y un `plans` alineado con las columnas — `Record`
por id de columna → `{ featured?, state? }` — para pintar acento/estado; fija
la primera columna si el app no pinneó ninguna (default sensato, opt-out con
`pinFeatures={false}`); la fila de precio compone `PlanPrice`; las celdas
booleanas componen `Icon.Check` + `aria-label` → `svelte-check` 0 en `pricing`
- `blocks:check` verde.
4. **Demo**: `createTable` del app con la matriz real (features × 3 planes) ·
control vivo `comparar` sí/no · `.Plans` y `.Compare` a la vez · el toggle de
periodo mueve la fila de precio de la tabla Y las cards a la vez → medido.
5. **Medir** (Playwright, píxeles y AX): 1280 → la tabla es `<table>` real con
`caption`/`aria-label`, columnas de plan con `data-featured`/estado, precio
cambia con el periodo · **375 → la tabla scrollea en horizontal y la columna
de características queda FIJA** (`position: sticky`, `left: 0`, borde de
`[data-pinned]`) · lectura AT: cada celda anuncia fila + columna, ✓/— con
nombre · claro/oscuro · RTL (la columna fija va a `right`).
6. **README + registro** (§«The comparison table» con las dos decisiones y las
medidas; fila de Gaps → SHIPPED; entrada en §7 del plan; handoff).
**Riesgos que el agente debe saber:**
- La otra sesión está tocando `hero/` y `eidos/generated` (componente
`background`): stage SÓLO `src/uix/blocks/pricing`, `web/routes/blocks/pricing`,
`web/routes/blocks/_lib/blocks-langs.ts`, `src/uix/eidos/components/table/README.md`
y los docs de proceso. Nada de `git add -A`, nada de `stash`.
- `Table` con `maxHeight` envuelve su propio scroll; sin él, pega al ancestro.
Aquí NO hay `maxHeight`: el scroll horizontal lo da el `overflow-x` del
contenedor de la tabla — comprobar qué envuelve el recipe antes de asumir.
- El pinning en RTL: soma escribe `${pinned}:${offset}px` con la posición FÍSICA
(`left`/`right`). El plan pide medir en RTL, no asumir que espeja.
**Fuera de la ola, a F5 con disparador** — el dossier declara `stats-band`
**«Paridad OK»**, así que estas dos son _adoptables_, no suelo, y meterlas aquí
diluiría E-2 (que dice suelo = v1, no «todo lo que exista en una referencia»):

Loading…
Cancel
Save

Powered by TurnKey Linux.