skill
Adom UI Design System
Public Made by Adomby adom
How the AI builds and tests interfaces people love to use in Adom. Ships as one installable skill that bundles focused skills (tooltips, floating-windows, toasts, responsive-ui, app-shell, ai-driven-apps, clickable-paths).
← Commit history
2.21.0 ships module 2.20.1: the refusal returns rows:[] so it cannot arrive as a TypeError; name the layer with the number
3 files changed
+42−8
assets/module/newbie-panel.js+11−5@@ -419,11 +419,17 @@ * as a specific layout regression rather than an invalid run, and project-manager nearly * filed it as a bug. A refusal cannot be misread. (project-manager, 2026-08-25.) */ var w0 = Math.round(panel.getBoundingClientRect().width);- if (w0 === 0) return { ok: false, invalid: true,- error: 'panel measures 0px wide: this tab is not foregrounded, so every layout row would ' ++ /* rows: [] is deliberate. The refusal previously omitted the key entirely, and EVERY+ * caller does r.rows.map(...) because every healthy result has rows, so a correct refusal+ * arrived at the caller as "Cannot read properties of undefined (reading 'map')" and read+ * like harness noise. kicad hit exactly that and logged it as its own crash. A guard whose+ * failure mode is a TypeError in someone else's stack is a guard that will be misread. */+ if (w0 === 0) return { ok: false, invalid: true, rows: [],+ error: 'panel measures 0px wide: this tab is not foregrounded (or the panel is hidden), ' ++ 'so every layout row would ' + 'be computed from a collapsed pane while the style rows pass normally. Activate ' +- 'the tab by name and re-run. No rows reported, because a partial result from an ' +- 'unrendered pane looks like a real bug.' };+ 'the tab by name (or open the panel) and re-run. No rows reported, because a ' ++ 'partial result from an unrendered pane looks like a real bug.' }; var cs = getComputedStyle(panel), rows = [], ok = true; /* Chrome reports the USED border-width, snapped to whole device pixels, so a declared * 1px reads as 0.666667px at dpr 1.5. Compare against the snapped value, not the@@ -587,6 +593,6 @@ } root.AdomNewbiePanel = { mount: mount, toast: toast, selfCheck: selfCheck, copyText: copyText,- checkSend: checkSend, version: '2.19.1',+ checkSend: checkSend, version: '2.20.1', TWO_COL_MIN: TWO_COL_MIN, PHRASE_BUDGET: PHRASE_BUDGET }; })(typeof window !== 'undefined' ? window : this);
package.json+1−1@@ -1,6 +1,6 @@ { "slug": "adom-ui-design",- "version": "2.20.0",+ "version": "2.21.0", "type": "skill", "description": "The Adom UI Design System plus a bundle of focused UI skills (tooltips, floating-windows, toasts, responsive-ui, app-shell, ai-driven-apps, clickable-paths, dark-default, input-feedback, settings-layout). One install drops the whole set of skill files onto your container, plus shared icon assets (the settings cog) so every Adom app draws the same glyph.", "dependencies": {},
skills/newbie-panel/SKILL.md+30−2@@ -654,8 +654,16 @@ when the habit fails. Have both. ### ⛔ A PARTIAL RESULT FROM AN UNRENDERED PANE IS WORSE THAN NO RESULT -`selfCheck` now **refuses to report** when the panel measures 0px wide, returning-`{ok:false, invalid:true, error:...}` and **no rows at all.**+`selfCheck` **refuses to report** when the panel measures 0px wide, returning+`{ok:false, invalid:true, rows:[], error:...}`.++**CHECK `invalid` BEFORE TOUCHING `rows`.** The first version omitted the `rows` key entirely,+and every caller does `r.rows.map(...)` because every healthy result has rows — so a correct+refusal arrived as `Cannot read properties of undefined (reading 'map')` and read like harness+noise. kicad hit exactly that and logged it as its own crash before finding the guard in the+source. It now returns `rows: []`, so the shape is safe, but branch on `invalid` anyway or you+will report an empty pass. **A guard whose failure mode is a TypeError in someone else's stack+is a guard that will be misread.** The reason is the most dangerous instrument shape found all day. An unforegrounded tab returns zero-height rects **while computed styles still resolve normally**, so the check produced@@ -672,6 +680,26 @@ The general form, worth more than the panel: **when an instrument can detect tha preconditions are unmet, it must refuse, not degrade.** Degrading produces confident wrong answers that cost someone a bug hunt. +### ⛔ NAME THE LAYER WITH THE NUMBER. THE PACKAGE AND THE MODULE ARE DIFFERENT VERSIONS.++`adom-ui-design` **2.20.0 ships module 2.19.1.** They move independently by design: a doc-only+package release deliberately leaves the module's bytes untouched, which is what makes an+unchanged sha a positive signal.++**So "the module is at 2.20.0" is a sentence that cannot be true**, and an app told it will+grep its vendored file, find 2.19.1, conclude it is behind, and either re-vendor an identical+file or hunt for an asset version that does not exist. kicad caught this on the way into a+convergence sweep.++Always say: **package X ships module Y, sha Z.** And the convergence question is never "what+version are you on", it is:++> **does my asset's sha match the asset in the current package?**++A sha comparison also survives a stale files-endpoint, which a version string does not. kicad's+form, converged three ways and byte-identical: the package source under+`~/.claude/skills/adom-ui-design/assets/module/`, its own working copy, and the INSTALLED tree.+ ### A PURE LAYOUT NUMBER DOES NOT NEED A SLOT ON HIS MACHINE **The module embeds Satoshi as base64, so the font program in a container is byte-identical to