wield-mcp 0.0.0-stage → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,201 @@
1
+ /* generated from design/tokens.css */
2
+ /* @tokens:start */
3
+ :root {
4
+ /* ---- type ---- */
5
+ --font-sans: "Instrument Sans", ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
6
+ --font-mono: "Fragment Mono", ui-monospace, "SF Mono", SFMono-Regular, Menlo, Consolas, "Liberation Mono", monospace;
7
+
8
+ --fs-display-xl: clamp(2.75rem, 1.55rem + 4.9vw, 5.5rem); /* 44 -> 88 */
9
+ --fs-display-l: clamp(2.125rem, 1.45rem + 2.8vw, 3.75rem); /* 34 -> 60 */
10
+ --fs-display-m: clamp(1.625rem, 1.3rem + 1.35vw, 2.375rem);/* 26 -> 38 */
11
+ --fs-title: 1.375rem; /* 22 */
12
+ --fs-lead: 1.1875rem; /* 19 */
13
+ --fs-body: 1rem; /* 16 */
14
+ --fs-small: 0.875rem; /* 14 */
15
+ --fs-xs: 0.8125rem; /* 13 */
16
+ --fs-label: 0.71875rem; /* 11.5 mono labels, buttons */
17
+ --fs-code: 0.8125rem; /* 13 */
18
+
19
+ --lh-display: 0.98;
20
+ --lh-heading: 1.08;
21
+ --lh-snug: 1.3;
22
+ --lh-body: 1.55;
23
+ --lh-code: 1.65;
24
+
25
+ --tr-display: -0.035em; /* display-xl */
26
+ --tr-heading: -0.03em; /* display-l */
27
+ --tr-heading-m: -0.022em; /* display-m */
28
+ --tr-title: -0.012em;
29
+ --tr-label: 0.06em;
30
+
31
+ --wght-display: 540;
32
+ --wght-strong: 560;
33
+ --wdth-display: 92%; /* Instrument Sans width axis; fallbacks ignore it */
34
+
35
+ /* ---- space (4px base) ---- */
36
+ --s-1: 4px; --s-2: 8px; --s-3: 12px; --s-4: 16px; --s-5: 24px;
37
+ --s-6: 32px; --s-7: 48px; --s-8: 64px; --s-9: 96px; --s-10: 128px;
38
+
39
+ /* ---- radii: grows with the size of the thing ---- */
40
+ --r-1: 3px; /* highlighter, keycaps */
41
+ --r-2: 6px; /* buttons, inputs, chips */
42
+ --r-3: 10px; /* cards */
43
+ --r-4: 14px; /* panels, playground */
44
+ --r-pill: 999px; /* status badges only */
45
+
46
+ /* ---- layout ---- */
47
+ --page-max: 1200px;
48
+ --header-h: 60px;
49
+
50
+ /* ---- motion ---- */
51
+ --dur-1: 120ms; /* hover, press */
52
+ --dur-2: 200ms; /* state change */
53
+ --dur-3: 320ms; /* panel swap */
54
+ --dur-4: 560ms; /* the URL swap */
55
+ --ease-out: cubic-bezier(0.2, 0.8, 0.2, 1);
56
+ --ease-in-out: cubic-bezier(0.6, 0, 0.3, 1);
57
+ --ease-mark: cubic-bezier(0.7, 0, 0.2, 1);
58
+
59
+ /* ---- color: light (default) ---- */
60
+ --bg: #f5f5f3; /* page */
61
+ --bg-sunken: #eeeeeb; /* code blocks, insets */
62
+ --surface: #ffffff; /* cards */
63
+ --surface-2: #fafaf8; /* hover */
64
+ --surface-3: #e9e9e5; /* chips, pressed */
65
+ --line: #e2e2dd; /* hairline */
66
+ --line-2: #d1d1cb; /* strong hairline, input border */
67
+ --line-3: #b4b4ad; /* input hover */
68
+ --ink: #121311; /* text, primary button */
69
+ --ink-2: #3b3c38; /* body */
70
+ --ink-3: #5f605a; /* secondary, 5.6:1 on --bg */
71
+ --ink-4: #8d8e88; /* disabled, decorative only (3.1:1) */
72
+ --on-ink: #f7f7f4; /* text on --ink */
73
+
74
+ --hivis: #ffc23d; /* the accent (molten). Fill only, never text on light */
75
+ --hivis-2: #ffb01f; /* hover/pressed fill */
76
+ --hivis-wash: #fff1dc; /* faint tint, max one area per view */
77
+ --on-hivis: #1a0c00; /* text on hi-vis */
78
+
79
+ --ok: #157a4a; --ok-wash: #e3f2e9; --ok-line: #b8dcc6;
80
+ --warn: #8f560b; --warn-wash: #fbf0dc; --warn-line: #ebd2a4;
81
+ --fail: #bf3328; --fail-wash: #fbe7e4; --fail-line: #efc0ba;
82
+ --run: #3b3c38; --run-wash: #ecece8; --run-line: #d6d6d0;
83
+
84
+ --focus: #121311;
85
+ --scrim: rgba(18, 19, 17, 0.4);
86
+
87
+ /* dark "bench" panels: build log, terminal, agent transcript */
88
+ --panel: #111210;
89
+ --panel-2: #181917;
90
+ --panel-3: #20211f;
91
+ --panel-line: #282926;
92
+ --panel-line-2: #363733;
93
+ --panel-ink: #ecece8;
94
+ --panel-ink-2: #aeafa8;
95
+ --panel-ink-3: #82837d; /* 4.9:1 on --panel */
96
+ --panel-ok: #62d39c;
97
+ --panel-warn: #f0b552;
98
+ --panel-fail: #ff7d70;
99
+ --syn-str: #e3d09c;
100
+ --syn-num: #a3d9c3;
101
+ --syn-key: #ecece8;
102
+ --syn-punc: #82837d;
103
+
104
+ /* elevation: stacked hairline shadows, never one heavy drop */
105
+ --e1: 0 0 0 1px rgba(18, 19, 17, 0.07);
106
+ --e2: 0 0 0 1px rgba(18, 19, 17, 0.07), 0 1px 1px rgba(18, 19, 17, 0.03), 0 2px 4px rgba(18, 19, 17, 0.04);
107
+ --e3: 0 0 0 1px rgba(18, 19, 17, 0.07), 0 2px 2px rgba(18, 19, 17, 0.03), 0 8px 16px -4px rgba(18, 19, 17, 0.07);
108
+ --e4: 0 0 0 1px rgba(18, 19, 17, 0.08), 0 2px 2px rgba(18, 19, 17, 0.03), 0 12px 24px -6px rgba(18, 19, 17, 0.10), 0 32px 56px -20px rgba(18, 19, 17, 0.16);
109
+ --e-panel: 0 0 0 1px rgba(18, 19, 17, 0.9), 0 12px 32px -12px rgba(18, 19, 17, 0.35);
110
+
111
+ color-scheme: light;
112
+ }
113
+
114
+ @media (prefers-color-scheme: dark) {
115
+ :root:not([data-theme="light"]) {
116
+ --bg: #0d0e0d;
117
+ --bg-sunken: #131412;
118
+ --surface: #161715;
119
+ --surface-2: #1b1c1a;
120
+ --surface-3: #252623;
121
+ --line: #272825;
122
+ --line-2: #363733;
123
+ --line-3: #4b4c47;
124
+ --ink: #f0f0ec;
125
+ --ink-2: #c8c9c2;
126
+ --ink-3: #9a9b94;
127
+ --ink-4: #6b6c66;
128
+ --on-ink: #121311;
129
+
130
+ --hivis: #ffc23d;
131
+ --hivis-2: #ffd35c;
132
+ --hivis-wash: #2a1a08;
133
+ --on-hivis: #1a0c00;
134
+
135
+ --ok: #55c98f; --ok-wash: #112a1d; --ok-line: #224d37;
136
+ --warn: #e8ab4c; --warn-wash: #2c2311; --warn-line: #574219;
137
+ --fail: #ff7568; --fail-wash: #321614; --fail-line: #5f2924;
138
+ --run: #c8c9c2; --run-wash: #222320; --run-line: #363733;
139
+
140
+ --focus: #ff8a1f;
141
+ --scrim: rgba(0, 0, 0, 0.6);
142
+
143
+ --panel: #121311;
144
+ --panel-2: #191a18;
145
+ --panel-3: #21221f;
146
+ --panel-line: #2a2b28;
147
+ --panel-line-2: #393a36;
148
+
149
+ --e1: 0 0 0 1px rgba(255, 255, 255, 0.07);
150
+ --e2: 0 0 0 1px rgba(255, 255, 255, 0.07), 0 1px 2px rgba(0, 0, 0, 0.4);
151
+ --e3: 0 0 0 1px rgba(255, 255, 255, 0.08), 0 8px 16px -4px rgba(0, 0, 0, 0.5);
152
+ --e4: 0 0 0 1px rgba(255, 255, 255, 0.09), 0 12px 24px -6px rgba(0, 0, 0, 0.55), 0 32px 56px -20px rgba(0, 0, 0, 0.7);
153
+ --e-panel: 0 0 0 1px rgba(255, 255, 255, 0.08), 0 12px 32px -12px rgba(0, 0, 0, 0.7);
154
+
155
+ color-scheme: dark;
156
+ }
157
+ }
158
+
159
+ :root[data-theme="dark"] {
160
+ --bg: #0d0e0d;
161
+ --bg-sunken: #131412;
162
+ --surface: #161715;
163
+ --surface-2: #1b1c1a;
164
+ --surface-3: #252623;
165
+ --line: #272825;
166
+ --line-2: #363733;
167
+ --line-3: #4b4c47;
168
+ --ink: #f0f0ec;
169
+ --ink-2: #c8c9c2;
170
+ --ink-3: #9a9b94;
171
+ --ink-4: #6b6c66;
172
+ --on-ink: #121311;
173
+
174
+ --hivis: #ffc23d;
175
+ --hivis-2: #ffd35c;
176
+ --hivis-wash: #2a1a08;
177
+ --on-hivis: #1a0c00;
178
+
179
+ --ok: #55c98f; --ok-wash: #112a1d; --ok-line: #224d37;
180
+ --warn: #e8ab4c; --warn-wash: #2c2311; --warn-line: #574219;
181
+ --fail: #ff7568; --fail-wash: #321614; --fail-line: #5f2924;
182
+ --run: #c8c9c2; --run-wash: #222320; --run-line: #363733;
183
+
184
+ --focus: #ff8a1f;
185
+ --scrim: rgba(0, 0, 0, 0.6);
186
+
187
+ --panel: #121311;
188
+ --panel-2: #191a18;
189
+ --panel-3: #21221f;
190
+ --panel-line: #2a2b28;
191
+ --panel-line-2: #393a36;
192
+
193
+ --e1: 0 0 0 1px rgba(255, 255, 255, 0.07);
194
+ --e2: 0 0 0 1px rgba(255, 255, 255, 0.07), 0 1px 2px rgba(0, 0, 0, 0.4);
195
+ --e3: 0 0 0 1px rgba(255, 255, 255, 0.08), 0 8px 16px -4px rgba(0, 0, 0, 0.5);
196
+ --e4: 0 0 0 1px rgba(255, 255, 255, 0.09), 0 12px 24px -6px rgba(0, 0, 0, 0.55), 0 32px 56px -20px rgba(0, 0, 0, 0.7);
197
+ --e-panel: 0 0 0 1px rgba(255, 255, 255, 0.08), 0 12px 32px -12px rgba(0, 0, 0, 0.7);
198
+
199
+ color-scheme: dark;
200
+ }
201
+ /* @tokens:end */
@@ -0,0 +1,216 @@
1
+ /* Wield extension UI. Tokens come from design/tokens.css (copied to dist/tokens.css
2
+ at build). No web fonts: an extension page that loaded Google Fonts would send a
3
+ request off the device, so we use the token fallback stacks. */
4
+ *, *::before, *::after { box-sizing: border-box; }
5
+ [hidden] { display: none !important; } /* component display rules must never override hidden */
6
+ html, body { margin: 0; }
7
+ body {
8
+ background: var(--bg);
9
+ color: var(--ink-2);
10
+ font: 400 var(--fs-small)/var(--lh-body) var(--font-sans);
11
+ -webkit-font-smoothing: antialiased;
12
+ }
13
+ :focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; border-radius: var(--r-1); }
14
+ ::selection { background: var(--hivis); color: var(--on-hivis); }
15
+
16
+ .mono { font-family: var(--font-mono); font-size: var(--fs-code); }
17
+ .label {
18
+ font: 400 var(--fs-label)/1.4 var(--font-mono);
19
+ text-transform: uppercase; letter-spacing: var(--tr-label); color: var(--ink-3);
20
+ margin: 0 0 var(--s-2);
21
+ }
22
+ .muted { color: var(--ink-3); }
23
+ .num { font-variant-numeric: tabular-nums; }
24
+
25
+ /* header */
26
+ .top {
27
+ display: flex; align-items: center; justify-content: space-between; gap: var(--s-3);
28
+ padding: var(--s-3) var(--s-4); border-bottom: 1px solid var(--line); background: var(--surface);
29
+ }
30
+ .brand { display: flex; align-items: center; gap: var(--s-2); color: var(--ink); text-decoration: none; }
31
+ .brand svg { width: 18px; height: 18px; display: block; }
32
+ .brand b { font: 600 15px/1 var(--font-sans); letter-spacing: -0.04em; }
33
+
34
+ /* status badge: text + color, never color alone */
35
+ .badge {
36
+ display: inline-flex; align-items: center; gap: 6px; white-space: nowrap;
37
+ font: 400 var(--fs-label)/1 var(--font-mono); text-transform: uppercase; letter-spacing: var(--tr-label);
38
+ padding: 5px 8px; border-radius: var(--r-pill); border: 1px solid var(--run-line); background: var(--run-wash); color: var(--run);
39
+ }
40
+ .badge::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
41
+ .badge.ok { color: var(--ok); background: var(--ok-wash); border-color: var(--ok-line); }
42
+ .badge.warn { color: var(--warn); background: var(--warn-wash); border-color: var(--warn-line); }
43
+ .badge.fail { color: var(--fail); background: var(--fail-wash); border-color: var(--fail-line); }
44
+ .badge.plain::before { display: none; }
45
+
46
+ section { padding: var(--s-4); border-bottom: 1px solid var(--line); }
47
+ section:last-of-type { border-bottom: 0; }
48
+
49
+ /* hairline rows */
50
+ .rows { list-style: none; margin: 0; padding: 0; }
51
+ .rows > li { display: grid; gap: 2px var(--s-3); padding: var(--s-2) 0; border-top: 1px solid var(--line); }
52
+ .rows > li:first-child { border-top: 0; padding-top: 0; }
53
+ .empty { color: var(--ink-3); margin: 0; }
54
+
55
+ .site { grid-template-columns: 1fr auto; align-items: center; }
56
+ .site .name { color: var(--ink); font-weight: 500; }
57
+ .site .sub { grid-column: 1; color: var(--ink-3); font-size: var(--fs-xs); }
58
+ .site .badge { grid-row: 1 / span 2; grid-column: 2; }
59
+
60
+ .run-head { display: flex; justify-content: space-between; gap: var(--s-2); align-items: flex-start; }
61
+ .run-head .id { flex: 1; min-width: 0; color: var(--ink); font-family: var(--font-mono); font-size: var(--fs-code); overflow-wrap: anywhere; }
62
+ .run-head .badge { flex: none; }
63
+ .run-meta { color: var(--ink-3); font-size: var(--fs-xs); }
64
+ .reqs {
65
+ list-style: none; margin: var(--s-1) 0 0; padding: var(--s-2) var(--s-3);
66
+ background: var(--bg-sunken); border-radius: var(--r-2); box-shadow: inset 0 0 0 1px var(--line);
67
+ font: 400 12px/1.5 var(--font-mono); color: var(--ink-2);
68
+ }
69
+ .reqs li { display: grid; grid-template-columns: 3.4em 1fr auto auto; gap: 2px var(--s-2); padding: 2px 0; }
70
+ .reqs .path { overflow-wrap: break-word; word-break: normal; color: var(--ink); min-width: 0; }
71
+ .reqs .host { color: var(--ink-3); }
72
+ .reqs .st { color: var(--ok); }
73
+ .reqs .st.bad { color: var(--fail); }
74
+ .reqs .ms { color: var(--ink-3); text-align: right; min-width: 4.5em; }
75
+
76
+ .proof {
77
+ margin: 0; padding: var(--s-3) var(--s-4); font-size: var(--fs-xs); color: var(--ink-3);
78
+ border-top: 1px solid var(--line); background: var(--surface);
79
+ }
80
+
81
+ .hint { margin: var(--s-2) 0 0; font-size: var(--fs-xs); color: var(--ink-3); }
82
+ .hint code { font-family: var(--font-mono); background: var(--bg-sunken); padding: 1px 4px; border-radius: var(--r-1); color: var(--ink-2); }
83
+
84
+ /* buttons */
85
+ .btn {
86
+ display: inline-flex; align-items: center; justify-content: center; gap: var(--s-2);
87
+ height: 40px; padding: 0 var(--s-4); border-radius: var(--r-2); cursor: pointer;
88
+ font: 400 var(--fs-label)/1 var(--font-mono); text-transform: uppercase; letter-spacing: var(--tr-label);
89
+ border: 1px solid transparent; transition: background var(--dur-1) var(--ease-out), border-color var(--dur-1) var(--ease-out);
90
+ }
91
+ .btn-sm { height: 32px; padding: 0 var(--s-3); }
92
+ .btn-primary { background: var(--ink); color: var(--on-ink); }
93
+ .btn-primary:hover { background: var(--ink-2); }
94
+ .btn-secondary { background: var(--surface); color: var(--ink); border-color: var(--line-2); }
95
+ .btn-secondary:hover { border-color: var(--line-3); background: var(--surface-2); }
96
+ .btn-ghost { background: transparent; color: var(--ink-2); }
97
+ .btn-ghost:hover { background: var(--surface-3); }
98
+ .btn:disabled { opacity: 0.5; cursor: default; }
99
+
100
+ @media (prefers-reduced-motion: reduce) { * { transition: none !important; animation: none !important; } }
101
+ .reqs li.dest { display: block; color: var(--ink-3); padding-bottom: 4px; margin-bottom: 2px; border-bottom: 1px solid var(--line); }
102
+
103
+ /* ---------------------------------------------------------------------------
104
+ Allow window (confirm.html). Calm on purpose: paper, ink, hairlines. No
105
+ warning colors; the decision is the user's, not an alarm. Classes are
106
+ semantic (ask-*) so a redesign only touches this block.
107
+ --------------------------------------------------------------------------- */
108
+ body.ask { min-height: 100vh; display: flex; flex-direction: column; background: var(--surface); }
109
+ .ask-body { flex: 1; padding: var(--s-5) var(--s-5) var(--s-4); }
110
+ .ask-eyebrow { margin-bottom: var(--s-2); }
111
+ .ask-title {
112
+ margin: 0 0 var(--s-2); color: var(--ink);
113
+ font: var(--wght-display) var(--fs-title)/var(--lh-snug) var(--font-sans);
114
+ letter-spacing: var(--tr-title); text-wrap: balance; overflow-wrap: anywhere;
115
+ }
116
+ .ask-site { margin: 0 0 var(--s-5); color: var(--ink-3); }
117
+ .ask-site b { color: var(--ink-2); font-weight: 500; }
118
+ .ask-section { margin: 0 0 var(--s-4); padding: 0; border: 0; }
119
+ .ask-writes { list-style: none; margin: 0; padding: 0; border-radius: var(--r-3); background: var(--bg-sunken); box-shadow: inset 0 0 0 1px var(--line); }
120
+ .ask-write { padding: var(--s-3) var(--s-4); border-top: 1px solid var(--line); }
121
+ .ask-write:first-child { border-top: 0; }
122
+ .ask-request { display: flex; gap: var(--s-2); align-items: baseline; font: 400 var(--fs-code)/1.5 var(--font-mono); }
123
+ .ask-method { color: var(--ink); font-weight: 500; min-width: 3.6em; }
124
+ .ask-path { color: var(--ink-2); overflow-wrap: anywhere; }
125
+ .ask-fields { list-style: none; margin: var(--s-2) 0 0; padding: 0; display: flex; flex-wrap: wrap; gap: var(--s-1); }
126
+ .ask-field { font: 400 12px/1 var(--font-mono); color: var(--ink-2); background: var(--surface); padding: 5px 7px; border-radius: var(--r-1); box-shadow: inset 0 0 0 1px var(--line-2); }
127
+ .ask-nofields { margin: var(--s-1) 0 0; font-size: var(--fs-xs); color: var(--ink-3); }
128
+ .ask-explain { margin: 0 0 var(--s-2); color: var(--ink-2); }
129
+ .ask-note { margin: 0; font-size: var(--fs-xs); color: var(--ink-3); max-width: 46ch; }
130
+ .ask-gone { padding: var(--s-6) 0; color: var(--ink-3); }
131
+
132
+ .ask-foot {
133
+ position: relative; display: flex; align-items: center; justify-content: space-between; gap: var(--s-3);
134
+ padding: var(--s-3) var(--s-5) var(--s-4); background: var(--bg); border-top: 1px solid var(--line);
135
+ }
136
+ .ask-timer { position: absolute; left: 0; right: 0; top: -1px; height: 1px; overflow: hidden; }
137
+ .ask-timer span { display: block; height: 100%; background: var(--ink-3); transform-origin: left; transition-property: transform; transition-timing-function: linear; }
138
+ .ask-timer span.run { transform: scaleX(0); }
139
+ .ask-countdown { margin: 0; font-size: var(--fs-xs); color: var(--ink-3); }
140
+ .ask-actions { display: flex; gap: var(--s-2); flex: none; }
141
+ @media (prefers-reduced-motion: reduce) { .ask-timer { display: none; } }
142
+
143
+ /* ---------------------------------------------------------------------------
144
+ Recording review (record.html). Same calm system as the Allow window.
145
+ --------------------------------------------------------------------------- */
146
+ body.rec { min-height: 100vh; display: flex; flex-direction: column; background: var(--surface); }
147
+ .rec-body { flex: 1; width: 100%; max-width: 760px; margin: 0 auto; padding: var(--s-6) var(--s-5) var(--s-5); }
148
+ .rec-title { margin: 0 0 var(--s-2); color: var(--ink); font: var(--wght-display) var(--fs-display-m)/var(--lh-heading) var(--font-sans); letter-spacing: var(--tr-heading-m); text-wrap: balance; }
149
+ .rec-sub { margin: 0 0 var(--s-5); color: var(--ink-3); }
150
+ .rec-facts { list-style: none; margin: 0 0 var(--s-6); padding: 0; border-radius: var(--r-3); box-shadow: inset 0 0 0 1px var(--line); }
151
+ .rec-fact { padding: var(--s-3) var(--s-4); border-top: 1px solid var(--line); color: var(--ink-2); }
152
+ .rec-fact:first-child { border-top: 0; }
153
+ .rec-section { margin-bottom: var(--s-5); }
154
+ .rec-requests { list-style: none; margin: 0; padding: 0; }
155
+ .rec-request { padding: var(--s-2) 0; border-top: 1px solid var(--line); }
156
+ .rec-line { display: grid; grid-template-columns: 3.6em 1fr auto; gap: var(--s-2); font: 400 var(--fs-code)/1.5 var(--font-mono); }
157
+ .rec-method { color: var(--ink); }
158
+ .rec-path { color: var(--ink-2); overflow-wrap: anywhere; }
159
+ .rec-status { color: var(--ink-3); }
160
+ .rec-detail { margin: 2px 0 0 4.2em; font-size: var(--fs-xs); color: var(--ink-3); }
161
+ .rec-raw summary { cursor: pointer; color: var(--ink-2); font-size: var(--fs-small); }
162
+ .rec-raw pre { max-height: 50vh; overflow: auto; margin: var(--s-3) 0 0; padding: var(--s-3); border-radius: var(--r-3); background: var(--bg-sunken); font: 12px/1.5 var(--font-mono); color: var(--ink-2); }
163
+ .rec-error { margin: var(--s-4) 0 0; padding: var(--s-3) var(--s-4); border-radius: var(--r-2); background: var(--fail-wash); color: var(--fail); box-shadow: inset 0 0 0 1px var(--fail-line); }
164
+ .rec-public { display: flex; gap: var(--s-2); align-items: flex-start; margin: var(--s-3) 0 var(--s-5); font-size: var(--fs-xs); color: var(--ink-2); line-height: 1.45; }
165
+ .rec-public input { margin-top: 2px; flex: none; accent-color: var(--ink); }
166
+ .rec-foot { position: sticky; bottom: 0; display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--s-3) var(--s-4); padding: var(--s-3) var(--s-5); border-top: 1px solid var(--line); background: var(--bg); }
167
+ .rec-note { margin: 0; font-size: var(--fs-xs); color: var(--ink-3); flex: 1 1 24ch; max-width: 52ch; }
168
+ .rec-actions { display: flex; flex-wrap: wrap; gap: var(--s-2); margin-left: auto; }
169
+
170
+ /* popup: teach a site */
171
+ .rec-start { display: flex; gap: var(--s-2); }
172
+ .input { flex: 1; min-width: 0; height: 32px; padding: 0 var(--s-3); border-radius: var(--r-2); border: 1px solid var(--line-2); background: var(--surface); color: var(--ink); font: inherit; }
173
+ .input:hover { border-color: var(--line-3); }
174
+
175
+ .ask-body-preview { margin: var(--s-2) 0 0; padding: var(--s-2) var(--s-3); max-height: 180px; overflow: auto; border-radius: var(--r-2); background: var(--surface); box-shadow: inset 0 0 0 1px var(--line-2); font: 12px/1.5 var(--font-mono); color: var(--ink); white-space: pre-wrap; overflow-wrap: anywhere; }
176
+
177
+ /* popup: per-site rows */
178
+ .site .site-actions { grid-column: 1 / -1; display: flex; gap: var(--s-1); margin-top: 2px; }
179
+ .site .site-hint { color: var(--ink-2); }
180
+ .site-policy .name { color: var(--ink); }
181
+ .btn-xs { height: 24px; padding: 0 var(--s-2); font-size: 10.5px; }
182
+ .sites-all { margin-top: var(--s-2); }
183
+ .sites-all summary { cursor: pointer; font-size: var(--fs-xs); color: var(--ink-3); }
184
+ .sites-all .site { grid-template-columns: 1fr auto auto; }
185
+ .sites-all .site .site-actions { grid-column: auto; margin: 0; }
186
+
187
+ /* ---------------------------------------------------------------------------
188
+ First-run page (welcome.html)
189
+ --------------------------------------------------------------------------- */
190
+ body.welcome { min-height: 100vh; background: var(--bg); }
191
+ .welcome-body { max-width: 720px; margin: 0 auto; padding: var(--s-7) var(--s-5) var(--s-8); }
192
+ .welcome-title { margin: 0 0 var(--s-3); color: var(--ink); font: var(--wght-display) var(--fs-display-m)/var(--lh-heading) var(--font-sans); letter-spacing: var(--tr-heading-m); text-wrap: balance; }
193
+ .welcome-lead { margin: 0 0 var(--s-6); font-size: var(--fs-lead); color: var(--ink-2); max-width: 36em; }
194
+ .welcome-steps { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--s-3); }
195
+ .welcome-step { display: grid; grid-template-columns: 32px 1fr; gap: var(--s-3); padding: var(--s-4); border-radius: var(--r-3); background: var(--surface); box-shadow: var(--e1); }
196
+ .welcome-step h2 { margin: 4px 0 var(--s-1); font: 560 var(--fs-body)/1.3 var(--font-sans); color: var(--ink); }
197
+ .welcome-step p { margin: 0 0 var(--s-2); color: var(--ink-2); }
198
+ .welcome-num { display: grid; place-items: center; width: 28px; height: 28px; border-radius: 50%; font: 12px/1 var(--font-mono); color: var(--ink-3); box-shadow: inset 0 0 0 1px var(--line-2); }
199
+ .welcome-step[data-state="done"] .welcome-num { background: var(--ok-wash); color: var(--ok); box-shadow: inset 0 0 0 1px var(--ok-line); }
200
+ .welcome-step[data-state="done"] .welcome-num::before { content: "✓"; font-size: 14px; }
201
+ .welcome-step[data-state="done"] .welcome-num { font-size: 0; }
202
+ .welcome-step[data-state="error"] .welcome-num { background: var(--fail-wash); color: var(--fail); box-shadow: inset 0 0 0 1px var(--fail-line); }
203
+ .welcome-cmd { display: flex; align-items: center; gap: var(--s-2); margin: var(--s-2) 0; }
204
+ .welcome-cmd code { flex: 1; padding: var(--s-2) var(--s-3); border-radius: var(--r-2); background: var(--bg-sunken); box-shadow: inset 0 0 0 1px var(--line); font: var(--fs-code)/1.4 var(--font-mono); color: var(--ink); }
205
+ .welcome-result { margin-top: var(--s-3); }
206
+ .welcome-ok { color: var(--ink); }
207
+ .welcome-err { color: var(--fail); }
208
+ .welcome-list { margin: 0; padding-left: var(--s-5); color: var(--ink-2); font-size: var(--fs-small); }
209
+
210
+ /* popup: developer mode */
211
+ .dev-toggle { display: flex; gap: var(--s-2); align-items: center; font-size: var(--fs-sm, 13px); color: var(--ink); }
212
+ .dev-toggle input { accent-color: var(--ink); }
213
+
214
+ /* Allow window: a draft that would reach another site */
215
+ .ask-warning { margin: 0 0 var(--s-3); padding: var(--s-2) var(--s-3); border-radius: var(--r-2); background: var(--hivis, #ffc23d); color: var(--on-hivis, #121311); font-size: var(--fs-sm, 13px); line-height: 1.45; }
216
+ .ask-field-foreign { font-weight: 600; box-shadow: inset 0 0 0 1px currentColor; }
@@ -0,0 +1,58 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1">
6
+ <title>Wield is installed</title>
7
+ <link rel="stylesheet" href="tokens.css">
8
+ <link rel="stylesheet" href="ui.css">
9
+ </head>
10
+ <!-- First-run page (product-100 §5). Classes are semantic (welcome-*). -->
11
+ <body class="welcome">
12
+ <header class="top">
13
+ <span class="brand" aria-label="Wield">
14
+ <svg viewBox="0 0 24 24" aria-hidden="true"><defs><linearGradient id="wm-hd" x1="0" y1="0" x2="0" y2="1"><stop offset="0" stop-color="#ffd85a"/><stop offset=".5" stop-color="#ff9a24"/><stop offset="1" stop-color="#ff5200"/></linearGradient><linearGradient id="wm-ht" x1="0" y1="0" x2="0" y2="1"><stop offset="0" stop-color="#ff6a0a"/><stop offset="1" stop-color="currentColor"/></linearGradient></defs><g transform="translate(0 -2.45)"><path d="M7.0 11.6 2.4 16.6 7.0 21.6M17.0 11.6 21.6 16.6 17.0 21.6" fill="none" stroke="currentColor" stroke-width="2.7" stroke-linecap="round" stroke-linejoin="round"/><path d="M11.0 21.6 12.6 10.28" stroke="currentColor" stroke-width="2.3" stroke-linecap="round"/><g transform="translate(12.6 10.28) rotate(8.045051779050041)"><rect x="-1.15" y="-.2" width="2.3" height="2.4" fill="url(#wm-ht)"/></g><g transform="translate(12.908 8.102) rotate(8.05) scale(0.84)"><path d="M-4.6 -1.9 -2.9 -1.9 -2.4 -1.5 1.3 -1.5 4.4 -0.55 4.6 -0.2 4.6 0.2 4.4 0.55 1.3 1.5 -2.4 1.5 -2.9 1.9 -4.6 1.9Z" fill="url(#wm-hd)" stroke="url(#wm-hd)" stroke-width=".35" stroke-linejoin="round"/><path d="M-4.2 -1.25H-2.9M-1.9 -.95H1.0" stroke="#fff1b8" stroke-width=".55" stroke-linecap="round" opacity=".85"/><rect x="-1.4" y="1.35" width="2.8" height=".8" rx=".3" fill="currentColor"/></g><rect x="7.01" y="5.50" width="1.3" height="1.3" fill="#ffc23d"/><rect x="5.41" y="7.20" width=".9" height=".9" fill="#ff8a1f"/></g></svg>
15
+ <b>wield</b>
16
+ </span>
17
+ <span class="badge" id="ready">Setting up</span>
18
+ </header>
19
+ <main class="welcome-body">
20
+ <p class="label">Welcome</p>
21
+ <h1 class="welcome-title">Your agent can now use websites through this browser.</h1>
22
+ <p class="welcome-lead">Wield runs each task in your own tab of the site, with your own login. You see every request in the toolbar popup, and nothing that changes something is sent without your Allow.</p>
23
+
24
+ <ol class="welcome-steps">
25
+ <li class="welcome-step" id="s-ext" data-state="done">
26
+ <span class="welcome-num" aria-hidden="true">1</span>
27
+ <div><h2>Extension installed</h2><p id="ext-text"></p></div>
28
+ </li>
29
+ <li class="welcome-step" id="s-bridge" data-state="wait">
30
+ <span class="welcome-num" aria-hidden="true">2</span>
31
+ <div>
32
+ <h2>Connect your agent</h2>
33
+ <p id="bridge-text">Checking…</p>
34
+ <div class="welcome-cmd" id="cmd-wrap" hidden>
35
+ <code id="cmd">npx -y wield-mcp init</code>
36
+ <button class="btn btn-secondary btn-sm" id="copy" type="button">Copy</button>
37
+ </div>
38
+ <p class="hint" id="bridge-hint" hidden>Run it once in a terminal. It sets up Wield’s small helper and adds Wield to Claude, Cursor or Codex. This page updates by itself.</p>
39
+ </div>
40
+ </li>
41
+ <li class="welcome-step" id="s-try" data-state="wait">
42
+ <span class="welcome-num" aria-hidden="true">3</span>
43
+ <div>
44
+ <h2>Try it once</h2>
45
+ <p id="try-text">Search Chefkoch for lasagne recipes, the way your agent would. Wield opens chefkoch.de in a background tab and sends one request to it.</p>
46
+ <button class="btn btn-primary btn-sm" id="try" type="button">Run a sample search</button>
47
+ <div class="welcome-result" id="result" hidden></div>
48
+ </div>
49
+ </li>
50
+ <li class="welcome-step" id="s-teach" data-state="info">
51
+ <span class="welcome-num" aria-hidden="true">4</span>
52
+ <div><h2>Teach it your sites</h2><p>On any site, open the Wield popup and click <b>Record</b>, then do the task once. You review exactly what would be sent before anything leaves your browser.</p></div>
53
+ </li>
54
+ </ol>
55
+ </main>
56
+ <script src="welcome.js"></script>
57
+ </body>
58
+ </html>
@@ -0,0 +1,69 @@
1
+ "use strict";
2
+ (() => {
3
+ // apps/extension/src/ui/welcome.ts
4
+ var $ = (id) => document.getElementById(id);
5
+ function setStep(id, state) {
6
+ $(id).dataset.state = state;
7
+ }
8
+ async function poll() {
9
+ const s = await chrome.runtime.sendMessage({ type: "popup_state" });
10
+ $("ext-text").textContent = `Wield ${s.version} in ${s.browser}.`;
11
+ const up = s.bridge.state === "connected";
12
+ setStep("s-bridge", up ? "done" : "wait");
13
+ $("bridge-text").textContent = up ? "Connected. Your agent can call Wield now." : "Not connected yet. Wield needs its small helper on this computer to talk to your agent.";
14
+ $("cmd-wrap").hidden = up;
15
+ $("bridge-hint").hidden = up;
16
+ const ready = $("ready");
17
+ ready.className = `badge ${up ? "ok" : ""}`;
18
+ ready.textContent = up ? "Ready" : "Setting up";
19
+ }
20
+ $("copy").addEventListener("click", async () => {
21
+ const text = $("cmd").textContent ?? "";
22
+ try {
23
+ await navigator.clipboard.writeText(text);
24
+ $("copy").textContent = "Copied";
25
+ } catch {
26
+ const r = document.createRange();
27
+ r.selectNodeContents($("cmd"));
28
+ getSelection()?.removeAllRanges();
29
+ getSelection()?.addRange(r);
30
+ }
31
+ });
32
+ $("try").addEventListener("click", async () => {
33
+ const btn = $("try");
34
+ btn.disabled = true;
35
+ btn.textContent = "Running\u2026";
36
+ const out = $("result");
37
+ out.hidden = false;
38
+ out.replaceChildren();
39
+ const t0 = performance.now();
40
+ const r = await chrome.runtime.sendMessage({ type: "sample_run" });
41
+ const ms = Math.round(r.duration_ms ?? performance.now() - t0);
42
+ if (r.ok) {
43
+ setStep("s-try", "done");
44
+ const head = document.createElement("p");
45
+ head.className = "welcome-ok";
46
+ head.textContent = `Wield is ready. ${r.output?.total ?? r.output?.recipes?.length ?? 0} lasagne recipes on chefkoch.de, in ${(ms / 1e3).toFixed(1)} s, ${r.requests ?? 1} request${r.requests === 1 ? "" : "s"} from this browser.`;
47
+ out.append(head);
48
+ const ul = document.createElement("ul");
49
+ ul.className = "welcome-list";
50
+ for (const x of (r.output?.recipes ?? []).slice(0, 3)) {
51
+ const li = document.createElement("li");
52
+ li.textContent = String(x.title ?? "");
53
+ ul.append(li);
54
+ }
55
+ out.append(ul);
56
+ btn.textContent = "Run again";
57
+ } else {
58
+ setStep("s-try", "error");
59
+ const p = document.createElement("p");
60
+ p.className = "welcome-err";
61
+ p.textContent = r.error?.message ?? "The sample run failed.";
62
+ out.append(p);
63
+ btn.textContent = "Try again";
64
+ }
65
+ btn.disabled = false;
66
+ });
67
+ void poll();
68
+ setInterval(() => void poll(), 2e3);
69
+ })();
@@ -0,0 +1 @@
1
+ mkgnkapppehppdfjgohaoclabmjgfkgn