@bongos/core 1.19.461 → 1.19.463
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/.bongos-core.json +145 -40
- package/.claude/skills/design/SKILL.md +2 -1
- package/docs/adr/0221-the-impeccable-method-is-one-skill-with-sub-command-playbooks.md +36 -0
- package/docs/adr/README.md +1 -0
- package/docs/copy-inventory.md +122 -125
- package/docs/copy-registry.json +306 -322
- package/docs/file-map.md +2 -2
- package/docs/module-api-changelog.md +4 -0
- package/modules/hall-ui/public/goals-lib.js +10 -6
- package/modules/hall-ui/public/goals-page.js +27 -12
- package/modules/hall-ui/public/goals-render.js +83 -52
- package/modules/hall-ui/public/goals.css +129 -120
- package/modules/hall-ui/public/goals.html +29 -11
- package/modules/hall-ui/public/goals.states.json +71 -3
- package/modules/hall-ui/public/people.css +27 -0
- package/modules/hall-ui/public/people.html +15 -7
- package/modules/hall-ui/public/people.js +111 -22
- package/modules/hall-ui/public/people.states.json +31 -1
- package/modules/hall-ui/public/scouting.html +30 -17
- package/modules/hall-ui/public/scouting.states.json +7 -2
- package/modules/hall-ui/public/sessions.css +18 -15
- package/modules/hall-ui/public/sessions.html +27 -22
- package/modules/hall-ui/public/sessions.js +32 -13
- package/modules/hall-ui/public/sessions.states.json +3 -2
- package/modules/ui-design/module.json +1 -1
- package/modules/ui-design/skills/README.md +4 -3
- package/modules/ui-design/skills/impeccable/SKILL.md +143 -0
- package/modules/ui-design/skills/impeccable/reference/adapt.md +25 -0
- package/modules/ui-design/skills/impeccable/reference/animate.md +27 -0
- package/modules/ui-design/skills/impeccable/reference/audit.md +19 -0
- package/modules/ui-design/skills/impeccable/reference/bolder.md +17 -0
- package/modules/ui-design/skills/impeccable/reference/clarify.md +25 -0
- package/modules/ui-design/skills/impeccable/reference/colorize.md +22 -0
- package/modules/ui-design/skills/impeccable/reference/critique.md +15 -0
- package/modules/ui-design/skills/impeccable/reference/distill.md +26 -0
- package/modules/ui-design/skills/impeccable/reference/document.md +25 -0
- package/modules/ui-design/skills/impeccable/reference/extract.md +20 -0
- package/modules/ui-design/skills/impeccable/reference/harden.md +21 -0
- package/modules/ui-design/skills/impeccable/reference/layout.md +20 -0
- package/modules/ui-design/skills/impeccable/reference/onboard.md +22 -0
- package/modules/ui-design/skills/impeccable/reference/optimize.md +22 -0
- package/modules/ui-design/skills/impeccable/reference/polish.md +22 -0
- package/modules/ui-design/skills/impeccable/reference/quieter.md +17 -0
- package/modules/ui-design/skills/impeccable/reference/shape.md +23 -0
- package/modules/ui-design/skills/impeccable/reference/typeset.md +24 -0
- package/package-lock.json +2 -2
- package/package.json +1 -1
- package/src/module-api.js +1 -1
- package/tests/hall_roster_world.mjs +287 -0
- package/tests/ui_design_skills.mjs +41 -0
- package/modules/hall-ui/public/scouting.js +0 -73
|
@@ -25,47 +25,42 @@
|
|
|
25
25
|
The ch unit is the zero glyph's width, not a character — the body measure is
|
|
26
26
|
--measure (48ch, measured at ~60 characters), never fresh ch arithmetic. */
|
|
27
27
|
|
|
28
|
-
/* ----
|
|
29
|
-
task
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
28
|
+
/* ---- the CARDS view: the row folded, not a second design ----
|
|
29
|
+
task 1003470: the rows|cards toggle stays — the archetype keeps it, because
|
|
30
|
+
a card wall is the better read when someone scans for a NAME rather than for
|
|
31
|
+
what can move — but the card is the row's compact sibling and nothing else:
|
|
32
|
+
the same title with the id inside it, the same pills and chips, the same
|
|
33
|
+
roll line, the same right-column state, from ONE fact source
|
|
34
|
+
(goalRenderFacts; pinned by tests/goals_card_view.mjs). A card inside the
|
|
35
|
+
list panel draws no box — a --bg-card tile on a --bg-card panel is the
|
|
36
|
+
card-in-a-card v3 removed — so the grid paints the hairline BETWEEN its rows
|
|
37
|
+
(a 1px row gap over the rule tone, each cell on the panel's own ground) and
|
|
38
|
+
nothing above the first or below the last. renderList nests id-less
|
|
39
|
+
.goal-grid wrappers per group, which this rule styles; the #goal-grid
|
|
40
|
+
override further down only flattens the OUTER container. */
|
|
41
|
+
.goal-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 1px 0; background: var(--rule-soft); --ring: 36px; }
|
|
35
42
|
.goal-card {
|
|
36
|
-
display: flex; flex-direction: column; gap:
|
|
37
|
-
|
|
38
|
-
|
|
43
|
+
display: flex; flex-direction: column; gap: 10px;
|
|
44
|
+
padding: 18px 32px 20px 0;
|
|
45
|
+
background: var(--bg-card);
|
|
39
46
|
color: var(--ink);
|
|
47
|
+
min-width: 0;
|
|
40
48
|
}
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
.goal-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
cards deliberately carry no drag affordance. */
|
|
47
|
-
/* task 1761: a goal blocked by an unachieved prerequisite is dimmed + hue-shifted. */
|
|
48
|
-
.goal-card--blocked { opacity: 0.62; border-style: dashed; }
|
|
49
|
-
.goal-card--blocked:hover { opacity: 0.85; }
|
|
49
|
+
.goal-card__head { display: flex; align-items: flex-start; gap: 12px; }
|
|
50
|
+
.goal-card__head .gr-title { font-size: 15px; }
|
|
51
|
+
.goal-card__title { flex: 1; min-width: 0; }
|
|
52
|
+
.goal-card__foot { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 8px 12px; margin-top: auto; }
|
|
53
|
+
/* task 1761: a goal blocked by an unachieved prerequisite (the detail view). */
|
|
50
54
|
.goal-deps { color: var(--ink-faint); }
|
|
51
55
|
.goal-deps--blocked { color: var(--warn); font-weight: 600; }
|
|
52
|
-
|
|
56
|
+
/* The detail head's meta line and its mono id (task 2163). */
|
|
53
57
|
.goal-card__meta { display: flex; flex-wrap: wrap; gap: 4px 6px; align-items: center; font-size: 11.5px; color: var(--ink-faint); }
|
|
54
|
-
/* task 2163 — the real goal id, shown as a monospace #NNN token so it reads as
|
|
55
|
-
an identifier and never gets confused with the priority ordinal on the left. */
|
|
56
58
|
.goal-card__id, .goal-detail__id {
|
|
57
59
|
font-family: var(--font-mono);
|
|
58
60
|
font-variant-numeric: tabular-nums; font-weight: 600; color: var(--ink-faint);
|
|
59
61
|
}
|
|
60
62
|
.goal-card__id { padding: 0 5px; border: var(--line) solid var(--rule-soft); border-radius: var(--radius-sm); }
|
|
61
63
|
.goal-detail__id { font-size: 0.72em; vertical-align: 0.12em; margin-right: 4px; }
|
|
62
|
-
.goal-card__foot { display: flex; flex-wrap: wrap; gap: 4px 10px; font-size: 11.5px; color: var(--ink-soft); }
|
|
63
|
-
.goal-card__foot strong { font-variant-numeric: tabular-nums; }
|
|
64
|
-
/* boot skeleton — goal-card-shaped shimmer placeholders (kit .kit-skel bars)
|
|
65
|
-
so the grid doesn't jump when data lands. */
|
|
66
|
-
.goal-card--skel { pointer-events: none; }
|
|
67
|
-
.goal-card--skel .kit-skel { width: 80%; }
|
|
68
|
-
.goal-card--skel .kit-skel + .kit-skel { width: 55%; }
|
|
69
64
|
|
|
70
65
|
/* ---- detail view ---- */
|
|
71
66
|
.goal-detail__head { display: flex; align-items: flex-start; gap: 20px; flex-wrap: wrap; }
|
|
@@ -228,117 +223,131 @@ a.goal-card:hover { text-decoration: none; background: var(--glass); }
|
|
|
228
223
|
.conflict__paths { font-family: var(--font-mono); font-size: 11.5px; color: var(--ink-soft); margin-top: 4px; word-break: break-all; }
|
|
229
224
|
.conflict-note { font-size: 12px; color: var(--ink-faint); margin: 10px 0 0; }
|
|
230
225
|
|
|
231
|
-
/*
|
|
232
|
-
.
|
|
226
|
+
/* The count line + the view toggle (list view): one line under the filter
|
|
227
|
+
bar. rows|cards is a VIEW, not a filter — it left the filter bar in task
|
|
228
|
+
1003470 for the archetype's segmented control (mock .viewtoggle). The pressed
|
|
229
|
+
side takes the tint the world gives a current thing (the ranks ladder, the
|
|
230
|
+
oversight select row), never the accent fill: a view is not a live door. */
|
|
231
|
+
.goals-line { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 10px 20px; margin: 0 0 6px; }
|
|
232
|
+
.goals-count-line { margin: 0; font-family: var(--font-mono); font-size: 12.5px; font-variant-numeric: tabular-nums; color: var(--ink-faint); }
|
|
233
|
+
.viewtoggle { display: inline-flex; align-items: center; gap: 3px; padding: 3px; border: var(--line) solid var(--rule-soft); border-radius: var(--radius-pill); }
|
|
234
|
+
.viewtoggle__btn {
|
|
235
|
+
min-height: 26px; min-width: 60px; padding: 0 14px;
|
|
236
|
+
font: inherit; font-size: 13px; text-transform: lowercase; color: var(--ink-faint);
|
|
237
|
+
background: none; border: 0; border-radius: var(--radius-pill); cursor: pointer;
|
|
238
|
+
}
|
|
239
|
+
.viewtoggle__btn:hover { color: var(--ink-soft); }
|
|
240
|
+
.viewtoggle__btn[aria-pressed="true"] { color: var(--accent-ink); background: var(--accent-tint); }
|
|
233
241
|
|
|
234
242
|
/* ============================================================
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
243
|
+
The list — task 1002439's grouped rollup, redesigned in task 1003470 (goal
|
|
244
|
+
1000081). ONE panel: the shell's .scroll (.goals-panel) holds the filter bar
|
|
245
|
+
under a hairline, the count line with the view toggle, the readiness band
|
|
246
|
+
(the family's .ov-figs) and the groups under .ov-group__head. The rows are
|
|
247
|
+
the archetype's (mock .goal): ring / content / right, air not edges, the
|
|
248
|
+
hairline on TOP so the first row after a head starts flush. Before this the
|
|
249
|
+
page was a bar of twelve controls on the ground over one --bg-card panel PER
|
|
250
|
+
GROUP, the readiness as three small dotted numbers, and the group heads on
|
|
251
|
+
the ground between panels.
|
|
240
252
|
============================================================ */
|
|
241
|
-
/* The OUTER container renders
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
253
|
+
/* The OUTER container renders full-width blocks, so it is block flow.
|
|
254
|
+
Id-selected on purpose: the cards view nests id-less .goal-grid wrappers per
|
|
255
|
+
group, which keep the real grid above. */
|
|
256
|
+
#goal-grid.goal-grid { display: block; gap: 0; background: none; }
|
|
257
|
+
/* The filter bar closes on a hairline so the figures under it read as the
|
|
258
|
+
panel's content, not as more controls. The kit's overflow row and its chips
|
|
259
|
+
sit inside the same rule. */
|
|
260
|
+
#goals-filters { margin: 0 0 18px; padding: 0 0 6px; border-bottom: var(--line) solid var(--rule-soft); }
|
|
261
|
+
#goals-filters .filters { margin-bottom: 10px; }
|
|
250
262
|
|
|
251
|
-
/* The
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
.gr-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
.gr-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
color: var(--ink-faint);
|
|
262
|
-
}
|
|
263
|
-
.gr-sec__n { font-size: 12px; color: var(--ink-faint); font-variant-numeric: tabular-nums; }
|
|
263
|
+
/* The readiness band: the family figure band with a dot in the label — the
|
|
264
|
+
same dots the roll line under every row uses, so the band and the rows are
|
|
265
|
+
one language. */
|
|
266
|
+
.gr-figs { margin-top: 18px; }
|
|
267
|
+
.gr-figs + .ov-group { margin-top: var(--sp-md); }
|
|
268
|
+
.gr-mark { display: inline-block; width: 7px; height: 7px; border-radius: 50%; margin-right: 8px; vertical-align: 1px; flex: none; }
|
|
269
|
+
.gr-mark--ready { background: var(--ok); }
|
|
270
|
+
.gr-mark--active { background: var(--info); }
|
|
271
|
+
.gr-mark--blocked { background: var(--warn); }
|
|
272
|
+
.gr-mark--backlog { background: var(--ink-faint); }
|
|
264
273
|
|
|
265
|
-
/* The
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
.gr-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
.gr-
|
|
275
|
-
.gr-row:hover { background: var(--glass); }
|
|
276
|
-
.gr-ringcol { flex: none; }
|
|
277
|
-
.gr-crit-none { display: inline-grid; place-items: center; width: 44px; height: 44px; border-radius: 50%; border: 2px solid var(--rule); color: var(--ink-faint); font-size: 13px; }
|
|
274
|
+
/* The rows. --ring is the ring column's width; the ring svg takes it. */
|
|
275
|
+
.gr-list { --ring: 44px; margin: 0; }
|
|
276
|
+
.gr-row { display: grid; grid-template-columns: var(--ring) minmax(0, 1fr) auto; gap: 24px; align-items: start; padding: 20px 0; border-top: var(--line) solid var(--rule-soft); }
|
|
277
|
+
.ov-group__head + .gr-list > .gr-row:first-child { border-top: 0; }
|
|
278
|
+
.gr-ringcol { width: var(--ring); flex: none; }
|
|
279
|
+
.gr-ringcol .goal-ring { width: var(--ring); height: var(--ring); display: block; }
|
|
280
|
+
/* The ring's figure is the machine's word: mono, quiet. */
|
|
281
|
+
.gr-ringcol .goal-ring__label { font-family: var(--font-mono); font-weight: 400; font-size: 11px; fill: var(--ink-soft); }
|
|
282
|
+
/* No done-when criteria yet: the empty track, and nothing drawn in it. */
|
|
283
|
+
.gr-crit-none { display: block; width: var(--ring); height: var(--ring); border-radius: 50%; border: 3px solid var(--rule-soft); box-sizing: border-box; }
|
|
278
284
|
.gr-main { min-width: 0; }
|
|
279
|
-
/* The
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
equal negative margin hands the space back so the row does not re-space. */
|
|
283
|
-
/* The name at the archetype's weight: 17px/500, not 15px/650. A heavy small
|
|
284
|
-
title reads as a label; this reads as the thing itself. It is also the way
|
|
285
|
-
into the goal, so it owes the 24px floor on both axes — the padding buys the
|
|
286
|
-
height and the equal negative margin hands the space back. */
|
|
285
|
+
/* The name at the archetype's weight: 17px/500, not a heavy label. It is the
|
|
286
|
+
way into the goal, so it owes the 24px floor on both axes — the padding buys
|
|
287
|
+
the height and the equal negative margin hands the space back. */
|
|
287
288
|
.gr-title {
|
|
288
289
|
display: inline-block; font-size: 17px; font-weight: 500; letter-spacing: -.014em;
|
|
289
290
|
color: var(--ink); line-height: 1.3; text-decoration: none;
|
|
290
|
-
min-height: 24px; min-width: 24px; padding: 3px 4px; margin:
|
|
291
|
+
min-height: 24px; min-width: 24px; padding: 3px 4px; margin: -3px -4px;
|
|
292
|
+
overflow-wrap: anywhere;
|
|
291
293
|
}
|
|
292
294
|
.gr-title:hover { color: var(--accent-ink); text-decoration: underline; text-underline-offset: 3px; }
|
|
293
|
-
/* The id rides INSIDE the title
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
/* The goal's own one-line explanation. Task 1003224 made this a tooltip; task
|
|
299
|
-
1003307 gives it the line back on the owner's call, because 35 of 72 goals
|
|
300
|
-
carry one and a tooltip does not exist on a touch screen. Empty goals render
|
|
301
|
-
no element at all, so a row without a subtitle simply closes up. */
|
|
295
|
+
/* The id rides INSIDE the title, mono and quiet, so every row's name starts at
|
|
296
|
+
the same x and the id never competes for the subtitle's line. */
|
|
297
|
+
.gr-title__id { font-family: var(--font-mono); font-size: 12px; font-weight: 400; font-variant-numeric: tabular-nums; color: var(--ink-faint); margin-right: 9px; }
|
|
298
|
+
/* The goal's own one-line explanation: 35 of 72 goals carry one, and a tooltip
|
|
299
|
+
does not exist on a touch screen (task 1003307, on the owner's call). */
|
|
302
300
|
.gr-sub { margin: 5px 0 0; color: var(--ink-soft); font-size: 14px; line-height: 1.5; max-width: var(--measure); }
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
how they sit together. */
|
|
301
|
+
/* The fact line: the state pill, the scope chips, the version chip and the
|
|
302
|
+
category chip — every label a goal carries, in one run. The pill and the
|
|
303
|
+
chips are the shell's; this only says how they sit together. */
|
|
307
304
|
.gr-facts { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 10px; margin: 12px 0 0; }
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
status became a pill. */
|
|
311
|
-
.gr-meta { font-size: 12px; color: var(--ink-faint); margin-top: 8px; font-variant-numeric: tabular-nums; }
|
|
305
|
+
.gr-facts .gr-cat { margin-left: 0; }
|
|
306
|
+
/* The roll line: what the goal's tasks are doing, only the non-zero buckets. */
|
|
312
307
|
.gr-roll { display: flex; flex-wrap: wrap; gap: 8px 18px; margin-top: 12px; }
|
|
313
|
-
.gr-d { display: inline-flex; align-items: center; gap:
|
|
314
|
-
.gr-d
|
|
308
|
+
.gr-d { display: inline-flex; align-items: center; gap: 8px; font-size: 13px; color: var(--ink-soft); font-variant-numeric: tabular-nums; }
|
|
309
|
+
.gr-d .gr-mark { margin-right: 0; }
|
|
315
310
|
.gr-d b { color: var(--ink); font-weight: 600; }
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
.gr-
|
|
321
|
-
.gr-
|
|
322
|
-
.gr-
|
|
323
|
-
.gr-
|
|
324
|
-
.gr-
|
|
311
|
+
/* The right column is ONE thing: the next action, or a one-line state. The
|
|
312
|
+
accent lands only on "claim next", the row's live door; the other states are
|
|
313
|
+
ink, and the blocked door is a ghost pill. Under it, the sort's date while a
|
|
314
|
+
date sort is on. */
|
|
315
|
+
.gr-right { display: flex; flex-direction: column; align-items: flex-end; gap: 10px; text-align: right; max-width: 244px; }
|
|
316
|
+
.gr-next { display: flex; flex-direction: column; align-items: flex-end; gap: 8px; max-width: 244px; }
|
|
317
|
+
.gr-next__t { font-size: 13px; color: var(--ink-soft); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 244px; }
|
|
318
|
+
.gr-state { display: inline-flex; align-items: center; gap: 7px; font-size: 13px; color: var(--ink-soft); text-align: left; }
|
|
319
|
+
.gr-state--ok { color: var(--ok); }
|
|
320
|
+
.gr-state__mark { width: 14px; height: 14px; flex: none; stroke: currentColor; fill: none; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
|
|
321
|
+
.gr-quiet { font-size: 13px; color: var(--ink-faint); }
|
|
322
|
+
.gr-when { font-size: 12.5px; color: var(--ink-faint); font-variant-numeric: tabular-nums; }
|
|
325
323
|
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
.gr-
|
|
329
|
-
.gr-pill
|
|
330
|
-
.gr-
|
|
331
|
-
.gr-
|
|
324
|
+
/* Achieved and archived goals are compact pills in BOTH views (mock .pill): a
|
|
325
|
+
hairline pill with the check drawn, the name at 500, the id in mono. */
|
|
326
|
+
.gr-pills { display: flex; flex-wrap: wrap; gap: 9px; margin: 18px 0 0; }
|
|
327
|
+
.gr-pill { display: inline-flex; align-items: center; gap: 10px; min-height: 34px; padding: 0 15px; border: var(--line) solid var(--rule); border-radius: var(--radius-pill); color: var(--ink-soft); font-size: 13px; text-decoration: none; }
|
|
328
|
+
.gr-pill:hover { border-color: var(--ink-faint); color: var(--ink); text-decoration: none; }
|
|
329
|
+
.gr-pill b { color: var(--ink); font-weight: 500; }
|
|
330
|
+
.gr-pill__mark { width: 16px; height: 16px; flex: none; stroke: var(--ok); fill: none; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
|
|
331
|
+
.gr-pill__id { font-family: var(--font-mono); font-size: 12px; color: var(--ink-faint); font-variant-numeric: tabular-nums; }
|
|
332
332
|
/* task 1002965 — the date an achieved/archived pill was ordered on, shown only
|
|
333
|
-
while a date sort is active (the pill's counterpart to .gr-
|
|
333
|
+
while a date sort is active (the pill's counterpart to .gr-when). */
|
|
334
334
|
.gr-pill__when { color: var(--ink-faint); font-variant-numeric: tabular-nums; }
|
|
335
|
-
.gr-pills--muted {
|
|
335
|
+
.gr-pills--muted .gr-pill { color: var(--ink-faint); }
|
|
336
|
+
.gr-pills--muted .gr-pill__mark { stroke: var(--ink-faint); }
|
|
337
|
+
|
|
338
|
+
/* Boot skeleton: row-shaped, in the skeleton tone (--bg-deep is black in dark). */
|
|
339
|
+
.gr-row--skel { pointer-events: none; }
|
|
340
|
+
.gr-skel__ring { display: block; width: var(--ring); height: var(--ring); border-radius: 50%; background: var(--skeleton); }
|
|
341
|
+
.gr-row--skel .kit-skel { display: block; width: 60%; }
|
|
342
|
+
.gr-row--skel .kit-skel + .kit-skel { width: 40%; margin-top: 10px; }
|
|
336
343
|
|
|
337
344
|
@media (max-width: 640px) {
|
|
338
|
-
.gr-
|
|
339
|
-
.gr-
|
|
340
|
-
.gr-next { align-items: flex-start; }
|
|
341
|
-
.gr-next__t { max-width: 100%; }
|
|
345
|
+
.gr-list { --ring: 36px; }
|
|
346
|
+
.gr-row { grid-template-columns: var(--ring) minmax(0, 1fr); gap: 14px 16px; padding: 18px 0; }
|
|
347
|
+
.gr-right, .gr-next { grid-column: 1 / -1; align-items: flex-start; text-align: left; max-width: 100%; }
|
|
348
|
+
.gr-next__t { max-width: 100%; white-space: normal; }
|
|
349
|
+
.goal-grid { grid-template-columns: minmax(0, 1fr); }
|
|
350
|
+
.goal-card { padding-right: 0; }
|
|
342
351
|
}
|
|
343
352
|
|
|
344
353
|
/* ── task 1003224: name, subtitle, and Claude's text at three weights ────────
|
|
@@ -9,6 +9,9 @@
|
|
|
9
9
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
10
10
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
11
11
|
<link rel="stylesheet" href="/builders/style.css?v=2026-07-03-goals1">
|
|
12
|
+
<!-- task 1003470: the family sheet the list's figure band and group heads
|
|
13
|
+
come from (.ov-figs, .ov-group__head), linked before the page's own. -->
|
|
14
|
+
<link rel="stylesheet" href="/builders/oversight.css">
|
|
12
15
|
<!-- Page-local styles (task 2171) — extracted from the old inline <style>
|
|
13
16
|
block per the hall placement rules; shared pager/filter/tab/count-pill
|
|
14
17
|
styles now live in style.css's hall-kit section. -->
|
|
@@ -42,19 +45,34 @@
|
|
|
42
45
|
</div>
|
|
43
46
|
|
|
44
47
|
<main id="hall-main">
|
|
45
|
-
<!-- LIST view
|
|
48
|
+
<!-- LIST view — ONE panel (task 1003470): the filter bar, the count line
|
|
49
|
+
with the rows|cards toggle, the readiness band and the groups all sit
|
|
50
|
+
on the shell's .scroll. It used to be a bar of twelve controls on the
|
|
51
|
+
ground over one panel PER GROUP. -->
|
|
46
52
|
<section id="goals-list-view" aria-labelledby="goals-list-h">
|
|
47
53
|
<h2 id="goals-list-h" class="sr-only">All goals</h2>
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
54
|
+
<div class="scroll goals-panel">
|
|
55
|
+
<!-- task 2171: the filter bar is built by OTBKit.makeFilterBar —
|
|
56
|
+
Version / Status / Sort in the open, the other five behind the
|
|
57
|
+
kit's Filters disclosure (task 1003470). Control ids are
|
|
58
|
+
unchanged so goals-page.js reads stay stable. -->
|
|
59
|
+
<div id="goals-filters"></div>
|
|
60
|
+
<div class="goals-line">
|
|
61
|
+
<p class="goals-count-line" id="goals-count" aria-live="polite"></p>
|
|
62
|
+
<!-- rows|cards is a view, not a filter. The hidden input is what
|
|
63
|
+
renderList reads (#f-goal-view) and what the saved pref restores;
|
|
64
|
+
the two buttons write it. -->
|
|
65
|
+
<div class="viewtoggle" role="group" aria-label="View" id="goals-view">
|
|
66
|
+
<input type="hidden" id="f-goal-view" value="list">
|
|
67
|
+
<button type="button" class="viewtoggle__btn" data-view="list" aria-pressed="true">rows</button>
|
|
68
|
+
<button type="button" class="viewtoggle__btn" data-view="cards" aria-pressed="false">cards</button>
|
|
69
|
+
</div>
|
|
70
|
+
</div>
|
|
71
|
+
<div class="goal-grid" id="goal-grid"></div>
|
|
72
|
+
<!-- task 2171: the grid's pager bar is stamped here by OTBKit
|
|
73
|
+
(pagerBarHtml('goals') — same ids, same otb.goals.perPage pref). -->
|
|
74
|
+
<div id="goals-pager-mount"></div>
|
|
75
|
+
</div>
|
|
58
76
|
</section>
|
|
59
77
|
|
|
60
78
|
<!-- DETAIL view (hash-routed: #/goal/N) -->
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
|
-
"_": "The hall's Goals list + goal detail through modules/ui-design/kit/render.js (task 1003307). Goals is the LIST ARCHETYPE the governance-and-lists re-skin applies across thirteen pages, so its floors are measured first and the rest are held against them. Populated look: node scripts/hall-preview/server.js --port 4620 --fixture-me, then --base-in/--base-out at that origin.",
|
|
2
|
+
"_": "The hall's Goals list + goal detail through modules/ui-design/kit/render.js (task 1003307; redesigned in task 1003470). Goals is the LIST ARCHETYPE the governance-and-lists re-skin applies across thirteen pages, so its floors are measured first and the rest are held against them. Populated look: node scripts/hall-preview/server.js --port 4620 --fixture-me, then --base-in/--base-out at that origin (the harness carries goals, goals/rollups and work-categories since task 1003470). `filters` opens the kit's Filters disclosure (the five lenses that left the open bar); `cards` flips the rows|cards toggle on the count line.",
|
|
3
3
|
"page": "/builders/goals",
|
|
4
4
|
"surface": "hall-ui",
|
|
5
5
|
"stub": {
|
|
6
6
|
"prefix": "/builders/"
|
|
7
7
|
},
|
|
8
8
|
"modeQuery": false,
|
|
9
|
-
"_feeds": "The kit's own stub carries no goal feed, so against it the page renders its EMPTY and SKELETON states — which is deliberate: an empty board is a state the floors must hold in. Against the hall-preview harness the same states render populated. The feed 404s are declared here, never hidden.
|
|
9
|
+
"_feeds": "The kit's own stub carries no goal feed, so against it the page renders its EMPTY and SKELETON states — which is deliberate: an empty board is a state the floors must hold in. Against the hall-preview harness the same states render populated. The feed 404s are declared here, never hidden.",
|
|
10
10
|
"ignoreRequests": [
|
|
11
11
|
"/api/(gds|bongos)/me$",
|
|
12
12
|
"/api/(gds|bongos)/me/",
|
|
@@ -36,13 +36,81 @@
|
|
|
36
36
|
"expect": {
|
|
37
37
|
"visible": [
|
|
38
38
|
"#goals-list-view",
|
|
39
|
-
"#goals-filters"
|
|
39
|
+
"#goals-filters",
|
|
40
|
+
"#goals-view"
|
|
40
41
|
],
|
|
41
42
|
"hidden": [
|
|
42
43
|
"#goal-detail-view"
|
|
43
44
|
]
|
|
44
45
|
}
|
|
45
46
|
},
|
|
47
|
+
"filters": {
|
|
48
|
+
"auth": true,
|
|
49
|
+
"actions": [
|
|
50
|
+
[
|
|
51
|
+
"wait",
|
|
52
|
+
600
|
|
53
|
+
],
|
|
54
|
+
[
|
|
55
|
+
"click",
|
|
56
|
+
"#goals-filters .filters__more"
|
|
57
|
+
],
|
|
58
|
+
[
|
|
59
|
+
"wait",
|
|
60
|
+
150
|
|
61
|
+
]
|
|
62
|
+
],
|
|
63
|
+
"expect": {
|
|
64
|
+
"visible": [
|
|
65
|
+
"#goals-filters .filters--overflow",
|
|
66
|
+
"#f-goal-category"
|
|
67
|
+
],
|
|
68
|
+
"attr": [
|
|
69
|
+
[
|
|
70
|
+
"#goals-filters .filters__more",
|
|
71
|
+
"aria-expanded",
|
|
72
|
+
"true"
|
|
73
|
+
]
|
|
74
|
+
]
|
|
75
|
+
}
|
|
76
|
+
},
|
|
77
|
+
"cards": {
|
|
78
|
+
"auth": true,
|
|
79
|
+
"actions": [
|
|
80
|
+
[
|
|
81
|
+
"wait",
|
|
82
|
+
600
|
|
83
|
+
],
|
|
84
|
+
[
|
|
85
|
+
"click",
|
|
86
|
+
"#goals-view [data-view=\"cards\"]"
|
|
87
|
+
],
|
|
88
|
+
[
|
|
89
|
+
"wait",
|
|
90
|
+
200
|
|
91
|
+
]
|
|
92
|
+
],
|
|
93
|
+
"expect": {
|
|
94
|
+
"attr": [
|
|
95
|
+
[
|
|
96
|
+
"#goals-view [data-view=\"cards\"]",
|
|
97
|
+
"aria-pressed",
|
|
98
|
+
"true"
|
|
99
|
+
],
|
|
100
|
+
[
|
|
101
|
+
"#goals-view [data-view=\"list\"]",
|
|
102
|
+
"aria-pressed",
|
|
103
|
+
"false"
|
|
104
|
+
]
|
|
105
|
+
],
|
|
106
|
+
"value": [
|
|
107
|
+
[
|
|
108
|
+
"#f-goal-view",
|
|
109
|
+
"cards"
|
|
110
|
+
]
|
|
111
|
+
]
|
|
112
|
+
}
|
|
113
|
+
},
|
|
46
114
|
"detail": {
|
|
47
115
|
"auth": true,
|
|
48
116
|
"url": "/builders/goals#/goal/1000081",
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/* people.css — page-local styles for the cross-project builder directory
|
|
2
|
+
(task 1003470, goal 1000081), served at /people and at its legacy door
|
|
3
|
+
/scouting, which loads the same page. Only the identity cell lives here: the
|
|
4
|
+
ledger, the filter bar, the pager, the chips and the empty state are the
|
|
5
|
+
shell's and the kit's. Tokens are the world's real names — no compat alias. */
|
|
6
|
+
|
|
7
|
+
/* The who cell: avatar, then the name over the login. A row that carries an
|
|
8
|
+
avatar centres its figures on it, so the numbers line up with the name. */
|
|
9
|
+
#people-body .ledger td { vertical-align: middle; }
|
|
10
|
+
.dir-who { display: inline-flex; align-items: center; gap: 11px; min-width: 0; }
|
|
11
|
+
.dir-avatar {
|
|
12
|
+
width: 30px; height: 30px; border-radius: 50%; flex: none;
|
|
13
|
+
object-fit: cover; background: var(--skeleton);
|
|
14
|
+
}
|
|
15
|
+
/* No avatar: the initial on the glass, never a broken image or a blank disc. */
|
|
16
|
+
.dir-avatar--initial {
|
|
17
|
+
display: inline-grid; place-items: center;
|
|
18
|
+
font-size: 12.5px; font-weight: 500; color: var(--ink-soft);
|
|
19
|
+
background: var(--glass-strong);
|
|
20
|
+
}
|
|
21
|
+
/* The name column keeps room for a login: on a phone the ledger scrolls in its
|
|
22
|
+
card (the shell's strip) rather than breaking a handle across two lines. */
|
|
23
|
+
.dir-who__t { display: flex; flex-direction: column; gap: 1px; min-width: 132px; }
|
|
24
|
+
.dir-name { font-weight: 500; color: var(--ink); overflow-wrap: anywhere; }
|
|
25
|
+
.dir-login { font-family: var(--font-mono); font-size: 11.5px; color: var(--ink-faint); }
|
|
26
|
+
.dir-crafts { display: inline-flex; flex-wrap: wrap; gap: 6px; }
|
|
27
|
+
.dir-none { color: var(--ink-faint); }
|
|
@@ -9,6 +9,9 @@
|
|
|
9
9
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
10
10
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
11
11
|
<link rel="stylesheet" href="/builders/style.css?v=2026-07-02-shell1">
|
|
12
|
+
<!-- task 1003470: the identity cell (avatar, name, login) is the one thing the
|
|
13
|
+
directory adds to the shell's ledger. -->
|
|
14
|
+
<link rel="stylesheet" href="/builders/people.css">
|
|
12
15
|
</head>
|
|
13
16
|
<body data-page="people" data-page-title="People">
|
|
14
17
|
|
|
@@ -18,19 +21,20 @@
|
|
|
18
21
|
<div class="app-body">
|
|
19
22
|
<header class="app-topbar" id="app-topbar"></header>
|
|
20
23
|
<div class="app-content">
|
|
21
|
-
<!--
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
is the LABEL voice, not a display line: on a working surface the
|
|
25
|
-
page's own name is the least interesting thing on it. -->
|
|
24
|
+
<!-- The board page head (task 1003307): the label voice, because on a
|
|
25
|
+
working surface the page's own name is the least interesting thing on
|
|
26
|
+
it. The sub is rewritten by people.js once the directory has loaded. -->
|
|
26
27
|
<div class="page-head page-head--board">
|
|
27
28
|
<h1 class="page-head__h">People</h1>
|
|
28
|
-
<p class="page-head__sub">Everyone building across hosted projects, ranked by track record. Descriptive only — cross-project numbers never carry authority here.</p>
|
|
29
|
+
<p class="page-head__sub" id="people-sub">Everyone building across hosted projects, ranked by track record. Descriptive only — cross-project numbers never carry authority here.</p>
|
|
29
30
|
</div>
|
|
30
31
|
|
|
31
32
|
<main id="hall-main">
|
|
33
|
+
<!-- task 1003470: ONE directory. /people and its legacy door /scouting
|
|
34
|
+
render this same page from the same script — the same
|
|
35
|
+
/api/gds/scouting rollup used to be drawn three different ways. -->
|
|
32
36
|
<section class="scroll" id="people-scroll" aria-labelledby="people-h">
|
|
33
|
-
<h2 id="people-h" class="scroll__h">Builder directory
|
|
37
|
+
<h2 id="people-h" class="scroll__h">Builder directory<span class="count-pill" id="people-count" hidden></span></h2>
|
|
34
38
|
<div id="people-filters"></div>
|
|
35
39
|
<div id="people-body">
|
|
36
40
|
<div class="profile__placeholder">Loading the directory…</div>
|
|
@@ -50,6 +54,10 @@
|
|
|
50
54
|
<script src="/builders/shell.js?v=2026-07-02-shell1"></script>
|
|
51
55
|
<!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
|
|
52
56
|
<script src="/builders/palette.js" defer></script>
|
|
57
|
+
<!-- shared frontend toolkit (window.OTB — rank labels, number formats) + the
|
|
58
|
+
branding pack's currency label, loaded BEFORE people.js. -->
|
|
59
|
+
<script src="/builders/dom-utils.js?v=2026-06-14-domutils"></script>
|
|
60
|
+
<script src="/builders/brand-apply.js"></script>
|
|
53
61
|
<script src="/builders/hall-kit.js"></script>
|
|
54
62
|
<script src="/builders/people.js"></script>
|
|
55
63
|
</body>
|