cursedbelt 5.67.0 → 5.69.0

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.
Files changed (143) hide show
  1. package/dist/looks.css +41 -0
  2. package/dist/react/canvas-hud/CanvasToolbar.d.ts +67 -0
  3. package/dist/react/canvas-hud/CanvasToolbar.d.ts.map +1 -0
  4. package/dist/react/canvas-hud/CanvasToolbar.js +84 -0
  5. package/dist/react/canvas-hud/CanvasToolbar.js.map +1 -0
  6. package/dist/react/canvas-hud/index.d.ts +2 -0
  7. package/dist/react/canvas-hud/index.d.ts.map +1 -1
  8. package/dist/react/canvas-hud/index.js +1 -0
  9. package/dist/react/canvas-hud/index.js.map +1 -1
  10. package/dist/react/components/ActionBar.d.ts.map +1 -1
  11. package/dist/react/components/ActionBar.js +9 -1
  12. package/dist/react/components/ActionBar.js.map +1 -1
  13. package/dist/react/components/DataTable/DataTable.d.ts.map +1 -1
  14. package/dist/react/components/DataTable/DataTable.js +3 -3
  15. package/dist/react/components/DataTable/DataTable.js.map +1 -1
  16. package/dist/react/components/EntityCard.d.ts +35 -0
  17. package/dist/react/components/EntityCard.d.ts.map +1 -0
  18. package/dist/react/components/EntityCard.js +18 -0
  19. package/dist/react/components/EntityCard.js.map +1 -0
  20. package/dist/react/components/Grid.d.ts.map +1 -1
  21. package/dist/react/components/Grid.js +4 -2
  22. package/dist/react/components/Grid.js.map +1 -1
  23. package/dist/react/components/ScrollArea.d.ts +1 -1
  24. package/dist/react/components/ScrollArea.js +1 -1
  25. package/dist/react/components/SecretInput.d.ts.map +1 -1
  26. package/dist/react/components/SecretInput.js +8 -2
  27. package/dist/react/components/SecretInput.js.map +1 -1
  28. package/dist/react/components/SegmentedControl.d.ts.map +1 -1
  29. package/dist/react/components/SegmentedControl.js +5 -1
  30. package/dist/react/components/SegmentedControl.js.map +1 -1
  31. package/dist/react/hooks/useKeyboardOpen.d.ts +13 -0
  32. package/dist/react/hooks/useKeyboardOpen.d.ts.map +1 -0
  33. package/dist/react/hooks/useKeyboardOpen.js +30 -0
  34. package/dist/react/hooks/useKeyboardOpen.js.map +1 -0
  35. package/dist/react/index.d.ts +3 -0
  36. package/dist/react/index.d.ts.map +1 -1
  37. package/dist/react/index.js +3 -0
  38. package/dist/react/index.js.map +1 -1
  39. package/dist/react/look/AppearanceMenu.d.ts +29 -0
  40. package/dist/react/look/AppearanceMenu.d.ts.map +1 -0
  41. package/dist/react/look/AppearanceMenu.js +39 -0
  42. package/dist/react/look/AppearanceMenu.js.map +1 -0
  43. package/dist/react/look/AppearancePanel.d.ts +18 -0
  44. package/dist/react/look/AppearancePanel.d.ts.map +1 -0
  45. package/dist/react/look/AppearancePanel.js +20 -0
  46. package/dist/react/look/AppearancePanel.js.map +1 -0
  47. package/dist/react/look/LookPicker.d.ts +6 -1
  48. package/dist/react/look/LookPicker.d.ts.map +1 -1
  49. package/dist/react/look/LookPicker.js +2 -2
  50. package/dist/react/look/LookPicker.js.map +1 -1
  51. package/dist/react/media/denseGallery.css +2 -0
  52. package/dist/styles-areas/canvas-hud.css +6 -4
  53. package/dist/styles-areas/core.css +45 -44
  54. package/dist/styles-areas/fields.css +2 -2
  55. package/dist/styles-areas/filter-rail.css +5 -5
  56. package/dist/styles-areas/nav.css +6 -6
  57. package/dist/styles-areas/notifications.css +3 -3
  58. package/dist/styles-areas/place-bar.css +2 -2
  59. package/dist/styles-utilities.css +43 -8
  60. package/dist/testing/appleDevices.d.ts +68 -0
  61. package/dist/testing/appleDevices.d.ts.map +1 -0
  62. package/dist/testing/appleDevices.js +65 -0
  63. package/dist/testing/appleDevices.js.map +1 -0
  64. package/dist/testing/appleWalk.d.ts +72 -0
  65. package/dist/testing/appleWalk.d.ts.map +1 -0
  66. package/dist/testing/appleWalk.js +209 -0
  67. package/dist/testing/appleWalk.js.map +1 -0
  68. package/dist/testing/designAudit.d.ts +1 -1
  69. package/dist/testing/designAudit.d.ts.map +1 -1
  70. package/dist/testing/designAudit.js +12 -0
  71. package/dist/testing/designAudit.js.map +1 -1
  72. package/dist/testing/designBaseline.d.ts +14 -0
  73. package/dist/testing/designBaseline.d.ts.map +1 -1
  74. package/dist/testing/designBaseline.js +26 -28
  75. package/dist/testing/designBaseline.js.map +1 -1
  76. package/dist/testing/index.d.ts +6 -0
  77. package/dist/testing/index.d.ts.map +1 -1
  78. package/dist/testing/index.js +9 -0
  79. package/dist/testing/index.js.map +1 -1
  80. package/dist/testing/lookPrePaint.d.ts +19 -0
  81. package/dist/testing/lookPrePaint.d.ts.map +1 -0
  82. package/dist/testing/lookPrePaint.js +56 -0
  83. package/dist/testing/lookPrePaint.js.map +1 -0
  84. package/dist/testing/phoneRules.d.ts +98 -0
  85. package/dist/testing/phoneRules.d.ts.map +1 -0
  86. package/dist/testing/phoneRules.js +282 -0
  87. package/dist/testing/phoneRules.js.map +1 -0
  88. package/dist/testing/safariDriver.d.ts +103 -0
  89. package/dist/testing/safariDriver.d.ts.map +1 -0
  90. package/dist/testing/safariDriver.js +288 -0
  91. package/dist/testing/safariDriver.js.map +1 -0
  92. package/dist/testing/safariRules.d.ts +57 -0
  93. package/dist/testing/safariRules.d.ts.map +1 -0
  94. package/dist/testing/safariRules.js +191 -0
  95. package/dist/testing/safariRules.js.map +1 -0
  96. package/package.json +2 -1
  97. package/scripts/styleAreas.ts +1 -0
  98. package/src/fonts/inter-OFL.txt +93 -0
  99. package/src/fonts/inter-latin-wght-normal.woff2 +0 -0
  100. package/src/looks.css +41 -0
  101. package/src/looks.spec.ts +59 -1
  102. package/src/react/canvas-hud/CanvasToolbar.tsx +177 -0
  103. package/src/react/canvas-hud/index.ts +2 -0
  104. package/src/react/components/ActionBar.spec.tsx +49 -1
  105. package/src/react/components/ActionBar.tsx +10 -2
  106. package/src/react/components/DataTable/DataTable.tsx +6 -1
  107. package/src/react/components/EntityCard.tsx +76 -0
  108. package/src/react/components/Grid.tsx +4 -2
  109. package/src/react/components/ScrollArea.tsx +1 -1
  110. package/src/react/components/SecretInput.spec.tsx +14 -0
  111. package/src/react/components/SecretInput.tsx +13 -1
  112. package/src/react/components/SegmentedControl.spec.tsx +1 -1
  113. package/src/react/components/SegmentedControl.tsx +5 -1
  114. package/src/react/components/tooltipWarm.spec.tsx +15 -0
  115. package/src/react/hooks/useKeyboardOpen.ts +29 -0
  116. package/src/react/index.ts +3 -0
  117. package/src/react/look/AppearanceMenu.spec.tsx +90 -0
  118. package/src/react/look/AppearanceMenu.tsx +64 -0
  119. package/src/react/look/AppearancePanel.tsx +54 -0
  120. package/src/react/look/LookPicker.tsx +14 -2
  121. package/src/react/media/denseGallery.css +2 -0
  122. package/src/styles-areas/canvas-hud.css +6 -4
  123. package/src/styles-areas/core.css +45 -44
  124. package/src/styles-areas/fields.css +2 -2
  125. package/src/styles-areas/filter-rail.css +5 -5
  126. package/src/styles-areas/nav.css +6 -6
  127. package/src/styles-areas/notifications.css +3 -3
  128. package/src/styles-areas/place-bar.css +2 -2
  129. package/src/styles-utilities.css +43 -8
  130. package/src/testing/appleDevices.spec.ts +36 -0
  131. package/src/testing/appleDevices.ts +97 -0
  132. package/src/testing/appleWalk.ts +232 -0
  133. package/src/testing/designAudit.ts +12 -0
  134. package/src/testing/designBaseline.spec.ts +9 -0
  135. package/src/testing/designBaseline.ts +26 -34
  136. package/src/testing/index.ts +18 -0
  137. package/src/testing/lookPrePaint.spec.ts +43 -0
  138. package/src/testing/lookPrePaint.ts +60 -0
  139. package/src/testing/phoneRules.spec.ts +75 -0
  140. package/src/testing/phoneRules.ts +332 -0
  141. package/src/testing/safariDriver.ts +331 -0
  142. package/src/testing/safariRules.spec.ts +92 -0
  143. package/src/testing/safariRules.ts +195 -0
@@ -0,0 +1,288 @@
1
+ /// <reference types="node" />
2
+ /**
3
+ * The Safari this Mac ships, driven over WebDriver (forge task apple-device-testing, 2026-10-06,
4
+ * after orbgem's safari script). Apple ships one WebKit release to the Mac and the iPhone,
5
+ * so the Mac's Safari is the phone's engine; Playwright's (`appleDevices.ts`) is a build of trunk
6
+ * that can be ahead or behind. `walkSafari` opens a Safari window at each Apple device's width and
7
+ * holds every screen to `auditApple` (the design audit and the phone rules that hold on any
8
+ * pointer — a Mac has no touchscreen, so the halo, the zoom and the hover rules stay with the
9
+ * WebKit pass) plus `safariRules.ts`: every declaration, selector and at-rule the app's
10
+ * stylesheets ask of this engine, as it parses them.
11
+ *
12
+ * It needs `safaridriver` (Develop → Allow Remote Automation) and Safari in front, so it is an
13
+ * app's `bun run safari`, never a gate stage. Four WebDriver verbs over plain HTTP are all it
14
+ * takes; `node:child_process` and `fetch`, so it runs under Bun and Node alike.
15
+ */
16
+ import { spawn, spawnSync } from 'node:child_process';
17
+ import { mkdirSync, rmSync, writeFileSync } from 'node:fs';
18
+ import { dirname, join } from 'node:path';
19
+ import { appleContext } from './appleDevices.js';
20
+ import { auditApple, KEYBOARD_STANDIN } from './appleWalk.js';
21
+ import { explainSafari, findGaps, judgeSupport, probeStylesInPage, styleClaims } from './safariRules.js';
22
+ const ELEMENT = 'element-6066-11e4-a52e-4f735466cecf';
23
+ export class SafariError extends Error {
24
+ }
25
+ const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
26
+ /** One Safari window under WebDriver. `start` is the only way to get one. */
27
+ export class SafariSession {
28
+ driver;
29
+ api;
30
+ id;
31
+ engine;
32
+ chrome = null;
33
+ constructor(driver, api, id,
34
+ /** `Safari 27.0.1` — what the report names. */
35
+ engine) {
36
+ this.driver = driver;
37
+ this.api = api;
38
+ this.id = id;
39
+ this.engine = engine;
40
+ }
41
+ /** Starts `safaridriver` on a free port and opens a session; the error names the remedy. */
42
+ static async start() {
43
+ const port = 4440 + Math.floor(Math.random() * 500);
44
+ const driver = spawn('safaridriver', ['-p', String(port)], { stdio: ['ignore', 'pipe', 'pipe'] });
45
+ let stderr = '';
46
+ driver.stderr?.on('data', (chunk) => {
47
+ stderr += String(chunk);
48
+ });
49
+ const api = `http://127.0.0.1:${port}`;
50
+ let up = false;
51
+ for (let i = 0; i < 100 && !up; i++) {
52
+ if (driver.exitCode !== null)
53
+ break;
54
+ try {
55
+ up = (await fetch(`${api}/status`)).ok;
56
+ }
57
+ catch {
58
+ await sleep(100);
59
+ }
60
+ }
61
+ if (!up) {
62
+ driver.kill();
63
+ throw new SafariError(explainSafari(`safaridriver did not start on port ${port}: ${stderr}`.trim()));
64
+ }
65
+ try {
66
+ const made = await call(api, 'POST', '/session', { capabilities: { alwaysMatch: { browserName: 'safari' } } });
67
+ return new SafariSession(driver, api, made.sessionId, `Safari ${made.capabilities.browserVersion}`);
68
+ }
69
+ catch (err) {
70
+ driver.kill();
71
+ throw new SafariError(explainSafari(err instanceof Error ? err.message : String(err)));
72
+ }
73
+ }
74
+ call(method, path, body) {
75
+ return call(this.api, method, `/session/${this.id}${path}`, body);
76
+ }
77
+ /** A fresh document each time: a hash alone would keep a page whose account or place is stale. */
78
+ async open(url) {
79
+ await this.call('POST', '/url', { url: 'about:blank' });
80
+ await this.call('POST', '/url', { url });
81
+ }
82
+ /** Runs a standalone function inside the page with one argument, awaiting a promise it returns. */
83
+ async run(fn, arg) {
84
+ const value = await this.call('POST', '/execute/async', {
85
+ script: `const done = arguments[arguments.length - 1]; Promise.resolve((${fn.toString()})(arguments[0])).then(done, (e) => done({ __thrown: String(e && e.message || e) }));`,
86
+ args: [arg],
87
+ });
88
+ if (value && typeof value === 'object' && '__thrown' in value)
89
+ throw new Error(String(value.__thrown));
90
+ return value;
91
+ }
92
+ /** Where the window is now. */
93
+ url() {
94
+ return this.call('GET', '/url');
95
+ }
96
+ evaluate(script) {
97
+ return this.call('POST', '/execute/sync', { script, args: [] });
98
+ }
99
+ async screenshot(path) {
100
+ mkdirSync(dirname(path), { recursive: true });
101
+ writeFileSync(path, Buffer.from(await this.call('GET', '/screenshot'), 'base64'));
102
+ }
103
+ async waitFor(css, ms = 10000) {
104
+ const until = Date.now() + ms;
105
+ while (Date.now() < until) {
106
+ if (await this.evaluate(`const el = document.querySelector(${JSON.stringify(css)}); return !!el && el.getClientRects().length > 0;`))
107
+ return;
108
+ await sleep(150);
109
+ }
110
+ throw new Error(`${css} did not appear within ${ms / 1000}s`);
111
+ }
112
+ /** The window is sized so that what the page sees is the device's viewport; Safari's own chrome sits above it. */
113
+ async size(width, height) {
114
+ if (this.chrome === null) {
115
+ await this.call('POST', '/window/rect', { width: 390, height: 844 });
116
+ this.chrome = 844 - (await this.evaluate('return window.innerHeight'));
117
+ }
118
+ await this.call('POST', '/window/rect', { width, height: height + this.chrome });
119
+ return this.evaluate('return { width: window.innerWidth, height: window.innerHeight }');
120
+ }
121
+ clearCookies() {
122
+ return this.call('DELETE', '/cookie');
123
+ }
124
+ /** Adds a cookie for the document's origin — navigate to the app first. */
125
+ addCookie(name, value) {
126
+ return this.call('POST', '/cookie', { cookie: { name, value, path: '/' } });
127
+ }
128
+ /**
129
+ * A click that is known to have arrived. Safari delivers a WebDriver click as a real mouse
130
+ * event, which reaches nothing while another app is in front: the page counts what lands, Safari
131
+ * is brought forward on a miss, and a second miss fails with the reason.
132
+ */
133
+ async click(ref) {
134
+ const count = () => this.evaluate("if (!window.__taps) { window.__taps = 0; addEventListener('pointerdown', () => { window.__taps++; }, true); } return window.__taps;");
135
+ for (let attempt = 0; attempt < 2; attempt++) {
136
+ const before = await count();
137
+ await this.call('POST', `/element/${ref[ELEMENT]}/click`, {});
138
+ await sleep(150);
139
+ if ((await count()) > before)
140
+ return;
141
+ spawnSync('open', ['-a', 'Safari']);
142
+ await sleep(400);
143
+ }
144
+ throw new Error(explainSafari('no click reached the page: Safari was not the frontmost app, and a WebDriver click goes to whatever is.'));
145
+ }
146
+ /** The first element matching `css` (and holding `text`) that is drawn, as a WebDriver reference. */
147
+ async find(css, text, ms = 8000) {
148
+ const until = Date.now() + ms;
149
+ const look = () => this.run(([c, t]) => {
150
+ const all = [...document.querySelectorAll(c)].filter((el) => el.getClientRects().length > 0);
151
+ return (t ? all.find((el) => (el.textContent ?? '').includes(t)) : all[0]) ?? null;
152
+ }, [css, text]);
153
+ let found = await look();
154
+ while (!found && Date.now() < until) {
155
+ await sleep(150);
156
+ found = await look();
157
+ }
158
+ if (!found)
159
+ throw new Error(`nothing to tap at ${css}${text ? ` "${text}"` : ''}`);
160
+ return found;
161
+ }
162
+ /** Arms the page: script errors collected from here on, and the stood-in keyboard. */
163
+ arm() {
164
+ return this.evaluate(`${COLLECT}; ${KEYBOARD_STANDIN}`);
165
+ }
166
+ errorsSoFar() {
167
+ return this.evaluate('const e = window.__errors || []; window.__errors = []; return e;');
168
+ }
169
+ /** Every style the app's sheets ask of this engine that it refuses, as findings. */
170
+ async styleGaps() {
171
+ return judgeSupport(await this.run(probeStylesInPage, [styleClaims.toString(), findGaps.toString()]), this.engine);
172
+ }
173
+ async close() {
174
+ await this.call('DELETE', '').catch(() => { });
175
+ this.driver.kill();
176
+ }
177
+ }
178
+ const COLLECT = "window.__errors = window.__errors || []; if (!window.__collecting) { window.__collecting = true; addEventListener('error', (e) => window.__errors.push(e.message)); addEventListener('unhandledrejection', (e) => window.__errors.push(String(e.reason && e.reason.message || e.reason))); }";
179
+ async function call(api, method, path, body) {
180
+ const response = await fetch(`${api}${path}`, { method, headers: { 'content-type': 'application/json' }, body: body === undefined ? undefined : JSON.stringify(body) });
181
+ const { value } = (await response.json());
182
+ if (value && typeof value === 'object' && 'error' in value && typeof value.error === 'string') {
183
+ const e = value;
184
+ throw new SafariError(`${e.error}: ${e.message}`);
185
+ }
186
+ return value;
187
+ }
188
+ /** Walks every screen at every device's width in the shipped Safari; writes `<out>/report.md`; answers the results. */
189
+ export async function walkSafari(options) {
190
+ const { base, cookie, screens, devices, registry, out, log = console.log } = options;
191
+ if (!/^https?:\/\/(localhost|127\.0\.0\.1)(:\d+)?$/.test(base.replace(/\/$/, '')))
192
+ throw new SafariError(`walkSafari runs against a local instance; ${base} is not one.`);
193
+ rmSync(out, { recursive: true, force: true });
194
+ mkdirSync(out, { recursive: true });
195
+ const safari = await SafariSession.start();
196
+ const results = [];
197
+ try {
198
+ for (const device of devices) {
199
+ const wanted = appleContext(registry, device).viewport ?? { width: 390, height: 659 };
200
+ const got = await safari.size(wanted.width, wanted.height);
201
+ const errors = [];
202
+ if (Math.abs(got.width - wanted.width) > 1 || Math.abs(got.height - wanted.height) > 1)
203
+ errors.push(`Safari would not be ${wanted.width}×${wanted.height}; it gave ${got.width}×${got.height}`);
204
+ // One Safari, one cookie jar: the signed-out screens are seen signed out, then the cookie goes in.
205
+ await safari.open(`${base}/`);
206
+ await safari.clearCookies();
207
+ const page = {
208
+ evaluate: (fn, arg) => safari.run(fn, arg),
209
+ viewportSize: () => got,
210
+ screenshot: ({ path }) => safari.screenshot(path),
211
+ waitForTimeout: sleep,
212
+ };
213
+ const visit = async (screen) => {
214
+ // Where `auditApple` writes this screen's frames: `<out>/<device>/<screen>[-NN|-keyboard].png`.
215
+ const shot = join(out, device.slug, `${screen.name.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-|-$/g, '') || 'root'}*.png`);
216
+ const findings = [];
217
+ const errs = [];
218
+ try {
219
+ if (typeof screen.open === 'string')
220
+ await safari.open(`${base}${screen.open}`);
221
+ else {
222
+ await safari.open(`${base}${screen.open.at}`);
223
+ await safari.arm();
224
+ const ref = await safari.find(screen.open.css, screen.open.text);
225
+ await sleep(300);
226
+ await safari.click(ref);
227
+ }
228
+ // Sent elsewhere (a signed-out visitor goes to the accounts app): nothing of this app is on screen.
229
+ await sleep(300);
230
+ const now = await safari.url();
231
+ if (!now.startsWith(base)) {
232
+ if (screen.signedIn)
233
+ errs.push(`${screen.name} left the app for ${now}`);
234
+ else
235
+ log(` · ${device.name} · ${screen.name} — went to ${now}; nothing of this app to judge`);
236
+ results.push({ device: device.name, screen: screen.name, shot: '', findings, errors: errs });
237
+ return;
238
+ }
239
+ await safari.waitFor(screen.ready);
240
+ await safari.arm();
241
+ const judged = await auditApple(page, screen.name, device, { ...options.audit, ...screen.audit, shots: out, touch: false });
242
+ findings.push(...judged.violations);
243
+ errs.push(...(await safari.errorsSoFar()));
244
+ }
245
+ catch (err) {
246
+ errs.push(`${screen.name} did not open: ${explainSafari(err instanceof Error ? (err.message.split('\n')[0] ?? err.message) : String(err))}`);
247
+ await safari.screenshot(shot.replace('*.png', '-failed.png')).catch(() => { });
248
+ }
249
+ results.push({ device: device.name, screen: screen.name, shot, findings, errors: errs });
250
+ log(` ${findings.length || errs.length ? '✗' : '✓'} ${device.name} · ${screen.name}${findings.length ? ` — ${findings.length} finding(s)` : ''}${errs.length ? ` — ${errs.join('; ')}` : ''}`);
251
+ };
252
+ for (const screen of screens.filter((s) => !s.signedIn))
253
+ await visit(screen);
254
+ if (cookie) {
255
+ await safari.open(`${base}/`);
256
+ await safari.addCookie(cookie.name, cookie.value);
257
+ }
258
+ const first = screens.find((s) => s.signedIn) ?? screens[0];
259
+ if (first) {
260
+ await safari.open(`${base}${typeof first.open === 'string' ? first.open : first.open.at}`);
261
+ await safari.waitFor(first.ready).catch(() => { });
262
+ results.push({ device: device.name, screen: 'stylesheets', shot: '', findings: await safari.styleGaps(), errors });
263
+ }
264
+ for (const screen of screens.filter((s) => s.signedIn))
265
+ await visit(screen);
266
+ }
267
+ }
268
+ finally {
269
+ await safari.close();
270
+ }
271
+ const failed = results.filter((r) => r.findings.length || r.errors.length).length;
272
+ const lines = [`# Safari check — ${new Date().toISOString()}`, '', `${base} in ${safari.engine}, at the width of ${devices.map((d) => d.name).join(', ')}: ${results.length} screens, ${failed} with findings.`, ''];
273
+ for (const device of devices) {
274
+ lines.push(`## ${device.name}`, '');
275
+ for (const r of results.filter((x) => x.device === device.name)) {
276
+ lines.push(`- ${r.findings.length || r.errors.length ? '✗' : '✓'} **${r.screen}**${r.shot ? ` — \`${r.shot}\`` : ''}`);
277
+ for (const f of r.findings)
278
+ lines.push(` - ${f.rule} · ${f.selector}: ${f.detail}`);
279
+ for (const e of r.errors)
280
+ lines.push(` - error · ${e}`);
281
+ }
282
+ lines.push('');
283
+ }
284
+ writeFileSync(join(out, 'report.md'), lines.join('\n'));
285
+ log(`\n${results.length} screens in ${safari.engine} at ${devices.length} width(s): ${failed} with findings. Report and screenshots: ${join(out, 'report.md')}`);
286
+ return { engine: safari.engine, results, failed };
287
+ }
288
+ //# sourceMappingURL=safariDriver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"safariDriver.js","sourceRoot":"","sources":["../../src/testing/safariDriver.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,57 @@
1
+ /**
2
+ * What the Safari this Mac ships is held to (forge task apple-device-testing, 2026-10-06, after
3
+ * orbgem's safari-rules script). Playwright's WebKit (`appleDevices.ts`) is a build of
4
+ * WebKit's trunk; the Safari Apple ships, on the Mac and on the iPhone alike, is a release behind
5
+ * or ahead of it, so a style the one engine takes the other may drop in silence. `styleClaims`
6
+ * reads a stylesheet for everything it asks of an engine, `probeStylesInPage` asks the engine
7
+ * inside the page, and `judgeSupport` turns what it refused into findings; `safariRules.spec.ts`
8
+ * proves each on the thing it exists to catch.
9
+ */
10
+ import type { DesignViolation } from './designAudit.js';
11
+ /** What a stylesheet asks of the engine: every declaration, selector and at-rule it holds, once each. */
12
+ export interface StyleClaims {
13
+ declarations: Array<{
14
+ property: string;
15
+ value: string;
16
+ }>;
17
+ selectors: string[];
18
+ atRules: string[];
19
+ }
20
+ /** What the engine refused, in `styleClaims`'s terms; `atRules` are those its parser dropped. */
21
+ export type StyleGaps = StyleClaims;
22
+ /**
23
+ * Reads a stylesheet's text for its claims. Runs inside the page (handed over as source), so it
24
+ * stands alone. A small walk over braces, strings and parentheses, not a CSS parser: it only has
25
+ * to find each prelude and each `property: value`, and Tailwind's output is regular.
26
+ */
27
+ export declare function styleClaims(css: string): StyleClaims;
28
+ /** The engine's answers, asked inside the page; `kept` is the at-rules its parser held onto. */
29
+ export interface StyleEngine {
30
+ supports: (property: string, value: string) => boolean;
31
+ supportsSelector: (selector: string) => boolean;
32
+ kept: Set<string>;
33
+ }
34
+ /**
35
+ * What an engine refused of a stylesheet's claims, less what it refuses by design. Runs inside
36
+ * the page (handed over as source beside `styleClaims`), so it stands alone.
37
+ * - A declaration whose `-webkit-` twin (same value) the engine takes is drawn by the twin;
38
+ * Tailwind writes both, and Safari still wants the prefix on `user-select`.
39
+ * - Some `-webkit-` properties exist on the iPhone and not on the Mac: the Mac's Safari saying no
40
+ * to them says nothing about the phone.
41
+ * - A selector with another engine's prefix names a part this engine does not have.
42
+ */
43
+ export declare function findGaps(claims: StyleClaims, engine: StyleEngine): StyleGaps;
44
+ /**
45
+ * Asks the engine, inside the page, about each claim of the page's own stylesheets. Stands alone:
46
+ * the two readers arrive as source, since nothing can be imported there. An at-rule the parser
47
+ * dropped is one the stylesheet names and the CSSOM does not hold.
48
+ */
49
+ export declare function probeStylesInPage([claimsSource, gapsSource]: readonly [string, string]): Promise<StyleGaps>;
50
+ /** What the shipped engine refused is a style the iPhone will not draw: a finding per kind (FND-16, both themes drawn as designed). */
51
+ export declare function judgeSupport(gaps: StyleGaps, engine: string): DesignViolation[];
52
+ /**
53
+ * What safaridriver's refusals mean, and what to do: each was met on 2026-10-06 while orbgem's
54
+ * check was first made, and the message Safari gives names no remedy.
55
+ */
56
+ export declare function explainSafari(message: string): string;
57
+ //# sourceMappingURL=safariRules.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"safariRules.d.ts","sourceRoot":"","sources":["../../src/testing/safariRules.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAExD,yGAAyG;AACzG,MAAM,WAAW,WAAW;IAC1B,YAAY,EAAE,KAAK,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACzD,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,iGAAiG;AACjG,MAAM,MAAM,SAAS,GAAG,WAAW,CAAC;AAEpC;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,WAAW,CAyFpD;AAED,gGAAgG;AAChG,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC;IACvD,gBAAgB,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC;IAChD,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;CACnB;AAED;;;;;;;;GAQG;AACH,wBAAgB,QAAQ,CAAC,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,WAAW,GAAG,SAAS,CAQ5E;AAED;;;;GAIG;AACH,wBAAsB,iBAAiB,CAAC,CAAC,YAAY,EAAE,UAAU,CAAC,EAAE,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,SAAS,CAAC,CAuBjH;AAID,uIAAuI;AACvI,wBAAgB,YAAY,CAAC,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,GAAG,eAAe,EAAE,CAM/E;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAMrD"}
@@ -0,0 +1,191 @@
1
+ /**
2
+ * Reads a stylesheet's text for its claims. Runs inside the page (handed over as source), so it
3
+ * stands alone. A small walk over braces, strings and parentheses, not a CSS parser: it only has
4
+ * to find each prelude and each `property: value`, and Tailwind's output is regular.
5
+ */
6
+ export function styleClaims(css) {
7
+ // At-rules whose blocks hold descriptors, not properties: `CSS.supports` knows nothing of them.
8
+ // `@supports` guards its block on purpose, so what it holds is the stylesheet's own condition.
9
+ const DESCRIPTOR_RULES = ['property', 'font-face', 'font-feature-values', 'font-palette-values', 'counter-style', 'page', 'view-transition', 'position-try', 'supports'];
10
+ // Blocks whose preludes are not selectors.
11
+ const NOT_SELECTORS = ['keyframes', '-webkit-keyframes', 'font-feature-values'];
12
+ const text = css.replace(/\/\*[\s\S]*?\*\//g, '');
13
+ const declarations = new Map();
14
+ const selectors = new Set();
15
+ const atRules = new Set();
16
+ const stack = [];
17
+ let buffer = '';
18
+ let quote = null;
19
+ let parens = 0;
20
+ const declare = (raw) => {
21
+ const colon = raw.indexOf(':');
22
+ if (colon < 0)
23
+ return;
24
+ const property = raw.slice(0, colon).trim();
25
+ const value = raw.slice(colon + 1).replace(/!important\s*$/i, '').trim();
26
+ // Custom properties take any value; other engines' prefixes are ignored by this one on purpose.
27
+ if (!/^[a-zA-Z-]+$/.test(property) || property.startsWith('--') || /^-(moz|ms|o)-/.test(property) || !value)
28
+ return;
29
+ if (stack.some((rule) => DESCRIPTOR_RULES.includes(rule)))
30
+ return;
31
+ declarations.set(`${property}:${value}`, { property, value });
32
+ };
33
+ const splitTop = (list) => {
34
+ const parts = [];
35
+ let depth = 0;
36
+ let part = '';
37
+ let q = null;
38
+ for (const ch of list) {
39
+ if (q) {
40
+ part += ch;
41
+ if (ch === q)
42
+ q = null;
43
+ continue;
44
+ }
45
+ if (ch === '"' || ch === "'")
46
+ q = ch;
47
+ if (ch === '(' || ch === '[')
48
+ depth++;
49
+ if (ch === ')' || ch === ']')
50
+ depth--;
51
+ if (ch === ',' && depth === 0) {
52
+ parts.push(part.trim());
53
+ part = '';
54
+ continue;
55
+ }
56
+ part += ch;
57
+ }
58
+ parts.push(part.trim());
59
+ return parts;
60
+ };
61
+ for (const ch of text) {
62
+ if (quote) {
63
+ buffer += ch;
64
+ if (ch === quote)
65
+ quote = null;
66
+ continue;
67
+ }
68
+ if (ch === '"' || ch === "'") {
69
+ quote = ch;
70
+ buffer += ch;
71
+ continue;
72
+ }
73
+ if (ch === '(')
74
+ parens++;
75
+ if (ch === ')')
76
+ parens = Math.max(0, parens - 1);
77
+ if (parens > 0) {
78
+ buffer += ch;
79
+ continue;
80
+ }
81
+ if (ch === '{') {
82
+ const prelude = buffer.trim();
83
+ buffer = '';
84
+ if (prelude.startsWith('@')) {
85
+ const name = /^@([\w-]+)/.exec(prelude)?.[1] ?? '';
86
+ atRules.add(name);
87
+ stack.push(name);
88
+ }
89
+ else {
90
+ stack.push('');
91
+ if (stack.some((rule) => NOT_SELECTORS.includes(rule)))
92
+ continue;
93
+ // `a, b` is two claims: `selector()` takes one at a time.
94
+ for (const one of splitTop(prelude))
95
+ if (one)
96
+ selectors.add(one);
97
+ }
98
+ continue;
99
+ }
100
+ if (ch === '}' || ch === ';') {
101
+ if (buffer.trim())
102
+ declare(buffer.trim());
103
+ buffer = '';
104
+ if (ch === '}')
105
+ stack.pop();
106
+ continue;
107
+ }
108
+ buffer += ch;
109
+ }
110
+ return { declarations: [...declarations.values()], selectors: [...selectors], atRules: [...atRules] };
111
+ }
112
+ /**
113
+ * What an engine refused of a stylesheet's claims, less what it refuses by design. Runs inside
114
+ * the page (handed over as source beside `styleClaims`), so it stands alone.
115
+ * - A declaration whose `-webkit-` twin (same value) the engine takes is drawn by the twin;
116
+ * Tailwind writes both, and Safari still wants the prefix on `user-select`.
117
+ * - Some `-webkit-` properties exist on the iPhone and not on the Mac: the Mac's Safari saying no
118
+ * to them says nothing about the phone.
119
+ * - A selector with another engine's prefix names a part this engine does not have.
120
+ */
121
+ export function findGaps(claims, engine) {
122
+ const IPHONE_ONLY = ['-webkit-text-size-adjust', '-webkit-tap-highlight-color', '-webkit-touch-callout', '-webkit-overflow-scrolling'];
123
+ const twinned = (d) => claims.declarations.some((t) => t.property === `-webkit-${d.property}` && t.value === d.value && engine.supports(t.property, t.value));
124
+ return {
125
+ declarations: claims.declarations.filter((d) => !IPHONE_ONLY.includes(d.property) && !engine.supports(d.property, d.value) && !twinned(d)),
126
+ selectors: claims.selectors.filter((s) => !/::?-(webkit|moz|ms)-/.test(s) && !engine.supportsSelector(s)),
127
+ atRules: claims.atRules.filter((name) => !engine.kept.has(name)),
128
+ };
129
+ }
130
+ /**
131
+ * Asks the engine, inside the page, about each claim of the page's own stylesheets. Stands alone:
132
+ * the two readers arrive as source, since nothing can be imported there. An at-rule the parser
133
+ * dropped is one the stylesheet names and the CSSOM does not hold.
134
+ */
135
+ export async function probeStylesInPage([claimsSource, gapsSource]) {
136
+ const read = new Function(`return (${claimsSource})`)();
137
+ const gaps = new Function(`return (${gapsSource})`)();
138
+ const texts = [];
139
+ const kept = new Set();
140
+ const walk = (rules) => {
141
+ for (const rule of rules) {
142
+ const name = /^@([\w-]+)/.exec(rule.cssText)?.[1];
143
+ if (name)
144
+ kept.add(name);
145
+ if ('cssRules' in rule)
146
+ walk(rule.cssRules);
147
+ }
148
+ };
149
+ for (const sheet of document.styleSheets) {
150
+ const owner = sheet.ownerNode;
151
+ if (owner instanceof HTMLStyleElement)
152
+ texts.push(owner.textContent ?? '');
153
+ else if (owner instanceof HTMLLinkElement && owner.href)
154
+ texts.push(await (await fetch(owner.href)).text());
155
+ try {
156
+ walk(sheet.cssRules);
157
+ }
158
+ catch {
159
+ // A stylesheet from another origin keeps its rules to itself; it is not this app's.
160
+ }
161
+ }
162
+ return gaps(read(texts.join('\n')), { supports: (p, v) => CSS.supports(p, v), supportsSelector: (s) => CSS.supports(`selector(${s})`), kept });
163
+ }
164
+ const list = (items, max = 6) => items.slice(0, max).join('; ') + (items.length > max ? `; and ${items.length - max} more` : '');
165
+ /** What the shipped engine refused is a style the iPhone will not draw: a finding per kind (FND-16, both themes drawn as designed). */
166
+ export function judgeSupport(gaps, engine) {
167
+ const found = [];
168
+ if (gaps.declarations.length)
169
+ found.push({ rule: 'FND-18', selector: '(stylesheets)', detail: `${engine} drops ${gaps.declarations.length} declaration(s) the stylesheet relies on: ${list(gaps.declarations.map((d) => `${d.property}: ${d.value}`))}` });
170
+ if (gaps.selectors.length)
171
+ found.push({ rule: 'FND-18', selector: '(stylesheets)', detail: `${engine} drops every rule under ${gaps.selectors.length} selector(s): ${list(gaps.selectors)}` });
172
+ if (gaps.atRules.length)
173
+ found.push({ rule: 'FND-18', selector: '(stylesheets)', detail: `${engine} drops ${gaps.atRules.length} at-rule(s) whole: ${list(gaps.atRules.map((a) => `@${a}`))}` });
174
+ return found;
175
+ }
176
+ /**
177
+ * What safaridriver's refusals mean, and what to do: each was met on 2026-10-06 while orbgem's
178
+ * check was first made, and the message Safari gives names no remedy.
179
+ */
180
+ export function explainSafari(message) {
181
+ if (/Allow Remote Automation/i.test(message))
182
+ return `${message}\n\nIn Safari: Settings → Advanced → “Show features for web developers”, then Develop → “Allow Remote Automation”. Quit Safari afterwards so the next launch starts with it on.`;
183
+ if (/timed out while connecting to a Safari instance/i.test(message))
184
+ return `${message}\n\nSafari is open from before Remote Automation was allowed, or is waiting on a dialog. Quit Safari (⌘Q) and run this again; it opens its own window.`;
185
+ if (/no click reached the page/i.test(message))
186
+ return `${message}\n\nSafari delivers a WebDriver click as a real mouse event, so the app in front gets it. The check brings Safari forward itself; this is what it says when that was not enough.`;
187
+ if (/Address already in use/i.test(message))
188
+ return `${message}\n\nAnother safaridriver holds the port: \`pkill -x safaridriver\` and run this again.`;
189
+ return message;
190
+ }
191
+ //# sourceMappingURL=safariRules.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"safariRules.js","sourceRoot":"","sources":["../../src/testing/safariRules.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cursedbelt",
3
- "version": "5.67.0",
3
+ "version": "5.69.0",
4
4
  "license": "ISC",
5
5
  "type": "module",
6
6
  "description": "The React design system of the cursedbelt split — components, styles, theme. cursedbelt-core below it; server tier in cursedbelt-server.",
@@ -890,6 +890,7 @@
890
890
  "@emoji-mart/data": "^1.2.1",
891
891
  "@ffmpeg/ffmpeg": "^0.12.15",
892
892
  "@ffmpeg/util": "^0.12.2",
893
+ "@fontsource-variable/inter": "^5.3.0",
893
894
  "@git-diff-view/react": "^0.1.6",
894
895
  "@glideapps/glide-data-grid": "^6.0.3",
895
896
  "@happy-dom/global-registrator": "^20.10.6",
@@ -155,6 +155,7 @@ export const AREAS: readonly Area[] = [
155
155
  'components/ButtonLink.tsx',
156
156
  'components/CardDisplayControls.tsx',
157
157
  'components/CardTapTarget.tsx',
158
+ 'components/EntityCard.tsx',
158
159
  'components/Checkbox.tsx',
159
160
  'components/ChoiceGroup.tsx',
160
161
  'components/ChoiceMenu.tsx',