create-pmos 0.512.0 → 0.514.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.
- package/package.json +27 -95
- package/payload/KIT-VERSION +1 -1
- package/payload/planning/evals/eval-calibration.md +1 -1
- package/payload/planning/okrs/health-budgets.md +1 -1
- package/payload/state/discoveries.md +1 -1
- package/workspace/briefing-premium-adddoc-test.js +3 -3
- package/workspace/briefing-premium-board-test.js +2 -2
- package/workspace/briefing-premium-initiative-test.js +3 -3
- package/workspace/briefing-premium-insights-test.js +2 -2
- package/workspace/briefing-premium-sources-test.js +4 -5
- package/workspace/briefing-premium-test.js +2 -2
- package/workspace/changelog.json +26 -0
- package/workspace/guide/home.md +1 -1
- package/workspace/intel-report-ui-test.js +1 -1
- package/workspace/intelligence-gaps-ui-test.js +1 -1
- package/workspace/lib/premium-console-type.js +15 -12
- package/workspace/lib/routes-boards.js +18 -6
- package/workspace/metric-drafts-ui-test.js +2 -2
- package/workspace/package-lock.json +2 -2
- package/workspace/package.json +1 -1
- package/workspace/premium-menu-rows-test.js +1 -1
- package/workspace/premium-vw-doc-test.js +1 -1
- package/workspace/public/pm/bd-pin-card.css +4 -4
- package/workspace/public/pm/bd-publish.css +11 -11
- package/workspace/public/pm/bd-shared.css +17 -17
- package/workspace/public/pm/c3-capture.css +9 -9
- package/workspace/public/pm/c3-initiatives.css +23 -23
- package/workspace/public/pm/c3-listen.css +1 -1
- package/workspace/public/pm/components.css +572 -572
- package/workspace/public/pm/console3.css +374 -373
- package/workspace/public/pm/cozy-adler.css +4 -4
- package/workspace/public/pm/cozy-aud.css +1 -1
- package/workspace/public/pm/cozy-board.css +328 -328
- package/workspace/public/pm/cozy-ev.css +78 -78
- package/workspace/public/pm/cozy-home-rows.css +32 -32
- package/workspace/public/pm/cozy-home.css +240 -240
- package/workspace/public/pm/cozy-insights.css +200 -200
- package/workspace/public/pm/cozy-live-pill.css +5 -5
- package/workspace/public/pm/cozy-mtg-present.css +28 -28
- package/workspace/public/pm/cozy-onboard.css +15 -15
- package/workspace/public/pm/cozy-panel.css +39 -39
- package/workspace/public/pm/cozy-pick.css +5 -5
- package/workspace/public/pm/cozy-rec-now.css +23 -23
- package/workspace/public/pm/cozy-rec-present.css +11 -11
- package/workspace/public/pm/cozy-rec-tab.css +13 -13
- package/workspace/public/pm/cozy-steps.css +14 -14
- package/workspace/public/pm/cozy-today.css +95 -95
- package/workspace/public/pm/cozy-viewer.css +27 -27
- package/workspace/public/pm/cozy-vw-mtg.css +113 -113
- package/workspace/public/pm/cozy-vw-rp.css +79 -79
- package/workspace/public/pm/cozy-vw-shell.css +43 -43
- package/workspace/public/pm/cozy-vw.css +129 -129
- package/workspace/public/pm/cozy-xv.css +15 -15
- package/workspace/public/pm/cozy.css +53 -21
- package/workspace/public/pm/dash-view.css +27 -27
- package/workspace/public/pm/hi-pop.css +26 -26
- package/workspace/public/pm/home-impact.css +8 -8
- package/workspace/public/pm/home-ini.css +36 -36
- package/workspace/public/pm/home-line.css +7 -7
- package/workspace/public/pm/impact.css +9 -9
- package/workspace/public/pm/ini-view.css +243 -243
- package/workspace/public/pm/load-shapes.css +1 -1
- package/workspace/public/pm/loose-props.css +14 -14
- package/workspace/public/pm/metric-drafts.css +20 -20
- package/workspace/public/pm/ms-suggest.css +9 -9
- package/workspace/public/pm/ov-view.css +14 -14
- package/workspace/public/pm/premium-insights.js +3 -3
- package/workspace/public/pm/premium-report-frame.css +1 -1
- package/workspace/public/pm/premium-report-intel.css +17 -17
- package/workspace/public/pm/premium-report-print.css +1 -1
- package/workspace/public/pm/premium-vw-backlog.css +13 -13
- package/workspace/public/pm/premium-vw-cal.css +32 -32
- package/workspace/public/pm/premium-vw-copy.css +7 -7
- package/workspace/public/pm/premium-vw-doc.css +69 -69
- package/workspace/public/pm/premium-vw-item.css +12 -12
- package/workspace/public/pm/premium-vw-jira.css +39 -39
- package/workspace/public/pm/premium-vw-meet.css +28 -28
- package/workspace/public/pm/premium-vw-notepad.css +13 -13
- package/workspace/public/pm/premium-vw-notes.css +11 -11
- package/workspace/public/pm/premium-vw-rec.css +27 -27
- package/workspace/public/pm/premium-vw-report.css +21 -21
- package/workspace/public/pm/premium-vw-slides.css +28 -28
- package/workspace/public/pm/premium.css +618 -618
- package/workspace/public/pm/prog-order.css +6 -6
- package/workspace/public/pm/prog-page.css +17 -17
- package/workspace/public/pm/program-charter.css +33 -33
- package/workspace/public/pm/ready-lib.css +6 -6
- package/workspace/public/pm/sort-order.css +1 -1
- package/workspace/public/pm/split-merge.css +18 -18
- package/workspace/public/pm/task-card.css +24 -24
- package/workspace/public/pm/tk-tasks.css +42 -42
- package/workspace/public/pm/tk-view.css +6 -6
- package/workspace/public/pm/wf-page.css +31 -31
- package/workspace/public/premium-aud.html +1 -1
- package/workspace/public/premium-board.html +1 -1
- package/workspace/public/premium-intelligence.html +1 -1
- package/workspace/public/premium-rec.html +1 -1
- package/workspace/public/premium-viewer.html +1 -1
- package/workspace/public/premium-workflows.html +1 -1
- package/workspace/public/premium.html +1 -1
- package/workspace/public/vendor/plus-jakarta-sans-var.woff2 +0 -0
- package/workspace/server.js +1 -0
- package/workspace/third-party/README.md +2 -1
- package/workspace/third-party/plus-jakarta-sans-OFL.LICENSE +93 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-pmos",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.514.0",
|
|
4
4
|
"description": "Scaffold the PMOS portable kit — run the PMOS product-management workflow (initiative → lane-fit spec → contract → build → three gates, with work-type lanes for features, research, maintenance, incidents, and content) entirely inside your own repo, with all state as git-versioned files. Includes `workflow-sweep`, which audits the state every board derives from and separates real defects from work you simply have not done. `create-pmos workspace` also installs + launches the local Terminal Workspace GUI. No database, no network, no telemetry.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"bin": {
|
|
@@ -32,6 +32,32 @@
|
|
|
32
32
|
"audit"
|
|
33
33
|
],
|
|
34
34
|
"pmosChanges": [
|
|
35
|
+
{
|
|
36
|
+
"v": "0.514.0",
|
|
37
|
+
"at": "2026-11-03T16:19:12.685Z",
|
|
38
|
+
"f": 4,
|
|
39
|
+
"prs": [
|
|
40
|
+
{
|
|
41
|
+
"n": 1205,
|
|
42
|
+
"t": "Closed also reads the Done category and terminal stage names",
|
|
43
|
+
"s": "Closed also reads the Done category and terminal stage names",
|
|
44
|
+
"k": "fix"
|
|
45
|
+
}
|
|
46
|
+
]
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
"v": "0.513.0",
|
|
50
|
+
"at": "2026-11-03T15:46:14.696Z",
|
|
51
|
+
"f": 4,
|
|
52
|
+
"prs": [
|
|
53
|
+
{
|
|
54
|
+
"n": 1203,
|
|
55
|
+
"t": "Typography roles with Plus Jakarta Sans, two weights, four sizes",
|
|
56
|
+
"s": "Typography roles with Plus Jakarta Sans, two weights, four sizes",
|
|
57
|
+
"k": "new"
|
|
58
|
+
}
|
|
59
|
+
]
|
|
60
|
+
},
|
|
35
61
|
{
|
|
36
62
|
"v": "0.512.0",
|
|
37
63
|
"at": "2026-11-03T15:33:10.629Z",
|
|
@@ -470,100 +496,6 @@
|
|
|
470
496
|
"d": "Every new initiative needed its workflow chosen by hand. Now you star one in Settings and new work uses it."
|
|
471
497
|
}
|
|
472
498
|
]
|
|
473
|
-
},
|
|
474
|
-
{
|
|
475
|
-
"v": "0.494.0",
|
|
476
|
-
"at": "2026-11-02T15:38:38.702Z",
|
|
477
|
-
"f": 4,
|
|
478
|
-
"prs": [
|
|
479
|
-
{
|
|
480
|
-
"n": 1156,
|
|
481
|
-
"t": "A report change from the chat edits the existing draft in place",
|
|
482
|
-
"s": "A report change from the chat edits the existing draft in place",
|
|
483
|
-
"k": "fix",
|
|
484
|
-
"h": "Report edits from chat change the draft",
|
|
485
|
-
"d": "Asking the chat to change a report could start a new draft. Now it edits the draft you already have."
|
|
486
|
-
},
|
|
487
|
-
{
|
|
488
|
-
"n": 1150,
|
|
489
|
-
"t": "A report's chat icon opens its own conversation beside it",
|
|
490
|
-
"s": "A report's chat icon opens its own conversation beside it",
|
|
491
|
-
"k": "new",
|
|
492
|
-
"h": "Talk about a report beside it",
|
|
493
|
-
"d": "A report had no place of its own to discuss it. Now its chat icon opens a conversation next to the report."
|
|
494
|
-
},
|
|
495
|
-
{
|
|
496
|
-
"n": 1149,
|
|
497
|
-
"t": "Product groups use the product name, not the folder name",
|
|
498
|
-
"s": "Product groups use the product name, not the folder name",
|
|
499
|
-
"k": "fix",
|
|
500
|
-
"h": "Products show their real names",
|
|
501
|
-
"d": "Board groups showed the folder name of a product. Now they show the product's own name."
|
|
502
|
-
},
|
|
503
|
-
{
|
|
504
|
-
"n": 1157,
|
|
505
|
-
"t": "Weekly impact check as thank-you bubbles, counted by default",
|
|
506
|
-
"s": "Weekly impact check as thank-you bubbles, counted by default",
|
|
507
|
-
"k": "new",
|
|
508
|
-
"h": "Your weekly impact, as thank-yous",
|
|
509
|
-
"d": "The weekly impact check was easy to miss. Now it arrives as small thank-you bubbles and is counted by default."
|
|
510
|
-
},
|
|
511
|
-
{
|
|
512
|
-
"n": 1158,
|
|
513
|
-
"t": "Grill every initiative with open work, not only late work; Home says how many",
|
|
514
|
-
"s": "Grill every initiative with open work, not only late work; Home says how many",
|
|
515
|
-
"k": "fix",
|
|
516
|
-
"h": "Every open initiative gets a grill",
|
|
517
|
-
"d": "Claude only grilled initiatives that were late. Now it grills every initiative with open work, and Home says how many."
|
|
518
|
-
},
|
|
519
|
-
{
|
|
520
|
-
"n": 1159,
|
|
521
|
-
"t": "Pages open faster after a break and after a start",
|
|
522
|
-
"s": "Pages open faster after a break and after a start",
|
|
523
|
-
"k": "imp",
|
|
524
|
-
"h": "Pages open faster",
|
|
525
|
-
"d": "Pages were slow after a break or a fresh start. Now they open quicker in both cases."
|
|
526
|
-
},
|
|
527
|
-
{
|
|
528
|
-
"n": 1161,
|
|
529
|
-
"t": "A report template keeps its look and sections",
|
|
530
|
-
"s": "A report template keeps its look and sections",
|
|
531
|
-
"k": "new",
|
|
532
|
-
"h": "Report templates keep their look",
|
|
533
|
-
"d": "A report made from a template could lose the template's look and sections. Now it keeps both."
|
|
534
|
-
},
|
|
535
|
-
{
|
|
536
|
-
"n": 1162,
|
|
537
|
-
"t": "Finished report slides, the Pyramid deck",
|
|
538
|
-
"s": "Finished report slides, the Pyramid deck",
|
|
539
|
-
"k": "new",
|
|
540
|
-
"h": "Finished report slides",
|
|
541
|
-
"d": "Reports could not become a finished slide deck. Now a report can come out as clean slides in the Pyramid style."
|
|
542
|
-
},
|
|
543
|
-
{
|
|
544
|
-
"n": 1160,
|
|
545
|
-
"t": "Tighter phone initiative page, one 16 px inset",
|
|
546
|
-
"s": "Tighter phone initiative page, one 16 px inset",
|
|
547
|
-
"k": "new",
|
|
548
|
-
"h": "A tidier initiative page on the phone",
|
|
549
|
-
"d": "On a phone the initiative page had uneven edges. Now everything lines up on one even margin."
|
|
550
|
-
}
|
|
551
|
-
]
|
|
552
|
-
},
|
|
553
|
-
{
|
|
554
|
-
"v": "0.493.0",
|
|
555
|
-
"at": "2026-11-02T14:41:05.438Z",
|
|
556
|
-
"f": 4,
|
|
557
|
-
"prs": [
|
|
558
|
-
{
|
|
559
|
-
"n": 1152,
|
|
560
|
-
"t": "Retire Now / Next / Later; the Roadmap is one ranked list",
|
|
561
|
-
"s": "Retire Now / Next / Later; the Roadmap is one ranked list",
|
|
562
|
-
"k": "new",
|
|
563
|
-
"h": "One ranked roadmap",
|
|
564
|
-
"d": "The roadmap split work into Now, Next and Later. Now it is one ranked list, and each initiative's stage says where it is."
|
|
565
|
-
}
|
|
566
|
-
]
|
|
567
499
|
}
|
|
568
500
|
]
|
|
569
501
|
}
|
package/payload/KIT-VERSION
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
type: Reference
|
|
3
3
|
title: "Eval calibration log"
|
|
4
4
|
description: "Append-only record of every PM override of an evaluator verdict."
|
|
5
|
-
generated: {by: process:create-pmos, at: "2026-11-
|
|
5
|
+
generated: {by: process:create-pmos, at: "2026-11-03T16:19:09Z"}
|
|
6
6
|
status: stable
|
|
7
7
|
---
|
|
8
8
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
type: Reference
|
|
3
3
|
title: "Health budgets"
|
|
4
4
|
description: "Closed registry of health-budget anchors (D59), edited only by the PM."
|
|
5
|
-
generated: {by: process:create-pmos, at: "2026-11-
|
|
5
|
+
generated: {by: process:create-pmos, at: "2026-11-03T16:19:09Z"}
|
|
6
6
|
status: stable
|
|
7
7
|
---
|
|
8
8
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
type: Reference
|
|
3
3
|
title: "Discoveries and friction log"
|
|
4
4
|
description: "Append-only record of what runs discovered and where the process rubbed."
|
|
5
|
-
generated: {by: process:create-pmos, at: "2026-11-
|
|
5
|
+
generated: {by: process:create-pmos, at: "2026-11-03T16:19:09Z"}
|
|
6
6
|
status: stable
|
|
7
7
|
---
|
|
8
8
|
|
|
@@ -145,7 +145,7 @@ const PAGES = {
|
|
|
145
145
|
ok('A3 the add route takes POST only', wrong === 405);
|
|
146
146
|
}
|
|
147
147
|
|
|
148
|
-
/* A8 fidelity: the form follows the Agreed design (premium-agreed-design): the Viewer is one cozy card in
|
|
148
|
+
/* A8 fidelity: the form follows the Agreed design (premium-agreed-design): the Viewer is one cozy card in Plus Jakarta Sans, its presses pills, the main one
|
|
149
149
|
* the solid colour. The colours are read from the page's own tokens, so a theme is checked against itself. */
|
|
150
150
|
for (const [w, h] of [[1280, 900], [390, 844]]) for (const th of ['light', 'dark']) {
|
|
151
151
|
const R = await open('initiative', { w, h, theme: th });
|
|
@@ -159,8 +159,8 @@ const PAGES = {
|
|
|
159
159
|
return { vw: cs('#czViewer').backgroundColor, card: tok('--cz-card', 'background-color'), vwR: cs('#czViewer').borderTopLeftRadius, ff: cs('#czViewer').fontFamily, go: [cs(go).backgroundColor, '700', cs(go).borderTopLeftRadius], solid: tok('--cz-solid', 'background-color'), no: bk ? getComputedStyle(bk).backgroundColor : 'rgba(0, 0, 0, 0)', dlg: !!(document.querySelector('#dlg') && !!document.querySelector('#dlg.on')) };
|
|
160
160
|
});
|
|
161
161
|
const d = [];
|
|
162
|
-
if (!/^
|
|
163
|
-
if (g.vw !== g.card || !/^
|
|
162
|
+
if (!/^"?Plus Jakarta Sans/.test(btn.ff) || btn.br !== '999px') d.push('button ' + JSON.stringify(btn));
|
|
163
|
+
if (g.vw !== g.card || !/^"?Plus Jakarta Sans/.test(g.ff) || (w > 760 && parseFloat(g.vwR) < 20)) d.push('viewer ' + [g.vw, g.card, g.vwR, g.ff].join(' '));
|
|
164
164
|
if (g.go[0] !== g.solid || +g.go[1] < 700 || g.go[2] !== '999px') d.push('Add document ' + g.go.join(' ') + ' want ' + g.solid);
|
|
165
165
|
if (g.no !== g.card && g.no !== 'rgba(0, 0, 0, 0)') d.push('Back ' + g.no); // ← cancels (batch 18 item 2-C): the header's quiet round press
|
|
166
166
|
if (g.dlg) d.push('the old dialog opened');
|
|
@@ -645,11 +645,11 @@ const IVREAD = () => {
|
|
|
645
645
|
await R.ctx.close();
|
|
646
646
|
}
|
|
647
647
|
|
|
648
|
-
/* B13 the Agreed design's look:
|
|
648
|
+
/* B13 the Agreed design's look: Plus Jakarta Sans, the soft panel, the chips and the track's rows */
|
|
649
649
|
for (const th of ['light', 'dark']) {
|
|
650
650
|
const R = await open({ w: 1440, h: 900, theme: th }), q = R.page;
|
|
651
651
|
const s = await q.evaluate(() => { const cs = (sel) => getComputedStyle(document.querySelector(sel)); const main = cs('main.bd-main'), row = document.querySelector('.bt-l').getBoundingClientRect(); return { font: cs('body').fontFamily, rad: main.borderTopLeftRadius, bg: main.backgroundColor, chip: Math.round(document.querySelector('#chJira').getBoundingClientRect().height), row: Math.round(row.height), tab: cs('#tabIni').fontWeight, fab: cs('#czFab').borderTopLeftRadius }; });
|
|
652
|
-
ok(`B13 the look of the Agreed design at 1440 px, ${th}:
|
|
652
|
+
ok(`B13 the look of the Agreed design at 1440 px, ${th}: Plus Jakarta Sans, a 28 px panel, 30 px chips, 54 px rows`, /^"?Plus Jakarta Sans/.test(s.font) && s.rad === '28px' && s.chip === 30 && s.row >= 54 && s.row <= 62 && s.tab === '600' && (th === 'light' ? s.bg === 'rgb(255, 255, 255)' : s.bg !== 'rgb(255, 255, 255)'), JSON.stringify(s));
|
|
653
653
|
await R.ctx.close();
|
|
654
654
|
}
|
|
655
655
|
return finish();
|
|
@@ -252,7 +252,7 @@ const WRITES = /^\/api\/(?:boards\/(?:move|tasks\/(?:add|state))|lifecycle|core-
|
|
|
252
252
|
const post = await fetch(BASE + '/api/initiative-premium?id=x', { method: 'POST' }); ok('I10 the route answers GET only', post.status === 405);
|
|
253
253
|
}
|
|
254
254
|
|
|
255
|
-
/* I12 fidelity: the Agreed design (premium-agreed-design, Inside one initiative):
|
|
255
|
+
/* I12 fidelity: the Agreed design (premium-agreed-design, Inside one initiative): Plus Jakarta Sans, the cozy card, the CTA in the solid colour, the floating
|
|
256
256
|
* menu. The colours are read from the page's own tokens, so each theme is checked against itself. */
|
|
257
257
|
for (const [w, h] of [[1440, 900], [390, 844]]) for (const th of ['light', 'dark']) {
|
|
258
258
|
const R = await open({ w, h, theme: th });
|
|
@@ -264,7 +264,7 @@ const WRITES = /^\/api\/(?:boards\/(?:move|tasks\/(?:add|state))|lifecycle|core-
|
|
|
264
264
|
return { font: cs('body').fontFamily, cta: (cs('#czViewer .iv-go') || {}).backgroundColor, ctaAlt: !document.querySelector('#czViewer .iv-go'), solid: tok('--cz-solid'), blue: tok('--cz-blue'), well: tok('--cz-well'), card: tok('--cz-card'), box: cs('#czViewer .iv-mc').backgroundColor, rad: parseFloat(cs(innerWidth <= 760 ? '#czViewer .iv-tel' : '#czViewer .iv-mc').borderTopLeftRadius), fab: fr ? [Math.round(fr.width), Math.round(fr.height)] : null, over: document.documentElement.scrollWidth - innerWidth, cardW: Math.round(c.width) };
|
|
265
265
|
});
|
|
266
266
|
const d = [];
|
|
267
|
-
if (!/^
|
|
267
|
+
if (!/^"?Plus Jakarta Sans/.test(g.font)) d.push('font ' + g.font);
|
|
268
268
|
if (!g.ctaAlt && ![g.solid, g.blue].includes(g.cta)) d.push('cta ' + g.cta + ' want ' + g.solid + ' or ' + g.blue);
|
|
269
269
|
if (![g.well, g.card].includes(g.box) && !/rgba/.test(g.box)) d.push('card box ' + g.box);
|
|
270
270
|
// a phone has no wrapper card (batch 23 item 5, canvas PmA): the mission is the first card there
|
|
@@ -272,7 +272,7 @@ const WRITES = /^\/api\/(?:boards\/(?:move|tasks\/(?:add|state))|lifecycle|core-
|
|
|
272
272
|
// on a phone the initiative's page is the Viewer, full screen over the list: the floating menu waits under it (HbCPhone)
|
|
273
273
|
if (w > 760 && (!g.fab || g.fab[0] !== 56 || g.fab[1] !== 56)) d.push('fab ' + JSON.stringify(g.fab));
|
|
274
274
|
if (g.over > 0) d.push('sideways scroll ' + g.over);
|
|
275
|
-
ok(`I12 the initiative follows the Agreed design at ${w} px, ${th}:
|
|
275
|
+
ok(`I12 the initiative follows the Agreed design at ${w} px, ${th}: Plus Jakarta Sans, the cozy card, the CTA, the floating menu`, d.length === 0, d.join(' ; '));
|
|
276
276
|
ok(`I12 no page error at ${w} px, ${th}`, R.errors.length === 0, R.errors.join(' | '));
|
|
277
277
|
await R.ctx.close();
|
|
278
278
|
}
|
|
@@ -603,13 +603,13 @@ const BMR = { ok: true, state: 'ready', model: { tiles: [
|
|
|
603
603
|
await R.ctx.close();
|
|
604
604
|
}
|
|
605
605
|
|
|
606
|
-
/* I11 fidelity to the Agreed design (AgInsGoals, AgInsPhone):
|
|
606
|
+
/* I11 fidelity to the Agreed design (AgInsGoals, AgInsPhone): Plus Jakarta Sans, the cozy panel, the pill tabs, the table, the strip and the six tiles */
|
|
607
607
|
for (const [w, h] of [[1440, 900], [390, 844]]) {
|
|
608
608
|
const R = await open({ w, h }); await sleep(300);
|
|
609
609
|
const f = await R.page.evaluate(() => { const cs = (s) => getComputedStyle(document.querySelector(s)); const main = cs('main.ins'), tab = cs('#viewChip'), strip = cs('#insHero'), row = document.querySelector('#goalTbl .ins-row').getBoundingClientRect();
|
|
610
610
|
return { font: cs('body').fontFamily, radius: main.borderTopLeftRadius, bg: main.backgroundColor, tabBg: tab.backgroundColor, tabR: tab.borderTopLeftRadius, tabW: tab.fontWeight, stripR: strip.borderTopLeftRadius, stripBg: strip.backgroundColor, rowH: Math.round(row.height), over: document.documentElement.scrollWidth > innerWidth, fab: document.querySelector('#czFab').getBoundingClientRect().width, fabX: Math.round(document.querySelector('#czFab').getBoundingClientRect().left) }; });
|
|
611
611
|
const phone = w < 720;
|
|
612
|
-
ok(`I11 the page wears the Agreed design at ${w} px:
|
|
612
|
+
ok(`I11 the page wears the Agreed design at ${w} px: Plus Jakarta Sans, the white panel, the pill View chip, the well strip, 56 px floating button`, /^"?Plus Jakarta Sans/.test(f.font) && f.radius === (phone ? '0px' : '28px') && (phone || f.bg === 'rgb(255, 255, 255)') && f.tabBg === 'rgb(244, 243, 240)' && f.tabR === '999px' && +f.tabW >= 600 && (phone || (f.stripR === '16px' && f.stripBg === 'rgb(244, 243, 240)' && f.rowH >= 60)) && !f.over && f.fab === 56 && (phone ? f.fabX > 300 : f.fabX === 36), JSON.stringify(f));
|
|
613
613
|
if (!phone) {
|
|
614
614
|
await toTrends(R.page);
|
|
615
615
|
const t = await R.page.evaluate(() => { const tiles = [...document.querySelectorAll('#bmBody [data-tile]')].map((x) => x.getBoundingClientRect()); return { n: tiles.length, tileH: tiles.length ? Math.round(tiles[0].height) : 0, over: document.documentElement.scrollWidth > innerWidth }; });
|
|
@@ -193,7 +193,7 @@ const sh = (cwd, args) => spawnSync('git', args, { cwd, encoding: 'utf8' });
|
|
|
193
193
|
{
|
|
194
194
|
// re-pointed again for the Agreed design's Home: the source row is a Needs-you row of Home's list, and the digest is a row of New for you.
|
|
195
195
|
// Re-pointed for Home A + C (HvAC, HvACDesk): a row is one line, its mark and its title; the subject moved to the row's tooltip and
|
|
196
|
-
// accessible name, and the title is
|
|
196
|
+
// accessible name, and the title is the row title role, 15 px at 600 (feedback batch 26 item 6)
|
|
197
197
|
const ROWS = [['row', '.hm-rm'], ['number', '.hv-d'], ['title', '.hm-rt b']];
|
|
198
198
|
const DIGS = [['event', ''], ['eventTime', '.ev-tx .ev-mut'], ['eventTitle', '.ev-tx b']];
|
|
199
199
|
const SANS = 'var(--cz-sans)';
|
|
@@ -201,10 +201,10 @@ const sh = (cwd, args) => spawnSync('git', args, { cwd, encoding: 'utf8' });
|
|
|
201
201
|
const WANT = {
|
|
202
202
|
row: { fontFamily: SANS, color: 'var(--cz-ink)', backgroundColor: 'transparent' },
|
|
203
203
|
number: { backgroundColor: 'var(--cz-blue)', borderRadius: '50%', width: '8px', height: '8px' }, // the row's dot is blue: it waits on you (HvAC .d)
|
|
204
|
-
title: { fontFamily: SANS, fontSize: '
|
|
204
|
+
title: { fontFamily: SANS, fontSize: 'var(--fs-row)', fontWeight: 'var(--fw-strong)', color: 'var(--cz-ink)' }, // the row title role (batch 26 item 6), desktop and phone
|
|
205
205
|
event: { fontFamily: SANS, color: 'var(--cz-ink)', backgroundColor: 'transparent' }, // a row of New for you's table (cozy-ev.css)
|
|
206
|
-
eventTime: { fontSize: '
|
|
207
|
-
eventTitle: { fontFamily: SANS, fontSize: '
|
|
206
|
+
eventTime: { fontSize: 'var(--fs-meta)', color: 'var(--cz-ink3)' },
|
|
207
|
+
eventTitle: { fontFamily: SANS, fontSize: 'var(--fs-row)', fontWeight: 'var(--fw-strong)', color: 'var(--cz-ink)' },
|
|
208
208
|
};
|
|
209
209
|
const grab = (pg, pairs, base, col) => pg.evaluate(([pairs, want, base, col]) => {
|
|
210
210
|
const o = {};
|
|
@@ -235,7 +235,6 @@ const sh = (cwd, args) => spawnSync('git', args, { cwd, encoding: 'utf8' });
|
|
|
235
235
|
await allNeeds(R.page);
|
|
236
236
|
// on a phone "Not in an initiative" starts folded (HvAC): open it to reach the source row
|
|
237
237
|
if (w === 390) { const lh = await R.page.$('#hmList .hv-lh[aria-expanded="false"]'); if (lh) await lh.click(); }
|
|
238
|
-
WANT.title.fontSize = w === 390 ? '16px' : '14px';
|
|
239
238
|
await sleep(500);
|
|
240
239
|
const rowSel = '#hmList .hm-r[data-id^="n:src:"]';
|
|
241
240
|
const diffs = diff(await grab(R.page, ROWS, rowSel, '.hm-pg'), ROWS, 4); // the row fills its group (the group's own inset aside)
|
|
@@ -127,7 +127,7 @@ const vw = () => { const v = document.querySelector('#czViewer:not([hidden])');
|
|
|
127
127
|
const selBg = await p.evaluate(() => getComputedStyle(document.querySelector('.hm-r.sel')).backgroundColor);
|
|
128
128
|
ok('R12 the selected row is tinted (HvACDesk .sel)', selBg && !/rgba\(0, 0, 0, 0\)|transparent/.test(selBg), selBg);
|
|
129
129
|
const hd = await p.evaluate(() => { const h = document.querySelector('#hmCh'); return h && !h.hidden ? { t: (h.querySelector('.hm-chb') || {}).textContent || '', mark: !!h.querySelector('.hv-mk .hv-d, .hv-mk .hv-ck'), y: Math.round(h.getBoundingClientRect().top), size: getComputedStyle(h.querySelector('.hm-chb')).fontSize } : null; });
|
|
130
|
-
ok('R12 the chat\'s header line names the open row: its mark and its title,
|
|
130
|
+
ok('R12 the chat\'s header line names the open row: its mark and its title, 15 px (the row title role, batch 26 item 6), at the top of the chat card (HvACDesk .ch)', !!hd && hd.t === r0.t && hd.mark && hd.y === 32 && hd.size === '15px', JSON.stringify(hd)); }
|
|
131
131
|
|
|
132
132
|
/* R10 */
|
|
133
133
|
ok('R10 a page where nothing was pressed to record sends no POST', A.posts.filter((x) => /briefing-premium\/(decide|put-off|return|start)/.test(x.path)).length === 0, JSON.stringify(A.posts.map((x) => x.path)));
|
|
@@ -273,7 +273,7 @@ const vw = () => { const v = document.querySelector('#czViewer:not([hidden])');
|
|
|
273
273
|
const desk = document.querySelector('#hmDesk'), list = document.querySelector('#hmList'), cs = getComputedStyle(document.querySelector('#hmChat')), r = list.getBoundingClientRect();
|
|
274
274
|
return { inset: Math.round(r.left), radius: cs.borderTopLeftRadius, list: Math.round(list.getBoundingClientRect().width), font: getComputedStyle(document.body).fontFamily, theme: document.documentElement.dataset.theme || '', bg: getComputedStyle(document.body).backgroundColor, rail: !!document.querySelector('nav.rail'), menu: !!document.querySelector('#czMenu, .cz-nav') };
|
|
275
275
|
});
|
|
276
|
-
ok(`R12 Home follows the Home A + C design at 1440 px (HvACDesk), ${theme}: the list at 16 px and 360 px wide, the chat a card with a 24 px radius,
|
|
276
|
+
ok(`R12 Home follows the Home A + C design at 1440 px (HvACDesk), ${theme}: the list at 16 px and 360 px wide, the chat a card with a 24 px radius, Plus Jakarta Sans, the floating place menu, no rail`, f.inset === 16 && f.radius === '24px' && f.list === 360 && /Plus Jakarta Sans/.test(f.font) && f.menu && !f.rail, JSON.stringify(f));
|
|
277
277
|
await D.ctx.close();
|
|
278
278
|
}
|
|
279
279
|
return finish();
|
package/workspace/changelog.json
CHANGED
|
@@ -1,4 +1,30 @@
|
|
|
1
1
|
[
|
|
2
|
+
{
|
|
3
|
+
"v": "0.514.0",
|
|
4
|
+
"at": "2026-11-03T16:19:12.685Z",
|
|
5
|
+
"f": 4,
|
|
6
|
+
"prs": [
|
|
7
|
+
{
|
|
8
|
+
"n": 1205,
|
|
9
|
+
"t": "Closed also reads the Done category and terminal stage names",
|
|
10
|
+
"s": "Closed also reads the Done category and terminal stage names",
|
|
11
|
+
"k": "fix"
|
|
12
|
+
}
|
|
13
|
+
]
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
"v": "0.513.0",
|
|
17
|
+
"at": "2026-11-03T15:46:14.696Z",
|
|
18
|
+
"f": 4,
|
|
19
|
+
"prs": [
|
|
20
|
+
{
|
|
21
|
+
"n": 1203,
|
|
22
|
+
"t": "Typography roles with Plus Jakarta Sans, two weights, four sizes",
|
|
23
|
+
"s": "Typography roles with Plus Jakarta Sans, two weights, four sizes",
|
|
24
|
+
"k": "new"
|
|
25
|
+
}
|
|
26
|
+
]
|
|
27
|
+
},
|
|
2
28
|
{
|
|
3
29
|
"v": "0.512.0",
|
|
4
30
|
"at": "2026-11-03T15:33:10.629Z",
|
package/workspace/guide/home.md
CHANGED
|
@@ -9,7 +9,7 @@ timestamp: 2026-11-03
|
|
|
9
9
|
|
|
10
10
|
Home is the page at `/premium.html`. It follows the Agreed design and the "Uncovered features" canvas (initiative `premium-uncovered-features`). The left side is one list. The middle is the chat. The right side is the Viewer. A row opens its item in the Viewer. On a phone the list is the page, and a row opens its conversation with a back bar.
|
|
11
11
|
|
|
12
|
-
Home, the Board, Insights and the Viewer use one
|
|
12
|
+
Home, the Board, Insights and the Viewer use one typeface, Plus Jakarta Sans, with two weights (regular and semibold) and four sizes: 13, 15, 18 and 26 px. Each kind of text has one role, and the role sets its size, weight and line height: a large number and a page title are 26 px, a panel title is 18 px, a group head, a row's name and a sentence are 15 px, and the quiet meta line, a label and a badge are 13 px. The same kind of text looks the same on every page. Rows have room to breathe, so a list row is about 52 to 58 px high. There is no compact setting. Slides and report templates keep their own sizes.
|
|
13
13
|
|
|
14
14
|
## The list
|
|
15
15
|
|
|
@@ -88,7 +88,7 @@ const FINDING = { id: 'rf-0123456789', name: 'Partner numbers to Lee', why: 'You
|
|
|
88
88
|
};
|
|
89
89
|
const vClose = async (pg) => { for (let k = 0; k < 4; k++) { const shown = await pg.evaluate(() => { const v = document.querySelector('#czViewer'); return !!v && !v.hidden; }); if (!shown) break; await pg.evaluate(() => window.czViewer && window.czViewer.close()); await sleep(250); } };
|
|
90
90
|
const sizes = (p, sel) => p.evaluate((s) => [...new Set([...document.querySelectorAll(s + ', ' + s + ' *')].filter((e) => e.childNodes.length && [...e.childNodes].some((n) => n.nodeType === 3 && n.textContent.trim())).map((e) => getComputedStyle(e).fontSize))], sel);
|
|
91
|
-
const SCALE = new Set(['
|
|
91
|
+
const SCALE = new Set(['13px', '15px', '18px', '26px']); // the typography roles (batch 26 item 6)
|
|
92
92
|
const panel = (p) => p.evaluate(() => {
|
|
93
93
|
const b = document.querySelector('#czViewer:not([hidden]) .ins-rpd') || document.querySelector('#side:not([hidden]) .ins-rpd'); if (!b) return null;
|
|
94
94
|
return { title: (document.querySelector('#czViewer .cz-vw-title') || {}).textContent || '', kind: (document.querySelector('#czViewer .cz-vw-kind') || {}).textContent || '', sum: (b.querySelector('.ins-rps b') || {}).textContent || '',
|
|
@@ -157,7 +157,7 @@ const WEEKLY = { view: 'view', weeks: 3, day: 'Mon', opens: 4 };
|
|
|
157
157
|
await p.evaluate(() => document.querySelector('#mdHost').remove());
|
|
158
158
|
|
|
159
159
|
/* ── T: the type scale ── */
|
|
160
|
-
const SCALE = new Set(['
|
|
160
|
+
const SCALE = new Set(['13px', '15px', '18px', '26px']); // the typography roles (batch 26 item 6)
|
|
161
161
|
const sizes = await p.evaluate(() => [...new Set([...document.querySelectorAll('#insHero, #insHero *, #nsRow, #nsRow *')].filter((e) => e.childNodes.length && [...e.childNodes].some((n) => n.nodeType === 3 && n.textContent.trim())).map((e) => getComputedStyle(e).fontSize))]);
|
|
162
162
|
ok('T the strip and the drafts use the type scale only', sizes.every((s) => SCALE.has(s)), sizes.join());
|
|
163
163
|
ok('no page errors', !A.errors.length, A.errors.join(' | '));
|
|
@@ -3,25 +3,25 @@
|
|
|
3
3
|
* The premium stylesheets were cut from the approved mockup, which set its own type: Geist and Geist Mono, a 15 px body and sizes from 10 to
|
|
4
4
|
* 44 px written as plain pixels, and weights from 550 to 700. The console (pm/console3.css + pm/tokens.css) sets Space Grotesk and IBM Plex
|
|
5
5
|
* Mono, a 14 px / 1.5 body, a six-step scale (--fs-1 to --fs-6: 11, 12, 14, 16, 20, 28 px) and three weights (400, 500, 600).
|
|
6
|
+
* Since feedback batch 26 item 6 (2026-11-03) the steps are the typography roles (cozy.css): sizes go to a role token (13, 15, 18 or 26 px)
|
|
7
|
+
* and weights to the two weight tokens (400, 600).
|
|
6
8
|
* transform(css) maps a premium stylesheet onto the console's type and changes nothing else: every font size goes to the nearest console
|
|
7
9
|
* step, every heavy weight to 600 (550 to 500), the two font families to the console's, and the body line height to 1.5. It is idempotent,
|
|
8
10
|
* so a stylesheet already on console type comes back unchanged (premium-console-type.test.js holds the committed stylesheets to that).
|
|
9
11
|
* The browser suites also run it over the mockup before they compare computed styles, so the mockup stays the reference for the look and
|
|
10
12
|
* the console is the reference for the type. */
|
|
11
13
|
|
|
12
|
-
const FS = '--fs-
|
|
14
|
+
const FS = '--fw-regular:400;--fw-strong:600;--fs-field:16px;--fs-display:26px;--fs-page:26px;--fs-panel:18px;--fs-section:15px;--fs-row:15px;--fs-body:15px;--fs-meta:13px;--fs-label:13px;--fs-badge:13px;--lh-display:1.2;--lh-page:1.2;--lh-panel:1.3;--lh-section:1.35;--lh-row:1.4;--lh-body:1.6;--lh-meta:1.5;--lh-label:1.35;--lh-badge:1.2';
|
|
13
15
|
|
|
14
|
-
/* a pixel size to the
|
|
16
|
+
/* a pixel size to the role size it reads as: 13 meta, 15 body, 18 panel, 26 display */
|
|
15
17
|
function step(px) {
|
|
16
18
|
const n = parseFloat(px);
|
|
17
|
-
if (n
|
|
18
|
-
if (n
|
|
19
|
-
if (n
|
|
20
|
-
|
|
21
|
-
if (n <= 30) return 'var(--fs-5)';
|
|
22
|
-
return 'var(--fs-6)';
|
|
19
|
+
if (n < 13.5) return 'var(--fs-meta)';
|
|
20
|
+
if (n < 17.5) return 'var(--fs-body)';
|
|
21
|
+
if (n < 23) return 'var(--fs-panel)';
|
|
22
|
+
return 'var(--fs-display)';
|
|
23
23
|
}
|
|
24
|
-
const weight = (w) => (
|
|
24
|
+
const weight = (w) => (+w >= 600 ? 'var(--fw-strong)' : 'var(--fw-regular)');
|
|
25
25
|
|
|
26
26
|
/* the console's font files; base is where /vendor/ is served ('/vendor/' on the server, a file:// path for the mockup) */
|
|
27
27
|
function fontFaces(base = '/vendor/') {
|
|
@@ -32,7 +32,9 @@ function fontFaces(base = '/vendor/') {
|
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
function transform(css, { base = '/vendor/', faces = true } = {}) {
|
|
35
|
-
|
|
35
|
+
// an @font-face's weight is a descriptor of the file (400, 300 700), not a style: set aside, then put back unchanged
|
|
36
|
+
const kept = [];
|
|
37
|
+
let out = String(css).replace(/@font-face\s*\{[^}]*\}/g, (m) => (/Geist/.test(m) ? m : '\u0000' + (kept.push(m) - 1) + '\u0000'))
|
|
36
38
|
.replace(/@font-face\s*\{[^}]*Geist[^}]*\}\s*/g, '')
|
|
37
39
|
.replace(/--sans:[^;}]*/g, '--sans:"Space Grotesk",ui-sans-serif,system-ui,sans-serif')
|
|
38
40
|
.replace(/--mono:[^;}]*/g, '--mono:"IBM Plex Mono",ui-monospace,SFMono-Regular,Menlo,Consolas,monospace')
|
|
@@ -49,8 +51,9 @@ function transform(css, { base = '/vendor/', faces = true } = {}) {
|
|
|
49
51
|
.replace(/font:\s*((?:italic\s+)?)(\d{3})(\s)/g, (m, it, w, sp) => 'font:' + it + weight(w) + sp)
|
|
50
52
|
// the body reads at the console's line height; the Briefing paragraph gets the width its smaller type needs
|
|
51
53
|
.replace(/(\bbody\{[^}]*?)line-height:1\.45/g, '$1line-height:1.5')
|
|
52
|
-
.replace(/(\.brief\{[^}]*?)max-width:42ch/g, '$1max-width:64ch')
|
|
53
|
-
|
|
54
|
+
.replace(/(\.brief\{[^}]*?)max-width:42ch/g, '$1max-width:64ch')
|
|
55
|
+
.replace(/\u0000(\d+)\u0000/g, (m, k) => kept[+k]);
|
|
56
|
+
if (!/--fs-body:/.test(out)) out = ':root{' + FS + '}\n' + out;
|
|
54
57
|
if (faces && !/space-grotesk-var\.woff2/.test(out)) out = fontFaces(base) + out;
|
|
55
58
|
return out;
|
|
56
59
|
}
|
|
@@ -477,15 +477,27 @@ const gapFields = (spans) => ({ gaps: holdSpans.planGaps(spans, 14), stageSpans:
|
|
|
477
477
|
const minDay = (a, b) => (!a ? b || null : !b ? a : a < b ? a : b);
|
|
478
478
|
const maxDay = (a, b) => (!a ? b || null : !b ? a : a > b ? a : b);
|
|
479
479
|
|
|
480
|
-
/** batch 26 item 5: whether an initiative stands in its workflow's terminal stage
|
|
481
|
-
*
|
|
480
|
+
/** batch 26 item 5: whether an initiative stands in its workflow's terminal stage. Read from the workflow first: the stage is in the Done
|
|
481
|
+
* category, or it is the last stage (stages after it that only end work, such as Won't do or Cancelled, do not count). A stage the workflow
|
|
482
|
+
* does not hold (a Jira-read status such as "Closed") is terminal when its name says so, as tkStatus reads a ticket (done, closed, resolved,
|
|
483
|
+
* released). Follow-up (CAS rows still late after #1202): the board column branch ignored the Done category and any stage outside the list. */
|
|
484
|
+
const TERMINAL_RE = /\b(done|closed|resolved|released|complete|completed|finished)\b/i;
|
|
485
|
+
const END_RE = /\b(won'?t do|cancel+ed|archived|abandoned|dropped|rejected)\b/i;
|
|
486
|
+
const isDoneCat = (c) => String(c || '').toLowerCase() === 'done';
|
|
482
487
|
function closedOf(row, wx) {
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
488
|
+
const cur = (wx && wx.stages || []).find((x) => x.key === wx.stage);
|
|
489
|
+
if (cur && (wx.own || cur.name === row.stage)) {
|
|
490
|
+
if (isDoneCat(cur.cat) || (cur.of > 1 && cur.n === cur.of)) return true;
|
|
491
|
+
if (wx.own) return false;
|
|
486
492
|
}
|
|
493
|
+
if (isDoneCat(row.cat)) return true;
|
|
487
494
|
const wf = Array.isArray(row.workflow) ? row.workflow : [];
|
|
488
|
-
|
|
495
|
+
const name = String(row.stage || '');
|
|
496
|
+
const i = wf.findIndex((x) => x && x.name === name);
|
|
497
|
+
if (i < 0) return TERMINAL_RE.test(name);
|
|
498
|
+
if (isDoneCat(wf[i].cat)) return true;
|
|
499
|
+
// the last stage, not counting the ones after it that only end work
|
|
500
|
+
return wf.length > 1 && wf.slice(i + 1).every((x) => END_RE.test(String(x && x.name || '')));
|
|
489
501
|
}
|
|
490
502
|
function boardRow(board, base, folded, lib) {
|
|
491
503
|
const s = B.stageOf(board, base.id, base.reading, folded);
|
|
@@ -108,9 +108,9 @@ const INITIATIVE = () => ({
|
|
|
108
108
|
why: c.querySelector('.md-why').textContent,
|
|
109
109
|
presses: [...c.querySelectorAll('.md-ft .md-ib')].map((b) => ({ label: b.getAttribute('aria-label'), title: b.getAttribute('title'), text: b.textContent.trim(), svg: !!b.querySelector('svg[aria-hidden="true"]'), solid: b.classList.contains('solid'), href: b.getAttribute('href') || '' })) };
|
|
110
110
|
});
|
|
111
|
-
// every font size the parts draw: the type
|
|
111
|
+
// every font size the parts draw: the type roles only (13, 15, 18, 26 px)
|
|
112
112
|
const sizes = (p, sel) => p.evaluate((s) => [...new Set([...document.querySelectorAll(s + ', ' + s + ' *')].filter((e) => e.childNodes.length && [...e.childNodes].some((n) => n.nodeType === 3 && n.textContent.trim())).map((e) => getComputedStyle(e).fontSize))], sel);
|
|
113
|
-
const SCALE = new Set(['
|
|
113
|
+
const SCALE = new Set(['13px', '15px', '18px', '26px']); // the typography roles (batch 26 item 6)
|
|
114
114
|
|
|
115
115
|
/* ── P: the program's proposed goal ── */
|
|
116
116
|
const D = await open();
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pmos-workspace",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.514.0",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "pmos-workspace",
|
|
9
|
-
"version": "0.
|
|
9
|
+
"version": "0.514.0",
|
|
10
10
|
"license": "MIT",
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"@anthropic-ai/sdk": "^1.3.0",
|
package/workspace/package.json
CHANGED
|
@@ -90,7 +90,7 @@ const ONE = { '.crmenu': 42, '.crmenu.tbmenu': 44, '.dsmn': 44 };
|
|
|
90
90
|
await page.goto(ORIGIN + '/menu.html');
|
|
91
91
|
const c1 = await page.evaluate(() => { const t = getComputedStyle(document.querySelector('.tag')), p = getComputedStyle(document.querySelector('.lsn-help')), c = getComputedStyle(document.querySelector('.c3'));
|
|
92
92
|
return { tag: t.backgroundColor, fs: p.fontSize, muted: c.getPropertyValue('--muted').trim(), fg: c.getPropertyValue('--foreground').trim() }; });
|
|
93
|
-
ok(`C1 a console sheet at ${w} ${theme}: its tokens are set, a tag has a fill and the body is
|
|
93
|
+
ok(`C1 a console sheet at ${w} ${theme}: its tokens are set, a tag has a fill and the body is 15px text (the body role)`, c1.muted && c1.fg && !/rgba\(0, 0, 0, 0\)|transparent/.test(c1.tag) && c1.fs === '15px', JSON.stringify(c1));
|
|
94
94
|
// H1: a long highlight keeps its tag on one line
|
|
95
95
|
ctx._html = page0(`<section class="rvsec" style="overflow-wrap:anywhere;max-width:${Math.min(w - 32, 560)}px"><ul class="rvhl"><li><time>0:00</time><span>${LONG.join(' ').repeat(3)}</span><em>decision</em></li></ul></section>`, theme);
|
|
96
96
|
await page.goto(ORIGIN + '/menu.html');
|
|
@@ -232,7 +232,7 @@ const prop = (o) => Object.assign({ id: 'prop-a', state: 'proposed', prompt: 'ad
|
|
|
232
232
|
const fs = [...root.querySelectorAll('*')].map((e) => getComputedStyle(e).fontSize).filter((x, i, a) => a.indexOf(x) === i);
|
|
233
233
|
return { sx: document.documentElement.scrollWidth - innerWidth, bad, out, fs };
|
|
234
234
|
}, [V, w < 600]);
|
|
235
|
-
ok(`D8 at ${w} px ${theme}: no sideways scroll, no small target, nothing past the edge,
|
|
235
|
+
ok(`D8 at ${w} px ${theme}: no sideways scroll, no small target, nothing past the edge, role sizes only`, f.sx <= 0 && f.bad.length === 0 && f.out === 0 && f.fs.every((x) => ['13px', '15px', '16px', '18px', '26px'].includes(x)), JSON.stringify(f));
|
|
236
236
|
const c = await R.page.evaluate((v) => { const e = document.querySelector(v + ' .cf'); return [getComputedStyle(document.querySelector('#czViewer')).backgroundColor, getComputedStyle(e).color]; }, V); // the page sits on the Viewer's card
|
|
237
237
|
ok(`D8 at ${w} px ${theme}: the page follows the theme`, theme === 'dark' ? c[0] === 'rgb(36, 38, 43)' && c[1] === 'rgb(236, 238, 241)' : c[0] === 'rgb(255, 255, 255)' && c[1] === 'rgb(42, 46, 53)', JSON.stringify(c)); // the initiative page is cozy (premium-agreed-design): the card is the cozy white or dark card
|
|
238
238
|
await R.ctx.close();
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
/* pm/bd-pin-card.css — the ◇ card on the Board timeline (feedback batch 13 item 4, XcalmA5Milestones): the initiative's milestones with a pin each.
|
|
2
2
|
* The card is a pm/bd-pop.js popover; the Filter's "Milestones on the timeline" group uses the Filter's own chips. */
|
|
3
3
|
.bd-pp.bd-pc { padding: 12px 12px 6px; }
|
|
4
|
-
.bd-pc-h { margin: 0; font:
|
|
5
|
-
.bd-pc-sub { margin: 2px 0 6px; font-size: var(--fs-
|
|
4
|
+
.bd-pc-h { margin: 0; font: var(--fw-strong) var(--fs-section)/1.3 var(--cz-sans); color: var(--cz-ink); }
|
|
5
|
+
.bd-pc-sub { margin: 2px 0 6px; font-size: var(--fs-label); font-weight: var(--fw-strong); line-height: var(--lh-label); }
|
|
6
6
|
.bd-pc-r { display: flex; align-items: center; gap: 10px; min-height: 44px; border-top: 1px solid var(--cz-hair); }
|
|
7
7
|
.bd-pc-r .tg-tm-i { margin-left: 4px; }
|
|
8
|
-
.bd-pc-n { flex: 1; min-width: 0; font:
|
|
8
|
+
.bd-pc-n { flex: 1; min-width: 0; font: var(--fw-strong) var(--fs-label)/1.25 var(--cz-sans); color: var(--cz-ink2); overflow-wrap: anywhere; }
|
|
9
9
|
.bd-pc-r.on .bd-pc-n { color: var(--cz-ink); }
|
|
10
|
-
.bd-pc-n small { display: block; font-size: var(--fs-
|
|
10
|
+
.bd-pc-n small { display: block; font-size: var(--fs-badge); font-weight: var(--fw-strong); color: var(--cz-ink3); line-height: var(--lh-badge); }
|
|
11
11
|
.bd-pc-n small.late { color: var(--cz-late); }
|
|
12
12
|
.bd-pc-pin { all: unset; flex: none; width: 32px; height: 32px; border-radius: 9px; display: inline-flex; align-items: center; justify-content: center; color: var(--cz-ink3); cursor: pointer; }
|
|
13
13
|
.bd-pc-pin svg { width: 15px; height: 15px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
|