← Commit history

Add SKILL.md + install scripts for adompkg release

John Lauer ·db237c3b5b ·4mo ago ·parent 19c28ea
4 files changed +373
SKILL.mdadded+348
@@ -0,0 +1,348 @@+---+name: adom-ui-design+user-invocable: true+description: >-+  The Adom UI Design System: the single source of truth for how every Adom surface looks and+  behaves. Read this BEFORE building any Adom UI, app, CLI, 3D viewer, or hero image so it comes+  out on-brand the first time. Covers exact color tokens (#0d1117 / #161b22 / #00b8b0 teal), the+  three brand fonts (Familjen Grotesk, Satoshi, JetBrains Mono), the monochrome-white icon law,+  spacing and radius, the 44px three-zone app header, tooltips and HUDs, AI-drivability+  (GET /state, GET /console), the OK/ERROR/Hint CLI contract, Babylon 3D viewer rules, hero-image+  rules, the copy voice (no em-dashes, no gimmick emoji), and the adom-ui-linter enforcement gate.+  Trigger words: ui design, design system, adom design, brand colors, color tokens, adom tokens,+  theme tokens, dark theme, typography, fonts, familjen grotesk, satoshi, jetbrains mono, icon+  rules, monochrome icons, favicon, app header, 44px header, top bar, tooltip, toggle state, HUD,+  spacing grid, border radius, on-brand, make it on-brand, ai-drivable, ai-drivability, GET /state,+  OK ERROR Hint, cli design, 3d viewer design, babylon not three, measure tool, hero image,+  billboard, windows chrome not mac, no em-dashes, copy voice, ui linter, lint my app, design audit.+---++# Adom UI Design System++The single source of truth for how every Adom surface looks and behaves. Color tokens, typography, the app header, panels, 3D viewers, hero images, AI-drivability, and the copy voice, plus the linter that enforces them. One page so that a person or an AI can build something new and have it come out unmistakably Adom on the first try.++![Adom UI Design System](screenshots/hero.png)++> **Why this page exists.** Adom ships a lot of small surfaces: webview apps, CLIs, 3D viewers, wiki pages, hero art. Without one written standard, each one drifts and the family stops looking like a family. This page collects every rule that was previously spread across a dozen skills into a system you can read top to bottom. If you only remember one thing: **Adom is dark, teal, monochrome-iconed, and driven by clean APIs.**++---++## The 90-second contract++The rules that get broken the most. If you do nothing else, do these.++1. **Dark by default.** Page background is `#0d1117`, panels are `#161b22`. Never a white or light primary background.+2. **Teal is the one accent.** Primary interactive color is `#00b8b0`. Purple `#8c6bf7` for grouping. Nothing else competes for attention.+3. **Every icon is monochrome white.** `#e6edf3` or `currentColor`. No colored icons, no emoji, in app UI, tab strips, or favicons. Brand color appears only in marketing art (hero, thumbnail).+4. **Three fonts, by role.** Familjen Grotesk for headings and identity, Satoshi for body, JetBrains Mono for code and numeric data. Never Inter, Arial, or a system stack as the primary face.+5. **One 44px header, three zones.** Brand on the left, subject in the middle, icon actions on the right. Per pixel above content is wasted screen.+6. **Every UI action has a matching API.** If a button does it, a plain HTTP call must do it too. State lives on the server, the UI polls `GET /state`. This is what makes an app AI-drivable.+7. **CLIs answer `OK:` or `ERROR:`,** and every error carries a `Hint:` with the exact command to run next.+8. **3D is Babylon.js,** never Three.js. Gradient background, zoom to cursor, two-light minimum.+9. **No em-dashes, no gimmick emoji** in any shipped copy.+10. **Lint before you publish.** `adom-ui-linter` turns most of this page into ~50 deterministic checks.++---++## 1. Color++Adom is a dark system. Color is used sparingly so that the one teal accent always means "this is interactive or important."++### Core theme tokens++| Token | Value | Use |+|---|---|---|+| `--bg` | `#0d1117` | Page, deepest background |+| `--surface` | `#161b22` | Panels, toolbars, cards |+| `--elevated` | `#1c2128` | Elevated cards, hover surfaces |+| `--overlay` | `#21262d` | Tooltips, dropdowns, modals |+| `--border` | `#30363d` | Standard border |+| `--border-muted` | `#21262d` | Subtle inner borders |+| `--text` | `#e6edf3` | Primary text |+| `--text-2` | `#8b949e` | Secondary text, labels |+| `--text-3` | `#484f58` | Disabled, placeholders |+| `--accent` | `#00b8b0` | Primary accent, the Adom teal |+| `--accent-bright` | `#00e6dc` | Hover and focus highlights |++### Status and grouping++| Token | Value | Use |+|---|---|---|+| `--purple` | `#8c6bf7` | Group labels, secondary accent |+| `--blue` | `#58a6ff` | Links, informational accents |+| `--green` | `#3fb950` | Success only |+| `--red` | `#f85149` | Destructive only |+| `--yellow` | `#d29922` | Warning only |++### Brand palette (marketing and illustration)++| Name | Hex | Use |+|---|---|---|+| Teal (primary) | `#00B8B1` | The brand color |+| Blue Light | `#64ABFF` | Accents, links, illustration |+| Purple Light | `#C5B3FF` | Hover states, secondary accent |+| Blue Dark | `#0061EF` | Strong CTAs |+| Purple | `#8C6BF7` | Grouping, secondary accent |+| Navy | `#00204F` | Deep dark backgrounds |+| Teal Dark | `#003C3F` | Dark teal panels |++### Rules++- Never use **pure black** (`#000`) or **pure white** (`#fff`) for a large surface. Black kills contrast against dark UI parts, white blows out a dark theme. Use the tokens above.+- Hover transitions are smooth, not snappy: `0.15s ease`.+- The signature gradient is teal to blue to purple: `linear-gradient(100deg, #00e6dc, #39b8ff 60%, #8c6bf7)`. Use it for headline accents and flagship art, not for body UI.++---++## 2. Typography++Three faces, each with one job. Mixing them up is the fastest way to make an app feel off-brand.++| Face | Weights | Job |+|---|---|---|+| **Familjen Grotesk** | 500, 600, 700 | Headlines, app name, section headers, identity |+| **Satoshi** | 400, 500, 700 | Body copy, descriptions, paragraphs |+| **JetBrains Mono** | 400, 500 | Source code, inline code, numeric and data rows |++### Rules++- **Monospace is only for code and data.** Labels, descriptions, status pills, tooltips, headings, and body never use a monospace face. A version number or a pad count is data, so it is mono. A button label is not.+- **Never ALL CAPS body text.** Small uppercase is allowed for tiny eyebrow labels and chips with wide letter spacing, never for sentences.+- Do not fall back to Inter, Arial, Helvetica, or the system stack as the primary face. Load the brand fonts from `https://adom.inc/fonts/`.++---++## 3. Spacing, radius, and icons++- **Spacing grid:** 8px, 12px, 16px. Stay on the grid.+- **Border radius:** `8px` for buttons and cards, `12px` for larger containers, `999px` for pills and chips.+- **Icons are monochrome white. No exceptions.** `#e6edf3` or `currentColor` inheriting from white text. This covers in-app icons, the Hydrogen tab-strip icon, and the favicon. A teal favicon is a UX lie because the tab strip is Adom chrome, not your art.+  - Prefer a clean custom SVG (`viewBox="0 0 24 24"`, stroke weight 1.5 to 2px) over a generic icon unless the concept is fully generic.+  - No emoji as icons, ever.+  - **Pre-publish icon audit.** Both of these greps must return zero hits:+    ```bash+    grep -nE 'fill="(#00b8b0|#00d4cb)"|stroke="(#00b8b0|#00d4cb)"' docs/icon.svg src/**/*.html src/**/*.svg+    grep -nE '\.logo[^{]*\{[^}]*color:\s*var\(--accent\)|\.icon[^{]*\{[^}]*color:\s*var\(--accent\)' src/**/*.html src/**/*.css+    ```+- The **only** place brand color is allowed is marketing art: the hero image and the thumbnail on the wiki page.++---++## 4. The app header++Every Adom webview app wears the same header so that a person always knows which app they are in and where the controls are. It is a **single row, 44px tall, three zones.**++```+[ icon  app-name ยท subtitle ] | [ Subject Name  meta ]            [ btn btn ]+        brand (left)            vsep      subject (center)          actions (right)+```++- **Brand zone (left):** a 16x16 monochrome icon, the app name, a middot, and a one to four word subtitle. Familjen Grotesk 600, in the accent color. Hovering the brand block reveals an app-info popover with version, build date, engine, author, and a clickable wiki link. None of that metadata sits in the header row itself.+- **Subject zone (center):** the current document or object name (bold, truncates with an ellipsis when narrow) plus a muted monospace meta line for secondary stats. The meta line hides below roughly 720px and returns on hover.+- **Actions zone (right):** icon buttons only, right aligned with `margin-left:auto`. Skip the zone entirely if there are no actions.+- A `1px` vertical hairline separates brand from subject.++### Header rules++- Never a multi-row header. Never a sticky header. Never the app version inline in the row. Never the app name in a monospace face. Never an all-caps app name.+- The popover that appears on hover must be reachable: give it `pointer-events:auto`, a 600ms show delay, and a ~220ms hide grace so the cursor can cross the gap to click a link inside it.++Copy the canonical header block rather than reinventing it. It is captured in the `adom-app-header` skill.++---++## 5. Components and interaction++### Tooltips++- **Tooltips are body-appended `position:fixed` elements at `z-index:99999`.** Never a CSS `::after` pseudo-element, because it gets clipped by panel `overflow:hidden`, `backdrop-filter`, or `transform` stacking contexts.+- **Every interactive element carries a tooltip.** No orphan controls.+- Reveal delay is **600ms.** Motion is a short fade plus translate, `0.18s ease`.+- Reset `text-transform:none` so the tooltip never inherits uppercase.+- A good tooltip says what the control does, what changes after the click, and for destructive actions what is and is not preserved. Explain jargon for non-experts.++### Buttons and toggles++- A toggle must **look** like its state. Flat push-button styling for both on and off is a lie. Show the difference.+- Primary actions use teal `#00b8b0`. Success is green, destructive is red, and those colors are reserved for those meanings.+- Every action gives **immediate visible feedback**: a toast, a class change, or a live preview.++### HUDs and floating panels++- Draggable by a visible grip, never clamped to a screen edge.+- `max-height: calc(100% - margin)` with internal scroll and a pinned header and footer.+- Offer minimize, close, and double-click to collapse.++### A note on animation++When several iterations of the same animation each help only a little, stop tuning and reframe. The classic fix for a janky content fade is not a smoother content fade, it is to cover the content with a solid block, let it paint underneath, then fade the block off. Animate a trivial proxy, not the expensive thing.++---++## 6. AI-drivability++This is the rule that makes an Adom app more than a web page: **anything a person can do in the UI, the AI can do over plain HTTP.** Build for it from the start.++- **Server is the single source of truth.** State changes go through the server, not in-memory JavaScript. Buttons fire `POST` commands only, they do not mutate local state.+- **Expose `GET /state`** returning JSON. The UI polls it every 300 to 500ms and drives every transition from it. The AI reads the same endpoint to check progress without scraping HTML.+- **Expose `GET /console`.** Override `console.log/warn/error` to also `POST /console`, keep a server-side ring buffer, and catch `window.onerror` and `unhandledrejection`. Now the AI can read the app's log output without DevTools.+- **Return structured JSON** from every `POST`, not an HTML redirect.+- The acceptance test: an AI driving the app with `curl` and a person clicking the UI should produce identical visible results.++### Talking to a container app from outside++- A Hydrogen webview and a desktop browser window both render **outside** the container. They cannot reach `http://localhost:<port>` or `http://127.0.0.1:<port>`. Always use the public proxy URL: `https://<slug>.adom.cloud/proxy/<port>/`.+- **Inside a webview, always use relative URLs.** A leading slash resolves to the host origin and bypasses the proxy. Every `fetch`, `href`, `src`, and CSS `url()` must be relative.++---++## 7. CLIs and hints++Most Adom tools ship a CLI, and the CLI is how the AI recovers when a skill has scrolled out of context. The output format is a contract.++- **Every response starts with `OK:` or `ERROR:`.** The AI reads the prefix to know instantly whether it worked.+- **Every error carries at least one `Hint:`** that is an actionable command, not an explanation.+  ```+  ERROR: Cannot connect to the server on port 8820.+  Hint: Start it with `mytool serve &`+  ```+  Hints name the exact command, flag, or file. Chain multiple hints for multi-step recovery. Hints can teach a pattern, for example steering the AI to use the CLI instead of calling an endpoint directly.+- **Strip ANSI color when stdout is not a TTY.** Gate every color on an `isatty` check so logs and command substitution stay clean.+- Ship a `health` subcommand and an `install` subcommand. `install` fetches the latest skill from the wiki rather than relying on an embedded copy.+- **Relay servers gate on User-Agent.** The CLI sets `User-Agent: <tool>-cli/<version>`. The relay rejects anything else with a structured hint telling the caller to use the CLI:+  ```json+  { "ok": false, "error": "direct_http_use_cli_instead",+    "_adom_use_cli_instead": "Use the `mytool` CLI: mytool <command>." }+  ```++Why hints matter: a skill is read once and then degrades as context fills. A hint in error output is read at the exact moment of need, always fresh. Hints are the most reliable way to steer an AI.++---++## 8. 3D viewers++Adom has many 3D viewports: CAD, PCB, mechanical, component preview. They share one design so they feel like one tool.++- **Babylon.js, always. Never Three.js.** Better PBR materials, better GLB fidelity, a first-class orbit camera, and a built-in ViewCube. This holds even for quick prototypes.+- **Start from the canonical Adom Babylon viewer.** Embed it, import it, or extend it before you ever roll your own. If you do roll your own, you inherit every rule below.+- **Background is a vertical gradient, never a flat color.** Pure black hid black IC bodies in the lower frame, which is why the gradient is mandatory. Dark mode default, light mode toggle required.+  - Dark: `linear-gradient(180deg, #1e2a3d 0%, #1e2a3d 20%, #0a121f 100%)`+  - Light: `linear-gradient(180deg, #5a6b7e 0%, #5a6b7e 20%, #2a3340 100%)`+- **Zoom to cursor is non-negotiable:** `camera.zoomToMouseLocation = true`.+- **Two lights minimum,** never a single-light rig: an HDRI environment plus a hemispheric light, with a bottom-light toggle for dark parts.+- **World-origin axis helpers default on** (X red, Y green, Z blue), with a screen-space corner triad always visible and a ViewCube in the top-right. Do not rebuild the buttons the ViewCube already provides.+- Camera limits are soft, and wheel, pan, and pinch precision adapt to the model size on each load rather than being hard-coded.++### The measure tool++When a viewer needs measurement, match Fusion 360 and SolidWorks behavior:++- **Live hover preview, not click-only.** Show the geometry you would snap to before the click commits it.+- Smart-pick priority is edge, then face, then vertex.+- The committed marker matches the previewed geometry. An edge preview commits to an edge tube, not a generic sphere.+- The dimension line is a distinct color from the snap markers: markers teal `#00B8B1`, dimension line blue `#64ABFF`.+- Show millimeters as the primary unit with mils as a secondary, never inches.+- Esc is multi-stage: pop the last pick, then the previous, then close the HUD. Never a single-stage close-everything.++---++## 9. Hero images++A hero is the 16:10 billboard at the top of a wiki page. It is reused unchanged on the page header, the landing card, the installer, the homepage, and the screensaver, so it has to read in about one second.++- **One app, one screenshot.** No collages. A single great shot of the real UI beats any montage.+- **Dark, on-brand background.** No white box around a logo. The only allowed texture is a faint dot grid or arc pattern, kept subtle.+- **Headline is the app name or a punchy value phrase,** with the signature gradient on one key word, plus a one-line value prop with a couple of words bolded white for scanning.+- **The product sits in a floating window** with a drop shadow, bleeding off the bottom. The window chrome is **Windows-style: minimize, maximize, and close at the top right.** Never macOS traffic-light dots.+- **Margins are sacred.** Keep every element at least 80px from the canvas edge and give text and the product window real separation. The most common failure is the window touching the copy.+- **The call to action is an AI prompt,** for example `"flash my board as a USB keyboard"`, not a shell install command. The install section of the page can show the CLI, the hero sells the outcome.+- Use the real app UI with realistic example data. A placeholder or a striped no-image panel is a failure, not a fallback.++The `adom-wiki-hero` skill renders all of this from a template.++---++## 10. Copy and voice++The words are part of the design.++- **No em-dashes or en-dashes** in any shipped copy. Use commas, colons, periods, parentheses, or "to" for ranges. Dashes read as machine-written and undercut credibility.+- **No gimmick emoji** in product UI text.+- **Name products by their short name,** never with the tagline baked in. The tagline belongs in a subtitle or a page brief.+- **Lead with Adom's own value:** fast turns, low cost, drone delivery, the Fort Worth facility. Keep the copy professional, for engineers and serious makers, rather than hobbyist.+- Provenance over magic. A diagnostic or computed view shows where its data came from and never silently auto-corrects.++---++## 11. The enforcement gate++Reading this page is step one. Proving an app follows it is `adom-ui-linter`, which encodes most of these rules as roughly 50 deterministic checks across six categories.++| Category | Checks |+|---|---|+| header | 44px height, brand and subject zones, fonts, popover, favicon |+| ui-patterns | tooltips body-appended and not `::after`, color tokens, toggle state, no all-caps |+| ai-drivability | `GET /state`, `GET /console`, relay User-Agent gate, CLI hints |+| cli-compliance | `OK:`/`ERROR:` prefix, `Hint:` lines, health and install subcommands, isatty gating |+| skills-docs | skill frontmatter and triggers, README with inline screenshots |+| build-publish | version files in sync, release profile, port registration |++```bash+adom-ui-linter lint . --category header,ui-patterns,ai-drivability+```++Fix every FAIL (the hint tells you exactly what to do), address relevant WARNs, and re-run to zero before publishing.++---++## 12. The skill map++This system is split across focused skills. The AI loads them by trigger word. Use this as the index of where each rule lives.++| Skill | Governs |+|---|---|+| `brand` | Colors, typography, logo, icon law, the dark theme tokens |+| `human-ui-patterns` | Tooltips, HUDs, toggles, text rules, feedback, AI-drivability primitives |+| `adom-app-header` | The 44px three-zone header and the app-info popover |+| `adom-app-model` | How an Adom app is structured, distributed, and versioned |+| `app-creator` | Building a webview app: favicon, proxy URL, two-way comms, publish flow |+| `pup-vs-webview` | Choosing a desktop browser window versus a Hydrogen webview tab |+| `carbon-preferences` | Per-user settings that persist across sessions |+| `adom-panels` | The panel catalog and per-panel control APIs |+| `adom-workspace-control` | Adding, splitting, moving, and resizing workspace panes safely |+| `adom-layouts` | The workcell layout JSON grammar |+| `3d-viewer-design` | Every rule for Adom 3D viewports |+| `measure-tool-design` | Fusion-grade measurement inside a Babylon viewer |+| `screen-capture-wake-lock` | Releasing the display lock after a screen capture |+| `adom-cli-design` | The `OK:`/`ERROR:`/`Hint:` CLI contract |+| `ai-hints-in-clis` | Writing hints that actually steer the AI |+| `relay-hint-pattern` | Teaching a relay server to redirect callers to the CLI |+| `adom-ui-linter` | The deterministic check suite that enforces this page |+| `readme-creator` | READMEs with inline screenshots for visual tools |+| `adom-screenshot` | Capturing and logging screenshots for visual feedback loops |+| `adom-wiki-hero` | Rendering a billboard-grade hero image |++---++## Talk to the AI++You drive all of this by asking. Useful prompts:++**Build**+- "build me an on-brand Adom webview app for X"+- "add a standard Adom 44px header to this app"+- "make this CLI follow the Adom OK/ERROR/Hint contract"++**Design**+- "what are the Adom color tokens"+- "give me the Adom 3D viewer defaults"+- "make a hero image for my app"++**Check**+- "lint my app against the Adom UI rules"+- "audit my icons for brand-color leaks"+- "is this app AI-drivable"++---++*Adom UI Design System. Dark, teal, monochrome-iconed, API-driven. Build it once, build it right.*
install.shadded+8
@@ -0,0 +1,8 @@+#!/usr/bin/env bash+# Install the Adom UI Design System as a reference skill.+set -e+DEST="$HOME/.claude/skills/adom-ui-design"+mkdir -p "$DEST"+cp SKILL.md "$DEST/SKILL.md"+echo "OK: Installed Adom UI Design System to $DEST/SKILL.md"+echo "Hint: Ask Claude 'what are the Adom color tokens' or 'build me an on-brand Adom app' to use it."
package.jsonadded+12
@@ -0,0 +1,12 @@+{+  "slug": "adom-ui-design",+  "version": "1.0.0",+  "type": "skill",+  "description": "The Adom UI Design System: color tokens, typography, the 44px app header, AI-drivability, Babylon 3D viewers, hero rules, and the linter that enforces them.",+  "dependencies": {},+  "files": ["SKILL.md", "README.md", "page.json", "install.sh", "uninstall.sh", "screenshots/hero.png"],+  "scripts": {+    "install": "./install.sh",+    "uninstall": "./uninstall.sh"+  }+}
uninstall.shadded+5
@@ -0,0 +1,5 @@+#!/usr/bin/env bash+set -e+DEST="$HOME/.claude/skills/adom-ui-design"+rm -rf "$DEST"+echo "OK: Removed Adom UI Design System skill."