diff --git a/docs/design/artboards/d215/README.md b/docs/design/artboards/d215/README.md index c9f39f3f3..4612c051f 100644 --- a/docs/design/artboards/d215/README.md +++ b/docs/design/artboards/d215/README.md @@ -4,13 +4,26 @@ The spec for D215 (artboard v2). Open `index.html` in a browser. The toggle at t - `index.html` holds the before shots and live mocks for seven surfaces: sidebar, pod chat, task board, agent memory, agent settings, settings and connectors. The mock's names, messages and task titles are neutral samples. Counts and times come from the captures. - A second block under agent settings draws the states of that page (policy and machine, identity edit, connector grants, runtime with the model and effort selects, own API key) at 1440 and 390. The runtime and key frames follow V2RuntimeControls and V2AgentProviderKey, including the stored-model refusal and the key-save error. Those frames carry `data-state`, so `measure_after.js` skips them and `targets.json` does not move. +- Two state-only surfaces: `task-record` (the task record page, loaded and not-available, under the reply trace) and `handoff` (the OAuth and Discord return pages, `data-state` working, done, error, on the auth card). Every frame carries `data-state`, so the scorer skips them and `targets.json` does not move. - A block under Settings draws the free-plan Plan row and the administrator-only Administration group (`data-state="admin-free"`, 1440 and 390, also skipped by the scorer). +- Under Activity and under Artifacts, a block redraws each page in the picked language (`#s-activity-signal`, `#s-artifacts-signal`): busy and day zero at 1440 and 390, built only from the seven picked surfaces' blocks. Sam approved them on 11-03. The frames carry `data-state="signal"`, so the scorer skips them until each page's build PR makes them the scored frames; the frames above them stay as the record of the live page until then. - The theme switch (sun / moon, D224) sits in the rail above the avatar at 1440. At 390 there is no rail, so the same switch rides the Pods top bar, left of Search. It is a two-item segment: the item for the theme in effect is the white key. - `before/` holds prod captures from 2026-10-31, blurred so they show layout and density only. - `targets.json` holds the helper-word and scroll targets per frame. `cap/measure_after.js` writes it from `index.html`. - `cap/` holds the measuring scripts. See the header of `measure_after.js` for its env. - Every frame without `data-state` must be listed in `measure_after.js`, either in `SURFACES` (scored) or in `SKIPPED` (not scored, with a reason). Activity, Artifacts and the two trace "before" frames are skipped. `node --test cap/measure_after.test.js` fails on any frame that is in neither list. +## Where each frame came from + +Passing the prod check means a page matches its frame. It means the page matches the style Sam picked only when the frame came from his pick. Every frame is in one of four groups. Only the first two have scored frames, and prod scores are reported per group, never as one total. + +| Group | Frames | Source | +|---|---|---| +| **From Sam's pick** | sidebar, chat, board, agent-memory, agent-settings, settings, connectors | The seven surfaces picked on 10-31 (#3059). Later edits: the theme switch (#3175) and the open thread (#3178). #3288 (the 390 agent-settings and settings frames, brought up to the shipped pages) and #3289 (memory notes drawn as the API holds them) moved those frames toward the live page, so read them with that in mind. | +| **Drawn after the pick** | dm, byo, byo-handoff, connect, team, firstrun-\*, signin, signup, signup-sent, verify-email, forgot-password, reset-password, cli-authorize, invite, invite-required, profile, agent-profile, run-trace-after, chat-trace, chat-agents-away, and the agent-settings and settings state blocks | New drawings in the picked language, from 11-01 on. Sam has not reviewed them as a set. | +| **Approved by Sam, 11-03** | activity-\*, artifacts-\* with `data-state="signal"`; task-record-\*; handoff-\* | Sam saw each one live-beside-proposed and answered "Build as drawn" for all four pages. Activity and Artifacts are built only from the picked surfaces' blocks. The scorer still skips these frames (they carry `data-state`). Each page's build PR makes its approved frame the scored one and retires the frame it replaces. | +| **Drawn from live, being retired** | activity-\*, artifacts-\* without `data-state` | Traced from the live pages with small fixes (#3316, #3318). The scorer skips them (`SKIPPED` in `cap/measure_after.js`). Scoring a page against them would only show it has not drifted from itself. The Activity and Artifacts build PRs remove them. The two before frames, `run-trace-before` and `chat-trace-before`, draw the old pages and are never a target. | + ## Rules for D215 PRs 1. Every PR attaches screenshots of the built page at 1440 and 390, in light and dark, beside the matching artboard frame. diff --git a/docs/design/artboards/d215/index.html b/docs/design/artboards/d215/index.html index c703aa066..eb954c040 100644 --- a/docs/design/artboards/d215/index.html +++ b/docs/design/artboards/d215/index.html @@ -1025,6 +1025,143 @@ .app.m .authcard { width: auto; box-shadow: none; border-radius: 0; padding: 28px 20px; } /* Phone auth controls keep the 44px touch floor the shipped CSS holds. */ .app.m .authcard .b, .app.m .authcard .field { height: 44px; } +/* signal-redraw:start */ +/* Activity and Artifacts redrawn in the picked language (#s-activity-signal, #s-artifacts-signal). + Built from the seven picked surfaces' blocks: .ph head, .gtitle labels, .list groups split by hairlines, + Memory's .hv hover keys and .jday mono column, .seg, .sel, .search, .b keys. Scoped to .sg. */ +.sg { --v2-focus-ring: 0 0 0 3px var(--c-soft); } +.sg button.sel { all: unset; box-sizing: border-box; cursor: pointer; height: 32px; border-radius: 9px; background: var(--sf); box-shadow: inset 0 0 0 1px var(--b); display: inline-flex; align-items: center; gap: 6px; padding: 0 8px 0 11px; font: 500 12.5px/1 var(--f-body); color: var(--ink2); white-space: nowrap; flex: none; } +.sg button.sel svg.i { width: 14px; height: 14px; color: var(--mu); } +.sg .ph .search { height: 32px; } +.sg-col { max-width: 760px; margin: 0 auto; display: flex; flex-direction: column; } +.sg .gtitle svg.i { width: 13px; height: 13px; } +.sg .gtitle .r { margin-left: auto; } +.sg .list { overflow: hidden; } +.sg-row { display: grid; grid-template-columns: 16px minmax(0, 1fr) auto; gap: 12px; align-items: center; min-height: 58px; padding: 9px 12px 9px 14px; border-top: 1px solid var(--d); position: relative; } +.sg-row:first-child { border-top: 0; } +.sg-row > svg.i { width: 16px; height: 16px; color: var(--se); align-self: start; margin-top: 2px; } +.sg-row .tx { font-size: 13.5px; line-height: 20px; font-weight: 600; color: var(--ink); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } +.sg-row .tx .mo { font-size: 11.5px; font-weight: 500; color: var(--mu); margin-left: 8px; } +.sg-row .tx--plain { font-weight: 400; color: var(--ink2); white-space: normal; } +.sg-row .sn { margin-top: 1px; font-size: 12.5px; line-height: 18px; color: var(--se); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } +.sg-row .sn.mo { font-size: 11.5px; color: var(--mu); } +.sg-row .ac { display: flex; align-items: center; gap: 8px; } +.sg-row .ac > .mo { font-size: 11.5px; color: var(--mu); white-space: nowrap; } +.sg-row .hv { display: flex; gap: 2px; padding: 2px; border-radius: 8px; background: var(--sf); box-shadow: var(--sh-pop); } +.sg-row.hov { background: var(--p); } +.sg-row.hov .ac > .mo { display: none; } +.sg-row--open { align-items: start; } +.sg-row--one > svg.i { align-self: center; margin-top: 0; } +.sg-row--open .tx, .sg-row--open .sn { white-space: normal; } +.sg-row .keys { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 10px; } +.sg-row .keys .b .mo { font-size: 10.5px; font-weight: 500; color: var(--mu); } +.sg .b.sg-quiet { box-shadow: inset 0 0 0 1px var(--d); } +.sg-empty { padding: 11px 14px 11px 42px; font-size: 13px; line-height: 20px; color: var(--mu); } +.sg-pod { display: flex; align-items: center; gap: 8px; height: 30px; padding: 0 14px; font: 500 11.5px/1 var(--f-mono); color: var(--se); background: var(--p); border-top: 1px solid var(--d); } +.sg-pod:first-child { border-top: 0; } +.sg-pod span { margin-left: auto; color: var(--mu); } +.sg .jday { grid-template-columns: 44px minmax(0, 1fr); padding: 9px 14px; } +.sg .jday b { font-weight: 600; color: var(--ink); margin-right: 4px; } +.sg-compose { flex: none; height: 40px; gap: 9px; padding: 0 4px 0 12px; margin-bottom: 4px; } +.sg-compose .ph1 { flex: 1; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } +.sg-compose--open { display: block; height: auto; padding: 12px 10px 10px 14px; border-radius: 12px; background: var(--sf); box-shadow: inset 0 0 0 1px var(--c), var(--v2-focus-ring); } +.sg-compose--open .in { min-height: 44px; font-size: 14px; line-height: 20px; color: var(--ph); } +.sg-compose--open .caret { display: inline-block; width: 1.5px; height: 18px; margin-right: 1px; vertical-align: -4px; background: var(--c); } +.sg-compose--open .ft { display: flex; align-items: center; gap: 8px; } +.sg-compose--open .ft > .mo { font-size: 11.5px; color: var(--mu); } +.sg-compose--open .ft .sp { flex: 1; } +.sg-ext { height: 22px; border-radius: 6px; background: var(--t); box-shadow: inset 0 0 0 1px var(--d); font: 600 9.5px/22px var(--f-mono); letter-spacing: .02em; color: var(--se); text-align: center; align-self: start; margin-top: 1px; } +.sg-row.sg-file { grid-template-columns: 38px minmax(0, 1fr) auto; } +.sg-foot { display: flex; align-items: center; justify-content: space-between; padding: 10px 4px 0; } +.sg-foot .mo { font-size: 11.5px; color: var(--mu); } +/* 390: the top bar holds title + count; one 44px control row; rows and keys at the 44px touch floor */ +.app.m.sg .mtop { padding: 0 10px 0 16px; } +.app.m.sg .mtop .meta { font: 500 11.5px/1 var(--f-mono); color: var(--mu); white-space: nowrap; } +.app.m.sg .mbody2 > * { flex: none; } +.app.m.sg .gtitle { margin: 8px 4px 0; } +.app.m.sg .sg-row .tx { white-space: normal; } +.app.m.sg .sg-row .tx .mo { display: block; margin: 1px 0 0; } +.app.m.sg .gtitle:first-child { margin-top: 0; } +.sg-ctl { display: flex; gap: 8px; flex: none; } +.app.m.sg .sg-ctl .seg { flex: 1; display: flex; } +.app.m.sg .sg-ctl .seg button { flex: 1; justify-content: center; height: 40px; } +.app.m.sg .sg-ctl .sel { height: 44px; } +.app.m.sg .sg-compose { height: 44px; margin: 0; } +.app.m.sg .sg-row { min-height: 60px; padding: 8px 8px 8px 12px; gap: 10px; } +.app.m.sg .sg-row .ac .b:not(.ib) { height: 44px; } +.app.m.sg .sg-row .ib { width: 44px; height: 44px; } +.app.m.sg .sg-row--open { padding: 12px 12px 12px; } +.app.m.sg .sg-row .keys { flex-direction: column; gap: 6px; } +.app.m.sg .sg-row .keys .b { width: 100%; justify-content: center; } +.app.m.sg .sg-row.sg-file { grid-template-columns: 38px minmax(0, 1fr) auto; } +.app.m.sg .sg-row .sn .mo { font-size: 11.5px; color: var(--mu); } +.app.m.sg .jday { padding: 8px 12px; } +.app.m.sg .sg-foot .b { height: 44px; } +/* signal-redraw:end */ +/* task record: new names (v2-task-record__*). The live page borrows v2-run-trace__*; this frame gives it its own. */ +.v2-task-record { max-width: 880px; min-width: 0; color: var(--ink); } +.v2-task-record h2 { font: 700 22px/1.25 var(--f-display); letter-spacing: -0.02em; margin: 0 0 20px; text-wrap: balance; } +.v2-task-record__day { font: 500 11.5px/1 var(--f-mono); color: var(--mu); margin: 0 0 4px 40px; } +.v2-task-record__list { list-style: none; margin: 0; padding: 0; } +.v2-task-record__e { display: grid; grid-template-columns: 28px minmax(0, 1fr) auto 28px; column-gap: 12px; align-items: center; min-height: 44px; position: relative; } +.v2-task-record__e::before { content: ""; position: absolute; left: 13.5px; top: 0; bottom: 0; width: 1px; background: var(--d); } +.v2-task-record__e:first-child::before { top: 22px; } +.v2-task-record__e:last-child::before { bottom: auto; height: 22px; } +.v2-task-record__mk { width: 28px; height: 28px; border-radius: 50%; display: grid; place-items: center; background: var(--sf); box-shadow: inset 0 0 0 1px var(--b); color: var(--se); position: relative; z-index: 1; } +.v2-task-record__mk svg.i { width: 14px; height: 14px; } +.v2-task-record__mk--done { background: var(--c-soft); box-shadow: inset 0 0 0 1px var(--c); color: var(--c-text); } +.v2-task-record__main { display: flex; align-items: center; gap: 8px; min-width: 0; font-size: 13.5px; } +.v2-task-record__main b { font-weight: 600; white-space: nowrap; } +.v2-task-record__who { display: inline-flex; align-items: center; gap: 6px; color: var(--ink2); white-space: nowrap; } +.v2-task-record__sys { width: 20px; height: 20px; border-radius: 6px; display: grid; place-items: center; background: var(--t); color: var(--se); flex: none; } +.v2-task-record__sys svg.i { width: 12px; height: 12px; } +.v2-task-record__d { font: 500 12px/1.2 var(--f-mono); color: var(--se); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; } +.v2-task-record__t { font: 500 11.5px/1 var(--f-mono); color: var(--mu); white-space: nowrap; } +.v2-task-record__e .ib .i { transition: transform 160ms; } +.v2-task-record__e.open .ib .i { transform: rotate(180deg); } +.v2-task-record__more { grid-column: 2 / -1; margin: 2px 0 10px; padding: 12px 14px; border-radius: 10px; background: var(--p); box-shadow: inset 0 0 0 1px var(--d); } +.v2-task-record__more .kv { grid-template-columns: 96px minmax(0, 1fr); } +.v2-task-record__more .kv > span:nth-child(even) { font: 500 12.5px/1.4 var(--f-mono); color: var(--ink); overflow-wrap: anywhere; } +.v2-task-record__foot { margin-top: 18px; padding-top: 12px; border-top: 1px solid var(--d); font: 500 11.5px/16px var(--f-mono); color: var(--mu); } +.v2-task-record__none { margin: 140px auto 0; max-width: 380px; display: grid; justify-items: center; gap: 10px; text-align: center; } +.v2-task-record__none .tile { width: 44px; height: 44px; border-radius: 12px; display: grid; place-items: center; background: var(--t); color: var(--se); box-shadow: inset 0 0 0 1px var(--d); } +.v2-task-record__none h3 { margin: 4px 0 0; font: 700 18px/1.25 var(--f-display); letter-spacing: -0.01em; } +.v2-task-record__none p { margin: 0; font-size: 13.5px; line-height: 1.5; color: var(--se); } +.menu { position: absolute; z-index: 6; width: 220px; padding: 4px; border-radius: 10px; background: var(--sf); box-shadow: var(--sh-pop); display: grid; gap: 2px; } +.menu button { all: unset; box-sizing: border-box; cursor: pointer; height: 34px; padding: 0 10px; border-radius: 7px; display: flex; align-items: center; gap: 9px; font-size: 13px; color: var(--ink); } +.menu button svg.i { width: 15px; height: 15px; color: var(--se); } +.menu button .mo { margin-left: auto; font-size: 11px; color: var(--mu); } +.menu button.hov { background: var(--t); } +.app.m .mbody2--rec { padding: 16px 16px 12px; display: block; } +.app.m .v2-task-record h2 { font-size: 19px; margin-bottom: 4px; } +.app.m .v2-task-record__id { font: 500 11.5px/1 var(--f-mono); color: var(--mu); margin: 0 0 16px; } +.app.m .v2-task-record__day { margin-left: 40px; } +.app.m .v2-task-record__e { grid-template-columns: 28px minmax(0, 1fr) auto; min-height: 56px; align-items: start; padding-top: 8px; } +.app.m .v2-task-record__e::before { top: 0; } +.app.m .v2-task-record__e:first-child::before { top: 22px; } +.app.m .v2-task-record__e:last-child::before { height: 22px; } +.app.m .v2-task-record__main { flex-wrap: wrap; row-gap: 3px; } +.app.m .v2-task-record__d { flex-basis: 100%; } +.app.m .v2-task-record__t { padding-top: 4px; } +.app.m .v2-task-record__more { grid-column: 1 / -1; margin-left: 40px; } +.app.m .v2-task-record__more .kv { grid-template-columns: 84px minmax(0, 1fr); } +.app.m .v2-task-record__none { margin-top: 120px; } +/* handoff: the auth card, with the brand row turned into provider → Commonly */ +.authcard .hand { display: flex; align-items: center; gap: 10px; } +.authcard .hand .pv { width: 30px; height: 30px; border-radius: 9px; display: grid; place-items: center; background: var(--sf); box-shadow: inset 0 0 0 1px var(--d); flex: none; } +.authcard .hand .pv svg { width: 20px; height: 20px; } +.authcard .hand .pv svg.i { width: 17px; height: 17px; color: var(--se); } +.authcard .hand .wire { position: relative; width: 52px; height: 18px; flex: none; display: grid; place-items: center; } +.authcard .hand .wire::before { content: ""; position: absolute; left: 0; right: 0; top: 50%; height: 0; border-top: 2px dotted var(--b); } +.authcard .hand .wire .run { position: absolute; top: calc(50% - 3px); left: 0; width: 6px; height: 6px; border-radius: 50%; background: var(--c); animation: wire 1.4s ease-in-out infinite; } +@keyframes wire { 0% { left: 0; opacity: 0; } 20% { opacity: 1; } 80% { opacity: 1; } 100% { left: calc(100% - 6px); opacity: 0; } } +.authcard .hand .wire--ok::before { border-top: 2px solid var(--c); } +.authcard .hand .wire .knot { position: relative; width: 18px; height: 18px; border-radius: 50%; display: grid; place-items: center; background: var(--sf); box-shadow: inset 0 0 0 1.5px var(--c); color: var(--c-text); } +.authcard .hand .wire .knot svg.i { width: 11px; height: 11px; stroke-width: 2.4; } +.authcard .hand .wire--bad .knot { box-shadow: inset 0 0 0 1.5px var(--ink); color: var(--ink); } +.authcard .hand .logo { margin-bottom: 0; } +.authcard .sel2 { justify-content: space-between; } +.authcard .sel2 svg.i { width: 16px; height: 16px; color: var(--mu); }

Same look. Less said.

  • One screen firstRepeated blocks become a table; rare settings collapse.
  • @@ -1619,6 +1759,31 @@

    Same look. Less said.

    +
    +

    Activity · in the picked language

    /v2/activity
    approved 11-03, not scored yet
    +
    Busy · 14404 need you, 2 pods moved; Fern hovered

    Activity

    4 need you · 5 moved
    Needs you4 · oldest first
    Which launch date goes in the customer email?Northwind · 12m
    Legal cleared both dates. Sage needs one before the 3pm send.
    Send the October invoices to 14 customersNorthwind · 40m
    Totals match the ledger. Nothing goes out until you approve.
    FernField notes · 1h
    @alex the interview notes are summarized. Post the three open questions to the pod, or keep them in the doc?
    Juno ParkNorthwind · 2h
    @alex can you check the pricing table before Ivy sends it? The annual column looks off.
    Moved forward5 · newest first
    Northwind3
    25mIvy Reconciled the October ledger; two refunds flagged for review.
    1hSage Drafted the launch email in two versions.
    2hAlex Moved “Pricing page copy” to Done.
    Field notes2
    1hFern Summarized six customer interviews into one doc.
    3hJuno Park Added notes from the Friday call.
    Day zero · 1440one pod, only Scout; composer focused

    Activity

    0 need you · 0 moved
    Write a message. Mention an agent to wake it…
    Post in⌘↵
    Get started2 steps
    Say something to it
    Say hello in the pod where it lives. If it doesn't answer, @mention it.
    Connect a channel
    Slack or Telegram — the agent answers where your team already talks.
    Needs you
    Nothing needs you.
    Moved forward
    Nothing yet today.
    +
    Busy · 390top of page

    Activity

    4 need you · 5 moved
    Needs you4
    Which launch date goes in the customer email?
    Legal cleared both dates. Sage needs one before the 3pm send.
    Northwind · 12m
    Send the October invoices to 14 customersNorthwind · 40m
    Totals match the ledger. Nothing goes out until you approve.
    FernField notes · 1h
    @alex the interview notes are summarized. Post the three open questions to the pod, or keep them in the doc?
    Juno ParkNorthwind · 2h
    @alex can you check the pricing table before Ivy sends it? The annual column looks off.
    Moved forward5
    Northwind3
    25mIvy Reconciled the October ledger; two refunds flagged for review.
    1hSage Drafted the launch email in two versions.
    2hAlex Moved “Pricing page copy” to Done.
    Field notes2
    1hFern Summarized six customer interviews into one doc.
    3hJuno Park Added notes from the Friday call.
    Pods
    4Needs you
    Team
    Settings
    Day zero · 3907 days selected

    Activity

    0 need you · 0 moved
    Get started2 steps
    Say something to it
    Say hello in the pod where it lives. If it doesn't answer, @mention it.
    Connect a channel
    Slack or Telegram — the agent answers where your team already talks.
    Needs you
    Nothing needs you.
    Moved forward
    Nothing moved in the last 7 days.
    Pods
    Needs you
    Team
    Settings
      +
    • Built only from the seven picked surfaces. Head is the Connectors .ph: display title, one mono count, then one Today / 7 days .seg and one All pods ▾ select. Body is a centred 760px column of mono section labels (.gtitle with a 13px line icon), each over ONE .list split by hairlines. No card stack, no filled glyph squares, no (i) on any heading: "oldest first" and "newest first" ride the label's right edge, as "saved 1h ago" does on Memory.
    • +
    • Against the current frame. The composer card becomes a one-line row in Memory's search shape that expands on focus (drawn open on day zero). The four equal cards become one list: the decision row stays open, the other three are two-line rows with one quiet key. The scope pill row (All pods / Northwind / Field notes / more ▾) becomes one select. "Moved forward" loses its table head and becomes one list with a mono pod sub-row per pod and Journal's mono time column.
    • +
    • The decision is the only open row. Its choices are three 28px keys inside the row: Tuesday (marked recommended in mono inside its own key, replacing the caption under a pill), Thursday, and a quiet Other…. ↗ opens it in the pod. At 390 the same keys go full width at 44px, inside that row only.
    • +
    • Hover keys, as on Memory. A hovered row shows a small key cluster before its key (drawn on Fern: ✓ Mark handled, ↗ Open in pod). On the approval row the cluster holds ✕ Reject and ↗ Open. Keyboard focus on the row shows the same cluster. At 390 there is no hover: the row's ⋯ key (44px) holds the same items, and tapping the row opens it in the pod.
    • +
    • Focus uses the token. The open composer's ring is box-shadow: var(--v2-focus-ring) (the artboard stands it in from its own cobalt tokens), replacing the hard-coded rgba halo. The ruled decision line drops its leading ✓ glyph; the ruled state reads as text only.
    • +
    • Day zero says less. Get started is a group of two rows like any other, with its current step as the one raised key (Open My Workspace) and the next step quiet. Needs you and Moved forward stay as one-line rows in their own groups, so the page keeps its shape when the first ask arrives.
    • +
    +

    Every live function, mapped

    + + + + + + + + + + + +
    Post to a podThe one-line composer row. Its pod select sits at the right; on focus it opens to the text area with Post in ▾, ⌘↵ and Send.
    Answer a decisionKeys inside the open row: Tuesday, Thursday, Other… (opens the editor in the row, as prod does).
    Approve or rejectApprove is the row's key; Reject is ✕ in the hover cluster (⋯ at 390).
    Reply to a mentionReply key on the row; the editor opens in the row at full width.
    Mark handled✓ in the hover cluster (⋯ at 390).
    Open in pod↗ in the hover cluster or on the decision row; at 390 tapping the row.
    Today / 7 daysThe head segment (control row at 390).
    Pod scopeThe All pods ▾ select; pods past the first two live in its list, as more ▾ did.
    Moved forwardIts own group: a mono sub-row per pod with its count, then time and line.
    Not drawnLoading, error, Get started · checking (the same two rows with bars), no agent yet, the ruled and Other… editors. Each keeps the row shape above.
    +

    Artifacts

    /v2/artifacts
    @@ -1631,6 +1796,28 @@

    Same look. Less said.

    • Class names are the page's own (v2-artifacts__*), so the build copies them. New names: __zero (the card) and __open (its ink key).
    • Day zero has nothing to filter, so it shows no filters. It applies when the total is 0 and no kind, pod or search filter is set, and the page is not loading and has no error. Then the kind segment, the pod segment, the search box and the head's count all drop, and one bordered card (not dashed) takes their place.
    • The card is the only act on the page. Its key opens the account's oldest pod (signup creates My Workspace first), labelled with that pod's name. An account with no pods gets the card without the key.
    • A filtered empty result keeps the controls. With a kind, pod or search set, the page keeps prod's dashed line, Nothing matches. Clear a filter or the search., under the controls, so the way out stays on screen.
    • At 390 the key is full width and 44px tall. Busy is prod's table, unchanged: the pod folds under the name as a mono line, and pod, shared by and size hide.

    Each state, one line

    Day zeroDrawn at 1440 and 390. Total 0, no kind, pod or search set, not loading, no error: no controls, no count, the card.
    BusyDrawn at 1440 and 390. Prod's table and foot, unchanged.
    Filtered, emptyNot drawn. Controls stay; prod's dashed emptyFiltered line under them.
    No podsNot drawn. The day-zero card without its key.
    Loading, errorNot drawn. They keep prod's spinner and __error line.
    +
    +

    Artifacts · in the picked language

    /v2/artifacts
    approved 11-03, not scored yet
    +
    Busy · 144014 files across 2 pods; one row hovered

    Artifacts

    14 files · 2 pods
    Northwind
    pricing-v3-final.pdf
    Fern · 12m
    2.1 MB
    onboarding-flow-1440.png
    Juno Park · 1h
    412 KB
    q4-pipeline.xlsx
    Alex Chen · 2d
    96 KB
    Field notes
    launch-checklist.html
    Scout · 3h
    —
    interview-synthesis.md
    Fern · 1d
    18 KB
    whiteboard-friday.jpg
    Juno Park · 4d
    1.4 MB
    6 of 14 · newest first
    Day zero · 1440nothing shared, no filter set

    Artifacts

    Files you and your agents share in a pod land here.
    +
    Busy · 390size folds under the name

    Artifacts

    14 files · 2 pods
    Northwind
    pricing-v3-final.pdf
    Fern · 12m · 2.1 MB
    onboarding-flow-1440.png
    Juno Park · 1h · 412 KB
    q4-pipeline.xlsx
    Alex Chen · 2d · 96 KB
    Field notes
    launch-checklist.html
    Scout · 3h
    interview-synthesis.md
    Fern · 1d · 18 KB
    whiteboard-friday.jpg
    Juno Park · 4d · 1.4 MB
    6 of 14 · newest first
    Pods
    Needs you
    Team
    Settings
    Day zero · 390key full width, 44px

    Artifacts

    Files you and your agents share in a pod land here.
    Pods
    Needs you
    Team
    Settings
      +
    • Head as Connectors draws it. Display title, one mono count (14 files · 2 pods), then the search field (⌘K), one All / Images / Docs / Pages segment and an All pods ▾ select at the right. The two pill groups and the count-only meta go.
    • +
    • The table becomes groups. No header row and no six columns: a mono section label per pod over one bordered list. Each row carries a mono file-type badge (grey, the pod-mark shape, so the Kind column is the badge), the bold name, one secondary line Fern · 12m (Shared by and When) and the size as a trailing mono value. Pod, Kind, Shared by, When and Size all survive; only the column chrome is cut.
    • +
    • Hover keys, as on Memory. A hovered row (drawn on onboarding-flow-1440.png) swaps its size for ↗ Open and ↓ Download. Clicking the row opens the file. ↓ is one new 24px line glyph in the sprite (#i-down), drawn in the same stroke as the rest.
    • +
    • Order and paging are unchanged. Newest first inside each pod, and pods ordered by their newest file. The foot keeps 6 of 14 · newest first and a quiet 8 more, which loads into both groups.
    • +
    • Day zero is one quiet row in the same group shape. It has the file glyph, one sentence and one raised key, Open My Workspace. The "Nothing shared yet" heading and the head controls drop, as the current frame already drops them. At 390 the key is full width at 44px inside the row.
    • +
    • At 390, the same rows. The size folds into the secondary line (Fern · 12m · 2.1 MB), the row is the open target, and the one trailing key is ↓ Download at 44px. Search is the top bar's search key, as on Connectors. Kind and pod share one 44px control row.
    • +
    +

    Every live function, mapped

    + + + + + + + + +
    Kind filterHead segment (control row at 390).
    Pod scopeAll pods ▾ select; pods past the first two are in its list, as more ▾ was. A chosen pod leaves one group.
    SearchHead field, ⌘K; the top bar's search key at 390.
    Open a fileThe row, or ↗ in the hover cluster.
    Newest firstWithin each group; stated once in the foot.
    N moreFoot, quiet key 8 more.
    Not drawnFiltered empty (controls stay; one row: Nothing matches. Clear a filter or the search.), no pods (the day-zero row without its key), loading, error.
    +

    How this reply was made

    /v2/pods/:podId/runs/:runId
    @@ -1643,6 +1830,27 @@

    Same look. Less said.

    +
    +

    Task record

    /v2/pods/:podId/tasks/:taskId/record
    intro 2 lines → (i)keys 2 → 1 + menu
    +
    Loaded · 1440Download open, entry 4 open

    Task record

    TASK-93 · 7 entries

    CI check: fail a PR unless the latest review at its head approves it

    Tue, Oct 28
    1. ClaimedFaylease until 10:31
    2. Approval requestedFayOpen pull request #409? · asked Alex
    3. Approval decidedAlexallow once
    4. Tool callFaygh.pr_create · completed
      entry4titleOpen pull request #409namegh.pr_createsurfaceclistatuscompletedtoolCallIdtc-4argsDigestsha256:9f2c…41ab
    5. ReleasedFayreason blocked
    6. ClaimedMosslease until 11:20
    7. DoneBoarddone by Alex
    Run srv-task-0123456789abcdef0123456789abcdef
    +
    Loaded · 390row is the target
    Task record

    CI check: fail a PR unless the latest review at its head approves it

    TASK-93 · 7 entries

    Tue, Oct 28
    1. ClaimedFaylease until 10:31
    2. Approval requestedFayOpen pull request #409? · asked Alex
    3. Approval decidedAlexallow once
    4. Tool callFaygh.pr_create · completed
      entry4titleOpen pull request #409namegh.pr_createsurfaceclistatuscompletedtoolCallIdtc-4argsDigestsha256:9f2c…41ab
    5. ReleasedFayreason blocked
    6. ClaimedMosslease until 11:20
    7. DoneBoarddone by Alex
    Run srv-task-0123456789abcdef0123456789abcdef
    Pods
    Needs you
    Team
    Settings
    Not available · 390
    Task record
    Pods
    Needs you
    Team
    Settings
      +
    • The task, not the word "record", leads. The h1 stays Task record in the pane header; the body opens on the task's title. The page reads it from the board's own GET /api/v1/tasks/:podId row; while that loads or fails, the title line is the id.
    • +
    • The chain explainer is behind (i). The hash-chain sentence was the first thing on the page; it is the (i) beside the h1 now.
    • +
    • Back is the icon key in the header, like the board's own back key. No grey words that click.
    • +
    • One row per entry: a mark per kind, the kind, who (avatar, or a tile for Board, System and Policy), one mono line of the entry's data, the time. Agents carry their avatar instead of "(agent)".
    • +
    • Data folds. The full key/value list, entry number included, opens under its row from the chevron (one shown open). At 390 the whole row is the 44px target.
    • +
    • Two downloads become one key and a menu. JSONL and OTLP sit under Download; at 390 the key is the icon. The run id moves to the foot, muted mono, as on the reply trace.
    • +
    • Done is the only filled mark, in cobalt soft. Nothing else on the page is coloured.
    • +

    Each state, one line

    + + + + + +
    LoadedDrawn at 1440 (Download menu open, one entry open) and 390.
    Not available (404)Drawn. Lock tile, title, one line. The header's back key is the way out. This is what prod shows today for every pod: none keep records yet.
    Members only, store down, error, unreadableNot drawn. Same block, its own line; the three retryable ones add a bordered Try again key under it.
    LoadingNot drawn. Header in place, three grey row skeletons on the timeline.
    Empty, download failedNot drawn. Empty is the same block with a clock tile; a failed download is the shared alert row above the list.
    +
    Not available · 1440404: no records kept, or no access

    Task record

    TASK-93
    +
    +

    First run

    /v2/pods/:id · Scout welcome + Guide dialog
    helper words welcome – → 16dialog – → 68scroll 390 – → 1.0×
    @@ -1712,6 +1920,24 @@

    Same look. Less said.

    Signed out · 390
    commonly
    DR
    You’re invited to

    Design review

    4 members · humans and agents working together on Commonly

    Already have an account? Log in
    Signed in · 390
    commonly
    DR
    You’re invited to

    Design review

    Crits on the launch screens before they ship. Agents post the first pass.

    4 members

    Unavailable · 390signed out; expired or revoked
    commonly

    Invite unavailable

    +
    +

    Sign-in handoff

    /v2/oauth/complete, /v2/discord/callback, /success, /error
    components MUI + auth → auth cardsubtitles 3 → none
    +
    Working · 1440Discord
    commonly

    Connecting Discord…

    Done · 1440pick the channel
    commonly

    Pick a channel

    Server
    Northwind HQ
    Channel
    #general
    Error · 1440server line, two keys
    commonly

    Discord didn't connect

    +
    Working · 390Discord
    commonly

    Connecting Discord…

    Done · 390
    commonly

    Pick a channel

    Server
    Northwind HQ
    Channel
    #general
    Error · 390
    commonly

    Discord didn't connect

    Working · 390OAuth
    commonly

    Signing you in…

    +
    Working · 1440OAuth
    commonly

    Signing you in…

      +
    • The auth card again. Same canvas, card, h1, alert row and keys as sign-in; edge to edge at 390. The MUI card, the 64px green and red icons and the dark-navy page are gone.
    • +
    • The brand row says the handoff. Provider tile, a wire, the Commonly mark. Working: a cobalt dot runs the dotted wire. Done: the wire is solid with a check. Error: an ink cross on the wire. No subtitle in any state.
    • +
    • Working is one line. "Connecting Discord…" or "Signing you in…". "Please wait while we set up…" and "Completing sign-in with your provider." are cut; the moving wire says it.
    • +
    • Done asks the one question left. "Discord Bot Added Successfully!", the divider and "Select Channel for Integration" become one h1, "Pick a channel"; the server is a fact row; Cancel and Connect share a row, Connect in ink.
    • +
    • Error carries a way forward. The server's line sits in the shared alert row; Back and Try again share a row.
    • +

    Each state, one line

    + + + + +
    workingDrawn, Discord (/discord/callback) and OAuth (/oauth/complete), 1440 and 390.
    doneDrawn, Discord (/discord/success). OAuth has no done screen: it navigates on as soon as the code is exchanged.
    errorDrawn, Discord (/discord/error). An OAuth failure lands on sign-in's alert row (drawn above), as today.
    Connected, opening the podNot drawn. Done with a status row in place of the keys.
    +
    +

    Dark mode

    one dark value per token