You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
svelte-kit-vice/docs/audit/components/banner.md

31 lines
2.0 KiB

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
# banner — ficha de auditoría (RE-AUDITADA 2026-07-07, profundidad piloto)
- **Familia**: overlays/avisos (variantes posicionales inline·overlay·persistent) · **Método**: solo análisis · demos fuera
- **Capas leídas**: [morfo](../../../src/uix/morfo/components/banner.ts) (45 líneas; header con la cita de la spec HTML)
uix(banner): la tira de aviso no es la cabecera del sitio, así que deja de reclamar su landmark Toda página con cabecera exponía DOS landmarks banner: el <header> del site-header y la tira de aviso, que estampaba role="banner" a mano. ARIA reserva ese rol para la cabecera DEL SITIO —identidad, búsqueda del sitio— y dice que un documento debería marcar como mucho uno (A-109). Las dos salidas que la ficha proponía estaban mal planteadas, y lo destapó una revisión adversarial de tres refutadores independientes: - «Estampar el rol ANTES de los rest props, que es la clase naming donde gana el consumidor» contradice la doctrina que la propia ficha citaba: role es clase CONTRATO por nombre de atributo (morfo/types.ts:811-832; ARIA_NAMING_ATTRS contiene sólo aria-label). El runtime siempre gana ahí, y con razón: un data-state o un role pisables son un componente que miente. - Y el orden de estampado NUNCA fue el mecanismo. Medido: el segundo landmark es el <header> del site-header, que no lleva atributo role ninguno — recibe banner IMPLÍCITO por ser una <header> fuera de un elemento de sección. Un rol pisable habría dejado quitarlo caso por caso, empujando el arreglo a cada app, en vez de arreglarlo por defecto. - El morfo, además, nunca declaró el rol (aria: []): era un literal del wrapper de eidos que el README daba por contrato de la parte. Drift morfo↔eidos que se queda sin objeto. Lo firmado: la tira deja de reclamar el landmark. defaultElement header→section en el morfo, fuera el role literal. Un <section> es region SÓLO cuando tiene nombre, así que el aria-label del consumidor la hace encontrable y su ausencia la deja como contenido plano — que es exactamente lo que el censo de landmarks de A-111 ya sancionaba por escrito. ⚠️ SIN nombre por defecto, y esta es la corrección que la revisión me obligó a hacer sobre mi propia propuesta: yo había planteado un default traducido («Aviso»), copiando el patrón de skeleton/spinner. Habría convertido TODA tira en landmark sin salida — /temas/grafito apila cuatro y habrían salido cuatro region con el mismo nombre, que es la clase de defecto de A-111 con otro traje. El precedente de <nav> no transfiere: un <nav> es SIEMPRE landmark y por eso pide nombre; un <section> lo es PORQUE lo tiene. Quien quiera una tira encontrable, la nombra. Derogadas por escrito las dos afirmaciones que decían lo contrario, porque existían y estaban firmadas: el README del canon («Banner is a landmark for page-level announcements — site header, persistent notice, system status bar») y el «✓ ejemplar» que docs/audit/components/banner.md le puso a ese contrato el 2026-07-07. La otra mitad de aquella decisión —no role="alert", el feedback transitorio es de Toast— sigue en pie y se dice. Verificado con el árbol AX de Chrome por CDP, servidor limpio: /blocks/landing banner ['Aviso del producto','Acme'] → banner ['Acme'] + region ['Aviso del producto'] /blocks/banner/preview banner ['Principal'] · region ['Aviso del producto'] /temas/grafito banner [] · region [] — las cuatro tiras sin nombre dejan de ser landmarks, que es lo correcto Píxel idéntico: la receta selecciona [data-banner], no el elemento — tira a sangre 1280×54 con el mismo fondo, capturada y mirada. Ningún test, guard, CSS ni consulta del repo seleccionaba por role=banner ni por el tag. Gates: svelte-check 72/62 antes y después · vitest eidos+blocks+morfo 692/693 (el rojo es skin-media-player, ajeno y documentado) · blocks:check 0/19 · docs:check 0/0 (644) · morfo:check PASS en banner. Prosa re-sincronizada en 11 sitios: los README de canon, block y app-shell, la ficha de auditoría, las tres demos, landing y su README. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2 months ago
- ⚠️ **DEROGADO 2026-08-19 (A-109)**: esta ficha calificó «ejemplar» el `role="banner"` explícito. La cita normativa era correcta y la conclusión no: HTML-AAM le quita el rol a una `<header>` anidada **a propósito**, porque ARIA reserva `banner` para la cabecera del SITIO, de la que un documento marca como mucho una. Medido en `/blocks/landing`: la tira y el `site-header` daban dos. El componente pasa a `<section>` sin rol — `region` sólo cuando el consumidor la nombra.
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
- **Máquina**: PASS limpio · README eidos ✓ · vocabulario de variantes posicional (no perceptual — §19) ✓
- **Corrección sobre el pass superficial**: decía "morfo —"; FALSO — morfo eidos-native con razón NORMATIVA escrita: "The explicit role stabilises the landmark across layouts — the HTML spec only grants `role='banner'` to `<header>` when it is a top-level child of `<body>`"
## Dimensiones (evidencia leída)
| # | Dimensión | Estado | Evidencia |
|---|---|---|---|
uix(banner): la tira de aviso no es la cabecera del sitio, así que deja de reclamar su landmark Toda página con cabecera exponía DOS landmarks banner: el <header> del site-header y la tira de aviso, que estampaba role="banner" a mano. ARIA reserva ese rol para la cabecera DEL SITIO —identidad, búsqueda del sitio— y dice que un documento debería marcar como mucho uno (A-109). Las dos salidas que la ficha proponía estaban mal planteadas, y lo destapó una revisión adversarial de tres refutadores independientes: - «Estampar el rol ANTES de los rest props, que es la clase naming donde gana el consumidor» contradice la doctrina que la propia ficha citaba: role es clase CONTRATO por nombre de atributo (morfo/types.ts:811-832; ARIA_NAMING_ATTRS contiene sólo aria-label). El runtime siempre gana ahí, y con razón: un data-state o un role pisables son un componente que miente. - Y el orden de estampado NUNCA fue el mecanismo. Medido: el segundo landmark es el <header> del site-header, que no lleva atributo role ninguno — recibe banner IMPLÍCITO por ser una <header> fuera de un elemento de sección. Un rol pisable habría dejado quitarlo caso por caso, empujando el arreglo a cada app, en vez de arreglarlo por defecto. - El morfo, además, nunca declaró el rol (aria: []): era un literal del wrapper de eidos que el README daba por contrato de la parte. Drift morfo↔eidos que se queda sin objeto. Lo firmado: la tira deja de reclamar el landmark. defaultElement header→section en el morfo, fuera el role literal. Un <section> es region SÓLO cuando tiene nombre, así que el aria-label del consumidor la hace encontrable y su ausencia la deja como contenido plano — que es exactamente lo que el censo de landmarks de A-111 ya sancionaba por escrito. ⚠️ SIN nombre por defecto, y esta es la corrección que la revisión me obligó a hacer sobre mi propia propuesta: yo había planteado un default traducido («Aviso»), copiando el patrón de skeleton/spinner. Habría convertido TODA tira en landmark sin salida — /temas/grafito apila cuatro y habrían salido cuatro region con el mismo nombre, que es la clase de defecto de A-111 con otro traje. El precedente de <nav> no transfiere: un <nav> es SIEMPRE landmark y por eso pide nombre; un <section> lo es PORQUE lo tiene. Quien quiera una tira encontrable, la nombra. Derogadas por escrito las dos afirmaciones que decían lo contrario, porque existían y estaban firmadas: el README del canon («Banner is a landmark for page-level announcements — site header, persistent notice, system status bar») y el «✓ ejemplar» que docs/audit/components/banner.md le puso a ese contrato el 2026-07-07. La otra mitad de aquella decisión —no role="alert", el feedback transitorio es de Toast— sigue en pie y se dice. Verificado con el árbol AX de Chrome por CDP, servidor limpio: /blocks/landing banner ['Aviso del producto','Acme'] → banner ['Acme'] + region ['Aviso del producto'] /blocks/banner/preview banner ['Principal'] · region ['Aviso del producto'] /temas/grafito banner [] · region [] — las cuatro tiras sin nombre dejan de ser landmarks, que es lo correcto Píxel idéntico: la receta selecciona [data-banner], no el elemento — tira a sangre 1280×54 con el mismo fondo, capturada y mirada. Ningún test, guard, CSS ni consulta del repo seleccionaba por role=banner ni por el tag. Gates: svelte-check 72/62 antes y después · vitest eidos+blocks+morfo 692/693 (el rojo es skin-media-player, ajeno y documentado) · blocks:check 0/19 · docs:check 0/0 (644) · morfo:check PASS en banner. Prosa re-sincronizada en 11 sitios: los README de canon, block y app-shell, la ficha de auditoría, las tres demos, landing y su README. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2 months ago
| 8 | Contrato morfo | ~~✓ ejemplar~~ → corregido (A-109) | era `<header data-banner role='banner'>` con la cita de la spec; hoy `<section data-banner>` sin rol propio. `data-intent` → canal color-role estándar |
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
| 10 | Theming | hallazgo | **F-1**: la variante `overlay` flota (banda z) sin estampar depth — al censo |
| 14 | Docs | gap menor | Clasificación formal → SYS-7 |
## Hallazgos y propuestas
| ID | Hallazgo | Propuesta |
|---|---|---|
| **F-1** | overlay-banner sin `data-depth` | Pass conjunto de depth (tooltip/toast/float-panel/banner-overlay) |
| **F-2** | Clasificación formal | SYS-7 |
## Escalan al sistema
SYS-7 · censo depth.
## Veredictos
*(pendiente — checkpoint post-barrido)*

Powered by TurnKey Linux.