fix(codex-audit): close P0 + tokenize drift introduced by Words sprint

Three categories of audit drift introduced during the recent Words
sprints (drawer redesign, image float bar, color marks, insert
panel, gutter rail), all caught by the existing contract tests now
that the work has landed:

1. **Undeclared morfo attr** (P0 contracts test):
   `data-words-block-selected` is stamped by the engine's render on
   the atomic-selected block (today only image) but wasn't in the
   morfo's data-attr list. Adds it as optional on the same parts
   array that already declares `data-words-image-*`.

2. **Missing i18n key** (translations:check):
   The drawer part references `components.words.drawer` for its
   aria-label, but the langs catalog was never updated when
   DRAWER-CANON landed. Add `drawer` to
   `src/uix/langs/components/words.ts` (es + en).

3. **Recipe CSS contract drift** (eidos recipe-css-contract test):
   - 3 undeclared CSS vars used in the drawer-Editable styles:
     `--words-toolbar-color` → `--words-command-color`
     `--words-command-hover-bg` → `--words-command-bg-hover`
     `--words-command-active-color` → `--words-command-color-hover`
     (Right names per `lib/recipes/base.ts > words`.)
   - 15 raw font-size literals (0.65rem / 0.7rem / 0.75rem / 0.8rem
     / 0.9rem) replaced with the existing words font-size tokens:
     0.65/0.7rem → `var(--words-status-font-size)`
     0.75/0.8rem → `var(--words-font-size-sm)`
     0.9rem → `var(--words-font-size-md)`

Result:
- `contracts.test.ts`: 31→32 pass (the data-attr violation is gone).
- `translations:check`: 219 refs / 76 catalogs / 0 errors / 0 warnings.
- `recipe-css-contract.test.ts`: 17→19 pass.
- Full `vitest run src/uix`: **867/867** pass (was 865/2-fail before).
- `npm run check` clean (only 6 pre-existing errors unrelated).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
active-uix
dev 4 months ago
parent 08ae867caf
commit d767d88c03

@ -316,7 +316,7 @@
background: var(--words-toolbar-bg);
color: var(--words-command-color);
font: inherit;
font-size: 0.8rem;
font-size: var(--words-font-size-sm);
cursor: pointer;
text-align: start;
transition:
@ -343,7 +343,7 @@
font-weight: var(--words-strong-font-weight);
letter-spacing: 0.02em;
text-transform: uppercase;
font-size: 0.7rem;
font-size: var(--words-status-font-size);
color: var(--words-status-color);
}
@ -401,7 +401,7 @@
border: 0;
background: transparent;
color: var(--words-status-color);
font-size: 0.7rem;
font-size: var(--words-status-font-size);
font-weight: var(--words-strong-font-weight);
letter-spacing: 0.04em;
text-transform: uppercase;
@ -498,7 +498,7 @@
[data-words-drawer-section-subtitle] {
color: var(--words-status-color);
font-size: 0.65rem;
font-size: var(--words-status-font-size);
font-weight: var(--words-strong-font-weight);
letter-spacing: 0.04em;
text-transform: uppercase;
@ -527,7 +527,7 @@
min-block-size: auto;
white-space: normal;
line-height: 1.35;
color: var(--words-toolbar-color);
color: var(--words-command-color);
}
[data-editable][data-words-drawer-editable] [data-editable-preview][data-placeholder-shown] {
@ -560,8 +560,8 @@
[data-editable][data-words-drawer-editable] [data-editable-edit-trigger]:hover {
opacity: 1;
background: var(--words-command-hover-bg);
color: var(--words-command-active-color);
background: var(--words-command-bg-hover);
color: var(--words-command-color-hover);
}
/* Edit mode: stack vertically. Textarea fills the row, action chips
@ -583,7 +583,7 @@
border: var(--words-border-width) solid var(--words-toolbar-border);
border-radius: var(--words-command-radius);
background: var(--words-bg, var(--words-toolbar-bg));
color: var(--words-toolbar-color);
color: var(--words-command-color);
font: inherit;
line-height: 1.35;
outline: none;
@ -641,7 +641,7 @@
gap: 0.2rem;
margin-inline-start: 0.4rem;
color: var(--words-status-color);
font-size: 0.65rem;
font-size: var(--words-status-font-size);
font-weight: normal;
letter-spacing: 0;
text-transform: none;
@ -711,7 +711,7 @@
border-radius: 999px;
background: transparent;
color: var(--words-status-color);
font-size: 0.9rem;
font-size: var(--words-font-size-md);
line-height: 1;
cursor: pointer;
}
@ -965,7 +965,7 @@
align-items: baseline;
gap: var(--words-command-gap);
margin: 0 0 var(--words-toolbar-py-sm) 0;
font-size: 0.7rem;
font-size: var(--words-status-font-size);
font-weight: var(--words-strong-font-weight);
letter-spacing: 0.04em;
text-transform: uppercase;
@ -982,14 +982,14 @@
border-radius: 999px;
background: var(--_words-accent-solid);
color: var(--_words-accent-on);
font-size: 0.65rem;
font-size: var(--words-status-font-size);
}
[data-words-drawer-empty] {
margin: 0;
color: var(--words-status-color);
font-style: italic;
font-size: 0.8rem;
font-size: var(--words-font-size-sm);
}
[data-words-drawer-empty][data-tone='affirm'] {
@ -1011,7 +1011,7 @@
align-items: baseline;
gap: 0.4rem;
padding-inline-start: 0;
font-size: 0.8rem;
font-size: var(--words-font-size-sm);
line-height: 1.3;
}
@ -1027,7 +1027,7 @@
flex-shrink: 0;
min-inline-size: 1.5rem;
color: var(--_words-accent-text);
font-size: 0.65rem;
font-size: var(--words-status-font-size);
font-weight: var(--words-strong-font-weight);
letter-spacing: 0.04em;
}
@ -1050,13 +1050,13 @@
justify-content: space-between;
align-items: baseline;
gap: 0.5rem;
font-size: 0.8rem;
font-size: var(--words-font-size-sm);
}
[data-words-drawer-stats] dt {
margin: 0;
color: var(--words-status-color);
font-size: 0.7rem;
font-size: var(--words-status-font-size);
text-transform: uppercase;
letter-spacing: 0.04em;
}
@ -1080,7 +1080,7 @@
padding-inline: 0.5rem;
border-radius: var(--words-command-radius);
background: color-mix(in srgb, var(--words-toolbar-border) 30%, transparent);
font-size: 0.75rem;
font-size: var(--words-font-size-sm);
line-height: 1.35;
}
@ -1109,7 +1109,7 @@
border-radius: var(--words-command-radius);
background: var(--words-bg);
color: var(--words-command-color);
font-size: 0.75rem;
font-size: var(--words-font-size-sm);
font-weight: var(--words-strong-font-weight);
cursor: pointer;
transition:
@ -1152,7 +1152,7 @@
border-radius: var(--words-command-radius);
background: color-mix(in srgb, var(--words-toolbar-border) 30%, transparent);
color: var(--words-command-color);
font-size: 0.75rem;
font-size: var(--words-font-size-sm);
line-height: 1.35;
word-break: break-all;
}

@ -36,5 +36,9 @@ export const wordsLangs = {
status: {
es: 'Estado del editor',
en: 'Editor status'
},
drawer: {
es: 'Cajón companion del editor',
en: 'Editor companion drawer'
}
} satisfies LangNode;

@ -261,6 +261,13 @@ export const wordsMorfo = {
values: ['pending', 'error'],
severity: 'optional'
},
/**
* Block-selection marker. The engine stamps this on the
* currently atomic-selected block (today only `image` since
* other block types receive a text caret). Eidos selectors
* use it to paint the accent outline + open the float bar.
*/
{ attr: 'data-words-block-selected', severity: 'optional' },
{ attr: 'data-words-cell-header', severity: 'optional' },
{
attr: 'data-words-cell-align',

Loading…
Cancel
Save

Powered by TurnKey Linux.