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/card-group.md

129 lines
6.7 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.

# card-group — 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-23 · **Alcance**: **90%** — 18 de 20 knobs por token público
- **Knobs de apariencia**: 22 — público 18 · privado 0 · global 0 · literal 2 · sistema 2 · excepción 0 _(los dos últimos, fuera del ratio)_
- **Contrato hoy** (`lib/recipes/base.ts`): 20 pública(s) — `padding-sm`, `padding-md`, `padding-lg`, `grid-gap-sm`, `grid-gap-md`, `grid-gap-lg`, `padding`, `grid-gap`, `card-radius`, `title-font-weight`, `title-fg`, `title-font-family`, `title-font-size`, `title-line-height`, `title-padding-block-end`, `chevron-size`, `chevron-width`, `description-fg`, `description-font-size`, `description-padding-block-end`
- **Eje `size`**: no · **ficheros**: `card-group.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 (2)
| # | fichero:línea | selector | propiedad | valor |
| ---: | --- | --- | --- | --- |
| 1 | `card-group.css:21` | `[data-card-group]` | `inline-size` | `100%` |
| 2 | `card-group.css:107` | `[data-card-group-item]` | `block-size` | `100%` |
### 1.4 Excepciones firmadas (0) — 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.
_Ninguno._
## 2. Sistema transversal (2) — 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 | `card-group.css:22` | `[data-card-group]` | `border-radius` | `var(--shape-outer-radius)` |
| 2 | `card-group.css:71` | `[data-card-group-title-chevron]` | `opacity` | `var(--opacity-muted)` |
## 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` (0)
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 (`--card-group-…`) | scope TSC | valor propuesto | usos |
| --- | --- | --- | ---: |
### 4.2 Sin nombre mecánico (2)
- **⚠ decisión: `100%` es un valor identidad o geometría de layout, no un knob de tema — el perímetro de «knob» es D-TH.2, sin firmar** — 2: `inline-size`, `block-size`.
### 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 -->
**Medido 2026-08-21** (sonda ×2 sobre el mismo código = 0 diffs en 2.581
valores · 7 estados). Es un CASCO de composición —compone ToggleGroup,
Collapsible, Card y Button— y su propia cabecera lo dice: la receta posee
«ONLY the genuinely CardGroup-level visual». Eso acota el contrato antes de
nombrar nada: el cromo de las tarjetas es de `Card`, el del título es de
`Button`, y aquí sólo entra lo del grupo.
1. **`--_cg-pad` y `--_cg-card-radius` son privados ABREVIADOS** (§6 r5 los
prohíbe: `cg` por `card-group`) — el mismo defecto que los `--_mp-*` de
media-player y los `--gp-*` de gradient-picker. Los dos pasan a públicos con
el nombre completo (`padding`, `card-radius`), que es a la vez el renombrado
que la regla pide y la tokenización. **La §3 de esta ficha se equivoca** al
decir «la receta no declara privados propios»: los declara en su bloque raíz
(`card-group.css:15-16`); el escáner no los vio porque los busca con el
prefijo completo del componente.
2. **`--shape-outer-radius` NO se acuña.** Es un token del sistema de forma que
esta receta CALCULA (`calc(card-radius + padding)`) para que las tarjetas
aniden concéntricamente (§30). El censo ya lo clasifica como `system`, y así
se queda: un tema mueve las dos coordenadas y el radio exterior se recompone
solo.
3. **El eje `size` es sm/md/lg, no las cinco tallas**
(`CardGroupSize = Extract<Size, 'sm' | 'md' | 'lg'>`), así que las
coordenadas por talla son SEIS, no diez. Escribir xs/xl habría sido
vocabulario muerto.
4. **Los tres `padding` son shorthand con una parte fija y otra variable**:
`var(--_cg-pad) var(--_cg-pad) var(--space-2)` (título estático),
`0 var(--_cg-pad) var(--space-2)` (descripción) y
`0 var(--_cg-pad) var(--_cg-pad)` (grid). Lo que varía y no es el padding
del grupo es el hueco inferior → `title-padding-block-end` y
`description-padding-block-end`; el resto lo cubre `padding`.
5. **El chevron es geometría propia, no un icono compuesto**: dos bordes
girados 45°. `inline-size` y `block-size` son UN knob (`chevron-size`,
`0.5em`) y la anchura del trazo otro (`chevron-width`). El `currentColor` no
es knob: hereda del título a propósito.
6. **`title-font-weight` lo comparten las dos formas del título** (el botón de
disclosure y el encabezado estático), con el mismo valor. Un solo knob.
7. **Los `font-size` van al BUNDLE, no al primitivo** —
`var(--size-md-font-size)` y `var(--size-sm-font-size)`, alias 1:1— porque
`recipe-css-contract` lo exige y la propuesta generada copia el CSS
verbatim. Es la misma trampa que acaba de caer en `code-block`: cuando el
valor de partida ya incumple el contrato, la propuesta hereda el
incumplimiento.
8. **Fuera del contrato**: los dos `100%` (identidad de layout, D-TH.2) y el
`opacity: var(--opacity-muted)` del chevron (sistema).
Quedan **20 claves** y el alcance esperado ronda el 90 %: lo que no llega son
los dos `100%`.
<!-- veredicto:end -->

Powered by TurnKey Linux.