uix(pin-input): temable — 65 % → 100 %, y un respaldo que mentía por 0,15

Dos claves nuevas (20 → 22), cuatro privados renombrados, VEINTIDÓS respaldos
retirados y seis adjudicaciones medidas. Diff de computed 0 sobre 1.856 valores
en 8 estados.

SU 35 % DE DEUDA ERAN TRES DEFECTOS, NINGUNO DE DISEÑO

1. Un prefijo ABREVIADO: los privados se llamaban --_pin-cell-* dentro de un
   componente llamado pin-input, así que el censo no podía reconocerlos como
   suyos y los cuatro knobs que los leen contaban como deuda aunque DERIVAN de
   públicos. Renombrados a --_pin-input-cell-* — el cuarto caso de esta clase
   tras color-picker, metrics y time-picker.
2. Un respaldo A SÍ MISMO: font-family leía
   var(--style-label-font-family, var(--style-label-font-family)), que es un
   no-op con forma de defecto. Ahora es la costura.
3. La tinta del dígito iba a --color-content-primary a pelo → cell-fg.

Y LOS VEINTIDÓS RESPALDOS ESCRITOS A MANO

Cada var(--pin-input-x, <valor>) duplicaba lo que el contrato ya declara en
:root: código muerto, y retirarlos dio 0 diffs, que es la prueba. Pero UNO
MENTÍA: disabled-opacity respaldaba 0.55 cuando --opacity-disabled vale 0.4.
Es la ley de los `, 1.4` contra un --font-line-height-sm de 1.45 que este mes ya
salió en dos componentes, aquí con más deriva. Un respaldo no es una red de
seguridad: es una segunda fuente que nadie actualiza.

SEIS ADJUDICACIONES, Y DÓNDE VIVE CADA ESTADO

La demo muestra un pin vacío, editable y válido, así que los seis tokens de
estado no tenían nodo. Forzados sobre los nodos reales alcanzan los seis — con
un detalle que costó una pasada: `filled` y `active` son atributos de la CELDA,
pero `invalid` y `readonly` se estampan en el CONTENEDOR y cascadean (soma los
OR-fusiona con el Field que las envuelve). Forzarlos en la celda no hace nada.

VERIFICACIÓN

Sonda antes/después 0 diffs (1.856 valores · 8 estados · 8 nodos) · R-5.4 16/22
con las seis adjudicadas, exit 0 · component:audit PASS · censo --only 100 % ·
eidos-lint 8 morfo-backed / 0 invalid / 0 class-hooks · rtl:check 0 ·
docs:check 0 · suite eidos 439/440 (el rojo conocido) · capturas 2× antes y
después · el ledger sigue en sus 63 hunks previos.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
alpha-0.1-background
dev 2 months ago
parent 2ebeb9b16c
commit 4b9354bba2

@ -10,9 +10,9 @@
- **Medido**: 2026-08-23 · **162 recetas** con CSS + **8 componentes sin receta** = 170 fichas, el árbol entero de `eidos/components/`
- **La pregunta**: ¿cuánto de la apariencia de cada componente puede cambiar un tema **sin tocar el sistema ni la receta**?
- **Alcance global**: **66%** — 3034 de 4578 knobs pasan por un token público del componente
- **Reparto**: público 3034 · privado 317 · global 827 · literal 400 · sistema transversal 509 · excepción firmada 131 _(los dos últimos, fuera del ratio)_
- **Sin token público propio**: 24 · **alcance < 20 %**: 12 · **alcance 100 %**: 27 · **con eje `size`**: 57
- **Alcance global**: **66%** — 3040 de 4578 knobs pasan por un token público del componente
- **Reparto**: público 3040 · privado 317 · global 821 · literal 400 · sistema transversal 509 · excepción firmada 131 _(los dos últimos, fuera del ratio)_
- **Sin token público propio**: 24 · **alcance < 20 %**: 12 · **alcance 100 %**: 28 · **con eje `size`**: 57
## Cómo se lee
@ -140,7 +140,6 @@ La columna «contrato» cuenta las claves **públicas** del bloque del component
| [password-field](./password-field.md) | 62% | 35 | 21 | 2 | 2 | 9 | 1 | 30 | y |
| [clipboard](./clipboard.md) | 63% | 8 | 5 | 2 | 1 | 0 | 0 | 6 | – |
| [spinner](./spinner.md) | 64% | 25 | 16 | 5 | 0 | 4 | 0 | 18 | – |
| [pin-input](./pin-input.md) | 65% | 18 | 11 | 0 | 6 | 0 | 1 | 20 | y |
| [tag-group](./tag-group.md) | 65% | 46 | 28 | 14 | 0 | 1 | 3 | 91 | y |
| [popover](./popover.md) | 67% | 51 | 32 | 4 | 12 | 0 | 3 | 46 | y |
| [dialog](./dialog.md) | 67% | 36 | 24 | 4 | 7 | 1 | 0 | 37 | y |
@ -234,6 +233,7 @@ La columna «contrato» cuenta las claves **públicas** del bloque del component
| [text](./text.md) | — | 24 | 0 | 0 | 0 | 0 | 24 | 0 | – |
| [breadcrumb](./breadcrumb.md) | 100% | 23 | 20 | 0 | 0 | 0 | 3 | 28 | y |
| [chat-list](./chat-list.md) | 100% | 18 | 18 | 0 | 0 | 0 | 0 | 18 | – |
| [pin-input](./pin-input.md) | 100% | 18 | 17 | 0 | 0 | 0 | 1 | 22 | y |
| [splitter](./splitter.md) | 100% | 18 | 17 | 0 | 0 | 0 | 1 | 15 | – |
| [empty-state](./empty-state.md) | 100% | 17 | 17 | 0 | 0 | 0 | 0 | 26 | y |
| [link-preview](./link-preview.md) | 100% | 17 | 14 | 0 | 0 | 0 | 3 | 35 | – |

@ -5,23 +5,16 @@
> 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**: **65%** — 11 de 17 knobs por token público
- **Knobs de apariencia**: 18 — público 11 · privado 0 · global 6 · literal 0 · sistema 1 · excepción 1 _(los dos últimos, fuera del ratio)_
- **Contrato hoy** (`lib/recipes/base.ts`): 20 pública(s) — `gap`, `disabled-opacity`, `cell-size-sm`, `cell-size-md`, `cell-size-lg`, `cell-size-xl`, `cell-font-size-sm`, `cell-font-size-md`, `cell-font-size-lg`, `cell-font-size-xl`, `cell-font-weight`, `cell-radius`, `cell-border-width`, `cell-border-fg`, `cell-bg`, `cell-filled-bg`, `cell-filled-border`, `cell-active-border`, `cell-invalid-border`, `cell-readonly-bg`
- **Medido**: 2026-08-23 · **Alcance**: **100%** — 17 de 17 knobs por token público
- **Knobs de apariencia**: 18 — público 17 · privado 0 · global 0 · literal 0 · sistema 1 · excepción 1 _(los dos últimos, fuera del ratio)_
- **Contrato hoy** (`lib/recipes/base.ts`): 22 pública(s) — `gap`, `disabled-opacity`, `cell-size-sm`, `cell-size-md`, `cell-size-lg`, `cell-size-xl`, `cell-font-size-sm`, `cell-font-size-md`, `cell-font-size-lg`, `cell-font-size-xl`, `font-family`, `cell-fg`, `cell-font-weight`, `cell-radius`, `cell-border-width`, `cell-border-fg`, `cell-bg`, `cell-filled-bg`, `cell-filled-border`, `cell-active-border`, `cell-invalid-border`, `cell-readonly-bg`
- **Eje `size`**: sí · **ficheros**: `pin-input.css`
## 1. Knobs fuera de alcance
### 1.1 Directo a primitivo global (6)
### 1.1 Directo a primitivo global (0)
| # | fichero:línea | selector | propiedad | valor |
| ---: | --- | --- | --- | --- |
| 1 | `pin-input.css:23` | `[data-pin-input]` | `font-family` | `var(--style-label-font-family, var(--style-label-font-family))` |
| 2 | `pin-input.css:41` | `[data-pin-input-cell]` | `inline-size` | `var(--_pin-cell-size)` |
| 3 | `pin-input.css:42` | `[data-pin-input-cell]` | `block-size` | `var(--_pin-cell-size)` |
| 4 | `pin-input.css:45` | `[data-pin-input-cell]` | `border-radius` | `var(--_pin-cell-radius)` |
| 5 | `pin-input.css:47` | `[data-pin-input-cell]` | `color` | `var(--color-content-primary)` |
| 6 | `pin-input.css:48` | `[data-pin-input-cell]` | `font-size` | `var(--_pin-cell-font-size)` |
_Ninguno._
### 1.2 A través de un privado (0)
@ -51,13 +44,17 @@ Un tema los alcanza **a nivel de sistema**, por diseño (recipe-contract §2).
## 3. Privados de la receta — ¿de dónde sale su valor?
_La receta no declara privados propios en su CSS._
| privado | declaraciones | valor(es) | origen | ¿deriva de un público? |
| --- | ---: | --- | --- | :-: |
| `--_pin-input-cell-size` | 4 | `var(--pin-input-cell-size-md)`, `var(--pin-input-cell-size-sm)`, `var(--pin-input-cell-size-lg)`, `var(--pin-input-cell-size-xl)` | public | **sí** |
| `--_pin-input-cell-font-size` | 4 | `var(--pin-input-cell-font-size-md)`, `var(--pin-input-cell-font-size-sm)`, `var(--pin-input-cell-font-size-lg)`, `var(--pin-input-cell-font-size-xl)` | public | **sí** |
| `--_pin-input-cell-radius` | 1 | `var(--pin-input-cell-radius)` | public | **sí** |
## 4. Propuesta de corrección
- **Tiene eje `size`**: los tokens dimensionales van por talla (`{part}-{eje}-{k}`) apuntando al bundle `--size-{k}-*`, nunca al primitivo crudo (theming §5; el guard `recipe-css-contract` prohíbe el primitivo).
### 4.1 Tokens a declarar en `lib/recipes/base.ts` (6)
### 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
@ -67,12 +64,6 @@ no distingue lo que debería — se marca `⚠`.
| token (`--pin-input-…`) | scope TSC | valor propuesto | usos |
| --- | --- | --- | ---: |
| `font-family` | `root` | `var(--style-label-font-family, var(--style-label-font-family))` | 1 |
| `cell-width` | `root` | `var(--_pin-cell-size)` | 1 |
| `cell-height` | `root` | `var(--_pin-cell-size)` | 1 |
| `cell-radius` _(ya existe)_ | `root` | `var(--_pin-cell-radius)` | 1 |
| `cell-fg` | `root` | `var(--color-content-primary)` | 1 |
| `cell-font-size` | `root` | `var(--_pin-cell-font-size)` | 1 |
### 4.2 Sin nombre mecánico (1)
@ -90,6 +81,41 @@ no distingue lo que debería — se marca `⚠`.
<!-- veredicto:start -->
_(pendiente — lo escribe el autor; se conserva al regenerar)_
**EJECUTADO 2026-08-23 — 65 % → 100 %.** Dos claves nuevas (20 → 22), cuatro
privados renombrados, **veintidós respaldos retirados** y seis adjudicaciones
medidas. Diff de computed **0 sobre 1.856 valores en 8 estados**.
**Su 35 % de deuda eran tres defectos, ninguno de diseño.**
1. **Un prefijo ABREVIADO.** Los privados se llamaban `--_pin-cell-*` dentro de
un componente llamado `pin-input`: el censo no podía reconocerlos como suyos,
así que los cuatro knobs que los leen (tamaño, radio y tipo de la celda)
contaban como deuda aunque DERIVAN de públicos. Renombrados a
`--_pin-input-cell-*` — el cuarto caso de esta clase tras `color-picker`,
`metrics` y `time-picker`.
2. **Un respaldo a SÍ MISMO**: `font-family` leía
`var(--style-label-font-family, var(--style-label-font-family))`, que es un
no-op con forma de defecto. Ahora es la costura: `--pin-input-font-family`.
3. **La tinta del dígito** iba a `--color-content-primary` a pelo → `cell-fg`.
**Y los veintidós respaldos escritos a mano.** Cada `var(--pin-input-x, <valor>)`
duplicaba lo que el contrato ya declara en `:root`, así que eran código muerto —
retirarlos dio **0 diffs**, que es la prueba. Pero uno **mentía**:
`disabled-opacity` respaldaba `0.55` cuando `--opacity-disabled` vale **0.4**.
Es la ley de los `, 1.4` contra un `--font-line-height-sm` de 1.45 que este mes
salió en dos componentes, aquí con más deriva. **Un respaldo no es una red de
seguridad: es una segunda fuente que nadie actualiza.**
**Las seis adjudicaciones, y dónde vive cada estado.** La demo muestra un pin
vacío, editable y válido, así que los seis tokens de estado no tenían nodo.
Forzados sobre los nodos reales, los seis alcanzan — con un detalle que costó una
pasada: `filled` y `active` son atributos de la CELDA, pero `invalid` y
`readonly` se estampan en el CONTENEDOR y cascadean a las celdas (soma los
OR-fusiona con el Field que las envuelve). Forzarlos en la celda no hace nada.
**Verificación**: sonda antes/después **0 diffs** (1.856 valores · 8 estados · 8
nodos) · R-5.4 **16/22** con las seis adjudicadas, exit 0 · `component:audit`
PASS · censo **100 %** · `eidos-lint` 8 morfo-backed / **0 invalid, 0
class-hooks** · capturas 2× antes y después.
<!-- veredicto:end -->

@ -77,6 +77,24 @@ export const SENTINEL_EXCEPTIONS: Record<string, Record<string, string>> = {
'radius-sm': 'only the step in force paints; forced data-rounded=sm → reaches (4px → 37px)',
'radius-lg': 'only the step in force paints; forced data-rounded=lg → reaches (10px → 37px)'
},
'pin-input': {
// 2026-08-23. Six STATE tokens: the demo shows an empty, editable, valid
// pin. Forced on the real nodes — note WHERE: `filled` and `active` are
// per-CELL attributes, but `invalid` and `readonly` are stamped on the
// CONTAINER and cascade down (forcing them on the cell does nothing).
'cell-filled-bg':
'no filled cell in the demo; forced data-filled -> reaches (oklch(0.9588 0.0249 311.71) -> rgb(1,2,3))',
'cell-filled-border':
'same state; forced -> reaches (oklch(0.8043 0.0918 309.69) -> rgb(1,2,3))',
'cell-active-border':
'the cell under the caret; forced data-active -> reaches (oklch(0.5556 0.1829 305.86) -> rgb(1,2,3))',
'cell-invalid-border':
'stamped on the CONTAINER (soma OR-merges it with the enclosing Field); forced there -> reaches (oklch(0.6256 0.1933 23.03) -> rgb(1,2,3))',
'cell-readonly-bg':
'container attribute too; forced there -> reaches (oklch(0.9551 0 0) -> rgb(1,2,3))',
'disabled-opacity':
'no disabled pin in the demo; forced data-disabled -> reaches (0.4 -> 0.137)'
},
'spin-field': {
// 2026-08-23. Measured inside number-field (this is a shared LAYER with no
// route of its own), transitions frozen except for the last pair.

@ -69,6 +69,39 @@ The component IS interactive from the user's perspective. "Passive"
here is a contract-layer classification, not a UX one — same logic
as `<AlertDialog>` (delegates events to the underlying primitive).
## Talla y tema
**22 claves públicas** en `lib/recipes/base.ts`: la caja (`gap`,
**`font-family`**, `disabled-opacity`), la celda por talla
(`cell-size-{sm…xl}`, `cell-font-size-{sm…xl}`) y su cromo
(`cell-radius`, `cell-border-width`, `cell-border-fg`, `cell-bg`,
**`cell-fg`**, `cell-font-weight`) más los cuatro estados
(`cell-filled-{bg,border}`, `cell-active-border`, `cell-invalid-border`,
`cell-readonly-bg`). La pestaña **Tokens** de su demo las resuelve en vivo.
Lo que entró el **2026-08-23** (65 % → 100 %):
- **`font-family`** — la costura. La receta leía
`var(--style-label-font-family, var(--style-label-font-family))`: un respaldo
A SÍ MISMO, que es un no-op con forma de defecto.
- **`cell-fg`** — la tinta del dígito, que iba a `--color-content-primary` a pelo.
- **Los privados dejan de usar un prefijo ABREVIADO**: eran `--_pin-cell-*`
dentro de un componente llamado `pin-input`, así que el censo no podía
reconocerlos como suyos y contaba sus cuatro knobs como deuda. Ahora son
`--_pin-input-cell-*` (mismo caso que `color-picker`, `metrics` y
`time-picker`).
- **Fuera los veintidós respaldos escritos a mano.** Cada `var(--pin-input-x, …)`
duplicaba el valor que el contrato ya declara en `:root`, así que eran código
muerto — y **uno mentía**: `disabled-opacity` respaldaba `0.55` cuando
`--opacity-disabled` vale `0.4`. Es la ley de los `, 1.4` del mismo mes, con
más deriva. Retirados: **0 diffs**, la prueba de que el token siempre llegaba.
**Lo que el guard da por silencioso**: los seis tokens de ESTADO, porque la demo
muestra un pin vacío, editable y válido. Todos medidos forzando el atributo
sobre el nodo real — y ojo a DÓNDE: `filled` y `active` son de la CELDA, pero
`invalid` y `readonly` se estampan en el CONTENEDOR y cascadean (forzarlos en la
celda no hace nada).
## Baseline
WAI-ARIA Textbox pattern:

@ -19,34 +19,34 @@
[data-pin-input] {
display: inline-flex;
align-items: center;
gap: var(--pin-input-gap, var(--space-2));
font-family: var(--style-label-font-family, var(--style-label-font-family));
gap: var(--pin-input-gap);
font-family: var(--pin-input-font-family);
}
[data-pin-input][data-disabled] {
opacity: var(--pin-input-disabled-opacity, 0.55);
opacity: var(--pin-input-disabled-opacity);
pointer-events: none;
}
/* ── Cell ─────────────────────────────────────────────────────────── */
[data-pin-input-cell] {
--_pin-cell-size: var(--pin-input-cell-size-md, 2.5rem);
--_pin-cell-font-size: var(--pin-input-cell-font-size-md, var(--font-size-lg));
--_pin-cell-radius: var(--pin-input-cell-radius, var(--radius-md));
--_pin-input-cell-size: var(--pin-input-cell-size-md);
--_pin-input-cell-font-size: var(--pin-input-cell-font-size-md);
--_pin-input-cell-radius: var(--pin-input-cell-radius);
display: inline-flex;
align-items: center;
justify-content: center;
inline-size: var(--_pin-cell-size);
block-size: var(--_pin-cell-size);
border: var(--pin-input-cell-border-width, 1px) solid
var(--pin-input-cell-border-fg, var(--color-border-default));
border-radius: var(--_pin-cell-radius);
background: var(--pin-input-cell-bg, var(--color-surface-default));
color: var(--color-content-primary);
font-size: var(--_pin-cell-font-size);
font-weight: var(--pin-input-cell-font-weight, 500);
inline-size: var(--_pin-input-cell-size);
block-size: var(--_pin-input-cell-size);
border: var(--pin-input-cell-border-width) solid
var(--pin-input-cell-border-fg);
border-radius: var(--_pin-input-cell-radius);
background: var(--pin-input-cell-bg);
color: var(--pin-input-cell-fg);
font-size: var(--_pin-input-cell-font-size);
font-weight: var(--pin-input-cell-font-weight);
font-variant-numeric: tabular-nums;
line-height: 1; /* literal: cells are single-glyph, line-height collapse */
user-select: none;
@ -57,48 +57,48 @@
}
[data-pin-input-cell][data-filled] {
background: var(--pin-input-cell-filled-bg, var(--color-primary-element));
border-color: var(--pin-input-cell-filled-border, var(--color-primary-border));
background: var(--pin-input-cell-filled-bg);
border-color: var(--pin-input-cell-filled-border);
}
[data-pin-input-cell][data-active] {
border-color: var(--pin-input-cell-active-border, var(--color-primary-solid));
border-color: var(--pin-input-cell-active-border);
/* Focus ring as a flush outline (no offset → no gap) — survives forced-colors. */
outline: var(--focus-ring-width) solid var(--focus-ring-color);
outline-offset: 0;
}
[data-pin-input-cell][data-disabled] {
opacity: var(--pin-input-disabled-opacity, 0.55);
opacity: var(--pin-input-disabled-opacity);
}
/* Invalid (Field-aware). Soma OR-merges `invalid` with the enclosing
* Field's state; both surface as `data-invalid` on the container which
* we cascade to cells. */
[data-pin-input][data-invalid] [data-pin-input-cell] {
border-color: var(--pin-input-cell-invalid-border, var(--color-threat-solid));
border-color: var(--pin-input-cell-invalid-border);
}
/* Read-only — cells keep their value visible but read as non-editable
* (muted surface, no text cursor), mirroring the date-field segment. */
[data-pin-input][data-readonly] [data-pin-input-cell] {
background: var(--pin-input-cell-readonly-bg, var(--color-surface-muted));
background: var(--pin-input-cell-readonly-bg);
cursor: default;
}
/* ── Size cascade ─────────────────────────────────────────────────── */
[data-pin-input][data-size='sm'] [data-pin-input-cell] {
--_pin-cell-size: var(--pin-input-cell-size-sm, 2rem);
--_pin-cell-font-size: var(--pin-input-cell-font-size-sm, var(--font-size-md));
--_pin-input-cell-size: var(--pin-input-cell-size-sm);
--_pin-input-cell-font-size: var(--pin-input-cell-font-size-sm);
}
[data-pin-input][data-size='lg'] [data-pin-input-cell] {
--_pin-cell-size: var(--pin-input-cell-size-lg, 3rem);
--_pin-cell-font-size: var(--pin-input-cell-font-size-lg, var(--font-size-xl));
--_pin-input-cell-size: var(--pin-input-cell-size-lg);
--_pin-input-cell-font-size: var(--pin-input-cell-font-size-lg);
}
[data-pin-input][data-size='xl'] [data-pin-input-cell] {
--_pin-cell-size: var(--pin-input-cell-size-xl, 3.5rem);
--_pin-cell-font-size: var(--pin-input-cell-font-size-xl, var(--font-size-xxl));
--_pin-input-cell-size: var(--pin-input-cell-size-xl);
--_pin-input-cell-font-size: var(--pin-input-cell-font-size-xl);
}

@ -4269,6 +4269,8 @@
--pin-input-cell-font-size-md: var(--size-lg-font-size);
--pin-input-cell-font-size-lg: var(--size-xl-font-size);
--pin-input-cell-font-size-xl: var(--size-xxl-font-size);
--pin-input-font-family: var(--style-label-font-family);
--pin-input-cell-fg: var(--color-content-primary);
--pin-input-cell-font-weight: 500;
--pin-input-cell-radius: var(--radius-md);
--pin-input-cell-border-width: var(--border-width);

@ -6929,6 +6929,13 @@ export const THEME_BASE_RECIPE_TOKENS = defineRecipes({
'cell-font-size-md': 'var(--size-lg-font-size)',
'cell-font-size-lg': 'var(--size-xl-font-size)',
'cell-font-size-xl': 'var(--size-xxl-font-size)',
// The face is the named typographic layer's; the KNOB is this component's
// (the seam), so a theme can give the code cells another face without
// moving `label` across the app. It used to read
// `var(--style-label-font-family, var(--style-label-font-family))` — a
// fallback to ITSELF, which is a no-op wearing the shape of a default.
'font-family': 'var(--style-label-font-family)',
'cell-fg': 'var(--color-content-primary)',
'cell-font-weight': '500',
'cell-radius': 'var(--radius-md)',
'cell-border-width': 'var(--border-width)',

@ -7,8 +7,9 @@
import { Field } from '$uix/eidos/components/field';
import { compileMorfo } from '$uix/morfo';
import { pinInputMorfo } from '@/uix/morfo/components/pin-input';
import TokensPanel from '../../lib/TokensPanel.svelte';
type Tab = 'live' | 'api' | 'morfo' | 'sema' | 'recipe' | 'a11y';
type Tab = 'live' | 'api' | 'morfo' | 'sema' | 'recipe' | 'tokens' | 'a11y';
let tab = $state<Tab>('live');
const sizes: PinInputSize[] = ['sm', 'md', 'lg', 'xl'];
@ -300,6 +301,9 @@
<span data-uix-tab-count>{events.length}</span>
</button>
<button data-uix-tab data-active={tab === 'recipe'} onclick={() => (tab = 'recipe')}>Recipe</button>
<button data-uix-tab data-active={tab === 'tokens'} onclick={() => (tab = 'tokens')}>
Tokens <span data-uix-tab-count>22</span>
</button>
<button data-uix-tab data-active={tab === 'a11y'} onclick={() => (tab = 'a11y')}>A11y</button>
</div>
@ -737,6 +741,10 @@
</section>
{/if}
{#if tab === 'tokens'}
<TokensPanel component="pin-input" stage={stageRef ?? undefined} />
{/if}
{#if tab === 'recipe'}
<section data-uix-section>
<h2 data-uix-section-title>Eidos recipe</h2>

Loading…
Cancel
Save

Powered by TurnKey Linux.