@bongos/core 1.19.455 → 1.19.456

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 (48) hide show
  1. package/.bongos-core.json +106 -41
  2. package/docs/copy-inventory.md +231 -228
  3. package/docs/copy-registry.json +352 -312
  4. package/docs/module-api-changelog.md +2 -0
  5. package/modules/hall-ui/public/atlas.css +41 -32
  6. package/modules/hall-ui/public/atlas.html +8 -0
  7. package/modules/hall-ui/public/atlas.states.json +60 -0
  8. package/modules/hall-ui/public/collab.css +2 -2
  9. package/modules/hall-ui/public/collab.html +7 -1
  10. package/modules/hall-ui/public/collab.states.json +60 -0
  11. package/modules/hall-ui/public/copy-desk.css +21 -16
  12. package/modules/hall-ui/public/copy-desk.html +9 -1
  13. package/modules/hall-ui/public/copy-desk.states.json +59 -0
  14. package/modules/hall-ui/public/drachmae.html +38 -5
  15. package/modules/hall-ui/public/drachmae.js +20 -2
  16. package/modules/hall-ui/public/drachmae.states.json +64 -0
  17. package/modules/hall-ui/public/gate.css +20 -25
  18. package/modules/hall-ui/public/gate.html +9 -1
  19. package/modules/hall-ui/public/gate.states.json +60 -0
  20. package/modules/hall-ui/public/goals-lib.js +22 -5
  21. package/modules/hall-ui/public/goals-render.js +27 -5
  22. package/modules/hall-ui/public/goals.css +141 -60
  23. package/modules/hall-ui/public/goals.html +8 -1
  24. package/modules/hall-ui/public/goals.states.json +74 -0
  25. package/modules/hall-ui/public/government.css +35 -36
  26. package/modules/hall-ui/public/government.html +9 -1
  27. package/modules/hall-ui/public/government.states.json +59 -0
  28. package/modules/hall-ui/public/harbor.css +23 -26
  29. package/modules/hall-ui/public/harbor.html +9 -1
  30. package/modules/hall-ui/public/harbor.states.json +59 -0
  31. package/modules/hall-ui/public/modules.css +22 -21
  32. package/modules/hall-ui/public/modules.html +9 -1
  33. package/modules/hall-ui/public/modules.states.json +73 -0
  34. package/modules/hall-ui/public/people.html +7 -1
  35. package/modules/hall-ui/public/people.states.json +59 -0
  36. package/modules/hall-ui/public/scouting.html +7 -1
  37. package/modules/hall-ui/public/scouting.states.json +54 -0
  38. package/modules/hall-ui/public/sessions.css +1 -1
  39. package/modules/hall-ui/public/sessions.html +9 -1
  40. package/modules/hall-ui/public/sessions.states.json +58 -0
  41. package/modules/hall-ui/public/style.css +125 -5
  42. package/modules/hall-ui/public/watch.css +36 -39
  43. package/modules/hall-ui/public/watch.html +9 -1
  44. package/modules/hall-ui/public/watch.states.json +60 -0
  45. package/package-lock.json +2 -2
  46. package/package.json +1 -1
  47. package/src/module-api.js +1 -1
  48. package/tests/goal_subtitle.mjs +14 -8
@@ -13,8 +13,8 @@
13
13
  margin: 6px 0 22px;
14
14
  }
15
15
  .gate-stat {
16
- border: 1px solid var(--border); border-radius: var(--radius-sm);
17
- background: var(--surface); padding: 12px 14px;
16
+ border: var(--line) solid var(--rule-soft); border-radius: var(--radius-sm);
17
+ background: var(--bg-card); padding: 12px 14px;
18
18
  }
19
19
  .gate-stat__label {
20
20
  font-size: 11.5px; font-weight: 600;
@@ -28,8 +28,8 @@
28
28
  .gate-list { display: flex; flex-direction: column; gap: 16px; }
29
29
 
30
30
  .gate-crate {
31
- border: 1px solid var(--border); border-radius: var(--radius);
32
- background: var(--surface); overflow: hidden;
31
+ border: var(--line) solid var(--rule-soft); border-radius: var(--radius);
32
+ background: var(--bg-card); overflow: hidden;
33
33
  }
34
34
  /* Verdict band along the top, painted by the held-verdict. */
35
35
  .gate-crate__seal { height: 4px; background-color: var(--danger); }
@@ -40,45 +40,40 @@
40
40
  .gate-crate__title a { color: inherit; text-decoration: none; }
41
41
  .gate-crate__title a:hover { text-decoration: underline; }
42
42
  .gate-crate__meta { color: var(--ink-soft); font-size: 12.5px; }
43
- .gate-crate__meta a { color: var(--accent-text); }
43
+ .gate-crate__meta a { color: var(--accent-ink); }
44
44
 
45
- .gate-pill {
46
- font-size: 11px; font-weight: 600;
47
- letter-spacing: 0.04em; text-transform: uppercase;
48
- padding: 2px 8px; border-radius: 999px; white-space: nowrap;
49
- border: 1px solid var(--border); color: var(--ink-soft); background: var(--surface-2);
50
- }
51
- .gate-pill--escalate { background: var(--danger-weak); border-color: color-mix(in srgb, var(--danger) 30%, transparent); color: var(--danger); }
52
- .gate-pill--needs_trust { background: var(--warn-weak); border-color: color-mix(in srgb, var(--warn) 30%, transparent); color: var(--warn); }
53
- .gate-pill--trusted { background: var(--info-weak); border-color: color-mix(in srgb, var(--info) 30%, transparent); color: var(--info); }
45
+ /* Base: the shell's .fact-pill (task 1003307). States are hairlines, not fills. */
46
+ .gate-pill--escalate { color: var(--danger); }
47
+ .gate-pill--needs_trust { color: var(--warn); }
48
+ .gate-pill--trusted { color: var(--info); }
54
49
 
55
50
  .gate-reasons { list-style: none; padding: 0; margin: 0; }
56
51
  .gate-reasons li {
57
- padding: 6px 0; border-bottom: 1px solid var(--border);
52
+ padding: 6px 0; border-bottom: var(--line) solid var(--rule-soft);
58
53
  font-size: 13px; color: var(--ink);
59
54
  }
60
55
  .gate-reasons li:last-child { border-bottom: 0; }
61
56
  .gate-reasons code {
62
- font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12px;
63
- color: var(--accent-text); background: var(--surface-2);
57
+ font-family: var(--font-mono); font-size: 12px;
58
+ color: var(--accent-ink); background: var(--glass);
64
59
  padding: 1px 5px; border-radius: 4px;
65
60
  }
66
61
  .gate-reasons .floor { color: var(--danger); font-weight: 600; }
67
62
 
68
63
  .gate-files { font-size: 12.5px; color: var(--ink-soft); }
69
- .gate-files code { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; }
64
+ .gate-files code { font-family: var(--font-mono); }
70
65
 
71
66
  .gate-actions { display: flex; gap: 10px; flex-wrap: wrap; align-items: center; margin-top: 2px; }
72
67
  .gate-btn {
73
68
  font: inherit; font-size: 13px; font-weight: 600;
74
- padding: 7px 16px; border: 1px solid var(--accent);
75
- background: var(--accent); color: #fff;
69
+ padding: 7px 16px; border: var(--line) solid var(--accent);
70
+ background: var(--accent); color: var(--accent-on);
76
71
  border-radius: var(--radius-sm); cursor: pointer;
77
72
  }
78
- .gate-btn:hover:not(:disabled) { background: var(--accent-deep); border-color: var(--accent-deep); }
73
+ .gate-btn:hover:not(:disabled) { background: var(--accent-lift); border-color: var(--accent-lift); }
79
74
  .gate-btn:disabled { opacity: 0.45; cursor: default; }
80
- .gate-btn--ghost { background: var(--surface); color: var(--ink); border-color: var(--border-strong); }
81
- .gate-btn--ghost:hover:not(:disabled) { background: var(--surface-2); border-color: var(--border-strong); }
75
+ .gate-btn--ghost { background: var(--bg-card); color: var(--ink); border-color: var(--rule); }
76
+ .gate-btn--ghost:hover:not(:disabled) { background: var(--glass); border-color: var(--rule); }
82
77
  .gate-approved-note { color: var(--ok); font-size: 13px; }
83
78
 
84
79
  .gate-empty, .gate-sealed { color: var(--ink-soft); padding: 16px 0; }
@@ -87,10 +82,10 @@
87
82
  /* Lightweight confirm modal (mirrors harbor). */
88
83
  .gate-modal-bg {
89
84
  position: fixed; inset: 0; background: color-mix(in srgb, var(--ink) 40%, transparent);
90
- display: flex; align-items: center; justify-content: center; z-index: 50; padding: 20px;
85
+ display: flex; align-items: center; justify-content: center; z-index: var(--z-modal); padding: 20px;
91
86
  }
92
87
  .gate-modal {
93
- background: var(--surface); border: 1px solid var(--border-strong); border-radius: var(--radius);
88
+ background: var(--bg-card); border: var(--line) solid var(--rule); border-radius: var(--radius);
94
89
  max-width: 480px; width: 100%; padding: 20px 22px; box-shadow: var(--shadow-pop);
95
90
  }
96
91
  .gate-modal h2 { color: var(--ink); margin: 0 0 8px; font-size: 17px; font-weight: 600; }
@@ -19,7 +19,15 @@
19
19
  <div class="app-body">
20
20
  <header class="app-topbar" id="app-topbar"></header>
21
21
  <div class="app-content">
22
- <div class="page-head"><p class="page-head__sub" id="gate-sub">Loading…</p></div>
22
+ <!-- task 1003307: the board page head. Gate shipped with NO <h1> at all
23
+ (one-header-main-h1 measured 0 on every render), so the re-skin
24
+ carries the structural fix rather than porting the hole. The heading
25
+ is the LABEL voice, not a display line: on a working surface the
26
+ page's own name is the least interesting thing on it. -->
27
+ <div class="page-head page-head--board">
28
+ <h1 class="page-head__h">Gate</h1>
29
+ <p class="page-head__sub" id="gate-sub">Loading…</p>
30
+ </div>
23
31
 
24
32
  <main id="hall-main">
25
33
  <p class="gate-sealed" id="gate-sealed" hidden>Archons only.</p>
@@ -0,0 +1,60 @@
1
+ {
2
+ "_": "Gate — the access-request queue behind requireGovernmentPage. Same confirm-modal component as harbor, which is why the two had guessed two different z-indexes for it. Written with the re-skin (task 1003307) so this page is MEASURED at three widths in both modes rather than looked at once.",
3
+ "page": "/builders/gate",
4
+ "surface": "hall-ui",
5
+ "stub": {
6
+ "prefix": "/builders/"
7
+ },
8
+ "modeQuery": false,
9
+ "_feeds": "The kit's own stub carries no feed for this page, so against it the page renders its EMPTY and SKELETON states — which is the point: those are states the floors must hold in. Against the hall-preview harness the same states render populated. Every declared 404 below is a fixture the harness does not carry, named rather than hidden.",
10
+ "ignoreRequests": [
11
+ "/api/(gds|bongos)/me$",
12
+ "/api/(gds|bongos)/me/",
13
+ "/api/(gds|bongos)/goals",
14
+ "/api/(gds|bongos)/inbox/",
15
+ "/api/(gds|bongos)/versions",
16
+ "/api/(gds|bongos)/gate-approvals",
17
+ "/api/(gds|bongos)/builders",
18
+ "/api/(gds|bongos)/access-requests"
19
+ ],
20
+ "ignoreConsole": [
21
+ "/api/(gds|bongos)/",
22
+ "\\b401\\b",
23
+ "\\b403\\b",
24
+ "\\b404\\b",
25
+ "\\b501\\b",
26
+ "Unauthorized",
27
+ "Forbidden",
28
+ "Not Found",
29
+ "Not Implemented",
30
+ "load failed"
31
+ ],
32
+ "states": {
33
+ "queue": {
34
+ "auth": true,
35
+ "actions": [
36
+ [
37
+ "wait",
38
+ 700
39
+ ]
40
+ ],
41
+ "expect": {
42
+ "visible": [
43
+ "#gate-body"
44
+ ]
45
+ }
46
+ },
47
+ "out": {
48
+ "auth": false
49
+ }
50
+ },
51
+ "reducedMotion": {
52
+ "auth": true,
53
+ "actions": [
54
+ [
55
+ "wait",
56
+ 600
57
+ ]
58
+ ]
59
+ }
60
+ }
@@ -90,15 +90,32 @@
90
90
  // goals.html loads task-lib.js before this file (the render-family order).
91
91
  const { msOf, taskActivityMs } = window.OTBTaskLib;
92
92
 
93
- // task 1003224 — on a LIST, a goal's subtitle is a TOOLTIP, never a second
94
- // visible line. The board's job there is to let someone find a goal by name;
95
- // rendering every explanation inline is what led 29 of 38 titles to carry
96
- // their own after a dash. Escaped because it lands inside an attribute.
93
+ // task 1003224 made a goal's subtitle a TOOLTIP on a list, because 29 of 38
94
+ // titles already carried their own explanation after a dash and a row would
95
+ // then say the same thing twice.
96
+ //
97
+ // Task 1003307 REVERSES that for the row, on the owner's call, against the
98
+ // approved archetype (docs/design/mocks/hall/goals/v3.html, .goal__sub). Two
99
+ // things changed under 1003224's reasoning: the dash-in-title rate fell to 17
100
+ // of 72, and 35 of those 72 goals now carry a real subtitle that a tooltip
101
+ // hides from anyone reading — and hides COMPLETELY from anyone on a touch
102
+ // screen, where there is no hover. A duplicated explanation is a copy-desk
103
+ // fix; an invisible one is not fixable at all.
104
+ //
105
+ // subtitleAttr survives for the CARD view, which has no room for a line.
97
106
  function subtitleAttr(g) {
98
107
  const t = (g && g.subtitle ? String(g.subtitle) : '').trim();
99
108
  return t ? ` title="${window.OTB.escapeHtml(t)}"` : '';
100
109
  }
101
110
 
111
+ // The row's visible subtitle. Empty string when the goal has none, so the row
112
+ // collapses to title + facts rather than reserving a blank line — the card's
113
+ // "every region hides on null" grammar, applied to a row.
114
+ function subtitleLine(g) {
115
+ const t = (g && g.subtitle ? String(g.subtitle) : '').trim();
116
+ return t ? `<p class="gr-sub">${window.OTB.escapeHtml(t)}</p>` : '';
117
+ }
118
+
102
119
  // task 1003224 — the three-layer prose rules for a goal's detail head, kept
103
120
  // here rather than in goals-page.js because that file is 500 lines over the
104
121
  // excess-lines ratchet and this one exists for exactly that reason. It WRITES
@@ -120,6 +137,6 @@
120
137
  ring, memberName,
121
138
  readinessOf, EMPTY_ROLLUP, goalRollLine,
122
139
  matchesTodoSearch, msOf, taskActivityMs,
123
- subtitleAttr, applyGoalProse,
140
+ subtitleAttr, subtitleLine, applyGoalProse,
124
141
  };
125
142
  })();
@@ -28,7 +28,7 @@
28
28
  emptyStateHtml, skeletonRows } = window.OTBKit;
29
29
  const { DONE_STATUSES, CUT_STATUSES, isTodoStatus, ring, memberName,
30
30
  readinessOf, EMPTY_ROLLUP, goalRollLine, matchesTodoSearch,
31
- msOf, taskActivityMs, subtitleAttr, applyGoalProse } = window.OTBGoalsLib;
31
+ msOf, taskActivityMs, subtitleAttr, subtitleLine, applyGoalProse } = window.OTBGoalsLib;
32
32
 
33
33
  const CONFLICT_CAP = 3;
34
34
  // task 1828 — the band's Completion / Members / Conflicts columns each cap
@@ -150,21 +150,43 @@
150
150
  right = `<span class="gr-quiet">No tasks yet</span>`;
151
151
  }
152
152
  const metaHtml = `#${escapeHtml(String(g.id))} · ${escapeHtml(g.version_id || '')}${(achieved || g.status === 'open') ? '' : ' · ' + escapeHtml(g.status)}${goalStampHtml(g)}`;
153
+ // task 1003307 — the archetype's fact line: the goal's STATE as a pill, then
154
+ // one chip per scope module and one for the version. The mock argues rows
155
+ // over cards precisely because a goal carries this many facts; the row was
156
+ // showing two of them as one run of grey text.
157
+ const stampHtml = goalStampHtml(g);
158
+ const idHtml = `<span class="gr-title__id">#${escapeHtml(String(g.id))}</span>`;
159
+ const chips = [];
160
+ for (const m of (Array.isArray(g.scope_modules) ? g.scope_modules : []).slice(0, 3)) {
161
+ chips.push(`<span class="fact-chip">${escapeHtml(String(m))}</span>`);
162
+ }
163
+ if (g.version_id) chips.push(`<span class="fact-chip">${escapeHtml(g.version_id)}</span>`);
164
+ const factsHtml = `<div class="gr-facts">`
165
+ + `<span class="fact-pill fact-pill--${escapeHtml(g.status || 'open')}">${escapeHtml(g.status || 'open')}</span>`
166
+ + chips.join('')
167
+ + `</div>`;
153
168
  // task 1003276 — the category chip. Computed here with the rest of the facts
154
169
  // so the row and the card (task 1003136) cannot drift on it.
155
170
  const catHtml = categoryChip(g.category);
156
- return { r, achieved, ringHtml, goalHref, right, metaHtml, catHtml };
171
+ return { r, achieved, ringHtml, goalHref, right, metaHtml, catHtml, idHtml, stampHtml, factsHtml };
157
172
  }
158
173
  function goalRowHtml(g) {
159
- const { r, achieved, ringHtml, goalHref, right, metaHtml, catHtml } = goalRenderFacts(g, 44);
174
+ const { r, achieved, ringHtml, goalHref, right, catHtml, idHtml, stampHtml, factsHtml } = goalRenderFacts(g, 44);
160
175
  // NOTE: a rollup row nests real links (title → goal, Claim → task overlay,
161
176
  // drill → goal), so the row itself is a <div>, not an <a> — nested anchors
162
177
  // are invalid. Only the explicit links navigate.
178
+ // task 1003307 — the archetype's row (mock .goal): the id rides INSIDE the
179
+ // title, mono and quiet, so the name starts at the same x on every row; the
180
+ // subtitle is a real line; the state and the scope are pills and chips
181
+ // rather than a grey run-on. The sort stamp is all that is left of .gr-meta,
182
+ // and it renders only while a date sort is active.
163
183
  return `<div class="gr-row" data-goal-id="${escapeHtml(String(g.id))}">
164
184
  <div class="gr-ringcol">${ringHtml}</div>
165
185
  <div class="gr-main">
166
- <a class="gr-title" href="${goalHref}"${subtitleAttr(g)}>${escapeHtml(g.title || 'Untitled goal')}</a>
167
- <div class="gr-meta">${metaHtml}${catHtml}</div>
186
+ <a class="gr-title" href="${goalHref}">${idHtml}${escapeHtml(g.title || 'Untitled goal')}</a>
187
+ ${subtitleLine(g)}
188
+ ${factsHtml}
189
+ ${stampHtml ? `<div class="gr-meta">${stampHtml.replace(/^ · /, '')}${catHtml}</div>` : (catHtml ? `<div class="gr-meta">${catHtml}</div>` : '')}
168
190
  ${achieved ? '' : goalRollLine(r)}
169
191
  </div>
170
192
  <div class="gr-right">${right}</div>