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.5.0: the gutter row measures the panel's insets against its pane, not against any named element - 2.4.0's yardstick could not pass for any app
3 files changed
+85−31
assets/module/newbie-panel.js+33−7@@ -437,13 +437,39 @@ * followed the skill. The containing block is scrollbar-agnostic and still catches the * real defect, which is a page adding its own padding around the mount point. * (parts-search, 2026-08-25, from reading the implementation rather than the prose.) */- var host = (panel.parentElement && panel.parentElement.parentElement) || document.body;- var hostW = host.clientWidth;- var want32 = hostW - 32, gotW = Math.round(panel.getBoundingClientRect().width);- var gutterOk = Math.abs(gotW - want32) <= 2;+ /* Measure BOTH INSETS AGAINST THE PANE, and never against a named element.+ * Two earlier versions asked the wrong element how wide the world is. documentElement+ * assumes the page scrolls, and fails every app-shell dashboard by one scrollbar width.+ * The mount div assumes the 16px lives on the mount div, and reds a visually perfect page+ * that puts the gutter on a shared outer container instead. Both encode a STRUCTURE the+ * fleet was never promised. What the contract actually says is where the panel's EDGES+ * land, so measure exactly that: find the nearest scrolling ancestor (or the document),+ * and check the panel sits 16px inside its client box on both sides. Structure-agnostic:+ * it does not care which element carries the padding, or how many wrappers sit between.+ * (pup found the mount-div version would red an outer-container page, before six apps+ * adopted the pattern I had recommended; parts-search found the documentElement one.) */+ var sc = panel.parentElement;+ while (sc && sc !== document.body) {+ var so = getComputedStyle(sc).overflowY;+ if ((so === 'auto' || so === 'scroll') && sc.scrollHeight > sc.clientHeight) break;+ sc = sc.parentElement;+ }+ var paneLeft, paneW;+ if (sc && sc !== document.body) { paneLeft = sc.getBoundingClientRect().left; paneW = sc.clientWidth; }+ else { paneLeft = 0; paneW = document.documentElement.clientWidth; }+ var pr = panel.getBoundingClientRect();+ var insetL = Math.round(pr.left - paneLeft);+ var insetR = Math.round(paneLeft + paneW - pr.right);+ var gutterOk = Math.abs(insetL - 16) <= 2 && Math.abs(insetR - 16) <= 2; if (!gutterOk) ok = false;- rows.push({ what: 'panel gutter', want: want32 + 'px wide (16px a side of its container)',- got: gotW + 'px (' + Math.round((hostW - gotW) / 2) + 'px a side)', pass: gutterOk });+ rows.push({ what: 'panel gutter', want: '16px inset both sides',+ got: insetL + 'px left, ' + insetR + 'px right', pass: gutterOk });+ /* THE LEFT-EDGE ROW closes the hole the gutter row cannot see. The gutter row measures+ * against whatever element the app mounts INTO, so an app that mounts into a wrapper+ * which itself carries padding passes while sitting inset from its neighbours, and the+ * fleet mismatch comes back in a form the check is blind to. This asserts the panel's+ * left edge against the PANE, which covers the whole ancestor chain in one number.+ * (parts-search, 2026-08-25, reasoning about what the new yardstick still could not see.) */ var fam = getComputedStyle(panel.querySelector('.anp-phrase span') || panel).fontFamily; var famOk = /Satoshi/.test(fam); if (!famOk) ok = false;@@ -451,6 +477,6 @@ return { ok: ok, rows: rows }; } - root.AdomNewbiePanel = { mount: mount, toast: toast, selfCheck: selfCheck, version: '2.4.0',+ root.AdomNewbiePanel = { mount: mount, toast: toast, selfCheck: selfCheck, version: '2.5.0', 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.4.0",+ "version": "2.5.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+51−23@@ -316,31 +316,59 @@ genuinely need to react to it, and then branch on `source`. **Mount the panel in a container with exactly 16px of horizontal padding, and nothing else.** ```-panel border-box == <the container you mount into>.clientWidth - 32 (+/- 2)+the panel sits 16px inside its pane on BOTH sides (+/- 2) ``` -**⛔ NEVER QUOTE AN ABSOLUTE TARGET, AND NEVER MEASURE AGAINST THE DOCUMENT.** Two versions of-this rule were wrong before this one, both because of scrollbars:--1. I told three apps "712 at his pane" by reasoning from `innerWidth` (744) when the check- read `clientWidth` (734, excluding the document scrollbar), so the real target was 702.- kicad read the implementation before acting and caught it; had it coded to my number it- would have shipped a 10px miss and failed the very row it was trying to pass.-2. Measuring against `documentElement` at all was the deeper mistake. **It silently assumes- the PAGE scrolls.** An `app-shell` dashboard, which is the structure this pack prescribes,- is a `position:fixed` shell with a 44px header and the scroller on an inner `.app-body`, so- there is no document scrollbar: `clientWidth` is the full pane and the inner scrollbar is- charged to content instead. **A correctly built app-shell page failed by exactly one- scrollbar width, and only pages that happened to scroll at document level passed.** The- check was failing the apps that followed the skill. Found by parts-search, from reading the- implementation rather than the prose, and reproduced before the fix: an app-shell test page- measured `documentElement` 1673 against a host of 1658, a 15px miss on a panel with a- perfect 16px gutter.--So the yardstick is **the panel's own containing block**, which is scrollbar-agnostic, works-identically for both structures, and still catches the real defect: a page adding its own-padding around the mount point. Negative-tested on an app-shell page with an inner scroller:-16px passes, 50px red, 0px red, restored green.+**The contract is about where the panel's EDGES land, not about which element carries the+padding.** Put the 16px wherever suits your page: on the mount div, or on a shared outer+container that also holds the regions below, or via one `--gutter` token used in both places.+All three pass.++**⛔ THREE VERSIONS OF THIS CHECK WERE WRONG BEFORE THIS ONE, AND EVERY ONE WAS CAUGHT BY AN+APP READING THE IMPLEMENTATION RATHER THAN MY PROSE.** They are worth listing, because they+share a cause: each asked some NAMED ELEMENT how wide the world is, and so encoded a page+structure the fleet was never promised.++0. **`documentElement.clientWidth`** assumes the PAGE scrolls. An app-shell dashboard has no+ document scrollbar, so a correctly built page failed by exactly one scrollbar width while+ looser pages passed. Found by parts-search, which was one command from restructuring its+ app to satisfy it.+1. **The mount div's `clientWidth`** could never pass for ANY app. The module's own CSS makes+ the panel fill its host exactly (`.anp{width:100%}`, margin top/bottom only), so panel+ width == host.clientWidth by construction and the miss was a constant 32 at every width.+ Padding the mount container shrinks host and panel together, so no page could fix it; only+ module-owned CSS could. kicad caught it by measuring, and held its slot rather than spend+ John's shell pasting a failure caused by the checker.+2. Separately, I told four apps **"712 at his pane"**, reasoning from `innerWidth` (744) when+ the code read `clientWidth` (734). The real number was 702. Never quote an absolute target;+ compute it.++pup caught the mount-div version too, from the implementation alone, and specifically before+six apps adopted a container pattern I had recommended that would have red-lined them all.++**The fix is to stop naming an element.** Find the nearest scrolling ancestor (or the+document), and check both of the panel's insets against its client box. Structure-agnostic: it+does not care which element carries the padding or how many wrappers sit between.++**Tested across every structure in the fleet before shipping,** which is the step that was+missing the previous two times:++| page structure | verdict |+|---|---|+| simple page, padding on the mount div | **pass** |+| app-shell, inner scroller, padding on the mount div | **pass** |+| shared outer container carries the gutter, mount flush | **pass** |+| a wrapper adding 40px on top of a correct mount div | **red** |+| no gutter anywhere | **red** |++**⛔ WHEN A CHECK FAILS, ASK WHETHER IT IS FAILING THE CORRECT IMPLEMENTATIONS.** pup's+framing, and it is the sharpest hazard on this page: a check that is wrong at random is noise,+but a check that is systematically wrong about the WELL-BUILT cases actively teaches the fleet+to break itself, because the fastest way to go green is to adopt the looser structure. Version+0 above was exactly that. And the cost of a wrong check is not only a false verdict: it is the+real damage apps do to themselves complying with it.++ This is not cosmetic. Four conformant apps measured at the SAME 744px pane reported panel widths of **734, 735, 702 and 694**, because each page put a different amount of its own