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
settings-layout: screenshots of the feature a setting changes, and parent/child made visible
Two more from John (2026-08-23).
Screenshots: a setting that points at a UI feature should SHOW that feature, because words
alone make the user guess what 'compact density' or 'group header chips' refers to. Section
covers when to use one (visual and nameable settings, not port numbers), where it goes (after
the description, before the control), the crop and width, capturing in the app's own theme,
before/after pairs for choices, alt text that describes the DIFFERENCE, lazy loading, and the
rule that a stale screenshot is a lie with a picture attached.
Parent/child: hierarchy is how a user builds a model of an app's options, so it is shown in
all three places and they must agree. Sidebar caret plus indentation, heading levels with the
row breadcrumb, and the case that actually matters: dependent settings indented under the
control they depend on with a 2px spine, dimmed and DISABLED when the parent is off but never
hidden, with a line saying why they are inert. Hiding them makes the card jump and conceals
that the capability exists.
package.json bumped to 1.7.0 and the assets/icons files added to the ship list, so an install
delivers the shared cog SVGs and not just the source tree.
2 files changed
+155−4
package.json+7−4@@ -1,8 +1,8 @@ { "slug": "adom-ui-design",- "version": "1.6.3",+ "version": "1.7.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.",+ "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": {}, "files": [ "SKILL.md",@@ -20,7 +20,10 @@ "skills/dark-default/SKILL.md", "screenshots/tokens.png", "skills/settings-layout/SKILL.md",- "skills/input-feedback/SKILL.md"+ "skills/input-feedback/SKILL.md",+ "assets/icons/settings-cog.svg",+ "assets/icons/settings-cog-outline.svg",+ "assets/icons/README.md" ], "scripts": { "install": "./install.sh",@@ -91,4 +94,4 @@ "type": "image", "path": "screenshots/hero.png" }-}+}
skills/settings-layout/SKILL.md+148@@ -494,6 +494,152 @@ relabels it; second click wipes. No confirmation modal on top of a modal: the bu confirmation, and it forgets on its own if the user walks away. The note says honestly where settings live. +## Parent and child, made visible at every level++John, 2026-08-23: "i really like parent/child relationships being conveyed in a settings+window." Hierarchy is how a user builds a mental model of an app's options, so show it. Adom+settings express it in three places, and all three should agree.++### 1. In the sidebar: caret plus indentation++Covered above. Parents with children get a caret and start EXPANDED; children indent one step;+parents without children get the same left padding so all labels align.++### 2. In the content: section, then card, then row breadcrumb++The heading levels ARE the hierarchy. A section (h2) holds group cards (h3), each holding rows.+The row name then repeats its ancestry as a breadcrumb whose last part is teal+(`Updater: Workspace Image`), so a row torn out of context still says where it belongs.++Do not go deeper than section > group > row. A fourth level means the settings are trying to be+a dashboard, and the answer is a new section, not another nesting level.++### 3. Within a card: dependent settings, indented under the one they depend on++The case that actually matters: a setting that only means anything when another is on. Do NOT+scatter these as siblings, and do NOT hide them when the parent is off.++```html+<div class="setting-row">+ <!-- parent -->+ <span class="row-label">Watch for wiki issues</span>+ <button class="toggle" role="switch" aria-checked="true" aria-label="Watch for wiki issues">…</button>+</div>++<div class="setting-children" data-enabled={watching}>+ <div class="setting-row child">+ <span class="row-label">Check every</span>+ <select disabled={!watching}>…</select>+ </div>+ <div class="setting-row child">+ <span class="row-label">Notify on new issues only</span>+ <button class="toggle" role="switch" aria-checked={notifyNew} disabled={!watching}>…</button>+ </div>+</div>+```++```css+.setting-children {+ margin-left: 0.75rem;+ padding-left: 1rem;+ border-left: 2px solid var(--border); /* the spine that says "these belong to that" */+}+.setting-children[data-enabled='false'] {+ opacity: 0.55; /* dimmed, still readable, still discoverable */+}+.setting-children[data-enabled='false'] .row-label { color: var(--text-2); }+```++The rules:++- **Indent children and draw a spine.** A 2px `--border` left rule down the child group is the+ cheapest, clearest signal that these belong to the control above them. Indentation alone is+ ambiguous once a card has more than a few rows.+- **Disable, never hide.** When the parent is off, dim the children to about 55% and set+ `disabled` on their controls, but keep them on screen. Hiding them makes the card jump as the+ user toggles, and worse, it conceals that the capability exists at all. A user needs to see+ what turning the parent on would give them.+- **Say WHY they are inert.** One short line under the parent, or a `title` on the child group:+ "Available when Watch for wiki issues is on." A greyed control with no explanation reads as+ broken.+- **A disabled child keeps its tooltip.** Keep `pointer-events` alive on the wrapper so the+ explanation is reachable; only the control itself is disabled.+- **Never let a hidden child keep acting.** If a child setting is inert in the UI, it must be+ inert in behavior too. A dimmed "Check every 5 minutes" that is still polling is a lie.+- **One level of dependency inside a card.** If a child needs children of its own, it is a+ group in its own right: promote it to its own card with its own h3.++Cross-check when you are done: the sidebar, the headings, and the indentation inside cards+should tell the SAME story about what belongs to what. If the sidebar says Appearance owns+Fonts but the card puts Fonts beside Appearance, the user trusts neither.++## Show a screenshot of the thing the setting changes++**A setting that points at a UI feature should SHOW that feature.** John, 2026-08-23:++> "i really like screenshots of ui features in the settings windows so the user knows what+> the heck we're talking about in our setting"++Words alone make the user guess. "Compact row density", "Show the group header chips", "Pin+the activity LED": each of those is one small screenshot away from being obvious, and the+screenshot answers the question the description is trying to answer in prose.++Use one when the setting changes something **visual and nameable**: a layout, a chrome+element, an indicator, a density, a theme, a badge, a panel. Skip it for settings with no+visual referent (a port number, a timeout, an API key), where a screenshot is decoration.++Where it goes: inside the card, **after the descriptive paragraph and before the control**,+so the reading order is name, explanation, picture, then the thing you flip.++```html+<div class="settings-card">+ <h3 class="subsection-title" id="density">Row density</h3>+ <p class="subsection-description">Compact fits about a third more rows on screen by+ trimming vertical padding. Nothing is hidden, the rows just sit closer together.</p>+ <figure class="setting-shot">+ <img src="/assets/shots/row-density.png" alt="The thread list at compact density, rows+ sitting closer together than the default" width="520" height="180" loading="lazy">+ <figcaption>Compact density, shown on the thread list.</figcaption>+ </figure>+ <!-- the control -->+</div>+```++```css+.setting-shot { margin: 0 0 0.75rem; }+.setting-shot img {+ display: block; max-width: 100%; height: auto;+ border: 1px solid var(--border); border-radius: 8px;+ background: var(--surface); /* so a transparent PNG does not float */+}+.setting-shot figcaption {+ margin-top: 0.35rem;+ font-family: var(--brand-body); font-size: 0.75rem; color: var(--text-2);+}+```++Rules that keep these from rotting:++- **Crop tight to the feature.** A full-window screenshot shrunk into a card shows nothing.+ Capture the panel, the header, the row, whatever the setting actually changes.+- **Cap the width around 520px** and let height follow. These sit inside a card, not a+ lightbox.+- **Capture in the app's own dark theme** so the shot does not fight the dialog around it. If+ your app ships light and dark and the setting looks materially different in each, show the+ one matching the CURRENT scheme, or show both side by side and label them.+- **A before/after pair beats a single shot** when the setting is a choice rather than an+ on/off: two images, each captioned, same crop and same zoom so the difference is the only+ thing that changes.+- **The alt text describes the DIFFERENCE**, not the app ("rows sitting closer together", not+ "screenshot of the thread list"). A screen reader user gets the same information.+- **`loading="lazy"`**, and keep each shot small (tens of KB). A settings dialog that stutters+ open because it is loading a dozen PNGs is worse than no screenshots.+- **Regenerate them when the UI changes.** A stale screenshot is a lie with a picture attached,+ and it is more convincing than stale prose. Store them in the repo next to the app so they+ are reviewable in a diff, and re-capture as part of any UI change that touches them.+- **Never put text in the image that the card already says.** The picture shows, the prose+ tells.+ ## Saving: local-first, optimistic, bounded Every rule here came from a real bug, and every one of them is invisible until it bites:@@ -526,6 +672,8 @@ Every rule here came from a real bug, and every one of them is invisible until i - [ ] Every section EXPLAINS itself in full sentences, naming mechanisms - [ ] Row names are breadcrumbs with a teal last part, full key in `title` - [ ] Every row shows its default, using the option LABEL for enums+- [ ] Settings that change something visual carry a tight, current screenshot of it+- [ ] Dependent settings are indented under their parent with a spine, dimmed and disabled (never hidden) when the parent is off, and say why - [ ] Booleans are toggles (`role="switch"`), never a native checkbox - [ ] Long actions stream a live console; no silent multi-minute buttons - [ ] Footer note plus two-click auto-disarming Restore defaults