From e4bcd505d107a3bd57211d90200d2ef18b9bd29b Mon Sep 17 00:00:00 2001 From: dev Date: Fri, 21 Aug 2026 23:59:30 +0200 Subject: [PATCH] =?UTF-8?q?uix(code):=20temable=20=E2=80=94=200=20%=20?= =?UTF-8?q?=E2=86=92=20100=20%,=20y=20el=20harness=20que=20tambi=C3=A9n=20?= =?UTF-8?q?le=20pisa=20el=20radio?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 6 claves fusionadas en el bloque `code` de `recipes/base.ts` (donde ya vivía el forward de paleta). Censo 0 % → **100 %**: no queda un knob de apariencia fuera del contrato. **Seis de sus trece knobs son SISTEMA y no se acuñan.** `code` es el primitivo tipográfico canónico: sus seis ejes de tipo consumen `--style-code-*` con la escotilla por instancia (`var(--_code-{eje}, var(--style-code-{eje}))`), la forma que D-TH.2-b fijó, y un primitivo no re-declara el vocabulario de su capa. Lo que entra al contrato es el CROMO de las variantes `soft` y `outline`. - El padding es em-relativo a propósito (la píldora crece con el código que envuelve) y lo declaran IGUAL las dos variantes con cromo: un knob por eje, no cuatro. - `--_code-color` sigue privado: conmutador de dos fuentes (tinta de contenido en línea / forward de paleta cuando llega `data-color`), mismo patrón que el borde de foco de textarea. - El `margin: 0` / `padding: 0` / `background: transparent` / `border: 0` de la base es RESET: la variante `plain` es texto desnudo por identidad. EL HALLAZGO — el harness pisa también a `code` (→ next-features §13, ampliado): Medido con CDP: `[data-uix-docs] code` declara `font-family`, `font-size`, `padding` y `border-radius` y gana **(0,1,1)** contra la regla BASE de la receta **(0,1,0)**. En la página de documentación el radio del componente es el del sitio (3px), no el suyo (4px). Sus reglas de VARIANTE (0,2,0) sí ganan, así que el efecto es selectivo y por eso sólo `radius` lee muerto. **No es un caso aislado**: es la misma familia de reglas del harness que tapa el `
` de
code-block con siete propiedades. Cualquier decisión sobre esa regla cubre los
dos componentes.

Artefactos y gates:
- Sonda antes/después = 0 diffs en 174 valores × 7 estados. Determinismo
  verificado.
- R-5.4: 0/6, los seis adjudicados con su medición — `radius` por el harness
  (CDP), los otros cinco porque la demo monta sólo la variante `plain`, sin
  cromo; forzando las variantes, los cinco alcanzan.
- censo --only 100 % · component:audit PASS · rtl:check 0 · docs:check 0 ·
  check por fichero limpio · suite eidos sin rojos nuevos.
- README con «Talla y tema» y tab `Tokens` en la demo (6 claves).

Nota de proceso: el fichero de excepciones llegó a quedar con sintaxis TS
inválida por un apóstrofe sin escapar, y la comprobación que hice lo dio por
bueno porque el `$?` capturado era el del `grep` de la tubería, no el del
guard. Corregido, y re-verificados los ONCE componentes con ledger comprobando
el código de salida REAL: cero fallos.

Co-Authored-By: Claude Fable 5 
---
 docs/audit/theming/README.md                | 12 ++--
 docs/audit/theming/code.md                  | 64 +++++++++------------
 docs/next-features.md                       |  8 +++
 scripts/theming-sentinel-exceptions.ts      | 12 ++++
 src/uix/eidos/components/code/README.md     | 36 ++++++++++++
 src/uix/eidos/components/code/code.css      | 14 ++---
 src/uix/eidos/generated/base.css            |  6 ++
 src/uix/eidos/lib/recipes/base.ts           | 12 ++++
 web/routes/uix/components/code/+page.svelte | 10 +++-
 9 files changed, 123 insertions(+), 51 deletions(-)

diff --git a/docs/audit/theming/README.md b/docs/audit/theming/README.md
index 904ee794c..0355af5f9 100644
--- a/docs/audit/theming/README.md
+++ b/docs/audit/theming/README.md
@@ -10,9 +10,9 @@
 
 - **Medido**: 2026-08-21 · **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**: **49%** — 2281 de 4676 knobs pasan por un token público del componente
-- **Reparto**: público 2281 · privado 635 · global 1189 · literal 571 · sistema transversal 509 _(fuera del ratio)_
-- **Sin token público propio**: 39 · **alcance < 20 %**: 32 · **alcance 100 %**: 8 · **con eje `size`**: 62
+- **Alcance global**: **49%** — 2288 de 4676 knobs pasan por un token público del componente
+- **Reparto**: público 2288 · privado 635 · global 1186 · literal 567 · sistema transversal 509 _(fuera del ratio)_
+- **Sin token público propio**: 38 · **alcance < 20 %**: 31 · **alcance 100 %**: 9 · **con eje `size`**: 62
 
 ## Cómo se lee
 
@@ -91,12 +91,12 @@ theming §6.7 lo pone delante (`hover-bg`). Las fichas proponen la forma
 | 19 | [timeline](./timeline.md) | 24 | 51% | 49 | 45 |
 | 20 | [avatar](./avatar.md) | 23 | 36% | 36 | 0 |
 
-## Sin ningún token público propio (39)
+## Sin ningún token público propio (38)
 
 Ni una clave pública en `lib/recipes/base.ts` — alguno tiene privados forward
 (`_palette-*`), que no son contrato: un tema no puede nombrarlos.
 
-[`alert-dialog`](./alert-dialog.md) · [`announce`](./announce.md) · [`aspect-ratio`](./aspect-ratio.md) · [`auto-grid`](./auto-grid.md) · [`avatar`](./avatar.md) · [`cascade`](./cascade.md) · [`clipboard`](./clipboard.md) · [`code`](./code.md) · [`css-field`](./css-field.md) · [`date-picker`](./date-picker.md) · [`display`](./display.md) · [`field-langs`](./field-langs.md) · [`heading`](./heading.md) · [`highlight`](./highlight.md) · [`knob`](./knob.md) · [`label`](./label.md) · [`mark`](./mark.md) · [`mask-field`](./mask-field.md) · [`menu-dial`](./menu-dial.md) · [`mockup`](./mockup.md) · [`month-grid`](./month-grid.md) · [`motion`](./motion.md) · [`number-field`](./number-field.md) · [`palabras`](./palabras.md) · [`range-calendar`](./range-calendar.md) · [`scroll-frames`](./scroll-frames.md) · [`skeleton`](./skeleton.md) · [`skin-media-player`](./skin-media-player.md) · [`stack`](./stack.md) · [`text`](./text.md) · [`text-blur`](./text-blur.md) · [`text-circular`](./text-circular.md) · [`text-focus`](./text-focus.md) · [`text-gradient`](./text-gradient.md) · [`text-scramble`](./text-scramble.md) · [`virtual-grid`](./virtual-grid.md) · [`virtual-list`](./virtual-list.md) · [`wrap`](./wrap.md) · [`year-grid`](./year-grid.md)
+[`alert-dialog`](./alert-dialog.md) · [`announce`](./announce.md) · [`aspect-ratio`](./aspect-ratio.md) · [`auto-grid`](./auto-grid.md) · [`avatar`](./avatar.md) · [`cascade`](./cascade.md) · [`clipboard`](./clipboard.md) · [`css-field`](./css-field.md) · [`date-picker`](./date-picker.md) · [`display`](./display.md) · [`field-langs`](./field-langs.md) · [`heading`](./heading.md) · [`highlight`](./highlight.md) · [`knob`](./knob.md) · [`label`](./label.md) · [`mark`](./mark.md) · [`mask-field`](./mask-field.md) · [`menu-dial`](./menu-dial.md) · [`mockup`](./mockup.md) · [`month-grid`](./month-grid.md) · [`motion`](./motion.md) · [`number-field`](./number-field.md) · [`palabras`](./palabras.md) · [`range-calendar`](./range-calendar.md) · [`scroll-frames`](./scroll-frames.md) · [`skeleton`](./skeleton.md) · [`skin-media-player`](./skin-media-player.md) · [`stack`](./stack.md) · [`text`](./text.md) · [`text-blur`](./text-blur.md) · [`text-circular`](./text-circular.md) · [`text-focus`](./text-focus.md) · [`text-gradient`](./text-gradient.md) · [`text-scramble`](./text-scramble.md) · [`virtual-grid`](./virtual-grid.md) · [`virtual-list`](./virtual-list.md) · [`wrap`](./wrap.md) · [`year-grid`](./year-grid.md)
 
 ## Tabla completa (162 recetas, por alcance ascendente)
 
@@ -108,7 +108,6 @@ La columna «contrato» cuenta las claves **públicas** del bloque del component
 | [month-grid](./month-grid.md) | 0% | 61 | 0 | 7 | 0 | 5 | 49 | 0 | – |
 | [year-grid](./year-grid.md) | 0% | 61 | 0 | 7 | 0 | 5 | 49 | 0 | – |
 | [field-langs](./field-langs.md) | 0% | 41 | 0 | 0 | 31 | 8 | 2 | 0 | – |
-| [code](./code.md) | 0% | 13 | 0 | 0 | 3 | 4 | 6 | 0 | – |
 | [virtual-list](./virtual-list.md) | 0% | 13 | 0 | 2 | 6 | 4 | 1 | 0 | y |
 | [virtual-grid](./virtual-grid.md) | 0% | 12 | 0 | 2 | 6 | 3 | 1 | 0 | y |
 | [skeleton](./skeleton.md) | 0% | 11 | 0 | 9 | 1 | 1 | 0 | 0 | y |
@@ -249,6 +248,7 @@ La columna «contrato» cuenta las claves **públicas** del bloque del component
 | [chat-list](./chat-list.md) | 100% | 18 | 18 | 0 | 0 | 0 | 0 | 18 | – |
 | [splitter](./splitter.md) | 100% | 18 | 17 | 0 | 0 | 0 | 1 | 15 | – |
 | [link-preview](./link-preview.md) | 100% | 15 | 12 | 0 | 0 | 0 | 3 | 33 | – |
+| [code](./code.md) | 100% | 13 | 7 | 0 | 0 | 0 | 6 | 6 | – |
 | [box](./box.md) | 100% | 9 | 9 | 0 | 0 | 0 | 0 | 43 | – |
 | [display](./display.md) | — | 6 | 0 | 0 | 0 | 0 | 6 | 0 | – |
 | [barcode](./barcode.md) | 100% | 5 | 5 | 0 | 0 | 0 | 0 | 7 | – |
diff --git a/docs/audit/theming/code.md b/docs/audit/theming/code.md
index 8e336a7c1..42352cad6 100644
--- a/docs/audit/theming/code.md
+++ b/docs/audit/theming/code.md
@@ -5,33 +5,24 @@
 > Vista de conjunto: [README](./README.md) · método y protocolo:
 > [`PLAN-theming.md`](../../process/PLAN-theming.md) §1, §2, §7.
 
-- **Medido**: 2026-08-20 · **Alcance**: **0%** — 0 de 7 knobs por token público
-- **Knobs de apariencia**: 13 — público 0 · privado 0 · global 3 · literal 4 · sistema 6 _(fuera del ratio)_
-- **Contrato hoy** (`lib/recipes/base.ts`): 0 pública(s) · 1 privada(s) forward — `_palette-text`
+- **Medido**: 2026-08-21 · **Alcance**: **100%** — 7 de 7 knobs por token público
+- **Knobs de apariencia**: 13 — público 7 · privado 0 · global 0 · literal 0 · sistema 6 _(fuera del ratio)_
+- **Contrato hoy** (`lib/recipes/base.ts`): 6 pública(s) — `radius`, `soft-bg`, `border-width`, `border`, `padding-inline`, `padding-block` · 1 privada(s) forward — `_palette-text`
 - **Eje `size`**: no · **ficheros**: `code.css`
 
 ## 1. Knobs fuera de alcance
 
-### 1.1 Directo a primitivo global (3)
+### 1.1 Directo a primitivo global (0)
 
-| # | fichero:línea | selector | propiedad | valor |
-| ---: | --- | --- | --- | --- |
-| 1 | `code.css:24` | `[data-code]` | `border-radius` | `var(--radius-sm)` |
-| 2 | `code.css:38` | `[data-code][data-variant='soft']` | `background` | `var(--color-neutral-element)` |
-| 3 | `code.css:44` | `[data-code][data-variant='outline']` | `border` | `var(--border-width) solid var(--color-neutral-border)` |
+_Ninguno._
 
 ### 1.2 A través de un privado (0)
 
 _Ninguno._
 
-### 1.3 Literales (4)
+### 1.3 Literales (0)
 
-| # | fichero:línea | selector | propiedad | valor |
-| ---: | --- | --- | --- | --- |
-| 1 | `code.css:39` | `[data-code][data-variant='soft']` | `padding-inline` | `0.32em` |
-| 2 | `code.css:40` | `[data-code][data-variant='soft']` | `padding-block` | `0.1em` |
-| 3 | `code.css:45` | `[data-code][data-variant='outline']` | `padding-inline` | `0.32em` |
-| 4 | `code.css:46` | `[data-code][data-variant='outline']` | `padding-block` | `0.1em` |
+_Ninguno._
 
 ## 2. Sistema transversal (6) — informativo, fuera del ratio
 
@@ -56,26 +47,7 @@ Consumidos y **no declarados en el CSS** (vienen de `base.ts` o de un estilo inl
 
 ## 4. Propuesta de corrección
 
-### 4.1 Tokens a declarar en `lib/recipes/base.ts` (6)
-
-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 (`--code-…`) | scope TSC | valor propuesto | usos |
-| --- | --- | --- | ---: |
-| `radius` | `root` | `var(--radius-sm)` | 1 |
-| `soft-bg` | `root` | `var(--color-neutral-element)` | 1 |
-| `soft-padding-inline` | `root` | `0.32em` | 1 |
-| `soft-padding-block` | `root` | `0.1em` | 1 |
-| `outline-padding-inline` | `root` | `0.32em` | 1 |
-| `outline-padding-block` | `root` | `0.1em` | 1 |
-
-### 4.2 Sin nombre mecánico (1)
-
-- **⚠ decisión: `border` es shorthand o eje físico — hay que partirlo en ejes lógicos antes de nombrarlo (recipe-contract §1, R-4.4)** — 1: `border`.
+_Nada que proponer: no hay knobs fuera de alcance._
 
 ### 4.4 Lo que hay que comprobar a mano (PLAN-theming §1.3 · §7.4)
 
@@ -89,6 +61,24 @@ no distingue lo que debería — se marca `⚠`.
 
 
 
-_(pendiente — lo escribe el autor; se conserva al regenerar)_
+**Medido 2026-08-21.** `code` es el PRIMITIVO TIPOGRÁFICO canónico, y el censo
+ya lo trata como tal: **seis de sus trece knobs son sistema** porque sus seis
+ejes de tipo consumen `--style-code-*` con la escotilla por instancia
+(`var(--_code-{eje}, var(--style-code-{eje}))`), que es la forma que D-TH.2-b
+fijó. **Ninguno de esos seis se acuña** — la capa los posee.
+
+Quedan siete puntuables, y son todos CROMO DE VARIANTE:
+
+1. `radius` (el pill), `soft-bg` y el par `border-width` + `border` del
+   outline.
+2. El `padding` em-relativo (`0.32em` / `0.1em`), declarado IGUAL en las dos
+   variantes con cromo: un knob por eje, no cuatro. Es em-relativo a propósito
+   — la píldora crece con la letra del código que envuelve.
+3. **`--_code-color` no se toca**: es el conmutador de dos fuentes (la tinta de
+   contenido en línea y el forward de paleta cuando llega `data-color`), el
+   mismo patrón que el borde de foco de `textarea`.
+4. `margin: 0`, `padding: 0`, `background: transparent` y `border: 0` de la
+   base son RESET, no knobs: la variante `plain` es texto desnudo por
+   identidad.
 
 
diff --git a/docs/next-features.md b/docs/next-features.md
index 68782652f..14d1582df 100644
--- a/docs/next-features.md
+++ b/docs/next-features.md
@@ -729,6 +729,14 @@ Lo que `code-block` añadió (2026-08-21):
   páginas y a los bloques de código de las fichas: no entra en el commit de un
   componente. Decisión aparte.
 
+  **No es un caso aislado — la misma familia de reglas pisa también a `code`**
+  (medido 2026-08-21 al tokenizarlo, con CDP): `[data-uix-docs] code` declara
+  `font-family`, `font-size`, `padding` y `border-radius`, y gana (0,1,1)
+  contra la regla BASE del componente (0,1,0). Sus reglas de VARIANTE (0,2,0)
+  sí ganan, así que el efecto es selectivo y por eso sólo su `radius` lee
+  muerto — 3px del sitio donde el componente pide 4px. Cualquier decisión sobre
+  la regla del harness cubre los dos componentes.
+
 - **⚠ El guard de claves duplicadas del handoff INSPECCIONA EL VACÍO.** El
   comando documentado en `CONTINUE-theming.md` («Trampas que costaron un commit
   cada una») es
diff --git a/scripts/theming-sentinel-exceptions.ts b/scripts/theming-sentinel-exceptions.ts
index a64460249..aca9d1e75 100644
--- a/scripts/theming-sentinel-exceptions.ts
+++ b/scripts/theming-sentinel-exceptions.ts
@@ -223,6 +223,18 @@ export const SENTINEL_EXCEPTIONS: Record> = {
 		'title-padding-block-end':
 			'static heading not mounted in the demo; forced → reaches (8 → 1234px)'
 	},
+	code: {
+		radius:
+			'the DEMO HARNESS wins: `[data-uix-docs] code` (uix.css, 0-1-1) beats the recipe base rule `[data-code]` (0-1-0) and sets border-radius/padding/font on the inline code — confirmed with CDP matched-rules. The variant rules (0,2,0) DO win, which is why only this base-rule token reads dead. Same harness rule that hides the 
 of code-block (next-features §13)',
+		'soft-bg':
+			"the demo mounts the `plain` variant only (no chrome); forced variant='soft' → reaches (rgb(1,2,3))",
+		'border-width':
+			"the demo mounts `plain` only; forced variant='outline' → reaches (1 → 9px)",
+		border: "the demo mounts `plain` only; forced variant='outline' → reaches (rgb(4,5,6))",
+		'padding-inline':
+			"only the chromed variants pad; forced → reaches (4.12 → 77px), and the variant rule (0,2,0) beats the harness",
+		'padding-block': "only the chromed variants pad; forced → reaches (1.29 → 66px)"
+	},
 	'code-block': {
 		'pre-padding':
 			'the DEMO HARNESS outweighs the component: `[data-uix-docs] pre` (uix.css:801, 0-1-1) beats `[data-code-block-pre]` (0-1-0) and paints padding/border/radius/bg/font on the 
. Forced with !important → reaches (16px 20px → 12px). Seven properties measured, registered in next-features §13'
diff --git a/src/uix/eidos/components/code/README.md b/src/uix/eidos/components/code/README.md
index e95b4e617..74de0161e 100644
--- a/src/uix/eidos/components/code/README.md
+++ b/src/uix/eidos/components/code/README.md
@@ -65,6 +65,42 @@ Adaptaciones para eidos:
 
 Code declara 0 eventos. Visual-only primitive — no estado interactivo.
 
+## Talla y tema
+
+**Guard R-5.4** (`npm run theming:sentinel -- code `): 0/6 en vivo, los
+seis adjudicados con su medición en
+`scripts/theming-sentinel-exceptions.ts`. Corrido 2026-08-21.
+
+Contrato en `lib/recipes/base.ts > code` (6 claves, fusionadas con el forward
+de paleta). Alcance del censo: **100 %** (era 0 %).
+
+**Seis de sus trece knobs son SISTEMA y no se acuñan.** `code` es el primitivo
+tipográfico canónico: sus seis ejes de tipo consumen `--style-code-*` a través
+de la escotilla por instancia (`var(--_code-{eje}, var(--style-code-{eje}))`),
+que es la forma que D-TH.2-b fijó, y un primitivo no re-declara el vocabulario
+de su capa. Lo que entra al contrato es el CROMO que añaden las variantes
+`soft` y `outline`.
+
+El padding es em-relativo a propósito —la píldora crece con el código que
+envuelve— y lo declaran IGUAL las dos variantes con cromo: un knob por eje, no
+cuatro. `--_code-color` se queda privado: es el conmutador de dos fuentes (la
+tinta de contenido en línea y el forward de paleta cuando llega `data-color`),
+el mismo patrón que el borde de foco de `textarea`. El `margin: 0` /
+`padding: 0` / `background: transparent` / `border: 0` de la base es RESET: la
+variante `plain` es texto desnudo por identidad.
+
+### ⚠ En la demo, el harness del sitio le pisa el radio
+
+Medido con CDP el 2026-08-21: `[data-uix-docs] code` (`web/routes/uix/uix.css`)
+declara `font-family`, `font-size`, `padding` y `border-radius`, y gana
+**(0,1,1)** contra la regla BASE de esta receta **(0,1,0)** — en la página de
+documentación el radio del componente es el del sitio (3px) y no el suyo (4px).
+Sus reglas de VARIANTE (0,2,0) sí ganan, así que el efecto es selectivo y por
+eso sólo `radius` lee muerto. Es la misma regla del harness que tapa el `
`
+de `code-block`: cualquier decisión sobre ella cubre los dos
+(`next-features.md` §13). Los otros cinco tokens callan porque la demo monta
+sólo la variante `plain`, sin cromo.
+
 ## Gaps
 
 | Gap | Disposición | Detalle |
diff --git a/src/uix/eidos/components/code/code.css b/src/uix/eidos/components/code/code.css
index a6a1b9469..1e91390dd 100644
--- a/src/uix/eidos/components/code/code.css
+++ b/src/uix/eidos/components/code/code.css
@@ -21,7 +21,7 @@
 	padding: 0;
 	background: transparent;
 	border: 0;
-	border-radius: var(--radius-sm);
+	border-radius: var(--code-radius);
 	vertical-align: baseline;
 }
 
@@ -35,13 +35,13 @@
 }
 
 [data-code][data-variant='soft'] {
-	background: var(--color-neutral-element);
-	padding-inline: 0.32em;
-	padding-block: 0.1em;
+	background: var(--code-soft-bg);
+	padding-inline: var(--code-padding-inline);
+	padding-block: var(--code-padding-block);
 }
 
 [data-code][data-variant='outline'] {
-	border: var(--border-width) solid var(--color-neutral-border);
-	padding-inline: 0.32em;
-	padding-block: 0.1em;
+	border: var(--code-border-width) solid var(--code-border);
+	padding-inline: var(--code-padding-inline);
+	padding-block: var(--code-padding-block);
 }
diff --git a/src/uix/eidos/generated/base.css b/src/uix/eidos/generated/base.css
index 9e7e8802c..cbe4e9a73 100644
--- a/src/uix/eidos/generated/base.css
+++ b/src/uix/eidos/generated/base.css
@@ -2121,6 +2121,12 @@
 	--link-external-icon-size: 0.85em;
 	--link-underline-width: 1px;
 	--link-underline-offset: 2px;
+	--code-radius: var(--radius-sm);
+	--code-soft-bg: var(--color-neutral-element);
+	--code-border-width: var(--border-width);
+	--code-border: var(--color-neutral-border);
+	--code-padding-inline: 0.32em;
+	--code-padding-block: 0.1em;
 	--proof-of-human-min-height-sm: calc(var(--size-sm-control-height) * 3);
 	--proof-of-human-min-height-md: calc(var(--size-md-control-height) * 3);
 	--proof-of-human-min-height-lg: calc(var(--size-lg-control-height) * 3);
diff --git a/src/uix/eidos/lib/recipes/base.ts b/src/uix/eidos/lib/recipes/base.ts
index 6eacee158..26ffb27f1 100644
--- a/src/uix/eidos/lib/recipes/base.ts
+++ b/src/uix/eidos/lib/recipes/base.ts
@@ -3084,6 +3084,18 @@ export const THEME_BASE_RECIPE_TOKENS = defineRecipes({
 		'_palette-text': { value: 'var(--color-primary-text)', scope: 'host' }
 	},
 	code: {
+		// The six TYPE axes are absent on purpose: they consume `--style-code-*`,
+		// the typographic layer, through the per-instance hatch. A primitive does
+		// not re-coin its layer's vocabulary (D-TH.2-b). What lives here is the
+		// chrome the `soft` / `outline` variants add on top.
+		radius: 'var(--radius-sm)',
+		'soft-bg': 'var(--color-neutral-element)',
+		'border-width': 'var(--border-width)',
+		border: 'var(--color-neutral-border)',
+		// em-relative on purpose: the pill grows with the code it wraps. Declared
+		// identically by both chromed variants, so one knob per axis.
+		'padding-inline': '0.32em',
+		'padding-block': '0.1em',
 		'_palette-text': { value: 'var(--color-primary-text)', scope: 'host' }
 	},
 	label: {
diff --git a/web/routes/uix/components/code/+page.svelte b/web/routes/uix/components/code/+page.svelte
index 3bd061c85..26942e6a5 100644
--- a/web/routes/uix/components/code/+page.svelte
+++ b/web/routes/uix/components/code/+page.svelte
@@ -7,8 +7,9 @@
 	} from '$uix/eidos/components/code';
 	import { compileMorfo } from '$uix/morfo';
 	import { codeMorfo } from '@/uix/morfo/components/code';
+	import TokensPanel from '../../lib/TokensPanel.svelte';
 
-	type Tab = 'live' | 'api' | 'morfo' | 'sema' | 'recipe' | 'a11y';
+	type Tab = 'live' | 'api' | 'morfo' | 'sema' | 'recipe' | 'tokens' | 'a11y';
 	type TraceEntry = { event: string; family: string; intent?: string; at: number };
 	let tab = $state('live');
 	let trace = $state([]);
@@ -148,6 +149,9 @@
 		
+		
 		
 	
 
@@ -379,6 +383,10 @@
 		
 	{/if}
 
+	{#if tab === 'tokens'}
+		
+	{/if}
+
 	{#if tab === 'a11y'}
 		

Accessibility