Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/design/artboards/d215/cap/measure_after.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ const fs = require('fs');
const HERE = __dirname;
const TARGETS = path.join(HERE, '..', 'targets.json');

const SURFACES = ['settings', 'agent-settings', 'agent-memory', 'board', 'connectors', 'chat', 'sidebar', 'byo', 'byo-handoff', 'firstrun-welcome', 'firstrun-waiting', 'firstrun-connected', 'firstrun-error', 'activity-queue', 'activity-empty', 'activity-error'];
const SURFACES = ['settings', 'agent-settings', 'agent-memory', 'board', 'connectors', 'chat', 'sidebar', 'byo', 'byo-handoff', 'firstrun-welcome', 'firstrun-waiting', 'firstrun-connected', 'firstrun-error', 'activity-queue', 'activity-empty', 'activity-error', 'profile-person', 'profile-empty', 'profile-error'];
// byo-handoff is drawn but can't be captured on prod: reaching it issues a real key. The first-run
// dialog is a latch-gated overlay, and the Scout welcome only exists in a brand-new pod, so neither is measured on prod.
const PROD_SURFACES = SURFACES.filter(s => s !== 'byo-handoff' && !s.startsWith('firstrun-'));
Expand Down
4 changes: 2 additions & 2 deletions docs/design/artboards/d215/cap/measure_after.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ test('--only with an unknown surface throws', () => {

test('the committed targets.json passes its own validation', () => {
const t = JSON.parse(fs.readFileSync(path.join(__dirname, '..', 'targets.json'), 'utf8'));
assert.strictEqual(Object.keys(t).length, 32);
assert.strictEqual(Object.keys(t).length, 38);
validateTargets(t);
});

Expand All @@ -39,7 +39,7 @@ test('an empty or partial measurement is refused', () => {
const partial = { ...t }; delete partial['board-390'];
assert.throws(() => validateTargets(partial), /missing board-390/);
assert.throws(() => validateTargets({ ...t, 'chat-1440': { helperWords: NaN, innerRatio: 2 } }), /invalid chat-1440/);
assert.strictEqual(EXPECTED.length, 32);
assert.strictEqual(EXPECTED.length, 38);
});

// A page whose SPA shell answers 200 and then redirects to `landsOn`. Its metrics would score
Expand Down
56 changes: 55 additions & 1 deletion docs/design/artboards/d215/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -612,6 +612,34 @@
.app.m .v2-activity__error .b { height: 44px; }
.app.m .v2-activity__moved-line { grid-template-columns: 44px minmax(0, 1fr) auto; }
.mtop .meta { font: 500 12px/1 var(--f-mono); color: var(--mu); white-space: nowrap; }
/* profile: the live profile page, lifted onto the connectors page's primitives. */
.av--64 { width: 64px; height: 64px; border-radius: 16px; }
.v2-profile { width: 100%; max-width: 860px; margin: 0 auto; display: flex; flex-direction: column; gap: 16px; min-width: 0; }
.v2-profile__card { display: grid; grid-template-columns: 64px minmax(0, 1fr) auto; gap: 16px; align-items: center; padding: 16px; border-radius: 12px; background: var(--sf); box-shadow: inset 0 0 0 1px var(--d); }
.v2-profile__who { display: grid; gap: 3px; min-width: 0; }
.v2-profile__who strong { font: 700 18px/1.25 var(--f-display); letter-spacing: -0.01em; color: var(--ink); }
.v2-profile__handle { font: 500 12px/16px var(--f-mono); color: var(--se); }
.v2-profile__since { font-size: 12.5px; line-height: 1.4; color: var(--mu); }
.v2-profile__cols { display: grid; grid-template-columns: minmax(0, 3fr) minmax(0, 2fr); gap: 16px; align-items: start; }
.v2-profile__block { display: grid; gap: 8px; min-width: 0; }
.v2-profile__block h2 { margin: 0; font: 700 15px/1.2 var(--f-display); letter-spacing: -0.01em; color: var(--ink); }
.v2-profile__none { margin: 0; padding: 16px 14px; border-radius: 12px; background: var(--sf); box-shadow: inset 0 0 0 1px var(--d); font-size: 13.5px; color: var(--se); }
.v2-profile__posts { border-radius: 12px; background: var(--sf); box-shadow: inset 0 0 0 1px var(--d); overflow: hidden; }
.v2-profile__post { display: grid; gap: 3px; padding: 11px 14px; border-top: 1px solid var(--d); cursor: pointer; font-size: 13.5px; line-height: 1.45; color: var(--ink); }
.v2-profile__post:first-child { border-top: 0; }
.v2-profile__meta { font: 500 11px/16px var(--f-mono); color: var(--mu); }
.v2-profile__chips { display: flex; flex-wrap: wrap; gap: 8px; }
.v2-profile__chip { all: unset; box-sizing: border-box; cursor: pointer; display: inline-flex; align-items: center; gap: 8px; height: 32px; padding: 0 12px; border-radius: 8px; background: var(--sf); box-shadow: inset 0 0 0 1px var(--d); font: 600 13px/1 var(--f-body); color: var(--ink); }
.v2-profile__chip span { font: 500 11px/1 var(--f-mono); color: var(--mu); }
.v2-profile__error { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 14px; border-radius: 12px; box-shadow: inset 0 0 0 1px var(--d); background: var(--sf); font-size: 13.5px; color: var(--ink); }
.app.m .v2-profile { gap: 14px; }
.app.m .v2-profile__card { grid-template-columns: 64px minmax(0, 1fr); }
.app.m .v2-profile__card > .b { grid-column: 1 / -1; height: 44px; width: 100%; }
.app.m .v2-profile__cols { grid-template-columns: minmax(0, 1fr); }
.app.m .v2-profile__post { min-height: 44px; }
.app.m .v2-profile__chip { height: 44px; }
.app.m .v2-profile__error { flex-direction: column; align-items: stretch; }
.app.m .v2-profile__error .b { height: 44px; }
</style>

<svg width="0" height="0" style="position:absolute" aria-hidden="true">
Expand Down Expand Up @@ -724,7 +752,7 @@ <h1>Same look. <em>Less said.</em></h1>
<li><svg viewBox="0 0 24 24"><use href="#i-grid"/></svg><b>One screen first</b><span>Repeated blocks become a table; rare settings collapse.</span></li>
</ol>
<nav class="toc" aria-label="Surfaces">
<a href="#s-sidebar">Sidebar controls</a><a href="#s-chat">Pod chat</a><a href="#s-board">Task board</a><a href="#s-memory">Memory</a><a href="#s-agent">Agent settings</a><a href="#s-settings">Settings</a><a href="#s-connectors">Connectors</a><a href="#s-byo">Bring your own</a><a href="#s-firstrun">First run</a><a href="#s-activity">Activity</a><a href="#s-dark">Dark mode</a>
<a href="#s-sidebar">Sidebar controls</a><a href="#s-chat">Pod chat</a><a href="#s-board">Task board</a><a href="#s-memory">Memory</a><a href="#s-agent">Agent settings</a><a href="#s-settings">Settings</a><a href="#s-connectors">Connectors</a><a href="#s-byo">Bring your own</a><a href="#s-firstrun">First run</a><a href="#s-activity">Activity</a><a href="#s-profile">Profile</a><a href="#s-dark">Dark mode</a>
</nav>

<section class="surf" id="s-sidebar">
Expand Down Expand Up @@ -1022,6 +1050,32 @@ <h1>Same look. <em>Less said.</em></h1>
</div>
</section>

<section class="surf" id="s-profile">
<div class="shead"><h2>Profile</h2><span class="route">/v2/profile/:id</span><div class="nums"><span class="num">helper words person <b>–</b> → <i>5</i></span><span class="num">empty <b>–</b> → <i>14</i></span><span class="num">scroll 390 <b>–</b> → <i>1.0×</i></span></div></div>
<div class="row1 row1--even">
<figure><figcaption><b>Person · 1440</b><span>public view</span></figcaption><div class="frame" style="--fw:1440;--fh:900" data-surface="profile-person" data-vp="1440"><div class="app d"><div class="sh sh--page"><nav class="rail"><div class="logo"><svg class="i" viewBox="0 0 24 24"><use href="#i-mark"/></svg></div><div class="nav" title="Pods"><svg class="i" viewBox="0 0 24 24"><use href="#i-layers"/></svg></div><div class="nav" title="Agents"><svg class="i" viewBox="0 0 24 24"><use href="#i-team"/></svg></div><div class="nav" title="Needs you"><svg class="i" viewBox="0 0 24 24"><use href="#i-activity"/></svg><span class="bd">3</span></div><div class="nav" title="Artifacts"><svg class="i" viewBox="0 0 24 24"><use href="#i-file"/></svg></div><div class="nav" title="Connectors"><svg class="i" viewBox="0 0 24 24"><use href="#i-plug"/></svg></div><div class="nav" title="Settings"><svg class="i" viewBox="0 0 24 24"><use href="#i-gear"/></svg></div><div class="sp"></div><div class="nav" title="Feedback"><svg class="i" viewBox="0 0 24 24"><use href="#i-feedback"/></svg></div><div class="seg seg--ic seg--rail" role="group" aria-label="Theme"><button type="button" data-t="light" title="Light" aria-label="Light" aria-pressed="false"><svg class="i" viewBox="0 0 24 24"><use href="#i-sun"/></svg></button><button type="button" data-t="dark" title="Dark" aria-label="Dark" aria-pressed="false"><svg class="i" viewBox="0 0 24 24"><use href="#i-moon"/></svg></button></div><span class="av av--36"><svg viewBox="0 0 40 40"><use href="#av-alex"/></svg></span></nav><div class="pane"><div class="ph"><h1>Profile</h1><span class="sp"></span></div><div class="pbody"><div class="v2-profile"><section class="v2-profile__card"><span class="av av--64"><svg viewBox="0 0 40 40"><use href="#av-dee"/></svg></span><div class="v2-profile__who"><strong>Dana Okafor</strong><span class="v2-profile__handle">@dana</span><span class="v2-profile__since">Member since 3 months ago</span></div><button class="b b-p">Follow</button></section><div class="v2-profile__cols"><section class="v2-profile__block"><h2>Recent public posts</h2><div class="v2-profile__posts"><a class="v2-profile__post"><span>Shipped the retry for the webhook; the 502s are gone on staging.</span><span class="v2-profile__meta">General · 2 days ago</span></a><a class="v2-profile__post"><span>Looking for one more person to try the install guide before Friday.</span><span class="v2-profile__meta">Docs · 5 days ago</span></a><a class="v2-profile__post"><span>Notes from the support sync are in the pod.</span><span class="v2-profile__meta">Support · 1 week ago</span></a></div></section><section class="v2-profile__block"><h2>Joined pods</h2><div class="v2-profile__chips"><button class="v2-profile__chip">Northwind<span>12</span></button><button class="v2-profile__chip">Support<span>8</span></button><button class="v2-profile__chip">Docs<span>5</span></button></div></section></div></div></div></div></div></div></div></figure>
<figure><figcaption><b>Nothing public yet · 1440</b><span>follow still works</span></figcaption><div class="frame" style="--fw:1440;--fh:900" data-surface="profile-empty" data-vp="1440"><div class="app d"><div class="sh sh--page"><nav class="rail"><div class="logo"><svg class="i" viewBox="0 0 24 24"><use href="#i-mark"/></svg></div><div class="nav" title="Pods"><svg class="i" viewBox="0 0 24 24"><use href="#i-layers"/></svg></div><div class="nav" title="Agents"><svg class="i" viewBox="0 0 24 24"><use href="#i-team"/></svg></div><div class="nav" title="Needs you"><svg class="i" viewBox="0 0 24 24"><use href="#i-activity"/></svg><span class="bd">3</span></div><div class="nav" title="Artifacts"><svg class="i" viewBox="0 0 24 24"><use href="#i-file"/></svg></div><div class="nav" title="Connectors"><svg class="i" viewBox="0 0 24 24"><use href="#i-plug"/></svg></div><div class="nav" title="Settings"><svg class="i" viewBox="0 0 24 24"><use href="#i-gear"/></svg></div><div class="sp"></div><div class="nav" title="Feedback"><svg class="i" viewBox="0 0 24 24"><use href="#i-feedback"/></svg></div><div class="seg seg--ic seg--rail" role="group" aria-label="Theme"><button type="button" data-t="light" title="Light" aria-label="Light" aria-pressed="false"><svg class="i" viewBox="0 0 24 24"><use href="#i-sun"/></svg></button><button type="button" data-t="dark" title="Dark" aria-label="Dark" aria-pressed="false"><svg class="i" viewBox="0 0 24 24"><use href="#i-moon"/></svg></button></div><span class="av av--36"><svg viewBox="0 0 40 40"><use href="#av-alex"/></svg></span></nav><div class="pane"><div class="ph"><h1>Profile</h1><span class="sp"></span></div><div class="pbody"><div class="v2-profile"><section class="v2-profile__card"><span class="av av--64"><svg viewBox="0 0 40 40"><use href="#av-dee"/></svg></span><div class="v2-profile__who"><strong>Dana Okafor</strong><span class="v2-profile__handle">@dana</span><span class="v2-profile__since">Member since 3 months ago</span></div><button class="b b-p">Follow</button></section><div class="v2-profile__cols"><section class="v2-profile__block"><h2>Recent public posts</h2><p class="v2-profile__none">No public posts yet.</p></section><section class="v2-profile__block"><h2>Joined pods</h2><p class="v2-profile__none">No joined pods to show.</p></section></div></div></div></div></div></div></div></figure>
</div>
<div class="row1 row1--even" style="margin-top:18px">
<figure><figcaption><b>Load failed · 1440</b><span>user could not be fetched</span></figcaption><div class="frame" style="--fw:1440;--fh:900" data-surface="profile-error" data-vp="1440"><div class="app d"><div class="sh sh--page"><nav class="rail"><div class="logo"><svg class="i" viewBox="0 0 24 24"><use href="#i-mark"/></svg></div><div class="nav" title="Pods"><svg class="i" viewBox="0 0 24 24"><use href="#i-layers"/></svg></div><div class="nav" title="Agents"><svg class="i" viewBox="0 0 24 24"><use href="#i-team"/></svg></div><div class="nav" title="Needs you"><svg class="i" viewBox="0 0 24 24"><use href="#i-activity"/></svg><span class="bd">3</span></div><div class="nav" title="Artifacts"><svg class="i" viewBox="0 0 24 24"><use href="#i-file"/></svg></div><div class="nav" title="Connectors"><svg class="i" viewBox="0 0 24 24"><use href="#i-plug"/></svg></div><div class="nav" title="Settings"><svg class="i" viewBox="0 0 24 24"><use href="#i-gear"/></svg></div><div class="sp"></div><div class="nav" title="Feedback"><svg class="i" viewBox="0 0 24 24"><use href="#i-feedback"/></svg></div><div class="seg seg--ic seg--rail" role="group" aria-label="Theme"><button type="button" data-t="light" title="Light" aria-label="Light" aria-pressed="false"><svg class="i" viewBox="0 0 24 24"><use href="#i-sun"/></svg></button><button type="button" data-t="dark" title="Dark" aria-label="Dark" aria-pressed="false"><svg class="i" viewBox="0 0 24 24"><use href="#i-moon"/></svg></button></div><span class="av av--36"><svg viewBox="0 0 40 40"><use href="#av-alex"/></svg></span></nav><div class="pane"><div class="ph"><h1>Profile</h1><span class="sp"></span></div><div class="pbody"><div class="v2-profile"><div class="v2-profile__error" role="alert"><span>Failed to fetch user data. Please try again later.</span><button class="b b-s">Retry</button></div></div></div></div></div></div></div></figure>
<div class="notes"><ul>
<li><b>One card, then what they have made public.</b> The card holds the avatar, the name, the handle and how long they have been here, with <span class="cd">Follow</span> as the one ink key. Recent public posts and Joined pods sit under it, side by side at 1440 and stacked at 390.</li>
<li><b>Rows are the targets.</b> A post row opens its thread; a pod chip opens the pod. Both are 44px tall at 390 and 32px at 1440, and neither carries an icon, because the whole row is the key.</li>
<li><b>Flag for Lily, drawn without the email.</b> The live card prints <span class="cd">user.email</span> under the name. A public page should not show someone's address, so the frame shows the handle. If the email has to stay, it needs to be owner-only.</li>
<li><b>Own profile is not drawn here.</b> <span class="cd">/v2/profile</span> already redirects to Settings; the Overview, Apps, API Token and User Admin tabs live there.</li>
</ul><h3>Each state, one line</h3><table class="ctl">
<tr><td>Person</td><td>Follow flips to Unfollow (a bordered key) once the call returns; it is disabled while the call is in flight.</td></tr>
<tr><td>Nothing public yet</td><td>Each block keeps its title and says so in one line: "No public posts yet." and "No joined pods to show."</td></tr>
<tr><td>Load failed</td><td>One line and <span class="cd">Retry</span>. The live page prints the line in red with no way out; Retry is new and is the one addition in this frame.</td></tr>
</table></div>
</div>
<div class="row2 row2--even">
<figure><figcaption><b>Person · 390</b><span></span></figcaption><div class="frame" style="--fw:390;--fh:844" data-surface="profile-person" data-vp="390"><div class="app m"><div class="mtop"><h1>Profile</h1><span class="sp"></span></div><div class="mbody2"><div class="v2-profile"><section class="v2-profile__card"><span class="av av--64"><svg viewBox="0 0 40 40"><use href="#av-dee"/></svg></span><div class="v2-profile__who"><strong>Dana Okafor</strong><span class="v2-profile__handle">@dana</span><span class="v2-profile__since">Member since 3 months ago</span></div><button class="b b-p">Follow</button></section><div class="v2-profile__cols"><section class="v2-profile__block"><h2>Recent public posts</h2><div class="v2-profile__posts"><a class="v2-profile__post"><span>Shipped the retry for the webhook; the 502s are gone on staging.</span><span class="v2-profile__meta">General · 2 days ago</span></a><a class="v2-profile__post"><span>Looking for one more person to try the install guide before Friday.</span><span class="v2-profile__meta">Docs · 5 days ago</span></a><a class="v2-profile__post"><span>Notes from the support sync are in the pod.</span><span class="v2-profile__meta">Support · 1 week ago</span></a></div></section><section class="v2-profile__block"><h2>Joined pods</h2><div class="v2-profile__chips"><button class="v2-profile__chip">Northwind<span>12</span></button><button class="v2-profile__chip">Support<span>8</span></button><button class="v2-profile__chip">Docs<span>5</span></button></div></section></div></div></div><div class="mtab"><div class=""><svg class="i" viewBox="0 0 24 24"><use href="#i-layers"/></svg><span>Pods</span></div><div class=""><svg class="i" viewBox="0 0 24 24"><use href="#i-activity"/></svg><span class="bd">3</span><span>Needs you</span></div><div class=""><svg class="i" viewBox="0 0 24 24"><use href="#i-team"/></svg><span>Team</span></div><div class=""><svg class="i" viewBox="0 0 24 24"><use href="#i-gear"/></svg><span>Settings</span></div></div></div></div></figure>
<figure><figcaption><b>Nothing public yet · 390</b><span></span></figcaption><div class="frame" style="--fw:390;--fh:844" data-surface="profile-empty" data-vp="390"><div class="app m"><div class="mtop"><h1>Profile</h1><span class="sp"></span></div><div class="mbody2"><div class="v2-profile"><section class="v2-profile__card"><span class="av av--64"><svg viewBox="0 0 40 40"><use href="#av-dee"/></svg></span><div class="v2-profile__who"><strong>Dana Okafor</strong><span class="v2-profile__handle">@dana</span><span class="v2-profile__since">Member since 3 months ago</span></div><button class="b b-p">Follow</button></section><div class="v2-profile__cols"><section class="v2-profile__block"><h2>Recent public posts</h2><p class="v2-profile__none">No public posts yet.</p></section><section class="v2-profile__block"><h2>Joined pods</h2><p class="v2-profile__none">No joined pods to show.</p></section></div></div></div><div class="mtab"><div class=""><svg class="i" viewBox="0 0 24 24"><use href="#i-layers"/></svg><span>Pods</span></div><div class=""><svg class="i" viewBox="0 0 24 24"><use href="#i-activity"/></svg><span class="bd">3</span><span>Needs you</span></div><div class=""><svg class="i" viewBox="0 0 24 24"><use href="#i-team"/></svg><span>Team</span></div><div class=""><svg class="i" viewBox="0 0 24 24"><use href="#i-gear"/></svg><span>Settings</span></div></div></div></div></figure>
<figure><figcaption><b>Load failed · 390</b><span></span></figcaption><div class="frame" style="--fw:390;--fh:844" data-surface="profile-error" data-vp="390"><div class="app m"><div class="mtop"><h1>Profile</h1><span class="sp"></span></div><div class="mbody2"><div class="v2-profile"><div class="v2-profile__error" role="alert"><span>Failed to fetch user data. Please try again later.</span><button class="b b-s">Retry</button></div></div></div><div class="mtab"><div class=""><svg class="i" viewBox="0 0 24 24"><use href="#i-layers"/></svg><span>Pods</span></div><div class=""><svg class="i" viewBox="0 0 24 24"><use href="#i-activity"/></svg><span class="bd">3</span><span>Needs you</span></div><div class=""><svg class="i" viewBox="0 0 24 24"><use href="#i-team"/></svg><span>Team</span></div><div class=""><svg class="i" viewBox="0 0 24 24"><use href="#i-gear"/></svg><span>Settings</span></div></div></div></div></figure>
</div>
</section>

<section class="surf" id="s-dark">
<div class="shead"><h2>Dark mode</h2><span class="route">one dark value per token</span></div>
<div class="dm">
Expand Down
Loading
Loading