@bongos/core 1.19.458 → 1.19.460
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 +117 -42
- package/.claude/skills/design/SKILL.md +10 -0
- package/docs/adr/0219-a-look-is-a-branding-pack-the-style-library.md +30 -0
- package/docs/adr/README.md +1 -0
- package/docs/branding-contract.md +1 -1
- package/docs/copy-inventory.md +52 -61
- package/docs/copy-registry.json +92 -203
- package/docs/file-map.md +1 -1
- package/docs/module-api-changelog.md +4 -0
- package/docs/recipes/ui-look-before-you-ship.md +2 -0
- package/modules/hall-ui/public/collab-lib.js +40 -4
- package/modules/hall-ui/public/collab.css +18 -34
- package/modules/hall-ui/public/collab.html +17 -17
- package/modules/hall-ui/public/collab.js +75 -39
- package/modules/hall-ui/public/collab.states.json +2 -2
- package/modules/hall-ui/public/copy-desk.css +64 -109
- package/modules/hall-ui/public/copy-desk.html +76 -69
- package/modules/hall-ui/public/copy-desk.js +175 -80
- package/modules/hall-ui/public/copy-desk.states.json +59 -2
- package/modules/hall-ui/public/oversight.css +11 -2
- package/modules/lifecycle/help-requests.js +18 -8
- package/modules/ui-design/kit/README.md +7 -5
- package/modules/ui-design/kit/check-mock.js +12 -5
- package/modules/ui-design/kit/contrast.js +13 -6
- package/modules/ui-design/kit/lib.js +39 -2
- package/modules/ui-design/kit/probe.js +4 -1
- package/modules/ui-design/kit/render.js +7 -4
- package/modules/ui-design/kit/serve.js +9 -2
- package/modules/ui-design/styles/README.md +54 -2
- package/modules/ui-design/styles/chrome-world/DESIGN.md +56 -0
- package/modules/ui-design/styles/chrome-world/mock.html +275 -0
- package/modules/ui-design/styles/chrome-world/mock.states.json +11 -0
- package/modules/ui-design/styles/chrome-world/pack.json +33 -0
- package/modules/ui-design/styles/expedition/DESIGN.md +141 -0
- package/modules/ui-design/styles/expedition/mock.html +285 -0
- package/modules/ui-design/styles/expedition/mock.states.json +11 -0
- package/modules/ui-design/styles/expedition/pack.json +33 -0
- package/modules/ui-design/styles/grove/DESIGN.md +148 -0
- package/modules/ui-design/styles/grove/mock.html +294 -0
- package/modules/ui-design/styles/grove/mock.states.json +11 -0
- package/modules/ui-design/styles/grove/pack.json +33 -0
- package/package-lock.json +2 -2
- package/package.json +1 -1
- package/src/module-api.js +1 -1
- package/tests/collab_page.mjs +13 -7
- package/tests/cosmos_token_contrast.mjs +9 -2
- package/tests/hall_collab_world.mjs +214 -0
- package/tests/hall_tokens.mjs +15 -6
- package/tests/ui_design_styles.mjs +218 -0
- package/tests/world_tokens.mjs +9 -2
|
@@ -1,124 +1,79 @@
|
|
|
1
|
-
/* modules/hall-ui/public/copy-desk.css — the Copy desk
|
|
2
|
-
of goal 1000074)
|
|
1
|
+
/* modules/hall-ui/public/copy-desk.css — the Copy desk page (task 1003113 /
|
|
2
|
+
R02 of goal 1000074), rebuilt on the hall's row archetype by task 1003471:
|
|
3
|
+
the counts are the shell's glass .stat-row, every list is a run of
|
|
4
|
+
oversight.css's .ov-row, the filters and the search are the kit's .filters,
|
|
5
|
+
the two dialogs are the family's .ov-modal on a native <dialog>. What is
|
|
6
|
+
left here is what only this page has: the quoted string as evidence, the
|
|
7
|
+
reason as prose, the places a duplicate lives, the dialog's scrim.
|
|
3
8
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
defined here. */
|
|
9
|
+
px and tokens throughout, and state is COLOUR — the pill's verification
|
|
10
|
+
vocabulary — never opacity. Opacity dims the panel behind the text as well
|
|
11
|
+
as the text, which is why the first cut read muddy rather than quiet. */
|
|
8
12
|
|
|
9
|
-
.
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
.cd-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
gap: 0.15rem;
|
|
19
|
-
padding: 0.75rem 0.9rem;
|
|
20
|
-
border: var(--line) solid var(--rule-soft);
|
|
21
|
-
border-radius: var(--radius-sm);
|
|
22
|
-
background: var(--glass);
|
|
23
|
-
}
|
|
24
|
-
.cd-stat__n { font-size: 1.6rem; font-weight: 700; line-height: 1.1; }
|
|
25
|
-
.cd-stat__l { font-size: 0.8rem; opacity: 0.7; }
|
|
26
|
-
|
|
27
|
-
.cd-note { font-size: 0.85rem; opacity: 0.75; line-height: 1.5; }
|
|
28
|
-
/* 4px, not --radius-sm: a 10px radius on a 16px-tall inline span reads as a
|
|
29
|
-
pill, and the tier has no smaller token. Deliberate, not missed. */
|
|
30
|
-
.cd-note code {
|
|
31
|
-
padding: 0.05rem 0.3rem;
|
|
32
|
-
border-radius: 0.25rem;
|
|
33
|
-
background: var(--glass);
|
|
34
|
-
font-size: 0.95em;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
.cd-filters { display: flex; flex-wrap: wrap; gap: 0.5rem 0.75rem; align-items: center; margin: 0.5rem 0 1rem; }
|
|
38
|
-
.cd-filters__label { font-size: 0.8rem; opacity: 0.7; }
|
|
39
|
-
.cd-filters__select,
|
|
40
|
-
.cd-browse__input,
|
|
41
|
-
.cd-dialog__select,
|
|
42
|
-
.cd-dialog__input,
|
|
43
|
-
.cd-dialog__text {
|
|
44
|
-
padding: 0.4rem 0.6rem;
|
|
45
|
-
border: var(--line) solid var(--rule-soft);
|
|
46
|
-
border-radius: var(--radius-sm);
|
|
47
|
-
background: var(--bg-deep);
|
|
48
|
-
color: inherit;
|
|
49
|
-
font: inherit;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
.cd-browse { margin: 0.5rem 0 1rem; }
|
|
53
|
-
.cd-browse__label { display: block; font-size: 0.8rem; opacity: 0.7; margin-bottom: 0.3rem; }
|
|
54
|
-
.cd-browse__input { width: 100%; max-width: 34rem; }
|
|
55
|
-
|
|
56
|
-
.cd-list { display: flex; flex-direction: column; gap: 0.6rem; }
|
|
57
|
-
.cd-empty { padding: 1rem; opacity: 0.65; font-size: 0.9rem; }
|
|
58
|
-
|
|
59
|
-
.cd-card {
|
|
60
|
-
padding: 0.85rem 1rem;
|
|
61
|
-
border: var(--line) solid var(--rule-soft);
|
|
62
|
-
border-radius: var(--radius-sm);
|
|
13
|
+
/* The summary strip sits closer to its provenance line than to the next panel.
|
|
14
|
+
The inline code takes 4px, not --radius-sm: a 10px radius on a 16px-tall
|
|
15
|
+
inline span reads as a pill, and the tier has no smaller token. */
|
|
16
|
+
.cd-summary { margin-bottom: 12px; }
|
|
17
|
+
.cd-registry-note { margin: 0 0 var(--sp-md); max-width: 72ch; }
|
|
18
|
+
.cd-registry-note code,
|
|
19
|
+
.cd-search-count code {
|
|
20
|
+
padding: 1px 5px;
|
|
21
|
+
border-radius: 4px;
|
|
63
22
|
background: var(--glass);
|
|
23
|
+
font-family: var(--font-mono);
|
|
24
|
+
font-size: 11.5px;
|
|
25
|
+
color: var(--ink-soft);
|
|
64
26
|
}
|
|
65
|
-
.cd-card--slim { padding: 0.6rem 0.8rem; }
|
|
66
|
-
.cd-card__head { display: flex; flex-wrap: wrap; gap: 0.4rem; align-items: center; margin-bottom: 0.4rem; }
|
|
67
|
-
.cd-card__target { margin: 0.2rem 0 0.45rem; line-height: 1.5; }
|
|
68
|
-
.cd-card__actions { display: flex; flex-wrap: wrap; gap: 0.5rem; align-items: center; justify-content: flex-end; margin-top: 0.5rem; }
|
|
69
27
|
|
|
70
28
|
/* The quoted string is the product's own words, shown as evidence — so it is
|
|
71
|
-
|
|
72
|
-
leading and trailing space in a string is often exactly what is
|
|
29
|
+
set apart from this page's own voice: mono, in the ink, wrapping preserved
|
|
30
|
+
because leading and trailing space in a string is often exactly what is
|
|
31
|
+
wrong. It is the row's title, so it sits at the title's line, in the mono's
|
|
32
|
+
own size and weight. */
|
|
73
33
|
.cd-quote {
|
|
74
34
|
quotes: '"' '"';
|
|
75
35
|
font-family: var(--font-mono);
|
|
76
|
-
font-size:
|
|
36
|
+
font-size: 13.5px;
|
|
37
|
+
font-weight: 400;
|
|
38
|
+
letter-spacing: 0;
|
|
39
|
+
color: var(--ink);
|
|
77
40
|
white-space: pre-wrap;
|
|
78
|
-
|
|
41
|
+
overflow-wrap: anywhere;
|
|
79
42
|
}
|
|
80
|
-
.cd-
|
|
81
|
-
.cd-byline { font-size: 0.8rem; opacity: 0.65; margin-left: auto; }
|
|
82
|
-
.cd-reason { margin: 0.3rem 0 0; line-height: 1.55; }
|
|
83
|
-
.cd-snapshot-label { font-size: 0.8rem; opacity: 0.6; }
|
|
84
|
-
.cd-closed { margin: 0.5rem 0 0; font-size: 0.85rem; opacity: 0.8; line-height: 1.5; }
|
|
85
|
-
.cd-places { margin: 0.3rem 0 0; padding-left: 1.1rem; font-size: 0.8rem; opacity: 0.65; font-family: var(--font-mono); }
|
|
43
|
+
.cd-snapshot-label { font-size: 12.5px; font-weight: 400; color: var(--ink-faint); }
|
|
86
44
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
letter-spacing: 0.02em;
|
|
94
|
-
opacity: 0.85;
|
|
95
|
-
}
|
|
96
|
-
.cd-tag--kind { font-weight: 600; opacity: 1; }
|
|
97
|
-
/* 'untouched' is the only state that is WORK, so it is the only one that carries
|
|
98
|
-
colour — a queue where everything is highlighted highlights nothing. */
|
|
99
|
-
.cd-tag--untouched { border-color: currentColor; opacity: 1; }
|
|
100
|
-
.cd-tag--flagged,
|
|
101
|
-
.cd-tag--settled,
|
|
102
|
-
.cd-tag--moved { opacity: 0.6; }
|
|
103
|
-
.cd-tag--gone { opacity: 0.75; font-style: italic; }
|
|
45
|
+
/* The reason is the judgement the artist reads, so it takes the body ink at
|
|
46
|
+
body size rather than the sub line's soft ink, and the detail-lines' 72ch
|
|
47
|
+
rather than the clause measure: a reason is a paragraph. */
|
|
48
|
+
.cd-reason { font-size: 14px; color: var(--ink); max-width: 72ch; }
|
|
49
|
+
.cd-closed { margin: 8px 0 0; font-size: 13px; line-height: 1.5; color: var(--ink-soft); max-width: 72ch; }
|
|
50
|
+
.cd-closed b { color: var(--ink); font-weight: 500; }
|
|
104
51
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
52
|
+
/* Where a duplicate lives: one mono line per place and no hairlines — seven
|
|
53
|
+
near-identical file:line lines ruled apart read as a table nobody laid out. */
|
|
54
|
+
.cd-places {
|
|
55
|
+
list-style: none;
|
|
56
|
+
margin: 8px 0 0;
|
|
57
|
+
padding: 0;
|
|
58
|
+
font-family: var(--font-mono);
|
|
59
|
+
font-size: 12px;
|
|
60
|
+
line-height: 1.6;
|
|
61
|
+
color: var(--ink-faint);
|
|
112
62
|
}
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
63
|
+
.cd-places li { overflow-wrap: anywhere; }
|
|
64
|
+
|
|
65
|
+
/* The search field takes the room a phrase needs. */
|
|
66
|
+
.cd-find .filter { flex: 1 1 280px; max-width: 520px; }
|
|
67
|
+
.cd-find .filter input[type="search"] { width: 100%; }
|
|
68
|
+
.cd-search-count { margin: 0 0 14px; }
|
|
69
|
+
|
|
70
|
+
/* The two dialogs are the family modal on a native <dialog>: bg-card, one rule
|
|
71
|
+
hairline, no shadow. The backdrop is the one literal this sheet keeps — pure
|
|
72
|
+
black with alpha as a SCRIM is the exception the Fifteen Rule names, and a
|
|
73
|
+
backdrop cannot take a ground token: it has to darken whatever is behind it
|
|
74
|
+
in either mode. */
|
|
75
|
+
.cd-dialog { width: min(480px, calc(100vw - 32px)); color: var(--ink); }
|
|
116
76
|
.cd-dialog::backdrop { background: rgba(0, 0, 0, 0.55); }
|
|
117
|
-
.cd-
|
|
118
|
-
.cd-
|
|
119
|
-
.cd-
|
|
120
|
-
.cd-dialog__hint { display: block; font-weight: 400; font-size: 0.78rem; opacity: 0.65; line-height: 1.45; margin-top: 0.1rem; }
|
|
121
|
-
.cd-dialog__select, .cd-dialog__input, .cd-dialog__text { width: 100%; }
|
|
122
|
-
.cd-dialog__text { resize: vertical; line-height: 1.5; }
|
|
123
|
-
.cd-dialog__err { min-height: 1.2rem; margin: 0.5rem 0 0; font-size: 0.85rem; color: var(--danger); line-height: 1.45; }
|
|
124
|
-
.cd-dialog__actions { display: flex; gap: 0.5rem; justify-content: flex-end; margin-top: 0.9rem; }
|
|
77
|
+
.cd-dialog .ov-form { margin: 14px 0 0; }
|
|
78
|
+
.cd-dialog textarea { resize: vertical; line-height: 1.5; }
|
|
79
|
+
.ov-modal .cd-dialog__err { min-height: 18px; margin: 8px 0 0; font-size: 13px; line-height: 1.45; color: var(--danger); }
|
|
@@ -9,6 +9,7 @@
|
|
|
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
|
+
<link rel="stylesheet" href="/builders/oversight.css">
|
|
12
13
|
<link rel="stylesheet" href="/builders/copy-desk.css">
|
|
13
14
|
</head>
|
|
14
15
|
<body data-page="copy-desk" data-page-title="Copy desk">
|
|
@@ -19,42 +20,33 @@
|
|
|
19
20
|
<div class="app-body">
|
|
20
21
|
<header class="app-topbar" id="app-topbar"></header>
|
|
21
22
|
<div class="app-content">
|
|
22
|
-
<!--
|
|
23
|
-
|
|
24
|
-
|
|
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. -->
|
|
23
|
+
<!-- The board page head: the page's own name in the LABEL voice, not a
|
|
24
|
+
display line — on a working surface it is the least interesting
|
|
25
|
+
thing on it. -->
|
|
27
26
|
<div class="page-head page-head--board">
|
|
28
27
|
<h1 class="page-head__h">Copy desk</h1>
|
|
29
28
|
<p class="page-head__sub" id="cd-sub">Loading the copy desk…</p>
|
|
30
29
|
</div>
|
|
31
30
|
|
|
32
31
|
<main id="hall-main">
|
|
33
|
-
<!-- The counts
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
32
|
+
<!-- The counts: the shell's glass band of figures at the top of the page,
|
|
33
|
+
not a panel of boxes. Deliberately four numbers and not a dashboard:
|
|
34
|
+
open work, the fast pile (targets that have since been edited away),
|
|
35
|
+
untouched duplicates, and how big the inventory is — each with the
|
|
36
|
+
clause that says what it means. The provenance line under it names
|
|
37
|
+
the artifact this whole page describes. -->
|
|
38
|
+
<section class="stat-row ov-summary cd-summary" id="cd-summary-scroll" aria-label="Where the words stand"></section>
|
|
39
|
+
<p class="ov-foot cd-registry-note" id="cd-registry-note"></p>
|
|
41
40
|
|
|
42
|
-
<!-- The queue.
|
|
41
|
+
<!-- The queue. Every flag is a row of the hall's row archetype: the
|
|
42
|
+
string as the title (the product's own words, as evidence), the
|
|
43
|
+
reason as the prose under it, the kind and the target's state as
|
|
44
|
+
pills, who flagged it as a fact, when in the right column. -->
|
|
43
45
|
<section class="scroll" id="cd-flags-scroll" aria-labelledby="cd-flags-h">
|
|
44
46
|
<h2 id="cd-flags-h" class="scroll__h">Flagged</h2>
|
|
45
|
-
<p class="scroll__lede">Copy someone has judged as needing attention, with their reason. Anyone can file one; closing it needs Metic
|
|
46
|
-
<div
|
|
47
|
-
|
|
48
|
-
<select id="cd-status" class="cd-filters__select">
|
|
49
|
-
<option value="open" selected>Open</option>
|
|
50
|
-
<option value="resolved">Resolved</option>
|
|
51
|
-
<option value="dismissed">Dismissed</option>
|
|
52
|
-
<option value="all">Everything</option>
|
|
53
|
-
</select>
|
|
54
|
-
<label class="cd-filters__label" for="cd-surface">Surface</label>
|
|
55
|
-
<select id="cd-surface" class="cd-filters__select"><option value="">All surfaces</option></select>
|
|
56
|
-
</div>
|
|
57
|
-
<div class="cd-list" id="cd-flags"><div class="cd-empty">Loading…</div></div>
|
|
47
|
+
<p class="scroll__lede">Copy someone has judged as needing attention, with their reason. Anyone can file one; closing it needs the <span id="cd-close-rank">Metic</span> rank or above, or that it is your own.</p>
|
|
48
|
+
<div id="cd-filters"></div>
|
|
49
|
+
<div id="cd-flags"><div class="empty-state"><p>Loading…</p></div></div>
|
|
58
50
|
</section>
|
|
59
51
|
|
|
60
52
|
<!-- The one signal a machine can compute with no judgement layer at all
|
|
@@ -63,7 +55,7 @@
|
|
|
63
55
|
<section class="scroll" id="cd-dupes-scroll" aria-labelledby="cd-dupes-h">
|
|
64
56
|
<h2 id="cd-dupes-h" class="scroll__h">Said more than once</h2>
|
|
65
57
|
<p class="scroll__lede">The same sentence, in several places. Sometimes that is right and the answer is to dismiss it; sometimes it is seven copies of an error message that should have been one. Nobody has looked at the ones marked untouched.</p>
|
|
66
|
-
<div
|
|
58
|
+
<div id="cd-dupes"><div class="empty-state"><p>Loading…</p></div></div>
|
|
67
59
|
</section>
|
|
68
60
|
|
|
69
61
|
<!-- Find any string in the product and flag it. Without this the queue
|
|
@@ -71,13 +63,9 @@
|
|
|
71
63
|
<section class="scroll" id="cd-find-scroll" aria-labelledby="cd-find-h">
|
|
72
64
|
<h2 id="cd-find-h" class="scroll__h">Find something to flag</h2>
|
|
73
65
|
<p class="scroll__lede">Search every string the product shows a person, by what it says or the file it lives in.</p>
|
|
74
|
-
<div class="cd-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
placeholder="a phrase you saw, or a file name…">
|
|
78
|
-
<p class="cd-note" id="cd-search-count" role="status" aria-live="polite"></p>
|
|
79
|
-
</div>
|
|
80
|
-
<div class="cd-list" id="cd-results"></div>
|
|
66
|
+
<div class="cd-find" id="cd-find"></div>
|
|
67
|
+
<p class="ov-foot cd-search-count" id="cd-search-count" role="status" aria-live="polite"></p>
|
|
68
|
+
<div id="cd-results"></div>
|
|
81
69
|
</section>
|
|
82
70
|
</main>
|
|
83
71
|
|
|
@@ -88,50 +76,68 @@
|
|
|
88
76
|
|
|
89
77
|
<!-- The flag composer. A dialog rather than an inline field because the reason is
|
|
90
78
|
the point: a one-line input invites "typo", and the queue is only worth
|
|
91
|
-
reading if the reasons are.
|
|
92
|
-
|
|
79
|
+
reading if the reasons are. A native <dialog> (its own focus trap and
|
|
80
|
+
Escape) dressed as the family's confirm modal. -->
|
|
81
|
+
<dialog id="cd-dialog" class="ov-modal cd-dialog">
|
|
93
82
|
<form method="dialog" id="cd-form">
|
|
94
|
-
<h3 class="
|
|
83
|
+
<h3 class="scroll__h" id="cd-dialog-h">Flag this copy</h3>
|
|
95
84
|
<p class="cd-dialog__target" id="cd-dialog-target"></p>
|
|
96
|
-
<
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
85
|
+
<div class="ov-form">
|
|
86
|
+
<div class="ov-field ov-field--wide">
|
|
87
|
+
<label class="ov-field__l" for="cd-kind">What kind of wrong?</label>
|
|
88
|
+
<select id="cd-kind">
|
|
89
|
+
<option value="off-voice">Off voice — says it in the wrong register</option>
|
|
90
|
+
<option value="slop">Slop — reads as machine-written</option>
|
|
91
|
+
<option value="unclear">Unclear — a person would not know what to do</option>
|
|
92
|
+
<option value="stale">Stale — describes something that changed</option>
|
|
93
|
+
<option value="duplicate">Duplicate — should be said once, in one place</option>
|
|
94
|
+
<option value="typo">Typo or grammar</option>
|
|
95
|
+
<option value="other" selected>Something else</option>
|
|
96
|
+
</select>
|
|
97
|
+
</div>
|
|
98
|
+
<div class="ov-field ov-field--wide">
|
|
99
|
+
<label class="ov-field__l" for="cd-reason">Why?</label>
|
|
100
|
+
<textarea id="cd-reason" rows="4" minlength="10" required
|
|
101
|
+
placeholder="What is wrong with it, and what would better look like?"></textarea>
|
|
102
|
+
</div>
|
|
103
|
+
<p class="ov-form__why">The artist reads this instead of guessing. A pointer with no judgement costs them a look and tells them nothing.</p>
|
|
104
|
+
</div>
|
|
109
105
|
<p class="cd-dialog__err" id="cd-dialog-err" role="alert"></p>
|
|
110
|
-
<div class="
|
|
111
|
-
<button type="button" class="btn
|
|
112
|
-
<button type="button" class="btn" id="cd-submit">File the flag</button>
|
|
106
|
+
<div class="ov-modal__actions">
|
|
107
|
+
<button type="button" class="btn-ghost" id="cd-cancel">Cancel</button>
|
|
108
|
+
<button type="button" class="btn-accent" id="cd-submit">File the flag</button>
|
|
113
109
|
</div>
|
|
114
110
|
</form>
|
|
115
111
|
</dialog>
|
|
116
112
|
|
|
117
113
|
<!-- Closing a flag asks for a note for the same reason opening one does. -->
|
|
118
|
-
<dialog id="cd-close-dialog" class="cd-dialog">
|
|
114
|
+
<dialog id="cd-close-dialog" class="ov-modal cd-dialog">
|
|
119
115
|
<form method="dialog" id="cd-close-form">
|
|
120
|
-
<h3 class="
|
|
116
|
+
<h3 class="scroll__h">Close this flag</h3>
|
|
121
117
|
<p class="cd-dialog__target" id="cd-close-target"></p>
|
|
122
|
-
<
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
118
|
+
<div class="ov-form">
|
|
119
|
+
<div class="ov-field ov-field--wide">
|
|
120
|
+
<label class="ov-field__l" for="cd-close-status">Outcome</label>
|
|
121
|
+
<select id="cd-close-status">
|
|
122
|
+
<option value="resolved" selected>Resolved — the copy was changed</option>
|
|
123
|
+
<option value="dismissed">Dismissed — looked at, leaving it as it is</option>
|
|
124
|
+
</select>
|
|
125
|
+
</div>
|
|
126
|
+
<div class="ov-field ov-field--wide">
|
|
127
|
+
<label class="ov-field__l" for="cd-close-task">Task that carried the fix</label>
|
|
128
|
+
<input type="number" id="cd-close-task" placeholder="e.g. 1003113" min="1">
|
|
129
|
+
</div>
|
|
130
|
+
<p class="ov-form__why">Optional. This is the ledger link — a copy change ships as a task like every other change.</p>
|
|
131
|
+
<div class="ov-field ov-field--wide">
|
|
132
|
+
<label class="ov-field__l" for="cd-close-note">Note</label>
|
|
133
|
+
<textarea id="cd-close-note" rows="3" minlength="10" required></textarea>
|
|
134
|
+
</div>
|
|
135
|
+
<p class="ov-form__why">The next person to notice this sentence reads your note instead of re-litigating it.</p>
|
|
136
|
+
</div>
|
|
131
137
|
<p class="cd-dialog__err" id="cd-close-err" role="alert"></p>
|
|
132
|
-
<div class="
|
|
133
|
-
<button type="button" class="btn
|
|
134
|
-
<button type="button" class="btn" id="cd-close-submit">Close it</button>
|
|
138
|
+
<div class="ov-modal__actions">
|
|
139
|
+
<button type="button" class="btn-ghost" id="cd-close-cancel">Cancel</button>
|
|
140
|
+
<button type="button" class="btn-accent" id="cd-close-submit">Close it</button>
|
|
135
141
|
</div>
|
|
136
142
|
</form>
|
|
137
143
|
</dialog>
|
|
@@ -141,6 +147,7 @@
|
|
|
141
147
|
<script src="/builders/shell.js?v=2026-07-02-shell1"></script>
|
|
142
148
|
<script src="/builders/palette.js" defer></script>
|
|
143
149
|
<script src="/builders/dom-utils.js?v=2026-06-23-contrib"></script>
|
|
144
|
-
<script src="/builders/
|
|
150
|
+
<script src="/builders/hall-kit.js"></script>
|
|
151
|
+
<script src="/builders/copy-desk.js?v=2026-09-01-redesign"></script>
|
|
145
152
|
</body>
|
|
146
153
|
</html>
|