create-pmos 0.511.0 → 0.513.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 (114) hide show
  1. package/package.json +27 -31
  2. package/payload/KIT-VERSION +1 -1
  3. package/payload/planning/evals/eval-calibration.md +1 -1
  4. package/payload/planning/okrs/health-budgets.md +1 -1
  5. package/payload/state/discoveries.md +1 -1
  6. package/workspace/briefing-premium-adddoc-test.js +3 -3
  7. package/workspace/briefing-premium-board-test.js +2 -2
  8. package/workspace/briefing-premium-initiative-test.js +3 -3
  9. package/workspace/briefing-premium-insights-test.js +2 -2
  10. package/workspace/briefing-premium-sources-test.js +4 -5
  11. package/workspace/briefing-premium-test.js +2 -2
  12. package/workspace/changelog.json +26 -0
  13. package/workspace/fixtures/next-prompt-replay.json +40 -0
  14. package/workspace/guide/home.md +1 -1
  15. package/workspace/guide/index.md +1 -0
  16. package/workspace/guide/next-prompt.md +62 -0
  17. package/workspace/guide/settings.md +3 -1
  18. package/workspace/intel-report-ui-test.js +1 -1
  19. package/workspace/intelligence-gaps-ui-test.js +1 -1
  20. package/workspace/lib/next-prompt.js +199 -0
  21. package/workspace/lib/premium-console-type.js +15 -12
  22. package/workspace/lib/route-modules.js +1 -0
  23. package/workspace/lib/routes-next-prompt.js +248 -0
  24. package/workspace/metric-drafts-ui-test.js +2 -2
  25. package/workspace/package-lock.json +2 -2
  26. package/workspace/package.json +1 -1
  27. package/workspace/premium-menu-rows-test.js +1 -1
  28. package/workspace/premium-vw-doc-test.js +1 -1
  29. package/workspace/public/pm/bd-pin-card.css +4 -4
  30. package/workspace/public/pm/bd-publish.css +11 -11
  31. package/workspace/public/pm/bd-shared.css +17 -17
  32. package/workspace/public/pm/c3-capture.css +9 -9
  33. package/workspace/public/pm/c3-initiatives.css +23 -23
  34. package/workspace/public/pm/c3-listen.css +1 -1
  35. package/workspace/public/pm/components.css +572 -572
  36. package/workspace/public/pm/console3.css +374 -373
  37. package/workspace/public/pm/cozy-adler.css +4 -4
  38. package/workspace/public/pm/cozy-aud.css +1 -1
  39. package/workspace/public/pm/cozy-board.css +328 -328
  40. package/workspace/public/pm/cozy-ev.css +80 -78
  41. package/workspace/public/pm/cozy-home-rows.css +32 -32
  42. package/workspace/public/pm/cozy-home.css +285 -241
  43. package/workspace/public/pm/cozy-insights.css +200 -200
  44. package/workspace/public/pm/cozy-live-pill.css +5 -5
  45. package/workspace/public/pm/cozy-mtg-present.css +28 -28
  46. package/workspace/public/pm/cozy-onboard.css +15 -15
  47. package/workspace/public/pm/cozy-panel.css +39 -39
  48. package/workspace/public/pm/cozy-pick.css +5 -5
  49. package/workspace/public/pm/cozy-rec-now.css +23 -23
  50. package/workspace/public/pm/cozy-rec-present.css +11 -11
  51. package/workspace/public/pm/cozy-rec-tab.css +13 -13
  52. package/workspace/public/pm/cozy-settings.js +37 -2
  53. package/workspace/public/pm/cozy-steps.css +14 -14
  54. package/workspace/public/pm/cozy-today.css +95 -95
  55. package/workspace/public/pm/cozy-viewer.css +27 -27
  56. package/workspace/public/pm/cozy-vw-mtg.css +113 -113
  57. package/workspace/public/pm/cozy-vw-rp.css +79 -79
  58. package/workspace/public/pm/cozy-vw-shell.css +43 -43
  59. package/workspace/public/pm/cozy-vw.css +129 -129
  60. package/workspace/public/pm/cozy-xv.css +15 -15
  61. package/workspace/public/pm/cozy.css +53 -21
  62. package/workspace/public/pm/dash-view.css +27 -27
  63. package/workspace/public/pm/hi-pop.css +26 -26
  64. package/workspace/public/pm/home-chat.js +21 -4
  65. package/workspace/public/pm/home-impact.css +8 -8
  66. package/workspace/public/pm/home-ini.css +36 -36
  67. package/workspace/public/pm/home-line.css +7 -7
  68. package/workspace/public/pm/impact.css +9 -9
  69. package/workspace/public/pm/ini-view.css +243 -243
  70. package/workspace/public/pm/load-shapes.css +1 -1
  71. package/workspace/public/pm/loose-props.css +14 -14
  72. package/workspace/public/pm/metric-drafts.css +20 -20
  73. package/workspace/public/pm/ms-suggest.css +9 -9
  74. package/workspace/public/pm/next-prompt-ui.js +117 -0
  75. package/workspace/public/pm/ov-view.css +14 -14
  76. package/workspace/public/pm/premium-insights.js +3 -3
  77. package/workspace/public/pm/premium-report-frame.css +1 -1
  78. package/workspace/public/pm/premium-report-intel.css +17 -17
  79. package/workspace/public/pm/premium-report-print.css +1 -1
  80. package/workspace/public/pm/premium-vw-backlog.css +13 -13
  81. package/workspace/public/pm/premium-vw-cal.css +32 -32
  82. package/workspace/public/pm/premium-vw-copy.css +7 -7
  83. package/workspace/public/pm/premium-vw-doc.css +69 -69
  84. package/workspace/public/pm/premium-vw-item.css +12 -12
  85. package/workspace/public/pm/premium-vw-jira.css +39 -39
  86. package/workspace/public/pm/premium-vw-meet.css +28 -28
  87. package/workspace/public/pm/premium-vw-notepad.css +13 -13
  88. package/workspace/public/pm/premium-vw-notes.css +11 -11
  89. package/workspace/public/pm/premium-vw-rec.css +27 -27
  90. package/workspace/public/pm/premium-vw-report.css +21 -21
  91. package/workspace/public/pm/premium-vw-slides.css +28 -28
  92. package/workspace/public/pm/premium.css +618 -618
  93. package/workspace/public/pm/prog-order.css +6 -6
  94. package/workspace/public/pm/prog-page.css +17 -17
  95. package/workspace/public/pm/program-charter.css +33 -33
  96. package/workspace/public/pm/ready-lib.css +6 -6
  97. package/workspace/public/pm/sort-order.css +1 -1
  98. package/workspace/public/pm/split-merge.css +18 -18
  99. package/workspace/public/pm/task-card.css +24 -24
  100. package/workspace/public/pm/tk-tasks.css +42 -42
  101. package/workspace/public/pm/tk-view.css +6 -6
  102. package/workspace/public/pm/wf-page.css +31 -31
  103. package/workspace/public/premium-aud.html +1 -1
  104. package/workspace/public/premium-board.html +1 -1
  105. package/workspace/public/premium-intelligence.html +1 -1
  106. package/workspace/public/premium-rec.html +1 -1
  107. package/workspace/public/premium-viewer.html +1 -1
  108. package/workspace/public/premium-workflows.html +1 -1
  109. package/workspace/public/premium.html +1 -1
  110. package/workspace/public/vendor/plus-jakarta-sans-var.woff2 +0 -0
  111. package/workspace/server.js +1 -0
  112. package/workspace/test-lists/next-prompt.json +5 -0
  113. package/workspace/third-party/README.md +2 -1
  114. package/workspace/third-party/plus-jakarta-sans-OFL.LICENSE +93 -0
@@ -36,7 +36,7 @@
36
36
  .ls-bd .ls-trk i { position: relative; width: 7px; height: 7px; background: var(--cz-well2); }
37
37
  .ls-bd .ls-trk i.ls-tdot { border-radius: 50%; }
38
38
  .ls-bd .ls-trk i.on { width: 12px; height: 12px; }
39
- .ls-slow { margin: 10px 14px 4px; font-size: var(--fs-2); font-weight: 700; color: var(--cz-ink3); }
39
+ .ls-slow { margin: 10px 14px 4px; font-size: var(--fs-label); font-weight: var(--fw-strong); color: var(--cz-ink3); line-height: var(--lh-label); }
40
40
  @media (max-width: 760px) {
41
41
  .ls-bd .ls-bh, .ls-bd .ls-br { grid-template-columns: 1fr; gap: 6px; }
42
42
  .ls-bd .ls-bh .ls-stg, .ls-bd .ls-br .ls-trk, .ls-bd .ls-br > .ls-sk:last-child { display: none; }
@@ -3,19 +3,19 @@
3
3
  .hv-lhw { position: relative; }
4
4
  .hv-lhw.has-chip .hv-lh .nl { margin-right: 64px; }
5
5
  .hv-lhw.has-chip .hv-lh .nl:empty { margin-right: 58px; }
6
- .lp-chip { position: absolute; right: 34px; top: calc(50% + 6px); transform: translateY(-50%); display: inline-flex; align-items: center; gap: 3px; height: 26px; padding: 0 9px 0 7px; border-radius: 999px; border: 1.5px solid var(--cz-blue); background: var(--cz-card); color: var(--cz-blueink); font: inherit; font-size: var(--fs-2); font-weight: 800; cursor: pointer; }
6
+ .lp-chip { position: absolute; right: 34px; top: calc(50% + 6px); transform: translateY(-50%); display: inline-flex; align-items: center; gap: 3px; height: 26px; padding: 0 9px 0 7px; border-radius: 999px; border: 1.5px solid var(--cz-blue); background: var(--cz-card); color: var(--cz-blueink); font: inherit; font-size: var(--fs-label); font-weight: var(--fw-strong); cursor: pointer; line-height: var(--lh-label); }
7
7
  .lp-chip:focus-visible { outline: 2px solid var(--cz-blue); outline-offset: 2px; }
8
8
  @media (hover: hover) { .lp-chip:hover { background: var(--cz-bluebg); } }
9
9
  @media (max-width: 760px) { .lp-chip { height: 32px; } .lp-chip::after { content: ''; position: absolute; inset: -6px; } }
10
10
 
11
11
  .lp { display: flex; flex-direction: column; gap: 10px; padding: 0 16px 24px; }
12
- .lp-intro { margin: 2px 0 4px; font-size: var(--fs-2); line-height: 1.5; color: var(--cz-ink2); max-width: 600px; }
13
- .lp-sec h4 { margin: 8px 0 2px; font-size: var(--fs-2); font-weight: 700; color: var(--cz-ink3); }
12
+ .lp-intro { margin: 2px 0 4px; font-size: var(--fs-meta); line-height: 1.5; color: var(--cz-ink2); max-width: 600px; }
13
+ .lp-sec h4 { margin: 8px 0 2px; font-size: var(--fs-label); font-weight: var(--fw-strong); color: var(--cz-ink3); line-height: var(--lh-label); }
14
14
  .lp-p { padding: 4px 0; }
15
15
  .lp-ph { display: flex; align-items: flex-start; gap: 8px; padding: 6px 0; }
16
16
  .lp-ph .w, .lp-r .w, .lp-hr .w { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
17
- .lp-ph b { font-size: var(--fs-3); font-weight: 800; color: var(--cz-ink); }
18
- .lp-ph small, .lp-r small, .lp-hr small { font-size: var(--fs-2); color: var(--cz-ink2); line-height: 1.4; display: inline-flex; align-items: center; gap: 4px; }
17
+ .lp-ph b { font-size: var(--fs-row); font-weight: var(--fw-strong); color: var(--cz-ink); line-height: var(--lh-row); }
18
+ .lp-ph small, .lp-r small, .lp-hr small { font-size: var(--fs-meta); color: var(--cz-ink2); line-height: 1.4; display: inline-flex; align-items: center; gap: 4px; }
19
19
  .lp-ic { width: 24px; height: 24px; display: inline-flex; align-items: center; justify-content: center; color: var(--cz-blueink); flex: none; margin-top: 1px; }
20
20
  .lp-ib { all: unset; box-sizing: border-box; cursor: pointer; width: 32px; height: 32px; border-radius: 999px; display: inline-flex; align-items: center; justify-content: center; color: var(--cz-ink2); flex: none; }
21
21
  .lp-ib.ok { color: var(--cz-blueink); }
@@ -24,31 +24,31 @@
24
24
  @media (hover: hover) { .lp-ib:hover { background: var(--cz-well); color: var(--cz-ink); } }
25
25
  .lp-rows { display: flex; flex-direction: column; margin: 2px 0 6px 12px; padding-left: 22px; border-left: 2px solid var(--cz-hair); }
26
26
  .lp-r { display: flex; align-items: center; gap: 8px; min-height: 44px; padding: 3px 0; }
27
- .lp-r b { font-size: var(--fs-3); font-weight: 600; color: var(--cz-ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
27
+ .lp-r b { font-size: var(--fs-row); font-weight: var(--fw-strong); color: var(--cz-ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; line-height: var(--lh-row); }
28
28
  .lp-r.out b { text-decoration: line-through; color: var(--cz-ink3); }
29
29
  .lp-mk { width: 16px; flex: none; display: inline-flex; align-items: center; justify-content: center; color: var(--cz-ink3); margin-left: -4px; }
30
30
  .lp-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--cz-blue); display: inline-block; }
31
31
  .lp-late { width: 9px; height: 9px; border-radius: 2px; background: var(--cz-risk); display: inline-block; }
32
32
  .lp-tile { all: unset; box-sizing: border-box; cursor: pointer; display: inline-flex; align-items: center; gap: 2px; height: 28px; padding: 0 6px 0 8px; border-radius: 999px; background: var(--cz-well); color: var(--cz-blueink); flex: none; }
33
- .lp-tile b { font-size: var(--fs-1); font-weight: 800; letter-spacing: .02em; }
33
+ .lp-tile b { font-size: var(--fs-badge); font-weight: var(--fw-strong); letter-spacing: .02em; line-height: var(--lh-badge); }
34
34
  .lp-tile.on { box-shadow: 0 0 0 1.5px var(--cz-blue); background: var(--cz-card); }
35
35
  .lp-tile.moved { background: var(--cz-bluebg); }
36
- .lp-more { all: unset; box-sizing: border-box; cursor: pointer; min-height: 36px; padding: 6px 0; font-size: var(--fs-2); font-weight: 700; color: var(--cz-blueink); }
36
+ .lp-more { all: unset; box-sizing: border-box; cursor: pointer; min-height: 36px; padding: 6px 0; font-size: var(--fs-label); font-weight: var(--fw-strong); color: var(--cz-blueink); line-height: var(--lh-label); }
37
37
  .lp-pick { align-self: flex-end; margin: 0 0 6px; width: min(330px, 100%); background: var(--cz-card); border-radius: 18px; box-shadow: 0 24px 60px -24px rgba(42,46,53,.45), 0 0 0 1px var(--cz-hair); padding: 6px; display: flex; flex-direction: column; }
38
- .lp-pick p { margin: 8px 10px 4px; font-size: var(--fs-2); font-weight: 700; color: var(--cz-ink3); }
39
- .lp-pick button { all: unset; box-sizing: border-box; cursor: pointer; min-height: 44px; padding: 6px 10px; border-radius: 12px; display: flex; align-items: center; gap: 10px; font-size: var(--fs-3); font-weight: 700; color: var(--cz-ink); }
38
+ .lp-pick p { margin: 8px 10px 4px; font-size: var(--fs-label); font-weight: var(--fw-strong); color: var(--cz-ink3); line-height: var(--lh-label); }
39
+ .lp-pick button { all: unset; box-sizing: border-box; cursor: pointer; min-height: 44px; padding: 6px 10px; border-radius: 12px; display: flex; align-items: center; gap: 10px; font-size: var(--fs-row); font-weight: var(--fw-strong); color: var(--cz-ink); line-height: var(--lh-row); }
40
40
  .lp-pick button .t { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
41
41
  .lp-pick button[aria-checked="true"] { background: var(--cz-well); }
42
42
  .lp-pick button[aria-checked="true"] svg { color: var(--cz-blueink); }
43
- .lp-pick button.nw { color: var(--cz-ink2); font-weight: 600; }
43
+ .lp-pick button.nw { color: var(--cz-ink2); font-weight: var(--fw-strong); }
44
44
  @media (hover: hover) { .lp-pick button:hover { background: var(--cz-well); } }
45
- .lp-tl { width: 26px; height: 26px; border-radius: 8px; background: var(--cz-bluebg); color: var(--cz-blueink); display: inline-flex; align-items: center; justify-content: center; font-size: var(--fs-1); font-weight: 800; flex: none; }
45
+ .lp-tl { width: 26px; height: 26px; border-radius: 8px; background: var(--cz-bluebg); color: var(--cz-blueink); display: inline-flex; align-items: center; justify-content: center; font-size: var(--fs-badge); font-weight: var(--fw-strong); flex: none; line-height: var(--lh-badge); }
46
46
  .lp-pick .nw .lp-tl { background: none; color: var(--cz-ink3); }
47
47
  .lp-hist { margin-top: 8px; border-top: 1px solid var(--cz-hair); padding-top: 6px; }
48
- .lp-hist summary { cursor: pointer; min-height: 40px; display: flex; align-items: center; font-size: var(--fs-2); font-weight: 700; color: var(--cz-ink3); list-style: none; }
48
+ .lp-hist summary { cursor: pointer; min-height: 40px; display: flex; align-items: center; font-size: var(--fs-label); font-weight: var(--fw-strong); color: var(--cz-ink3); list-style: none; line-height: var(--lh-label); }
49
49
  .lp-hist summary::-webkit-details-marker { display: none; }
50
50
  .lp-hist summary:focus-visible { outline: 2px solid var(--cz-blue); outline-offset: 1px; border-radius: 8px; }
51
51
  .lp-hr { display: flex; align-items: center; gap: 8px; min-height: 44px; }
52
- .lp-hr b { font-size: var(--fs-3); font-weight: 700; color: var(--cz-ink); }
52
+ .lp-hr b { font-size: var(--fs-row); font-weight: var(--fw-strong); color: var(--cz-ink); line-height: var(--lh-row); }
53
53
  .lp-hr.undone b { color: var(--cz-ink3); }
54
54
  @media (max-width: 760px) { .lp { padding: 0 12px 24px; } .lp-ib { width: 40px; height: 40px; } .lp-rows { margin-left: 4px; padding-left: 12px; } }
@@ -6,38 +6,38 @@
6
6
  /* the proposal: a dashed card, Claude's blue */
7
7
  .md-card { border: 1px dashed color-mix(in srgb, var(--cz-blueink) 45%, transparent); border-radius: 16px; padding: 12px 14px; display: flex; flex-direction: column; gap: 10px;
8
8
  background: linear-gradient(100deg, var(--cz-bluebg) 0%, var(--cz-card) 60%); color: var(--cz-ink); }
9
- .md-hd { display: flex; align-items: center; gap: 8px; font-size: var(--fs-3); color: var(--cz-blueink); min-width: 0; }
10
- .md-hd b { font-weight: 800; white-space: nowrap; }
9
+ .md-hd { display: flex; align-items: center; gap: 8px; font-size: var(--fs-body); color: var(--cz-blueink); min-width: 0; line-height: var(--lh-body); }
10
+ .md-hd b { font-weight: var(--fw-strong); white-space: nowrap; }
11
11
  .md-sp { display: inline-flex; flex: none; }
12
- .md-src { margin-left: auto; font-size: var(--fs-2); font-weight: 600; color: var(--cz-ink3); min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
13
- .md-gl { margin: 0; font-size: var(--fs-4); font-weight: 800; line-height: 1.35; }
12
+ .md-src { margin-left: auto; font-size: var(--fs-label); font-weight: var(--fw-strong); color: var(--cz-ink3); min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; line-height: var(--lh-label); }
13
+ .md-gl { margin: 0; font-size: var(--fs-row); font-weight: var(--fw-strong); line-height: 1.35; }
14
14
  .md-cps { display: flex; flex-wrap: wrap; gap: 6px; }
15
- .md-cp { display: inline-flex; align-items: center; gap: 6px; font-size: var(--fs-2); font-weight: 700; color: var(--cz-ink2); background: var(--cz-card); border: 1px solid var(--cz-hair); border-radius: 999px; padding: 3px 10px; }
15
+ .md-cp { display: inline-flex; align-items: center; gap: 6px; font-size: var(--fs-label); font-weight: var(--fw-strong); color: var(--cz-ink2); background: var(--cz-card); border: 1px solid var(--cz-hair); border-radius: 999px; padding: 3px 10px; line-height: var(--lh-label); }
16
16
  .md-dm { width: 9px; height: 9px; transform: rotate(45deg); border-radius: 3px; border: 2px solid var(--pp-prog, var(--cz-ink3)); box-sizing: border-box; flex: none; }
17
- .md-pill { display: inline-flex; align-items: center; max-width: 100%; font-size: var(--fs-1); font-weight: 800; border-radius: 999px; padding: 2px 8px; white-space: nowrap; background: var(--cz-riskbg); color: var(--cz-risk); }
17
+ .md-pill { display: inline-flex; align-items: center; max-width: 100%; font-size: var(--fs-badge); font-weight: var(--fw-strong); border-radius: 999px; padding: 2px 8px; white-space: nowrap; background: var(--cz-riskbg); color: var(--cz-risk); line-height: var(--lh-badge); }
18
18
 
19
19
  /* Built from: Now and Target */
20
20
  .md-bt { display: flex; flex-direction: column; }
21
- .md-ru { display: grid; grid-template-columns: minmax(0, 1fr) 64px minmax(0, 150px); gap: 10px; align-items: center; font-size: var(--fs-3); padding: 7px 0; border-top: 1px solid var(--cz-hair); }
22
- .md-ru.q { border-top: 0; padding-top: 0; font-size: var(--fs-2); color: var(--cz-ink3); }
23
- .md-ru.q span:first-child { font-weight: 800; }
24
- .md-ru b { font-weight: 800; }
21
+ .md-ru { display: grid; grid-template-columns: minmax(0, 1fr) 64px minmax(0, 150px); gap: 10px; align-items: center; font-size: var(--fs-body); padding: 7px 0; border-top: 1px solid var(--cz-hair); line-height: var(--lh-body); }
22
+ .md-ru.q { border-top: 0; padding-top: 0; font-size: var(--fs-meta); color: var(--cz-ink3); line-height: var(--lh-meta); }
23
+ .md-ru.q span:first-child { font-weight: var(--fw-strong); }
24
+ .md-ru b { font-weight: var(--fw-strong); }
25
25
  .md-ru .md-pill { white-space: normal; }
26
26
 
27
27
  /* the success measure's rows: what it is, Now, Target */
28
28
  .md-ms { display: flex; flex-direction: column; }
29
- .md-mr { display: grid; grid-template-columns: minmax(0, 1fr) 56px minmax(0, 110px); gap: 10px; align-items: center; padding: 8px 0; border-top: 1px solid var(--cz-hair); font-size: var(--fs-3); }
29
+ .md-mr { display: grid; grid-template-columns: minmax(0, 1fr) 56px minmax(0, 110px); gap: 10px; align-items: center; padding: 8px 0; border-top: 1px solid var(--cz-hair); font-size: var(--fs-body); line-height: var(--lh-body); }
30
30
  .md-mr:first-child { border-top: 0; padding-top: 0; }
31
31
  .md-nm { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
32
- .md-nm b { font-weight: 800; }
33
- .md-nm small { font-size: var(--fs-2); color: var(--cz-ink3); }
34
- .md-role { font-size: var(--fs-1); font-weight: 800; color: var(--cz-ink3); }
32
+ .md-nm b { font-weight: var(--fw-strong); }
33
+ .md-nm small { font-size: var(--fs-meta); color: var(--cz-ink3); line-height: var(--lh-meta); }
34
+ .md-role { font-size: var(--fs-badge); font-weight: var(--fw-strong); color: var(--cz-ink3); line-height: var(--lh-badge); }
35
35
  .md-now { color: var(--cz-ink2); }
36
- .md-to { font-weight: 800; }
36
+ .md-to { font-weight: var(--fw-strong); }
37
37
 
38
38
  /* the why and the presses */
39
39
  .md-ft { display: flex; align-items: center; gap: 6px; }
40
- .md-why { flex: 1; min-width: 0; margin: 0; font-size: var(--fs-2); line-height: 1.45; color: var(--cz-ink3); }
40
+ .md-why { flex: 1; min-width: 0; margin: 0; font-size: var(--fs-meta); line-height: 1.45; color: var(--cz-ink3); }
41
41
  .md-why:empty { visibility: hidden; }
42
42
  .md-ib { all: unset; box-sizing: border-box; cursor: pointer; width: 36px; height: 36px; border-radius: 999px; display: inline-flex; align-items: center; justify-content: center; color: var(--cz-ink2); flex: none; }
43
43
  .md-ib.solid { background: var(--cz-ink); color: var(--cz-card); }
@@ -54,13 +54,13 @@
54
54
  .md-kept-i { display: flex; align-items: flex-start; gap: 6px; }
55
55
  .md-kept-i .md-folds { flex: 1; min-width: 0; }
56
56
  .md-kept-i > .md-ib { margin-top: 6px; }
57
- .md-ok { display: inline-flex; align-items: center; font-size: var(--fs-1); font-weight: 800; border-radius: 999px; padding: 2px 8px; white-space: nowrap; background: var(--cz-okbg); color: var(--cz-ok); }
57
+ .md-ok { display: inline-flex; align-items: center; font-size: var(--fs-badge); font-weight: var(--fw-strong); border-radius: 999px; padding: 2px 8px; white-space: nowrap; background: var(--cz-okbg); color: var(--cz-ok); line-height: var(--lh-badge); }
58
58
  .md-list { display: flex; flex-direction: column; gap: 2px; }
59
59
  .md-lr { display: flex; align-items: flex-start; gap: 10px; padding: 6px 0; }
60
60
  .md-mk { width: 8px; height: 8px; border-radius: 50%; background: var(--cz-dot-ok); flex: none; margin-top: 6px; }
61
61
  .md-w { display: flex; flex-direction: column; min-width: 0; }
62
- .md-w b { font-size: var(--fs-3); font-weight: 800; }
63
- .md-w span { font-size: var(--fs-2); color: var(--cz-ink3); }
62
+ .md-w b { font-size: var(--fs-row); font-weight: var(--fw-strong); line-height: var(--lh-row); }
63
+ .md-w span { font-size: var(--fs-meta); color: var(--cz-ink3); line-height: var(--lh-meta); }
64
64
 
65
65
  /* the wide Viewer (.cz-vw-w2): the part first in the panel sits above the summary, in its column */
66
66
  .cz-vw-w2 .cz-vw-body > .md-top { grid-column: 1; max-width: none; }
@@ -94,5 +94,5 @@
94
94
  .md-ed { display: flex; flex-direction: column; gap: 10px; }
95
95
  .md-er { display: flex; flex-direction: column; gap: 4px; }
96
96
  .md-ef { display: grid; grid-template-columns: minmax(0, 110px) minmax(0, 1fr); gap: 6px; align-items: center; }
97
- .md-fld { box-sizing: border-box; width: 100%; min-width: 0; height: 32px; border: 1px solid var(--cz-hair); border-radius: 10px; padding: 0 9px; font: inherit; font-size: var(--fs-3); font-weight: 700; background: var(--cz-card); color: var(--cz-ink); }
97
+ .md-fld { box-sizing: border-box; width: 100%; min-width: 0; height: 32px; border: 1px solid var(--cz-hair); border-radius: 10px; padding: 0 9px; font: inherit; font-size: var(--fs-row); font-weight: var(--fw-strong); background: var(--cz-card); color: var(--cz-ink); line-height: var(--lh-row); }
98
98
  .md-fld:focus { outline: 2px solid color-mix(in srgb, var(--cz-blueink) 45%, transparent); outline-offset: 0; border-color: var(--cz-blueink); }
@@ -3,9 +3,9 @@
3
3
  * Quiet: no motion. Every class starts with msg-. */
4
4
  .msg-box, .msg-list { --msg-prog: var(--pp-prog, var(--cz-c-6b4fa3)); --msg-progbg: var(--pp-progbg, rgba(107,79,163,.10)); }
5
5
  .msg-box { border: 1px dashed color-mix(in srgb, var(--msg-prog) 45%, transparent); border-radius: 16px; overflow: hidden; }
6
- .msg-hd { display: flex; align-items: center; gap: 8px; padding: 8px 8px 8px 12px; background: var(--msg-progbg); font-size: var(--fs-2); color: var(--cz-ink2); }
6
+ .msg-hd { display: flex; align-items: center; gap: 8px; padding: 8px 8px 8px 12px; background: var(--msg-progbg); font-size: var(--fs-meta); color: var(--cz-ink2); line-height: var(--lh-meta); }
7
7
  .msg-ht { flex: 1; min-width: 0; }
8
- .msg-ht b { color: var(--msg-prog); font-weight: 700; }
8
+ .msg-ht b { color: var(--msg-prog); font-weight: var(--fw-strong); }
9
9
  .msg-list { display: flex; flex-direction: column; }
10
10
  .msg-r { display: flex; align-items: flex-start; gap: 10px; padding: 10px 8px 10px 12px; }
11
11
  .msg-box .msg-r + .msg-r, .msg-box .msg-hd + div .msg-r:first-child { border-top: 1px dashed color-mix(in srgb, var(--msg-prog) 25%, transparent); }
@@ -13,10 +13,10 @@
13
13
  .msg-mk { color: var(--msg-prog); display: inline-flex; flex: none; padding-top: 2px; }
14
14
  .msg-t { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px; align-items: flex-start; }
15
15
  .msg-h { display: flex; gap: 8px; align-items: baseline; width: 100%; }
16
- .msg-h b { font-size: var(--fs-3); font-weight: 700; color: var(--cz-ink); flex: 1; min-width: 0; }
17
- .msg-d { font-size: var(--fs-2); font-weight: 700; color: var(--cz-ink2); white-space: nowrap; }
18
- .msg-w { font-size: var(--fs-2); color: var(--cz-ink3); line-height: 1.4; }
19
- .msg-src { display: inline-flex; align-items: center; gap: 5px; font-size: var(--fs-1); font-weight: 600; color: var(--cz-ink2); background: var(--cz-well); border-radius: 999px; padding: 2px 8px; }
16
+ .msg-h b { font-size: var(--fs-row); font-weight: var(--fw-strong); color: var(--cz-ink); flex: 1; min-width: 0; line-height: var(--lh-row); }
17
+ .msg-d { font-size: var(--fs-label); font-weight: var(--fw-strong); color: var(--cz-ink2); white-space: nowrap; line-height: var(--lh-label); }
18
+ .msg-w { font-size: var(--fs-meta); color: var(--cz-ink3); line-height: 1.4; }
19
+ .msg-src { display: inline-flex; align-items: center; gap: 5px; font-size: var(--fs-badge); font-weight: var(--fw-strong); color: var(--cz-ink2); background: var(--cz-well); border-radius: 999px; padding: 2px 8px; line-height: var(--lh-badge); }
20
20
  .msg-src svg { color: var(--cz-ink3); }
21
21
  .msg-gd { width: 7px; height: 7px; transform: rotate(45deg); border-radius: 2px; background: var(--msg-prog); display: inline-block; }
22
22
  .msg-ends { display: inline-flex; align-items: center; gap: 2px; flex: none; }
@@ -32,18 +32,18 @@
32
32
  .pp-needs .msg-list { background: var(--cz-card); border-radius: 12px; margin-bottom: 4px; }
33
33
 
34
34
  /* the charter: last checked and Check now (XmsgB, last frame), and the change filled in from the pencil */
35
- .msg-chk { display: flex; align-items: center; gap: 8px; font-size: var(--fs-2); color: var(--cz-ink3); }
35
+ .msg-chk { display: flex; align-items: center; gap: 8px; font-size: var(--fs-meta); color: var(--cz-ink3); line-height: var(--lh-meta); }
36
36
  .msg-chk span { flex: 1; min-width: 0; }
37
37
  .msg-chk .msg-ib { width: 28px; height: 28px; }
38
38
  .msg-chk .msg-ib.on svg { animation: msg-spin 1.2s linear infinite; }
39
39
  @keyframes msg-spin { to { transform: rotate(360deg); } }
40
40
  @media (prefers-reduced-motion: reduce) { .msg-chk .msg-ib.on svg { animation: none; } }
41
- .msg-risk { display: flex; align-items: center; gap: 6px; font-size: var(--fs-2); color: var(--cz-risk); }
41
+ .msg-risk { display: flex; align-items: center; gap: 6px; font-size: var(--fs-meta); color: var(--cz-risk); line-height: var(--lh-meta); }
42
42
  .msg-risk span { flex: 1; min-width: 0; }
43
43
  .msg-risk { margin: 4px 0 0 30px; }
44
44
  .msg-risk i { width: 7px; height: 7px; border-radius: 50%; background: var(--pc-amberdot, var(--cz-risk)); flex: none; }
45
45
  .msg-risk .pc-ib { width: 28px; height: 28px; }
46
- .msg-chg { display: flex; align-items: flex-start; gap: 6px; margin: 4px 0 0 30px; font-size: var(--fs-2); color: var(--cz-ink2); }
46
+ .msg-chg { display: flex; align-items: flex-start; gap: 6px; margin: 4px 0 0 30px; font-size: var(--fs-meta); color: var(--cz-ink2); line-height: var(--lh-meta); }
47
47
  .msg-chg svg { color: var(--pp-prog, var(--cz-c-6b4fa3)); flex: none; margin-top: 1px; }
48
48
  .pc-lnw.msg-on > .pc-ln { border: 1px dashed color-mix(in srgb, var(--pp-prog, var(--cz-c-6b4fa3)) 45%, transparent); border-radius: 14px; }
49
49
  .pc-ms > .msg-chg { margin: 0 0 8px; }
@@ -0,0 +1,117 @@
1
+ /* pm/next-prompt-ui.js — the chat's suggested next prompt and its Sharper card (batch 26 item 2, design B: canvas NpB, NpBw).
2
+ *
3
+ * After a reply ends: up to two cards above the box, the one Claude recommends lit (white, blue ring, blue ✦), the other grey. A tap puts its
4
+ * text in the box; nothing sends, and the PM sends with the box's own ↑. No ↵, edit or dismiss icon. No card when there is no clear next step.
5
+ * The cards hide when the PM types or a new reply starts; they have no timeout.
6
+ * While the PM types a rough prompt (3 or more words), after a 1.5 s pause: a spinner card while Claude sharpens it, then one lit Sharper card.
7
+ * Its sliders icon opens the style menu: Sharpen as Polish, Prompt engineer (the default) or Your own, and the Sharpen as I type switch.
8
+ * After a tap on the Sharper card, ↶ in the box puts back what the PM wrote (NpB 5).
9
+ * Server: GET /api/next-prompt/prefs, POST /api/next-prompt/next and /sharpen (lib/routes-next-prompt.js, through lib/ai-guard.js); the style
10
+ * and the switch are saved with POST /api/next-prompt/prefs (style, sharpen). Settings › Claude › Sharpen prompts holds the same.
11
+ *
12
+ * nextPromptUi({ el, host, box, redrawFoot }) → { turnEnded(ctx), read(busy), input(value), sent(), open(), undoHtml(), click(target) → bool }
13
+ * ctx: { key, asked, reply, initiative?, stage?, title? } box() → the textarea redrawFoot() draws the box again (for ↶) */
14
+ const STAR = '<svg aria-hidden="true" width="15" height="15" viewBox="0 0 24 24" class="np-star"><path d="M12 3l1.8 5.2L19 10l-5.2 1.8L12 17l-1.8-5.2L5 10l5.2-1.8z"/></svg>';
15
+ const SLIDERS = 'M4 7h9M17 7h3M4 17h3M11 17h9M13 4v6M7 14v6', CHECK = 'M5 12l5 5L20 7', UNDO = 'M9 14L4 9l5-5M4 9h11a5 5 0 0 1 0 10h-3', SPIN = 'M12 3a9 9 0 1 1-9 9';
16
+ const ic = (d, w = 16) => `<svg aria-hidden="true" width="${w}" height="${w}" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><path d="${d}"/></svg>`;
17
+ const STYLES = [['polish', 'Polish', 'Clearer and shorter, your meaning kept'], ['engineer', 'Prompt engineer', 'Builds the best prompt for the job'], ['own', 'Your own', 'Your wording rules, written once in Settings']];
18
+ const PAUSE = 1500;
19
+ export const roughText = (t) => { const s = String(t || '').trim(); return !s.startsWith('/') && s.length >= 12 && s.split(/\s+/).filter(Boolean).length >= 3; };
20
+
21
+ export function nextPromptUi({ el, host, box, redrawFoot }) {
22
+ const esc = host.esc;
23
+ const N = { mode: null, cards: [], sharp: null, menu: false, prefs: null, seq: 0, timer: null, ctx: null, orig: null, filled: null, sent: null };
24
+ const wrap = document.createElement('div');
25
+ wrap.className = 'np'; wrap.id = 'hmNp'; wrap.hidden = true;
26
+ const foot = el.querySelector('#hmFoot');
27
+ foot.parentNode.insertBefore(wrap, foot);
28
+
29
+ const loadPrefs = () => host.pmGet('/api/next-prompt/prefs').then((r) => { if (r && r.ok) { N.prefs = r; if (!r.sharpen && N.mode !== 'cards') clear(); else draw(); } }).catch(() => {});
30
+ loadPrefs();
31
+ document.addEventListener('pmos:prompt-prefs', loadPrefs); // Settings › Claude changed them
32
+
33
+ function clear() { N.seq++; clearTimeout(N.timer); N.mode = null; N.cards = []; N.sharp = null; N.menu = false; draw(); }
34
+ function draw() {
35
+ let html = '';
36
+ if (N.mode === 'cards' && N.cards.length) {
37
+ html = `<div class="np-list" role="group" aria-label="Suggested next prompts">${N.cards.map((c, i) => `<button type="button" class="np-card${c.rec ? ' rec' : ''}" data-np-use="${i}" aria-label="Use this prompt: ${esc(c.text)}"${c.rec ? ' title="Claude recommends this one"' : ''}>${STAR}<span class="np-t">${esc(c.text)}</span></button>`).join('')}</div>`;
38
+ } else if (N.mode === 'spin') {
39
+ html = `<div class="np-spin" role="status" aria-label="Claude is sharpening your prompt"><span class="np-sp">${ic(SPIN, 20)}</span><span class="np-sk"><i></i><i></i></span></div>`;
40
+ } else if (N.mode === 'sharp' && N.sharp) {
41
+ const P = N.prefs || {}, st = P.style || 'engineer';
42
+ const menu = N.menu ? `<div class="np-menu" role="menu" aria-label="Style of sharper prompts" data-esc-layer><p class="np-mh">Sharpen as</p>${STYLES.map(([k, l, d]) => `<button type="button" role="menuitemradio" aria-checked="${st === k}" class="np-mi" data-np-voice="${k}"><span class="np-ck">${st === k ? ic(CHECK) : ''}</span><span><b>${esc(l)}</b><em>${esc(k === 'own' && !P.rules ? 'Write your rules in Settings first' : d)}</em></span></button>`).join('')}`
43
+ + `<span class="np-sep" role="separator"></span><button type="button" role="menuitemcheckbox" class="np-mi np-swr" aria-checked="${!!P.sharpen}" data-np-sw><b>Sharpen as I type</b><span class="np-sw${P.sharpen ? ' on' : ''}" aria-hidden="true"><i></i></span></button></div>` : '';
44
+ html = `<div class="np-card rec np-sh"><button type="button" class="np-use" data-np-sharp aria-label="Use the sharper prompt: ${esc(N.sharp)}" title="Claude sharpened your prompt">${STAR}<span class="np-t">${esc(N.sharp)}</span></button>`
45
+ + `<button type="button" class="np-ib" data-np-menu aria-haspopup="menu" aria-expanded="${N.menu}" aria-label="Style of sharper prompts" title="Style of sharper prompts">${ic(SLIDERS)}</button>${menu}</div>`;
46
+ }
47
+ if (wrap.__h !== html) { wrap.__h = html; wrap.innerHTML = html; }
48
+ wrap.hidden = !html;
49
+ }
50
+ function fill(text, keepOrig) {
51
+ const ta = box(); if (!ta) return;
52
+ N.orig = keepOrig && ta.value.trim() && ta.value !== text ? ta.value : null;
53
+ N.filled = text; ta.value = text;
54
+ clear(); redrawFoot();
55
+ const t2 = box(); if (t2) { t2.dispatchEvent(new Event('np-grow')); t2.focus(); t2.setSelectionRange(t2.value.length, t2.value.length); }
56
+ }
57
+ async function sharpen(value) {
58
+ const my = ++N.seq;
59
+ N.mode = 'spin'; N.sharp = null; draw();
60
+ const c = N.ctx || {};
61
+ const r = await host.pmPost('/api/next-prompt/sharpen', { key: c.key || '', text: value, reply: c.reply || '', initiative: c.initiative || '', title: c.title || '' }).catch(() => null);
62
+ const ta = box();
63
+ if (my !== N.seq || !ta || ta.value !== value) return; // the PM typed on, or sent: this answer is for words no longer in the box
64
+ if (r && r.ok && r.text) { N.mode = 'sharp'; N.sharp = r.text; } else { N.mode = null; }
65
+ draw();
66
+ }
67
+ async function save(key, value) {
68
+ const r = await host.pmPost('/api/next-prompt/prefs', { key, value }).catch(() => null);
69
+ if (!(r && r.ok)) { host.toast((r && r.error) || 'Not saved.'); return; }
70
+ await loadPrefs();
71
+ document.dispatchEvent(new CustomEvent('pmos:prompt-prefs-saved', { detail: { key, value } }));
72
+ }
73
+
74
+ return {
75
+ /** A reply ended: ask for the next prompts, unless the PM is already typing. */
76
+ async turnEnded(ctx) {
77
+ N.ctx = ctx;
78
+ const ta = box();
79
+ if (!N.prefs || !N.prefs.next || !ctx || !ctx.reply || (ta && ta.value.trim())) return;
80
+ const my = ++N.seq; clearTimeout(N.timer);
81
+ const r = await host.pmPost('/api/next-prompt/next', ctx).catch(() => null);
82
+ const t2 = box();
83
+ if (my !== N.seq || (t2 && t2.value.trim())) return;
84
+ N.cards = r && r.ok && Array.isArray(r.cards) ? r.cards.slice(0, 2) : [];
85
+ N.mode = N.cards.length ? 'cards' : null; N.menu = false; draw();
86
+ },
87
+ /** Each read of the conversation: a new turn at work hides the cards. */
88
+ read(busy, ctx) { if (ctx) N.ctx = { ...(N.ctx || {}), ...ctx }; if (busy && N.mode) clear(); },
89
+ input(value) {
90
+ if (N.orig != null && !value.trim()) { N.orig = null; redrawFoot(); }
91
+ if (N.mode === 'cards' || N.mode === 'sharp' || N.mode === 'spin') { N.seq++; N.mode = null; N.menu = false; draw(); }
92
+ clearTimeout(N.timer);
93
+ if (!N.prefs || !N.prefs.sharpen || value === N.filled || !roughText(value)) return;
94
+ N.timer = setTimeout(() => { const ta = box(); if (ta && ta.value === value) sharpen(value); }, PAUSE);
95
+ },
96
+ sent() { N.orig = null; N.filled = null; clear(); },
97
+ open() { N.ctx = null; N.orig = null; N.filled = null; clear(); },
98
+ undoHtml: () => (N.orig != null ? `<button type="button" class="hm-tool np-undo" data-np-undo aria-label="Back to what I wrote" title="Back to what I wrote">${ic(UNDO)}</button>` : ''),
99
+ /** A click inside the chat: true when it was one of ours. */
100
+ click(b) {
101
+ if (!b) return false;
102
+ if ('npUse' in b.dataset) { const c = N.cards[Number(b.dataset.npUse)]; if (c) fill(c.text, false); return true; }
103
+ if ('npSharp' in b.dataset) { if (N.sharp) fill(N.sharp, true); return true; }
104
+ if ('npUndo' in b.dataset) { const ta = box(); if (ta && N.orig != null) { const o = N.orig; N.orig = null; N.filled = null; ta.value = o; redrawFoot(); const t2 = box(); if (t2) { t2.dispatchEvent(new Event('np-grow')); t2.focus(); } } return true; }
105
+ if ('npMenu' in b.dataset) { N.menu = !N.menu; draw(); if (N.menu) { const f = wrap.querySelector('.np-mi'); if (f) f.focus(); } return true; }
106
+ if (b.dataset.npVoice) {
107
+ const k = b.dataset.npVoice;
108
+ if (k === 'own' && !(N.prefs && N.prefs.rules)) { N.menu = false; draw(); import('./cozy-settings.js').then((M) => M.openSettings('claude')).catch(() => {}); return true; }
109
+ N.menu = false; save('style', k).then(() => { const ta = box(); if (ta && roughText(ta.value)) sharpen(ta.value); });
110
+ return true;
111
+ }
112
+ if ('npSw' in b.dataset) { const on = !(N.prefs && N.prefs.sharpen); save('sharpen', on ? 'on' : 'off').then(() => { if (!on) clear(); else draw(); }); return true; }
113
+ return false;
114
+ },
115
+ escape() { if (!N.menu) return false; N.menu = false; draw(); const m = wrap.querySelector('[data-np-menu]'); if (m) m.focus(); return true; },
116
+ };
117
+ }
@@ -1,25 +1,25 @@
1
1
  /* pm/ov-view.css — the parts every object Viewer shares (feedback batch 6 item 1b; canvas OvViewers, OvReport): the facts card, a quiet
2
2
  * label over a block of words, the clamped description with its open icon, and the one "where it sits" row. Over cozy.css's tokens, so the
3
3
  * dark theme follows. task-card.js, tk-view.js and the goal Viewer (premium-insights.js) load it. */
4
- .ovf { border-radius: 18px; box-shadow: inset 0 0 0 1px var(--cz-hair); background: var(--cz-card); padding: 14px 16px; display: grid; grid-template-columns: max-content 1fr; column-gap: 18px; row-gap: 6px; align-items: center; font-size: var(--fs-3); }
5
- .ovf > .k { color: var(--cz-ink3); font-size: var(--fs-2); font-weight: 600; min-height: 30px; display: flex; align-items: center; }
6
- .ovf > .v { min-width: 0; min-height: 30px; display: flex; align-items: center; gap: 6px; flex-wrap: wrap; font-weight: 700; color: var(--cz-ink); }
7
- .ovf > .v .late { color: var(--cz-risk); font-weight: 700; }
8
- .ovf > .foot { grid-column: 1 / -1; margin: 10px 0 0; font-size: var(--fs-2); color: var(--cz-ink3); font-weight: 600; }
9
- .ovf .av { width: 22px; height: 22px; border-radius: 7px; background: var(--cz-well); color: var(--cz-ink2); font-size: var(--fs-1); font-weight: 800; display: inline-flex; align-items: center; justify-content: center; flex: none; }
4
+ .ovf { border-radius: 18px; box-shadow: inset 0 0 0 1px var(--cz-hair); background: var(--cz-card); padding: 14px 16px; display: grid; grid-template-columns: max-content 1fr; column-gap: 18px; row-gap: 6px; align-items: center; font-size: var(--fs-body); line-height: var(--lh-body); }
5
+ .ovf > .k { color: var(--cz-ink3); font-size: var(--fs-label); font-weight: var(--fw-strong); min-height: 30px; display: flex; align-items: center; line-height: var(--lh-label); }
6
+ .ovf > .v { min-width: 0; min-height: 30px; display: flex; align-items: center; gap: 6px; flex-wrap: wrap; font-weight: var(--fw-strong); color: var(--cz-ink); }
7
+ .ovf > .v .late { color: var(--cz-risk); font-weight: var(--fw-strong); }
8
+ .ovf > .foot { grid-column: 1 / -1; margin: 10px 0 0; font-size: var(--fs-label); color: var(--cz-ink3); font-weight: var(--fw-strong); line-height: var(--lh-label); }
9
+ .ovf .av { width: 22px; height: 22px; border-radius: 7px; background: var(--cz-well); color: var(--cz-ink2); font-size: var(--fs-badge); font-weight: var(--fw-strong); display: inline-flex; align-items: center; justify-content: center; flex: none; line-height: var(--lh-badge); }
10
10
  .ovf .av.j { border-radius: 50%; background: var(--cz-okbg); color: var(--cz-ok); }
11
11
  .ovf .av.no { background: transparent; border: 1.5px dashed var(--cz-ink3); box-sizing: border-box; }
12
12
 
13
13
  /* a quiet label over a block (Notes, Your notes, Description · from Jira) */
14
14
  .ovb { display: flex; flex-direction: column; gap: 4px; }
15
- .ovl { margin: 0; font-size: var(--fs-2); font-weight: 700; color: var(--cz-ink3); }
16
- .ovl small { font-weight: 600; font-size: var(--fs-2); }
17
- .ovt { margin: 0; font-size: var(--fs-3); line-height: 1.55; color: var(--cz-ink); }
15
+ .ovl { margin: 0; font-size: var(--fs-label); font-weight: var(--fw-strong); color: var(--cz-ink3); line-height: var(--lh-label); }
16
+ .ovl small { font-weight: var(--fw-strong); font-size: var(--fs-label); line-height: var(--lh-label); }
17
+ .ovt { margin: 0; font-size: var(--fs-body); line-height: 1.55; color: var(--cz-ink); }
18
18
  /* the description: shown open, cut at five lines, an icon opens the rest */
19
19
  .ovd { position: relative; }
20
- .ovd .ovdx { font-size: var(--fs-3); line-height: 1.55; color: var(--cz-ink); overflow-wrap: anywhere; }
20
+ .ovd .ovdx { font-size: var(--fs-body); line-height: 1.55; color: var(--cz-ink); overflow-wrap: anywhere; }
21
21
  .ovd .ovdx p, .ovd .ovdx ul, .ovd .ovdx ol { margin: 0 0 6px; }
22
- .ovd .ovdx h4 { margin: 8px 0 2px; font-size: var(--fs-3); }
22
+ .ovd .ovdx h4 { margin: 8px 0 2px; font-size: var(--fs-body); line-height: var(--lh-body); }
23
23
  .ovd.cut .ovdx { max-height: calc(1.55em * 5); overflow: hidden; -webkit-mask-image: linear-gradient(180deg, var(--cz-ink) 55%, transparent); mask-image: linear-gradient(180deg, var(--cz-ink) 55%, transparent); }
24
24
  .ovd .ovdm { display: flex; justify-content: center; margin-top: 2px; }
25
25
  .ovib { width: 30px; height: 30px; border-radius: 999px; border: 0; padding: 0; background: var(--cz-well); color: var(--cz-ink2); display: inline-flex; align-items: center; justify-content: center; cursor: pointer; }
@@ -31,8 +31,8 @@
31
31
  .ovw .go:hover { background: var(--cz-well2); }
32
32
  .ovw .tl { width: 28px; height: 28px; border-radius: 9px; background: var(--cz-bluebg); color: var(--cz-blueink); display: inline-flex; align-items: center; justify-content: center; flex: none; }
33
33
  .ovw .tx { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
34
- .ovw .tx b { font-size: var(--fs-3); font-weight: 800; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
35
- .ovw .tx small { font-size: var(--fs-2); color: var(--cz-ink3); font-weight: 600; display: flex; align-items: center; gap: 4px; flex-wrap: wrap; }
34
+ .ovw .tx b { font-size: var(--fs-row); font-weight: var(--fw-strong); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; line-height: var(--lh-row); }
35
+ .ovw .tx small { font-size: var(--fs-label); color: var(--cz-ink3); font-weight: var(--fw-strong); display: flex; align-items: center; gap: 4px; flex-wrap: wrap; line-height: var(--lh-label); }
36
36
  .ovw .tx small .sep { opacity: .7; }
37
37
  .ovw .cv { color: var(--cz-ink3); display: inline-flex; flex: none; }
38
38
  .ovw .ovmv { width: 38px; height: 38px; border-radius: 999px; border: 0; background: transparent; color: var(--cz-ink2); display: inline-flex; align-items: center; justify-content: center; cursor: pointer; }
@@ -40,5 +40,5 @@
40
40
 
41
41
  /* the foot link (Open in Jira) */
42
42
  .ovft { display: flex; justify-content: center; padding: 6px 0 4px; }
43
- .ovft a { display: inline-flex; align-items: center; gap: 6px; font-size: var(--fs-2); font-weight: 700; color: var(--cz-ink2); text-decoration: none; padding: 6px 12px; border-radius: 999px; }
43
+ .ovft a { display: inline-flex; align-items: center; gap: 6px; font-size: var(--fs-label); font-weight: var(--fw-strong); color: var(--cz-ink2); text-decoration: none; padding: 6px 12px; border-radius: 999px; line-height: var(--lh-label); }
44
44
  .ovft a:hover { background: var(--cz-well); color: var(--cz-ink); }
@@ -1065,11 +1065,11 @@ function detailSvg(g, c, W = 490, H = 150) {
1065
1065
  let out = '';
1066
1066
  if (g.target !== null) { const ty = y(g.target); out += `<path class="tg" d="M0 ${f(ty)}H${W}"/><text class="tgl" x="${W - 2}" y="${f(ty < 18 ? ty + 14 : ty - 6)}" text-anchor="end">Target ${esc(g.targetTxt)}</text>`; }
1067
1067
  // the labels at the foot never overlap: the first milestone label (Deliver, Evaluate) keeps the bottom line, and a milestone or release label
1068
- // that would touch one moves up a line (7.5 units a character is the bold label font, a little over; a line is 17 units)
1068
+ // that would touch one moves up a line (7.5 units a character is the bold 13 px label font, a little over; a line is 19 units, the 13 px label's box and a gap)
1069
1069
  const lanes = [], laneOf = (a, b) => { let i = 0; while ((lanes[i] || []).some(([p, q]) => a < q + 6 && b > p - 6)) i++; (lanes[i] = lanes[i] || []).push([a, b]); return i; };
1070
1070
  const span = (px, end, label) => { const w = String(label).length * 7.5; return end ? [px - w, px] : [px, px + w]; };
1071
- for (const m of marks) { const mx = x(m.t), end = mx > W - 120, lx = end ? mx - 9 : mx + 9; const [a, b] = span(lx, end, m.label), ly = H - 5 - 17 * laneOf(Math.min(a, mx - 6), Math.max(b, mx + 6)); out += `<path class="msr" d="M${f(mx)} 14V${H - 16}"/><path class="msd" d="M${f(mx)} ${H - 14}l5 5-5 5-5-5z"/><text class="msl" x="${f(lx)}" y="${ly}"${end ? ' text-anchor="end"' : ''}>${esc(m.label)}</text>`; }
1072
- for (const s of shipsOf(g)) { if (s.t < t0 || s.t > t1) continue; const sx = x(s.t), end = sx > W - 160, lx = end ? sx - 4 : sx + 4, ly = H - 5 - 17 * laneOf(...span(lx, end, s.label)); out += `<path class="ship" d="M${f(sx)} 20V${H - 10}"/><text class="shipl" x="${f(lx)}" y="${ly}"${end ? ' text-anchor="end"' : ''}>${esc(s.label)}</text>`; }
1071
+ for (const m of marks) { const mx = x(m.t), end = mx > W - 120, lx = end ? mx - 9 : mx + 9; const [a, b] = span(lx, end, m.label), ly = H - 5 - 19 * laneOf(Math.min(a, mx - 6), Math.max(b, mx + 6)); out += `<path class="msr" d="M${f(mx)} 14V${H - 16}"/><path class="msd" d="M${f(mx)} ${H - 14}l5 5-5 5-5-5z"/><text class="msl" x="${f(lx)}" y="${ly}"${end ? ' text-anchor="end"' : ''}>${esc(m.label)}</text>`; }
1072
+ for (const s of shipsOf(g)) { if (s.t < t0 || s.t > t1) continue; const sx = x(s.t), end = sx > W - 160, lx = end ? sx - 4 : sx + 4, ly = H - 5 - 19 * laneOf(...span(lx, end, s.label)); out += `<path class="ship" d="M${f(sx)} 20V${H - 10}"/><text class="shipl" x="${f(lx)}" y="${ly}"${end ? ' text-anchor="end"' : ''}>${esc(s.label)}</text>`; }
1073
1073
  const L = pts.map((p) => f(x(day(p.at))) + ' ' + f(y(p.v))), last = L[L.length - 1], zp = pts[pts.length - 1];
1074
1074
  const FL = fc && proj ? FCV.chartLayer(g, { x, y, H, day, last: { t: day(zp.at), v: zp.v } }) : null;
1075
1075
  out = (FL ? FL.under : '') + out + `<path class="ln" d="M${L.join('L')}"/>` + (FL ? FL.over : proj ? `<path class="pj" d="M${last}L${f(x(proj.t))} ${f(y(proj.v))}"/>` : '');
@@ -13,7 +13,7 @@ body.pmos-doc { overflow: hidden; }
13
13
  [data-more] .pmos-more { display: none; }
14
14
  [data-more][data-open] .pmos-more { display: revert; }
15
15
  .pmos-chg { background: color-mix(in oklab, var(--slide-note-warning) 22%, transparent); }
16
- .pmos-was { margin-left: 6px; font-weight: 400; color: var(--slide-muted); white-space: nowrap; }
16
+ .pmos-was { margin-left: 6px; font-weight: var(--fw-regular); color: var(--slide-muted); white-space: nowrap; }
17
17
  /* print: one slide per 1280 x 720 page, nothing else */
18
18
  @page deck { size: 1280px 720px; margin: 0; }
19
19
  body.pmos-print-deck > .pmos-slide { page: deck; break-after: page; width: 1280px; height: 720px; overflow: hidden; box-sizing: border-box; }
@@ -3,7 +3,7 @@
3
3
  .ins-menu.ins-rpmenu { min-width: 280px; }
4
4
  .ins-menu#repMenu [role="menuitem"] { flex-direction: row; align-items: center; gap: 10px; }
5
5
  .ins-menu#repMenu [role="menuitem"] > span { flex: 1; min-width: 0; }
6
- .ins-menu#repMenu [role="menuitem"] small { display: block; font-size: var(--fs-1); font-weight: 600; color: var(--cz-ink3); }
6
+ .ins-menu#repMenu [role="menuitem"] small { display: block; font-size: var(--fs-badge); font-weight: var(--fw-strong); color: var(--cz-ink3); line-height: var(--lh-badge); }
7
7
  .ins-menu#repMenu .ins-rpback { color: var(--cz-ink2); }
8
8
 
9
9
  .ins-rpd { display: flex; flex-direction: column; gap: 14px; }
@@ -11,30 +11,30 @@
11
11
  .ins-rps.ok { background: var(--cz-okbg); }
12
12
  .ins-rps .sp { display: inline-flex; color: var(--cz-blueink); }
13
13
  .ins-rps.ok .sp { color: var(--cz-ok); }
14
- .ins-rps .t { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; font-size: var(--fs-2); color: var(--cz-ink2); }
15
- .ins-rps .t b { font-size: var(--fs-3); color: var(--cz-ink); }
14
+ .ins-rps .t { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; font-size: var(--fs-meta); color: var(--cz-ink2); line-height: var(--lh-meta); }
15
+ .ins-rps .t b { font-size: var(--fs-body); color: var(--cz-ink); line-height: var(--lh-body); }
16
16
 
17
17
  .ins-rpc { display: flex; flex-wrap: wrap; gap: 6px; }
18
- .ins-rpchip { display: inline-flex; align-items: center; gap: 6px; min-height: 32px; padding: 0 10px; border-radius: 999px; background: var(--cz-well); font-size: var(--fs-2); font-weight: 700; color: var(--cz-ink); }
18
+ .ins-rpchip { display: inline-flex; align-items: center; gap: 6px; min-height: 32px; padding: 0 10px; border-radius: 999px; background: var(--cz-well); font-size: var(--fs-label); font-weight: var(--fw-strong); color: var(--cz-ink); line-height: var(--lh-label); }
19
19
  .ins-rpchip svg[aria-hidden="true"] { width: 14px; height: 14px; }
20
- .ins-rpchip select, .ins-rpchip input { border: 0; background: none; font: inherit; font-size: var(--fs-2); font-weight: 700; color: var(--cz-ink); outline: 0; padding: 0; min-width: 0; }
21
- .ins-rpchip input::placeholder { color: var(--cz-ink3); font-weight: 600; }
20
+ .ins-rpchip select, .ins-rpchip input { border: 0; background: none; font: inherit; font-size: var(--fs-label); font-weight: var(--fw-strong); color: var(--cz-ink); outline: 0; padding: 0; min-width: 0; line-height: var(--lh-label); }
21
+ .ins-rpchip input::placeholder { color: var(--cz-ink3); font-weight: var(--fw-strong); }
22
22
  .ins-rpchip:focus-within { box-shadow: 0 0 0 2px var(--cz-blue); }
23
- .ins-rpchip.gh { background: none; color: var(--cz-ink3); font-weight: 600; }
23
+ .ins-rpchip.gh { background: none; color: var(--cz-ink3); font-weight: var(--fw-strong); }
24
24
 
25
25
  .ins-rpb { display: flex; flex-direction: column; gap: 6px; }
26
- .ins-rpl { font-size: var(--fs-1); font-weight: 800; color: var(--cz-ink3); }
27
- .ins-rpl span { font-weight: 600; margin-left: 6px; }
28
- .ins-rpa { width: 100%; box-sizing: border-box; resize: vertical; border: 1px solid var(--cz-hair); border-radius: 12px; padding: 10px 12px; background: var(--cz-card); font: inherit; font-size: var(--fs-3); font-weight: 800; line-height: 1.35; color: var(--cz-ink); }
26
+ .ins-rpl { font-size: var(--fs-badge); font-weight: var(--fw-strong); color: var(--cz-ink3); line-height: var(--lh-badge); }
27
+ .ins-rpl span { font-weight: var(--fw-strong); margin-left: 6px; }
28
+ .ins-rpa { width: 100%; box-sizing: border-box; resize: vertical; border: 1px solid var(--cz-hair); border-radius: 12px; padding: 10px 12px; background: var(--cz-card); font: inherit; font-size: var(--fs-row); font-weight: var(--fw-strong); line-height: 1.35; color: var(--cz-ink); }
29
29
  .ins-rpa:focus { outline: 0; box-shadow: 0 0 0 2px var(--cz-blue); }
30
30
  .ins-rpbox { border: 1px solid var(--cz-hair); border-radius: 14px; padding: 2px 14px; background: var(--cz-card); }
31
- .ins-rpst { display: grid; grid-template-columns: 20px minmax(0, 1fr) auto auto; gap: 10px; align-items: center; padding: 9px 0; border-bottom: 1px solid var(--cz-hair); font-size: var(--fs-3); }
31
+ .ins-rpst { display: grid; grid-template-columns: 20px minmax(0, 1fr) auto auto; gap: 10px; align-items: center; padding: 9px 0; border-bottom: 1px solid var(--cz-hair); font-size: var(--fs-body); line-height: var(--lh-body); }
32
32
  .ins-rpst:last-child { border-bottom: 0; }
33
- .ins-rpst .n { font-size: var(--fs-1); font-weight: 800; color: var(--cz-ink3); }
34
- .ins-rpst b { display: block; font-weight: 800; line-height: 1.3; }
35
- .ins-rpst small { display: block; font-size: var(--fs-1); color: var(--cz-ink3); margin-top: 1px; }
33
+ .ins-rpst .n { font-size: var(--fs-badge); font-weight: var(--fw-strong); color: var(--cz-ink3); line-height: var(--lh-badge); }
34
+ .ins-rpst b { display: block; font-weight: var(--fw-strong); line-height: 1.3; }
35
+ .ins-rpst small { display: block; font-size: var(--fs-meta); color: var(--cz-ink3); margin-top: 1px; line-height: var(--lh-meta); }
36
36
  .ins-rpst.off .w { opacity: .55; }
37
- .ins-rplive { display: inline-flex; align-items: center; gap: 5px; font-size: var(--fs-1); font-weight: 700; color: var(--cz-ok); }
37
+ .ins-rplive { display: inline-flex; align-items: center; gap: 5px; font-size: var(--fs-badge); font-weight: var(--fw-strong); color: var(--cz-ok); line-height: var(--lh-badge); }
38
38
  .ins-rplive i { width: 6px; height: 6px; border-radius: 50%; background: var(--cz-dot-ok); }
39
39
  .ins-rptog { position: relative; width: 34px; height: 20px; border-radius: 999px; border: 0; background: var(--cz-well2); cursor: pointer; padding: 0; flex: none; }
40
40
  .ins-rptog::after { content: ""; position: absolute; top: 2px; left: 2px; width: 16px; height: 16px; border-radius: 50%; background: var(--cz-card); transition: transform .15s ease; }
@@ -43,9 +43,9 @@
43
43
  .ins-rptog:disabled { opacity: .5; cursor: default; }
44
44
  .ins-rptog:focus-visible { outline: 2px solid var(--cz-blue); outline-offset: 2px; }
45
45
  .ins-rpask { grid-column: 2 / -1; display: grid; grid-template-columns: minmax(0, 1fr) 120px 140px; gap: 6px; }
46
- .ins-rpask input { min-width: 0; height: 32px; border: 1px solid var(--cz-hair); border-radius: 8px; padding: 0 8px; background: var(--cz-card); font: inherit; font-size: var(--fs-2); color: var(--cz-ink); }
46
+ .ins-rpask input { min-width: 0; height: 32px; border: 1px solid var(--cz-hair); border-radius: 8px; padding: 0 8px; background: var(--cz-card); font: inherit; font-size: var(--fs-meta); color: var(--cz-ink); line-height: var(--lh-meta); }
47
47
  .ins-rpck { display: grid; grid-template-columns: 1fr 1fr; column-gap: 12px; }
48
- .ins-rpck .ck { display: flex; align-items: flex-start; gap: 8px; font-size: var(--fs-2); color: var(--cz-ink2); padding: 4px 0; line-height: 1.35; }
48
+ .ins-rpck .ck { display: flex; align-items: flex-start; gap: 8px; font-size: var(--fs-meta); color: var(--cz-ink2); padding: 4px 0; line-height: 1.35; }
49
49
  .ins-rpck .m { width: 18px; height: 18px; border-radius: 50%; background: var(--cz-okbg); color: var(--cz-ok); display: inline-flex; align-items: center; justify-content: center; flex: none; }
50
50
  .ins-rpck .m svg[aria-hidden="true"] { width: 12px; height: 12px; }
51
51
  .ins-rpck .ck.w .m { background: var(--cz-latebg); color: var(--cz-late); }
@@ -6,4 +6,4 @@ body.pmos-print-deck > .pmos-slide { padding: 72px 96px; display: flex; flex-dir
6
6
  .rp-slide__t p, .rp-slide__t li { margin: 0; font-size: 16px; line-height: 1.45; }
7
7
  .rp-slide__t ul { margin: 0; display: grid; gap: 12px; }
8
8
  body.pmos-print-doc { padding: 48px; }
9
- body.pmos-print-doc h2 { margin: 24px 0 8px; font-size: 20px; }
9
+ body.pmos-print-doc h2 { margin: 24px 0 8px; font-size: var(--fs-panel); line-height: var(--lh-panel); }
@@ -1,30 +1,30 @@
1
- :root{--fs-1:11px;--fs-2:12px;--fs-3:14px;--fs-4:16px;--fs-5:20px;--fs-6:28px}
1
+ :root{--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}
2
2
  /* pm/premium-vw-backlog.css — the Jira backlog as a viewer tab (initiative premium-viewer, R10; premium-vw-backlog.js).
3
3
  * Loaded once by vwStyle('backlog'). Sizes are only var(--fs-1..6), weights 400/500/600 (premium-console-type.test.js). */
4
4
  .vbl .bl{display:grid;gap:14px}
5
- .vbl .bl-src{margin:0;font-size:var(--fs-2);color:var(--ink-3)}
5
+ .vbl .bl-src{margin:0;font-size:var(--fs-meta);color:var(--ink-3);line-height:var(--lh-meta);}
6
6
  .vbl .bl-f{display:flex;gap:4px;flex-wrap:wrap;padding:4px;border-radius:8px;background:var(--well);width:max-content;max-width:100%}
7
- .vbl .bl-f button{min-height:44px;padding:0 16px;border-radius:6px;font-size:var(--fs-2);font-weight:600;color:var(--ink-2)}
7
+ .vbl .bl-f button{min-height:44px;padding:0 16px;border-radius:6px;font-size:var(--fs-label);font-weight:var(--fw-strong);color:var(--ink-2);line-height:var(--lh-label);}
8
8
  .vbl .bl-f button[aria-pressed="true"]{background:var(--solid);color:var(--on-solid)}
9
9
  .vbl .bl-s{background:var(--card-solid);border:1px solid var(--hair);border-radius:8px;box-shadow:var(--card-shadow);overflow:hidden}
10
10
  .vbl .bl-h{display:flex;align-items:center;gap:10px;flex-wrap:wrap;padding:10px 14px;border-bottom:1px solid var(--hair)}
11
- .vbl .bl-h b{font-size:var(--fs-3);font-weight:600}
12
- .vbl .bl-h small{font-size:var(--fs-2);color:var(--ink-3)}
11
+ .vbl .bl-h b{font-size:var(--fs-row);font-weight:var(--fw-strong);line-height:var(--lh-row);}
12
+ .vbl .bl-h small{font-size:var(--fs-meta);color:var(--ink-3);line-height:var(--lh-meta);}
13
13
  .vbl .bl-gap{flex:1}
14
14
  .vbl .bl-rws{list-style:none;margin:0;padding:0}
15
15
  .vbl .bl-rw{display:flex;align-items:center;gap:10px;flex-wrap:wrap;padding:4px 14px;border-top:1px solid var(--hair)}
16
16
  .vbl .bl-rw:first-child{border-top:0}
17
17
  .vbl .bl-rw.risk{box-shadow:inset 3px 0 0 var(--bad)}
18
- .vbl .bl-t{flex:1 1 220px;min-width:0;min-height:44px;display:flex;align-items:center;gap:10px;text-align:left;font-size:var(--fs-3);color:var(--ink)}
19
- .vbl .bl-t b{font-weight:500;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
18
+ .vbl .bl-t{flex:1 1 220px;min-width:0;min-height:44px;display:flex;align-items:center;gap:10px;text-align:left;font-size:var(--fs-body);color:var(--ink);line-height:var(--lh-body);}
19
+ .vbl .bl-t b{font-weight:var(--fw-regular);min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
20
20
  @media (hover:hover){.vbl .bl-t:hover b{text-decoration:underline;text-underline-offset:3px}}
21
- .vbl .bl-k{font:500 var(--fs-2) var(--mono);color:var(--ink-3);flex:none}
21
+ .vbl .bl-k{font:var(--fw-regular) var(--fs-meta)/var(--lh-meta) var(--mono);color:var(--ink-3);flex:none}
22
22
  .vbl .bl-m{display:flex;align-items:center;gap:8px;flex:none}
23
- .vbl .bl-st{font-size:var(--fs-1);font-weight:600;padding:2px 8px;border-radius:6px;background:var(--well);color:var(--ink-2)}
23
+ .vbl .bl-st{font-size:var(--fs-badge);font-weight:var(--fw-strong);padding:2px 8px;border-radius:6px;background:var(--well);color:var(--ink-2);line-height:var(--lh-badge);}
24
24
  .vbl .bl-st.doing{color:var(--ember-ink)}
25
- .vbl .bl-p{font:500 var(--fs-2) var(--mono);min-width:24px;text-align:center;padding:1px 6px;border-radius:6px;border:1px solid var(--hair);color:var(--ink-2)}
26
- .vbl .bl-in{font-size:var(--fs-2);color:var(--ink-3);max-width:16ch;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
27
- .vbl .bl-why{flex-basis:100%;margin:-6px 0 6px;font-size:var(--fs-2);color:var(--bad)}
28
- .vbl .bl-none,.vbl .bl-empty{margin:0;padding:12px 14px;font-size:var(--fs-2);color:var(--ink-3)}
25
+ .vbl .bl-p{font:var(--fw-regular) var(--fs-meta)/var(--lh-meta) var(--mono);min-width:24px;text-align:center;padding:1px 6px;border-radius:6px;border:1px solid var(--hair);color:var(--ink-2)}
26
+ .vbl .bl-in{font-size:var(--fs-meta);color:var(--ink-3);max-width:16ch;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;line-height:var(--lh-meta);}
27
+ .vbl .bl-why{flex-basis:100%;margin:-6px 0 6px;font-size:var(--fs-meta);color:var(--bad);line-height:var(--lh-meta);}
28
+ .vbl .bl-none,.vbl .bl-empty{margin:0;padding:12px 14px;font-size:var(--fs-meta);color:var(--ink-3);line-height:var(--lh-meta);}
29
29
  .vbl .bl-f button:focus-visible,.vbl .bl-t:focus-visible{outline:2px solid var(--ember);outline-offset:2px}
30
30
  @media (max-width:560px){.vbl .bl-in{display:none}}