You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
design(web): §01 pastes an install that builds; the leads stop saying what follows them
The dependency snippet was half an install: the copy button handed over a
.package line that does not build without the target's .product line, which
is the one people forget. It carries both halves now, with the call broken
across its arguments so a phone reads eight of eleven lines whole instead of
one line that stops at "gpu-cli". The URL cannot be made to fit a 320 px
column in any formatting, so the plate keeps its scroll area for that line
and copy.ts says why, with the numbers.
The prose around it was arguing with itself. The lead promised one taxonomy
(AppKit, SwiftUI, iOS), the tail promised another (AppKit, SwiftUI, UIKit),
and the note promised a third; the lead now names none, which settles it
without picking a side. The paragraph listing what else the README covers is
gone, because a table of contents is not copy and it pointed at the README a
third time in four lines. Its slot carries the Xcode route, displaced from a
64-character caption that wrapped at every width. The note opens on what the
snippet does not say and then states the working-directory gotcha, which is
the thing that costs a reader a morning and the reason the README link has
something to earn.
Elsewhere the same fault, treated the same way: the hero standfirst loses the
field list §03 shows verbatim and lands its payoff at word 39 rather than 57;
§02's lead stops reciting the three terms printed underneath it; §05 stops
making one promise three times, so the lead owns what arrives, the privacy
line owns whose list it is, and the helper stays a field hint.
The hero's primary now sends the reader one section down rather than off the
site, and the repo-visibility branch moves onto the README link with it: an
anchor into this same document has nothing to be unavailable about.
The §01 grid override goes with the snippet that justified it. It floored the
narrow track at 29 rem for a ClipboardSink line that has not been in §01 for
two commits, and the floor was quietly stealing 27 px from the plate at 1600.
Verified: build, 124 tests, responsive-check at 320/375/414/768/1280. Column
and caption widths measured against dist at seven widths; the hero anchor
clicked headlessly at 1280 and 375.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Copy file name to clipboardExpand all lines: .beads/interactions.jsonl
+11Lines changed: 11 additions & 0 deletions
Original file line number
Diff line number
Diff line change
@@ -23,3 +23,14 @@
23
23
{"id":"int-5fc8bfc7c0dfa68822c658816e6b8e94","kind":"field_change","created_at":"2026-08-20T17:09:16.762437Z","actor":"Angus Bezzina","issue_id":"annotkit-dmu","extra":{"field":"status","new_value":"closed","old_value":"open","reason":"Bare Lucide Sun/Moon at strokeWidth 1.5, in its own flow row above the masthead (not pinned: the centred dateline reaches the right edge below 48rem and would collide). 44x44 target, aria-label names the destination theme, svg aria-hidden+focusable=false. Gate 30's justification is now weaker and the record says so rather than rewriting the old argument. Fold budget re-verified: CTAs at 709px of 800."}}
24
24
{"id":"int-a1b30624ca7c46e6192b68275c02f6e2","kind":"field_change","created_at":"2026-08-20T17:09:17.244552Z","actor":"Angus Bezzina","issue_id":"annotkit-bqh","extra":{"field":"status","new_value":"closed","old_value":"open","reason":"Seven hairline frames drifting and cross-fading behind the page: the app's marquee at rest, which is what makes it survive gates 29/45 where a blob field would not. CSS only, aria-hidden, pointer-events none, overflow hidden, transform+opacity only, near-prime 43-97s cycles so no two frames rephase. Reduced motion holds them still at rest opacity rather than removing them. Measured: 7,136px2 of stroke, 0.62% of a viewport before alpha, drawn at 6-9%. Gates 29 and 45 changed from plain 'no' to justifications."}}
25
25
{"id":"int-0fe7247da53b0f235927a1f1fc435201","kind":"field_change","created_at":"2026-08-20T17:39:53.415873Z","actor":"Angus Bezzina","issue_id":"annotkit-6y6","extra":{"field":"status","new_value":"closed","old_value":"in_progress","reason":"All six changes landed. Theme toggle moved into the masthead link row (maintainer rejected the under-wordmark row on render). Every icon on Lucide via src/components/Icon.tsx, one stroke weight, two sizes; copy button is Copy/Check/X. Backdrop retuned from ~0.5px/s to 3-7px/s with alpha up to 10-12%. Figure frames on --color-rule-2. Subfoot link hovers to GPU CLI green (verbatim rgb(24,220,106) in dark, same hue re-derived for AA in light). Machine text in prose wrapped in <code> via a backtick convention + src/markup.tsx. Gates: 116 tests, typecheck, 30/30 contrast, responsive 5/5."}}
{"id":"int-6f4b0709bef645bef1fa00d3f3dc82d5","kind":"field_change","created_at":"2026-08-21T02:46:27.044421Z","actor":"Angus Bezzina","issue_id":"annotkit-0i4.5","extra":{"field":"status","new_value":"closed","old_value":"open","reason":"Measured, not a defect. The backdrop is viewport-anchored, so its frames sit behind running text on every section at every width, by design and at 10-12% accent on a 1px stroke; there is no §01-scoped fix and the finding's coordinates came from an artificial 4000px-tall viewport. See notes."}}
36
+
{"id":"int-ab2eaeffeb29c6c884d50256e60012f4","kind":"field_change","created_at":"2026-08-21T02:46:39.863426Z","actor":"Angus Bezzina","issue_id":"annotkit-0i4","extra":{"field":"status","new_value":"closed","old_value":"open","reason":"All ten children resolved: nine implemented in web/, one (0i4.5, backdrop) closed as measured-not-a-defect. Gates green: npm run build, npm test (124), npm run responsive (320-1280 PASS). Not committed — conservative profile."}}
Copy file name to clipboardExpand all lines: web/src/copy.ts
+43-13Lines changed: 43 additions & 13 deletions
Original file line number
Diff line number
Diff line change
@@ -43,38 +43,68 @@ export const masthead = {
43
43
exportconsthero={
44
44
display: "Point at the view. Hand the agent the map.",
45
45
standfirst:
46
-
"AnnotKit is a Swift package that mounts a floating toolbar in the dev build of your macOS or iOS app. Click a control, or draw a frame around a whole card, then type a note. It writes an agent-readable annotation: a stable selector, an element path, the element’s role and text, and your words. Your coding agent stops guessing.",
47
-
ctaPrimary: "Read the README",
48
-
ctaSecondary: "Get release notes",
46
+
"AnnotKit mounts a floating toolbar in your macOS or iOS dev build. Click a control, or draw a frame around a card, then type a note. The note carries a selector that locates that control in code. Your coding agent stops guessing.",
47
+
ctaPrimary: "Install it",
48
+
ctaSecondary: "Read the README",
49
49
}asconst;
50
50
51
51
exportconstinstall={
52
52
number: "§01",
53
53
title: "Install",
54
-
lead: "Add the package, mount the toolbar in your dev build. The README walks through AppKit, SwiftUI and iOS.",
54
+
lead: "Add the package, then mount the toolbar once your dev build has a window.",
55
+
/**
56
+
* Both halves of the dependency, not just the first. The `.package` line
57
+
* alone is what people copy and it does not build on its own: the product
58
+
* has to reach the app target too, and that is the line that gets forgotten.
59
+
*
60
+
* The call is broken across its arguments to cut what the plate has to
61
+
* scroll on a phone: 121 px at 375 rather than 214, and eight of its eleven
62
+
* lines read whole there, where the old single line read as far as
63
+
* `gpu-cli` and stopped. The URL cannot be made to fit at a phone width in
64
+
* any formatting: the quoted string alone measures 289 px at --text-sm and
65
+
* the 320 px column leaves 246 for it. So the plate keeps its scroll area
66
+
* for that line, which is what the scroll area is for.
67
+
*/
55
68
package: {
56
-
caption: "Add the dependency, or File ▸ Add Package Dependencies… in Xcode",
Annotation.install() // floating toolbar; click a view, type a note
67
90
#endif`,
68
91
},
69
-
note: "`install()` mounts the floating toolbar and writes notes to `ANNOTKIT_NOTES.md` in the working directory. SwiftUI on iOS attaches it with `.installAnnotation()` instead.",
70
-
more: "Where to call it from AppKit, SwiftUI and UIKit, how to point the notes file at your repo, other sinks, and world context: all in the README.",
92
+
/** Beside the first plate: the route most app projects actually take. */
93
+
xcode:
94
+
"An Xcode project does it through File ▸ Add Package Dependencies… instead: paste the URL there, then add the AnnotKit library to your app target.",
95
+
/**
96
+
* Beside the second. It opens on what the snippet does NOT say rather than
97
+
* restating it, and the working-directory line is the one thing a reader
98
+
* loses a morning to if the page leaves it out (README §3).
99
+
*/
100
+
note: "SwiftUI on iOS attaches the toolbar to the root view with `.installAnnotation()` instead. Either way the notes land in `ANNOTKIT_NOTES.md` in the working directory, which is usually not your repo when Xcode launches the app. Set that in the scheme, or hand `install()` a sink with a path of its own.",
71
101
readme: "Setup guide in the README",
72
102
}asconst;
73
103
74
104
exportconstannotate={
75
105
number: "§02",
76
106
title: "Annotate",
77
-
lead: "A click means this exact spot: AnnotKit descends to the deepest actionable control. A drawn frame means this whole thing: the largest element the frame surrounds wins. One rule, both platforms. The selector anchors itself to the nearest `accessibilityIdentifier`, so it round-trips back to code.",
107
+
lead: "One rule, both platforms: what you point at is what the note binds to.",
78
108
points: [
79
109
{
80
110
term: "Click",
@@ -86,7 +116,7 @@ export const annotate = {
86
116
},
87
117
{
88
118
term: "Anchor",
89
-
body: "An unidentified target is anchored to its nearest seeded identifier (`#Settings.Profile >> @Save`), so the selector points an agent at the right component’s code.",
119
+
body: "An unidentified target is anchored to the nearest `accessibilityIdentifier` above it (`#Settings.Profile >> @Save`), so the selector points an agent at the right component’s code.",
90
120
},
91
121
],
92
122
}asconst;
@@ -102,7 +132,7 @@ export const agentNotes = {
102
132
* whole sample off the page.
103
133
*/
104
134
sample: {
105
-
caption: "The block `AnnotationFormatter` writes, one per note",
lead: "The GPU CLI list: releases and design notes for AnnotKit, for the CLI that runs cloud GPUs from your terminal, and for whatever ships next. No digest, no drip campaign.",
180
+
lead: "Releases and design notes for AnnotKit. No digest, no drip campaign.",
0 commit comments