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/theming/skip-link.md

113 lines
5.5 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# skip-link — alcance de tema: análisis y propuesta
> Generado por `node --import tsx/esm scripts/theming-census.ts --report`.
> Lo **medido** y la **propuesta** se regeneran; el **Veredicto** (§5) se conserva.
> Vista de conjunto: [README](./README.md) · método y protocolo:
> [`PLAN-theming.md`](../../process/PLAN-theming.md) §1, §2, §7.
- **Medido**: 2026-08-24 · **Alcance**: **100%** — 5 de 5 knobs por token público
- **Knobs de apariencia**: 6 — público 5 · privado 0 · global 0 · literal 0 · sistema 1 · excepción 2 _(los dos últimos, fuera del ratio)_
- **Contrato hoy** (`lib/recipes/base.ts`): 8 pública(s) — `z-index`, `offset`, `padding-block`, `padding-inline`, `radius`, `bg`, `fg`, `shadow`
- **Eje `size`**: no · **ficheros**: `skip-link.css`
## 1. Knobs fuera de alcance
### 1.1 Directo a primitivo global (0)
_Ninguno._
### 1.2 A través de un privado (0)
_Ninguno._
### 1.3 Literales (0)
_Ninguno._
### 1.4 Excepciones firmadas (2) — fuera del ratio
Literales que llevan su anotación `/* literal: <razón> */` en la propia
declaración: la válvula de recipe-contract §3, la misma que honra
`component-audit`. **Una desviación firmada no es deuda** — se listan para que la
razón se lea, no para acuñarlas.
| # | fichero:línea | selector | propiedad | valor |
| ---: | --- | --- | --- | --- |
| 1 | `skip-link.css:25` | `[data-skip-link]` | `inline-size` | `1px` |
| 2 | `skip-link.css:26` | `[data-skip-link]` | `block-size` | `1px` |
## 2. Sistema transversal (1) — informativo, fuera del ratio
Un tema los alcanza **a nivel de sistema**, por diseño (recipe-contract §2).
| # | fichero:línea | selector | propiedad | valor |
| ---: | --- | --- | --- | --- |
| 1 | `skip-link.css:67` | `[data-skip-link]:focus` | `outline` | `var(--focus-ring-width) solid var(--focus-ring-color)` |
## 3. Privados de la receta — ¿de dónde sale su valor?
_La receta no declara privados propios en su CSS._
## 4. Propuesta de corrección
### 4.1 Tokens a declarar en `lib/recipes/base.ts` (2)
Valor **verbatim** del CSS de hoy: el default no se mueve, sólo cambia quién
puede moverlo. Nombres derivados de recipe-contract §1 (ejes lógicos, talla
al final) y theming §6.7 (slots de color, modificador delante). Un token con
DOS valores distintos es una colisión de nombre: son dos knobs, o el nombre
no distingue lo que debería — se marca `⚠`.
| token (`--skip-link-…`) | scope TSC | valor propuesto | usos |
| --- | --- | --- | ---: |
| `width` | `root` | `1px` | 1 |
| `height` | `root` | `1px` | 1 |
### 4.4 Lo que hay que comprobar a mano (PLAN-theming §1.3 · §7.4)
- [ ] **Privado que no deriva de un público** — §3 lo marca; el privado debe leer el público o desaparecer.
- [ ] **Velo o acento en el nodo equivocado** (`archetype: 'item'` en un envoltorio, un `background` en shorthand que mata la capa de estado) — se mide desde el píxel hacia arriba.
- [ ] **Doble animación** al mover un sello a una superficie con animación propia — registro de `animationstart`/`animationend`.
- [ ] **Diff de computed = 0** en reposo · hover · abierto · disabled · foco, por talla, antes y después.
- [ ] **Centinela por token nuevo**: valor imposible en el root → el nodo lo sigue. Si no, el token miente.
## 5. Veredicto
<!-- veredicto:start -->
**EJECUTADO 2026-08-23 — 71 % → 100 %, y sin una sola clave nueva.** Diff de
computed **0** sobre 192 valores en 7 estados, más 52 valores del estado
ENFOCADO —el único que se ve— medidos aparte; capturas 2× byte a byte
idénticas; centinela **0/8 → 8/8, exit 0, cero adjudicaciones**.
**La §4 pedía `width` y `height`, y las dos son la TÉCNICA.** El `1px × 1px` no
es un tamaño: es la mitad del sr-only canónico (la otra mitad es el par
`clip` / `clip-path`). Un tema que lo mueva no cambia una apariencia, rompe el
mecanismo — y a `0 × 0` algunos motores sacan el enlace del árbol de
accesibilidad, que es exactamente lo único que este componente no puede
permitirse (su propia cabecera lo razona para `display: none`, `visibility` y el
`tabindex` negativo). Van firmados con `/* literal: */`, la válvula de
recipe-contract §3: salen del ratio como ausencia ESCRITA, no como deuda. Es la
misma clase que `text-blur` y `text-scramble`.
**Su 29 % era eso y nada más.** Los 5 knobs restantes ya pasaban por token
público, y las dos ausencias que quedan son doctrina aplicada, no hueco: la
tipografía se HEREDA (no hay `font-*` declarado; acuñarla fijaría el default,
D-TH.5) y el anillo de foco es del SISTEMA (`--focus-ring-*`, recipe-contract
§2). El `background:` en shorthand no mata ninguna capa de estado: su parte
lleva `archetype: 'provider'`, que no recibe velo.
⚠ **El instrumento leía 0 de 8 — la octava clase de punto ciego.** Toda la
superficie de este componente existe SÓLO bajo `:focus`: sr-only mientras no lo
tiene, píldora cuando sí. El guard no lo enfocaba nunca, y el `blur` que hace
tras abrir lo habría deshecho igual; y clicarlo tampoco vale, porque su handler
manda el foco a la región de destino y la píldora se va por el camino. Nace
`openBy: 'focus'` (y con él `openingIsFragile`, el conjunto de aperturas que el
blur y el aparcado del puntero NO deben deshacer — hasta hoy sólo `hover`). Con
eso, 8/8 y ninguna adjudicación. Re-verificados `dialog` (37/44, la cifra exacta
de su commit), `tooltip` (15/23) y `context-menu` (27/28): sin regresión.
**Lo que queda fuera y no es deuda**: nada medible. Los 5 knobs pasan por token
público, 2 son excepción firmada y 1 es sistema.
<!-- veredicto:end -->

Powered by TurnKey Linux.