bootstrap
Adom Core
Public Made by Adomby adom
Bootstrap a standard Adom workstation in one command.
← Commit history
Update 5 file(s)
5 files changed
+217
README.md+8@@ -7,3 +7,11 @@ helpers — and the **adom-wiki** package-manager skill so Claude knows how to p ``` bash <(curl -fsSL https://wiki.adom.inc/static/bootstrap.sh) ```++## The Identity Card++Every Adom surface (wiki, Hydrogen Desktop, Hydrogen Web, auth pages) shows **who you are signed+in as** the same way: one avatar-username-email-org card in three sizes, with monochrome icons and+the avatar itself as the change-avatar affordance. Consistency makes identity a single learnable+object across the whole ecosystem. Full spec, renderings, and rendering rules:+[identity-card/README.md](identity-card/README.md).
identity-card/README.mdadded+81@@ -0,0 +1,81 @@+# The Adom Identity Card++A single, consistent way to show **who you are signed in as**, used identically across every+Adom surface: the wiki, Hydrogen Desktop (HD), Hydrogen Web (HW), the auth-intent page, and any+future app. It is a design contract, not one app's component: the same fields, the same three+sizes, the same actions, everywhere.++## Why it must be consistent everywhere++Users move between the wiki, HD, and HW constantly, and they may belong to more than one org or+have more than one account signed in. If each surface renders identity differently, the user+can't build a reliable mental model of "this is me, this is which account I'm acting as." A+recognizable, identical card makes identity a **single learnable object** they carry through the+whole ecosystem, the way the avatar-in-the-top-corner is learnable on GitHub or Google. Today+the surfaces diverge (HD's menu shows only a bare avatar with no name or email; the wiki shows+name but not email; casing differs: "My issues" vs "My Issues"). This spec ends that drift.++## The fields (from the identity API — `adom-wiki whoami` / the session)++| Field | Source | Shown where |+|---|---|---|+| **avatar** | `avatarUrl` | every size |+| **username** | `username` (e.g. `john`) | every size |+| **real name** | `displayName` (e.g. `John Lauer`) | medium + large |+| **email** | `email` (e.g. `[email protected]`) | medium + large |+| **org** | first of `orgs[]` (teal pill) | medium + large |+| **admin** | `isAdmin` (amber pill) | large |++**Email is shown, never hidden behind a hover.** It is the true identity disambiguator, usernames+repeat across orgs but the email is unique, and the account you are "acting as" is consequential+enough that it must be readable at a glance. Hover tooltips also do not exist on touch, so hiding+identity there fails on a phone (see the adom-ui-design skill, tooltips section).++## The three renderings++++- **Compressed** (header chip): avatar + `username`. The "who, at a glance" chip for a title bar+ or site header. No email, no name, it's a handle.+- **Medium** (every profile pulldown): avatar + username + real name + **email** + org pill. This+ is the standard header of the profile dropdown on all three surfaces.+- **Large** (profile / settings hero): the medium fields, bigger, plus the admin pill.++## Actions: the avatar is the affordance, not a kebab++**Changing your avatar = clicking your avatar.** On hover it shows a small camera badge; clicking+opens the avatar picker. This is discoverable (you click your face to change your face) and needs+no extra control. Everything else, edit name/bio, sign out, is a **normal menu row** below the+card, because the profile pulldown already lists those actions. There is deliberately **no `⋯`+kebab**: it would duplicate the menu's own "Your profile"/"Settings" rows. The card is identity+**display**; the menu is the action list.++## Per-surface: same card, only the item list differs++++Every surface's profile dropdown is: **the medium card as the header**, then a divider, then that+surface's own menu rows, then Log out. Same header, same monochrome icon style, same **sentence+case** ("My issues", not "My Issues"). Only the middle rows change per surface (the wiki adds+Notifications + Settings; HD adds "Your wiki repos"; etc.).++## Rendering rules (conform to these on any surface)++- **Surface**: `#0d1117` background, `#30363d` hairline border, one teal accent (`#00b8b0`) for+ the org pill; amber (`#d29922`) for the admin pill. No other accent colors.+- **Icons are monochrome (mdi / iconify), never emoji.** Emoji read as mismatched "skittles" and+ violate the brand's monochrome-icon rule (adom-ui-design, brand skill).+- **Typography**: the surface's brand body face; username 600 weight; real name + email muted+ (`#8b949e`); email in a monospace face.+- **Never invent fields.** Render only what the identity API returns; hide a pill whose field is+ absent (no org → no pill), never show a placeholder.+- Compressed chip clamps to available bar width; medium/large are fixed-width dropdown headers.++## For implementers (Colby, Kyle, and future apps)++The wiki, HW (Colby), and HD each render this from the same identity payload; the auth-intent page+(Kyle already ships an identity card there) should converge on these exact fields, sizes, and the+no-emoji / email-shown / avatar-is-the-action rules. If your surface needs a field this spec+doesn't list, propose it here first so all surfaces gain it together, rather than forking. The+mock these images come from is a single self-contained HTML file, keep it the one source so the+renderings never drift from the spec.
identity-card/idc-renderings.pngadded⋯ 1 unchanged line ⋯
identity-card/idc-surfaces.pngadded⋯ 1 unchanged line ⋯
identity-card/identity-card.htmladded+128@@ -0,0 +1,128 @@+<!DOCTYPE html>+<html><head><meta charset="utf-8"><title>Adom Identity Card — v2 (no emoji, email in, avatar-badge action)</title>+<style>+ * { margin:0; padding:0; box-sizing:border-box; }+ body { background:#0a0d10; color:#e6edf3; font-family:'Segoe UI',system-ui,sans-serif; padding:28px 32px; }+ h2 { font-size:12px; text-transform:uppercase; letter-spacing:0.09em; color:#8b949e; margin:34px 0 12px; font-weight:600; }+ .note { font-size:11px; color:#566068; margin-top:6px; max-width:520px; line-height:1.5; }+ section { display:inline-block; vertical-align:top; }+ svg { display:block; }+ .ico { width:18px; height:18px; fill:#c9d1d9; flex:none; }++ /* ── The card family: #0d1117 surface, #30363d hairline, one teal accent. ── */+ .idc { background:#0d1117; border:1px solid #30363d; border-radius:10px; }+ .av-wrap { position:relative; flex:none; }+ .avatar { border-radius:50%; background:#22262a; object-fit:cover; display:block; }+ /* The avatar IS the change-avatar affordance (no kebab): a camera badge on hover. */+ .av-badge { position:absolute; right:-2px; bottom:-2px; width:18px; height:18px; border-radius:50%;+ background:#161b22; border:1px solid #30363d; display:flex; align-items:center; justify-content:center;+ opacity:0; transition:opacity .12s; }+ .av-badge svg { width:11px; height:11px; fill:#c9d1d9; }+ .av-wrap:hover .av-badge { opacity:1; }+ .av-wrap:hover .avatar { filter:brightness(.7); cursor:pointer; }+ .uname { font-weight:600; color:#e6edf3; line-height:1.25; }+ .real { color:#8b949e; line-height:1.3; }+ .email { font-family:Consolas,monospace; color:#8b949e; line-height:1.35; }+ .org { display:inline-flex; align-items:center; gap:5px; font-size:11px; color:#00b8b0;+ background:rgba(0,184,176,0.12); border:1px solid rgba(0,184,176,0.35);+ padding:1px 8px; border-radius:999px; }+ .org::before { content:''; width:5px; height:5px; border-radius:50%; background:#00b8b0; }++ .idc-sm { display:inline-flex; align-items:center; gap:8px; padding:4px 12px 4px 4px; border-radius:999px; }+ .idc-sm .avatar { width:26px; height:26px; } .idc-sm .uname { font-size:13px; }++ .idc-md { display:flex; align-items:flex-start; gap:12px; padding:13px 16px; width:290px; }+ .idc-md .avatar { width:44px; height:44px; } .idc-md .uname { font-size:15px; }+ .idc-md .real { font-size:12.5px; } .idc-md .email { font-size:11.5px; margin-top:1px; } .idc-md .org { margin-top:6px; }++ .idc-lg { width:380px; padding:20px; }+ .idc-lg .top { display:flex; gap:16px; align-items:flex-start; }+ .idc-lg .avatar { width:64px; height:64px; } .idc-lg .uname { font-size:19px; }+ .idc-lg .real { font-size:14px; } .idc-lg .email { font-size:13px; margin-top:2px; } .idc-lg .org { margin-top:8px; }+ .idc-lg .adminbadge { font-size:11px; color:#d29922; background:rgba(210,153,34,.12);+ border:1px solid rgba(210,153,34,.35); padding:1px 8px; border-radius:999px; margin-left:6px; }++ /* Menu rows (monochrome mdi icons, NEVER emoji) */+ .menu { padding:6px; }+ .menu .row { display:flex; align-items:center; gap:12px; padding:8px 12px; border-radius:7px;+ font-size:13.5px; color:#c9d1d9; cursor:pointer; }+ .menu .row:hover { background:rgba(255,255,255,0.06); }+ .menu .count { margin-left:auto; font-size:11px; font-weight:600; color:#00b8b0;+ background:rgba(0,184,176,.14); padding:1px 8px; border-radius:999px; }+ .menu hr { border:0; border-top:1px solid #22262a; margin:6px 8px; }++ .pulldown { width:300px; background:#0d1117; border:1px solid #30363d; border-radius:12px;+ box-shadow:0 14px 34px rgba(0,0,0,.6); overflow:hidden; }+ .pulldown .idc-md { width:100%; border:0; border-bottom:1px solid #22262a; border-radius:0; }+ .cols { display:flex; gap:40px; flex-wrap:wrap; }+</style></head><body>++<h2 id="s-compressed">Compressed (header chip) — avatar + username only</h2>+<section id="card-sm"><span class="idc idc-sm">+ <img class="avatar" src="https://cdn.adom.inc/avatars/8ab76fde9133f53b0481a9148b677e73.png">+ <span class="uname">john</span>+</span></section>+<div class="note">Too small for email; it's the "who, at a glance" chip in a title bar / site header.</div>++<h2 id="s-medium">Medium — + real name, EMAIL (shown, not hidden), org. Hover the avatar to change it.</h2>+<section id="card-md"><div class="idc idc-md">+ <span class="av-wrap">+ <img class="avatar" src="https://cdn.adom.inc/avatars/8ab76fde9133f53b0481a9148b677e73.png">+ <span class="av-badge"><svg viewBox="0 0 24 24"><path d="M4,4H7L9,2H15L17,4H20A2,2 0 0,1 22,6V18A2,2 0 0,1 20,20H4A2,2 0 0,1 2,18V6A2,2 0 0,1 4,4M12,7A5,5 0 0,0 7,12A5,5 0 0,0 12,17A5,5 0 0,0 17,12A5,5 0 0,0 12,7M12,9A3,3 0 0,1 15,12A3,3 0 0,1 12,15A3,3 0 0,1 9,12A3,3 0 0,1 12,9Z"/></svg></span>+ </span>+ <div><div class="uname">john</div><div class="real">John Lauer</div>+ <div class="email">[email protected]</div><span class="org">adom</span></div>+</div></section>+<div class="note">EMAIL LIVES HERE. It's the true identity disambiguator (usernames repeat across orgs; the email is unique), and identity you're "acting as" must be visible, not a hover you can't do on a phone.</div>++<h2 id="s-large">Large (profile / settings hero) — + admin. Actions are the surface's menu items, not a kebab.</h2>+<section id="card-lg"><div class="idc idc-lg"><div class="top">+ <span class="av-wrap">+ <img class="avatar" src="https://cdn.adom.inc/avatars/8ab76fde9133f53b0481a9148b677e73.png">+ <span class="av-badge"><svg viewBox="0 0 24 24"><path d="M4,4H7L9,2H15L17,4H20A2,2 0 0,1 22,6V18A2,2 0 0,1 20,20H4A2,2 0 0,1 2,18V6A2,2 0 0,1 4,4M12,7A5,5 0 0,0 7,12A5,5 0 0,0 12,17A5,5 0 0,0 17,12A5,5 0 0,0 12,7M12,9A3,3 0 0,1 15,12A3,3 0 0,1 12,15A3,3 0 0,1 9,12A3,3 0 0,1 12,9Z"/></svg></span>+ </span>+ <div><div class="uname">john <span class="adminbadge">admin</span></div>+ <div class="real">John Lauer</div><div class="email">[email protected]</div><span class="org">adom</span></div>+</div></div></section>+<div class="note">Change avatar = click the avatar (camera badge). Everything else (edit name/bio, sign out) is a normal menu row below — no redundant "⋯". The card is identity DISPLAY; the menu is the action list.</div>++<h2>The three surfaces — same medium card header, monochrome icons, only the item list differs</h2>+<div class="cols">++<section id="ctx-wiki"><h2 style="margin-top:0">Wiki pulldown</h2>+ <div class="pulldown">+ <div class="idc-md"><span class="av-wrap"><img class="avatar" src="https://cdn.adom.inc/avatars/8ab76fde9133f53b0481a9148b677e73.png"><span class="av-badge"><svg viewBox="0 0 24 24"><path d="M4,4H7L9,2H15L17,4H20A2,2 0 0,1 22,6V18A2,2 0 0,1 20,20H4A2,2 0 0,1 2,18V6A2,2 0 0,1 4,4M12,7A5,5 0 0,0 7,12A5,5 0 0,0 12,17A5,5 0 0,0 17,12A5,5 0 0,0 12,7Z"/></svg></span></span>+ <div><div class="uname">john</div><div class="real">John Lauer</div><div class="email">[email protected]</div><span class="org">adom</span></div></div>+ <div class="menu">+ <div class="row"><svg class="ico" viewBox="0 0 24 24"><path d="M12,2A2,2 0 0,0 10,4V4.29C7.12,5.14 5,7.82 5,11V17L3,19V20H21V19L19,17V11C19,7.82 16.88,5.14 14,4.29V4A2,2 0 0,0 12,2M12,22A2,2 0 0,0 14,20H10A2,2 0 0,0 12,22Z"/></svg>Notifications<span class="count">99+</span></div>+ <div class="row"><svg class="ico" viewBox="0 0 24 24"><path d="M12,4A4,4 0 0,1 16,8A4,4 0 0,1 12,12A4,4 0 0,1 8,8A4,4 0 0,1 12,4M12,14C16.42,14 20,15.79 20,18V20H4V18C4,15.79 7.58,14 12,14Z"/></svg>Your profile</div>+ <div class="row"><svg class="ico" viewBox="0 0 24 24"><path d="M12,9A3,3 0 0,1 15,12A3,3 0 0,1 12,15A3,3 0 0,1 9,12A3,3 0 0,1 12,9M12,4.5C17,4.5 21.27,7.61 23,12C21.27,16.39 17,19.5 12,19.5C7,19.5 2.73,16.39 1,12C2.73,7.61 7,4.5 12,4.5Z"/></svg>Review queue</div>+ <div class="row"><svg class="ico" viewBox="0 0 24 24"><path d="M9,22A1,1 0 0,1 8,21V18H4A2,2 0 0,1 2,16V4C2,2.89 2.9,2 4,2H20A2,2 0 0,1 22,4V16A2,2 0 0,1 20,18H13.9L10.2,21.71C10,21.9 9.75,22 9.5,22Z"/></svg>My issues</div>+ <div class="row"><svg class="ico" viewBox="0 0 24 24"><path d="M12,17.27L18.18,21L16.54,13.97L22,9.24L14.81,8.62L12,2L9.19,8.62L2,9.24L7.45,13.97L5.82,21L12,17.27Z"/></svg>My stars</div>+ <div class="row"><svg class="ico" viewBox="0 0 24 24"><path d="M21,16.5C21,16.88 20.79,17.21 20.47,17.38L12.57,21.82C12.41,21.94 12.21,22 12,22C11.79,22 11.59,21.94 11.43,21.82L3.53,17.38C3.21,17.21 3,16.88 3,16.5V7.5C3,7.12 3.21,6.79 3.53,6.62L11.43,2.18C11.59,2.06 11.79,2 12,2C12.21,2 12.41,2.06 12.57,2.18L20.47,6.62C20.79,6.79 21,7.12 21,7.5V16.5M12,4.15L6.04,7.5L12,10.85L17.96,7.5L12,4.15Z"/></svg>My packages</div>+ <hr>+ <div class="row"><svg class="ico" viewBox="0 0 24 24"><path d="M12,15.5A3.5,3.5 0 0,1 8.5,12A3.5,3.5 0 0,1 12,8.5A3.5,3.5 0 0,1 15.5,12A3.5,3.5 0 0,1 12,15.5M19.43,12.97C19.47,12.65 19.5,12.33 19.5,12C19.5,11.67 19.47,11.34 19.43,11L21.54,9.37C21.73,9.22 21.78,8.95 21.66,8.73L19.66,5.27C19.54,5.05 19.27,4.96 19.05,5.05L16.56,6.05C16.04,5.66 15.5,5.32 14.87,5.07L14.5,2.42C14.46,2.18 14.25,2 14,2H10C9.75,2 9.54,2.18 9.5,2.42L9.13,5.07C8.5,5.32 7.96,5.66 7.44,6.05L4.95,5.05C4.73,4.96 4.46,5.05 4.34,5.27L2.34,8.73C2.21,8.95 2.27,9.22 2.46,9.37L4.57,11C4.53,11.34 4.5,11.67 4.5,12C4.5,12.33 4.53,12.65 4.57,12.97L2.46,14.63L4.34,18.73L7.44,17.94C7.96,18.34 8.5,18.68 9.13,18.93L9.5,21.58C9.54,21.82 9.75,22 10,22H14L14.5,21.58L14.87,18.93C15.5,18.67 16.04,18.34 16.56,17.94L19.05,18.95L21.66,15.27L19.43,12.97Z"/></svg>Settings</div>+ <div class="row"><svg class="ico" viewBox="0 0 24 24"><path d="M16,17V14H9V10H16V7L21,12L16,17M14,2A2,2 0 0,1 16,4V6H14V4H5V20H14V18H16V20A2,2 0 0,1 14,22H5A2,2 0 0,1 3,20V4A2,2 0 0,1 5,2H14Z"/></svg>Log out</div>+ </div>+ </div></section>++<section id="ctx-hd"><h2 style="margin-top:0">HD pulldown (gains the header it lacks today)</h2>+ <div class="pulldown">+ <div class="idc-md"><span class="av-wrap"><img class="avatar" src="https://cdn.adom.inc/avatars/8ab76fde9133f53b0481a9148b677e73.png"><span class="av-badge"><svg viewBox="0 0 24 24"><path d="M4,4H7L9,2H15L17,4H20A2,2 0 0,1 22,6V18A2,2 0 0,1 20,20H4A2,2 0 0,1 2,18V6A2,2 0 0,1 4,4M12,7A5,5 0 0,0 7,12A5,5 0 0,0 12,17A5,5 0 0,0 17,12A5,5 0 0,0 12,7Z"/></svg></span></span>+ <div><div class="uname">john</div><div class="real">John Lauer</div><div class="email">[email protected]</div><span class="org">adom</span></div></div>+ <div class="menu">+ <div class="row"><svg class="ico" viewBox="0 0 24 24"><path d="M12,4A4,4 0 0,1 16,8A4,4 0 0,1 12,12A4,4 0 0,1 8,8A4,4 0 0,1 12,4M12,14C16.42,14 20,15.79 20,18V20H4V18C4,15.79 7.58,14 12,14Z"/></svg>Your profile</div>+ <div class="row"><svg class="ico" viewBox="0 0 24 24"><path d="M21,16.5C21,16.88 20.79,17.21 20.47,17.38L12.57,21.82C12.41,21.94 12.21,22 12,22C11.79,22 11.59,21.94 11.43,21.82L3.53,17.38C3.21,17.21 3,16.88 3,16.5V7.5C3,7.12 3.21,6.79 3.53,6.62L11.43,2.18C11.59,2.06 11.79,2 12,2C12.21,2 12.41,2.06 12.57,2.18L20.47,6.62C20.79,6.79 21,7.12 21,7.5V16.5Z"/></svg>Your wiki repos</div>+ <div class="row"><svg class="ico" viewBox="0 0 24 24"><path d="M12,9A3,3 0 0,1 15,12A3,3 0 0,1 12,15A3,3 0 0,1 9,12A3,3 0 0,1 12,9M12,4.5C17,4.5 21.27,7.61 23,12C21.27,16.39 17,19.5 12,19.5C7,19.5 2.73,16.39 1,12C2.73,7.61 7,4.5 12,4.5Z"/></svg>Review queue</div>+ <div class="row"><svg class="ico" viewBox="0 0 24 24"><path d="M9,22A1,1 0 0,1 8,21V18H4A2,2 0 0,1 2,16V4C2,2.89 2.9,2 4,2H20A2,2 0 0,1 22,4V16A2,2 0 0,1 20,18H13.9L10.2,21.71C10,21.9 9.75,22 9.5,22Z"/></svg>My issues</div>+ <div class="row"><svg class="ico" viewBox="0 0 24 24"><path d="M12,17.27L18.18,21L16.54,13.97L22,9.24L14.81,8.62L12,2L9.19,8.62L2,9.24L7.45,13.97L5.82,21L12,17.27Z"/></svg>My stars</div>+ <div class="row"><svg class="ico" viewBox="0 0 24 24"><path d="M21,16.5C21,16.88 20.79,17.21 20.47,17.38L12.57,21.82C12.41,21.94 12.21,22 12,22C11.79,22 11.59,21.94 11.43,21.82L3.53,17.38C3.21,17.21 3,16.88 3,16.5V7.5C3,7.12 3.21,6.79 3.53,6.62L11.43,2.18C11.59,2.06 11.79,2 12,2C12.21,2 12.41,2.06 12.57,2.18L20.47,6.62C20.79,6.79 21,7.12 21,7.5V16.5M12,4.15L6.04,7.5L12,10.85L17.96,7.5L12,4.15Z"/></svg>My packages</div>+ <hr>+ <div class="row"><svg class="ico" viewBox="0 0 24 24"><path d="M16,17V14H9V10H16V7L21,12L16,17M14,2A2,2 0 0,1 16,4V6H14V4H5V20H14V18H16V20A2,2 0 0,1 14,22H5A2,2 0 0,1 3,20V4A2,2 0 0,1 5,2H14Z"/></svg>Log out</div>+ </div>+ </div>+ <div class="note" style="width:300px">Today HD's menu shows only a bare avatar (no name/email at all). The card header fixes exactly what you flagged. Casing unified to sentence case (wiki = "My issues", HD said "My Issues" — the card standard picks one).</div>+</section>++</div>+</body></html>