@lovek4d/kickflip 0.3.1 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CONTEXT.md +151 -115
- package/README.md +23 -14
- package/SKILL.md +37 -37
- package/bin/doctor.mjs +4 -4
- package/bin/install.mjs +3 -3
- package/bin/kickflip.mjs +34 -26
- package/bin/wait-events.mjs +2 -2
- package/board/arch-review.mjs +1 -1
- package/board/auto-review.mjs +2 -0
- package/board/bin/board.mjs +186 -69
- package/board/domain.mjs +8 -5
- package/board/finish.mjs +3 -0
- package/board/headless.mjs +3 -0
- package/board/on-host.mjs +1 -1
- package/board/permissions.mjs +2 -0
- package/board/public/app-arch.js +2 -2
- package/board/public/app-asks.js +57 -38
- package/board/public/app-banner.js +2 -2
- package/board/public/app-cards.js +156 -72
- package/board/public/app-core.js +2 -4
- package/board/public/app-header.js +12 -5
- package/board/public/app-lanes.js +201 -47
- package/board/public/app-needs.js +2 -1
- package/board/public/app-snapshot.js +2 -2
- package/board/public/app-threads.js +11 -14
- package/board/public/app.html +2 -1
- package/board/public/app.js +53 -83
- package/board/public/attach.js +39 -3
- package/board/public/dialogs.js +59 -14
- package/board/public/hub-kit.js +9 -6
- package/board/public/hub.css +5 -18
- package/board/public/linear-key.js +6 -4
- package/board/public/log.html +48 -0
- package/board/public/prompts.js +9 -8
- package/board/public/prototype-kit.js +6 -6
- package/board/public/prototype-switcher.js +13 -5
- package/board/public/prototype.html +1 -0
- package/board/public/router.js +8 -7
- package/board/public/rules-editor.js +3 -4
- package/board/public/shell.js +20 -6
- package/board/public/sidebar.css +21 -1
- package/board/public/sidebar.js +64 -31
- package/board/public/style.css +155 -62
- package/board/public/toasts.js +2 -2
- package/board/public/ui-cards.js +176 -71
- package/board/public/ui-enums.js +5 -4
- package/board/public/ui-header.js +10 -10
- package/board/public/ui-hub.js +4 -4
- package/board/public/ui-markdown.js +1 -1
- package/board/public/ui-order.js +9 -6
- package/board/public/ui-page-header.js +10 -7
- package/board/public/ui-patch.js +53 -0
- package/board/public/ui-phase-bars.js +17 -0
- package/board/public/ui-prompts.js +8 -8
- package/board/public/ui-questions.js +26 -23
- package/board/public/ui-sidebar.js +46 -22
- package/board/public/ui-snapshot.js +20 -9
- package/board/public/ui-threads.js +17 -11
- package/board/public/ui.js +80 -12
- package/board/public/view-frame.js +1 -1
- package/board/public/view-hub-settings.js +25 -18
- package/board/public/view-hub.js +53 -12
- package/board/public/view-notes.js +1 -1
- package/board/public/view-questions.js +101 -50
- package/board/public/view-settings.js +167 -49
- package/board/review.mjs +1 -1
- package/board/server.mjs +18 -12
- package/board/store.mjs +13 -12
- package/board/tickets.mjs +3 -3
- package/board/worktree.mjs +20 -14
- package/docs/hub-session.md +4 -4
- package/hooks-plugin/hooks/codex-share-auto.mjs +1 -1
- package/hooks-plugin/hooks/watcher-stop.mjs +2 -2
- package/hub/board-repo.mjs +1 -1
- package/hub/boards.mjs +4 -4
- package/hub/close-board.mjs +1 -1
- package/hub/github.mjs +4 -4
- package/hub/home.mjs +1 -1
- package/hub/hub.mjs +12 -12
- package/hub/incoming.mjs +2 -0
- package/hub/linear.mjs +2 -2
- package/hub/live.mjs +2 -2
- package/hub/new-board.mjs +2 -2
- package/hub/permission-denied-hook.mjs +2 -0
- package/hub/pr-report.mjs +3 -1
- package/hub/presence.mjs +1 -1
- package/hub/prompts.mjs +1 -1
- package/hub/push.mjs +2 -2
- package/hub/readiness.mjs +2 -2
- package/hub/repos.mjs +3 -3
- package/hub/restart-board.mjs +1 -1
- package/hub/schedule.mjs +1 -1
- package/hub/sessions.mjs +2 -2
- package/hub/sw.js +1 -1
- package/hub/try.mjs +8 -4
- package/hub/usage.mjs +3 -3
- package/hub/views.mjs +1 -1
- package/package.json +5 -1
- package/shared/card-prs.mjs +1 -0
- package/shared/colors.css +5 -4
- package/shared/fake-gh.mjs +59 -8
- package/shared/repos.mjs +1 -1
- package/shared/usage-gate.mjs +1 -1
- package/board/public/view-polling.js +0 -87
package/board/public/style.css
CHANGED
|
@@ -14,7 +14,7 @@ button:disabled { opacity: .5; cursor: default; }
|
|
|
14
14
|
button.primary { background: var(--accent); border-color: var(--accent); color: var(--on-accent); }
|
|
15
15
|
a.button { display: inline-block; border: 1px solid var(--line); border-radius: 7px; padding: 6px 10px; background: var(--panel); color: var(--text); text-decoration: none; }
|
|
16
16
|
/* resolves: the button that clears a card's Action needed (board/domain.mjs resolvedBy), in that badge's notice tone. */
|
|
17
|
-
:is(a, button).resolves, button.build, button.unhold, button.closes { border-color: var(--color-notice); background: var(--color-notice); color: #1c1407; }
|
|
17
|
+
:is(a, button).resolves, button.build.ready, button.unhold, button.closes { border-color: var(--color-notice); background: var(--color-notice); color: #1c1407; }
|
|
18
18
|
button.ghost { border-color: transparent; background: transparent; font-size: 18px; padding: 2px 8px; }
|
|
19
19
|
textarea, input { font: inherit; color: inherit; background: var(--panel); border: 1px solid var(--line);
|
|
20
20
|
border-radius: 8px; padding: 8px 10px; width: 100%; resize: vertical; }
|
|
@@ -72,7 +72,7 @@ main { max-width: 860px; margin: 0 auto; padding: 12px 16px 80px; }
|
|
|
72
72
|
padding: 1px 7px; font-size: 12px; white-space: nowrap; color: var(--text); }
|
|
73
73
|
button.chip { border: 0; }
|
|
74
74
|
.chip.tone-quiet { color: var(--color-quiet); } .chip.tone-normal { color: var(--color-info); } .chip.tone-notice { color: var(--color-notice); }
|
|
75
|
-
.chip.tone-danger { color: var(--color-danger); } .chip.tone-ready { color: var(--color-success); }
|
|
75
|
+
.chip.tone-danger { color: var(--color-danger); } .chip.tone-ready { color: var(--color-success); } .chip.tone-merged { color: var(--color-merged); }
|
|
76
76
|
/* Action needed keeps the notice orange; unread takes the accent so the two never read alike. */
|
|
77
77
|
.dot { width: 8px; height: 8px; border-radius: 50%; display: inline-block; background: var(--color-quiet); }
|
|
78
78
|
.dot.pass { background: var(--color-success); } .dot.pending { background: var(--color-notice); } .dot.fail { background: var(--color-danger); }
|
|
@@ -86,7 +86,7 @@ button.chip { border: 0; }
|
|
|
86
86
|
.card-ready { color: var(--color-success); }
|
|
87
87
|
.sub.next.idle { color: var(--muted); }
|
|
88
88
|
.sub.refused { color: var(--color-danger); }
|
|
89
|
-
.toast-stack { position: fixed; left: 50%; bottom: calc(var(--app-bottom, 0px) +
|
|
89
|
+
.toast-stack { position: fixed; left: 50%; bottom: calc(var(--app-bottom, 0px) + 12px + env(safe-area-inset-bottom));
|
|
90
90
|
width: min(520px, calc(100vw - 32px)); height: 0; transform: translateX(-50%); z-index: 25; pointer-events: none; }
|
|
91
91
|
.toast-row { position: absolute; top: 0; left: 0; width: 100%; display: flex; justify-content: center;
|
|
92
92
|
transition: transform 200ms ease; pointer-events: none; }
|
|
@@ -101,7 +101,7 @@ button.chip { border: 0; }
|
|
|
101
101
|
.grid { display: grid; grid-template-columns: 110px 1fr; gap: 4px 10px; font-size: 13px; margin: 6px 0 10px; }
|
|
102
102
|
.grid dt { color: var(--muted); }
|
|
103
103
|
.grid dd { margin: 0; min-width: 0; overflow-wrap: anywhere; }
|
|
104
|
-
/* A link row's labels open their cards, with room to tap (docs/adr/
|
|
104
|
+
/* A link row's labels open their cards, with room to tap (docs/adr/2026-11-03-0526-a-follow-up-is-a-work-card-with-a-parent.md). */
|
|
105
105
|
.grid dd a.card-link { display: inline-block; padding: 6px 4px; margin: -6px 0; text-decoration: underline; text-underline-offset: 2px; }
|
|
106
106
|
.external-links-label { position: absolute; width: 1px; height: 1px; padding: 0; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
|
|
107
107
|
.grid .external-links { grid-column: 1 / -1; display: flex; flex-wrap: wrap; align-items: baseline; gap: 3px 0; }
|
|
@@ -128,7 +128,7 @@ button.chip { border: 0; }
|
|
|
128
128
|
.thread-more:active { background: var(--accent-soft); }
|
|
129
129
|
.thread-more:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
|
|
130
130
|
.thread-more .n { color: var(--muted); font-weight: 400; }
|
|
131
|
-
/*
|
|
131
|
+
/* [answered asks have their own section below Done, and Done and Asks show 10 cards at a time](docs/adr/2026-11-03-0259-answered-asks-have-their-own-section-below-done.md): Done's and Asks' Show more, the thread's look as a row of the lane's list */
|
|
132
132
|
.list > .thread-more { width: 100%; margin: 0; border-top: 1px solid var(--line); border-radius: 0; }
|
|
133
133
|
|
|
134
134
|
@media (max-width: 560px) {
|
|
@@ -140,23 +140,41 @@ button.chip { border: 0; }
|
|
|
140
140
|
.calls ul { margin: 4px 0 8px; padding-left: 18px; font-size: 13px; }
|
|
141
141
|
button.link { background: none; border: 0; color: var(--accent); padding: 8px 12px; font-size: 13px; cursor: pointer; }
|
|
142
142
|
.wave-icon { display: inline-block; vertical-align: -2px; flex: none; }
|
|
143
|
-
.wv-row { padding: 10px 12px; border-top: 1px solid var(--line); min-width: 0; cursor: pointer; }
|
|
144
|
-
.wv-row:first-child { border-top: 0; }
|
|
145
|
-
.wv-row.on { background: var(--accent-soft); box-shadow: inset 3px 0 0 var(--accent); }
|
|
146
|
-
.wv-id { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0 8px; min-width: 0; }
|
|
147
|
-
.wv-name { display: inline-flex; align-items: center; gap: 5px; min-height: 30px; min-width: 0; padding: 0; border: 0; background: none;
|
|
148
|
-
font: inherit; font-weight: 600; color: var(--text); text-align: left; overflow-wrap: anywhere; cursor: pointer; }
|
|
149
|
-
.wv-name .wave-icon { color: var(--color-quiet); }
|
|
150
|
-
.wv-row.on .wv-name, .wv-row.on .wv-name .wave-icon { color: var(--accent); }
|
|
151
|
-
.wv-id .muted { white-space: nowrap; }
|
|
152
|
-
.wv-note { margin-top: 4px; font-size: 13px; color: var(--muted); overflow-wrap: anywhere; }
|
|
153
|
-
.wv-note b { color: var(--text); font-weight: 600; }
|
|
154
|
-
.wv-links { display: flex; flex-wrap: wrap; align-items: baseline; gap: 3px 0; margin-top: 6px; font-size: 13px; }
|
|
155
143
|
.wv-link { border: 0; background: none; padding: 0; min-height: 0; color: var(--accent); font: inherit; cursor: pointer; }
|
|
156
|
-
.wv-
|
|
144
|
+
.wv-link:disabled { color: var(--muted); cursor: default; }
|
|
157
145
|
.wv-busy { display: inline-flex; align-items: center; gap: 6px; color: var(--color-notice); }
|
|
158
|
-
.
|
|
159
|
-
.
|
|
146
|
+
/* docs/adr/2026-11-03-1840-waves-are-bands-in-todo.md: each wave is a lane-style band inside Todo's list. */
|
|
147
|
+
.wb + .wb, .wb-loose { border-top: 1px solid var(--line); }
|
|
148
|
+
.wb-head { position: relative; display: flex; flex-wrap: wrap; align-items: center; gap: 2px 8px; min-height: 34px; padding: 5px 12px;
|
|
149
|
+
background: var(--band); font-size: 13px; font-weight: 500; cursor: pointer; user-select: none; }
|
|
150
|
+
.wb-head:hover { background: color-mix(in srgb, var(--band), var(--text) 5%); }
|
|
151
|
+
.wb-head:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
|
|
152
|
+
.wb-head .wave-icon { color: var(--muted); }
|
|
153
|
+
.wb-head .count { color: var(--muted); font-weight: 400; }
|
|
154
|
+
.wb[data-open] > .wb-head { border-bottom: 1px solid var(--line); }
|
|
155
|
+
.wb-label { flex: 1 1 12em; min-width: 0; overflow-wrap: anywhere; }
|
|
156
|
+
.wb-name { -webkit-touch-callout: none; }
|
|
157
|
+
.wb-end { display: flex; align-items: baseline; gap: 10px; margin-left: auto; font-weight: 400; }
|
|
158
|
+
.wb-links { display: inline-flex; align-items: baseline; white-space: nowrap; }
|
|
159
|
+
.wb-next { color: var(--muted); white-space: nowrap; }
|
|
160
|
+
.wb-head .wv-link { font-weight: 500; }
|
|
161
|
+
.wb-pop { position: absolute; left: 34px; right: 12px; top: calc(100% - 2px); z-index: 6; padding: 8px 10px; border: 1px solid var(--line); border-radius: 10px;
|
|
162
|
+
background: var(--panel); box-shadow: 0 6px 18px rgba(0,0,0,.18); color: var(--text); font-weight: 400; line-height: 1.35; overflow-wrap: anywhere; cursor: default; }
|
|
163
|
+
.wb-done { padding: 8px 12px; font-size: 12.5px; color: var(--muted); }
|
|
164
|
+
.wb-done a { color: inherit; text-decoration: underline; text-underline-offset: 2px; }
|
|
165
|
+
.wb-loosehead { cursor: default; }
|
|
166
|
+
.wb-loosehead:hover { background: var(--band); }
|
|
167
|
+
/* A wave card's step number, inside its id chip, and its ⋯ menu. */
|
|
168
|
+
.wn { color: var(--muted); font-variant-numeric: tabular-nums; padding-right: 5px; margin-right: 4px; border-right: 1px solid var(--line); }
|
|
169
|
+
.wb .item, .wb .item > summary .title-wrap { position: relative; }
|
|
170
|
+
.wb-dots[aria-expanded="true"] { color: var(--text); background: var(--chip); }
|
|
171
|
+
.wb-dots svg { display: block; }
|
|
172
|
+
.wb-menu { position: absolute; right: 0; top: calc(100% + 4px); z-index: 5; display: grid; min-width: 160px; padding: 4px;
|
|
173
|
+
border: 1px solid var(--line); border-radius: 10px; background: var(--panel); box-shadow: 0 6px 18px rgba(0,0,0,.18); }
|
|
174
|
+
.wb-menu button { border: 0; background: none; text-align: left; padding: 8px 10px; min-height: 0; border-radius: 6px; font: inherit; font-size: 13px; color: var(--text); cursor: pointer; }
|
|
175
|
+
.wb-menu button:hover:not(:disabled) { background: var(--chip); }
|
|
176
|
+
.wb-menu button:disabled { color: var(--muted); cursor: default; }
|
|
177
|
+
.lane[data-lane="todo"] > .list:has(.wb) { overflow: visible; }
|
|
160
178
|
.nav a.icon { display: inline-flex; align-items: center; padding: 4px; color: var(--muted); }
|
|
161
179
|
.nav a.icon:hover { color: var(--text); }
|
|
162
180
|
.refresh { display: inline-flex; align-items: center; gap: 2px; line-height: 1.3; min-width: 0; }
|
|
@@ -184,12 +202,20 @@ code { overflow-wrap: anywhere; }
|
|
|
184
202
|
/* The ⌘↵ / Ctrl+↵ hint left of Send: only where there is a keyboard to press it on. */
|
|
185
203
|
.send-hint { display: none; color: var(--muted); font-size: 12px; white-space: nowrap; }
|
|
186
204
|
@media (hover: hover) and (pointer: fine) { .send-hint { display: inline; } }
|
|
205
|
+
/* A composer's text box (BoardUI.dropZone): while files are dragged over the composer, attach.js marks it .dragging and
|
|
206
|
+
the box gets a dashed accent outline with Drop to attach over it. */
|
|
207
|
+
.dz { position: relative; clear: both; border-radius: 8px; }
|
|
208
|
+
.dz > textarea { display: block; }
|
|
209
|
+
.dz-hint { display: none; position: absolute; inset: 0; align-items: center; justify-content: center; border-radius: 8px; pointer-events: none;
|
|
210
|
+
background: color-mix(in srgb, var(--panel) 80%, transparent); color: var(--accent); font-weight: 600; font-size: 15px; }
|
|
211
|
+
[data-composer].dragging .dz { outline: 2px dashed var(--accent); outline-offset: 3px; }
|
|
212
|
+
[data-composer].dragging .dz-hint { display: flex; }
|
|
187
213
|
.pending-files { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 6px; }
|
|
188
214
|
.pending-files:empty { display: none; }
|
|
189
215
|
.pfile { position: relative; display: inline-flex; flex-direction: column; justify-content: center; width: 64px; height: 64px;
|
|
190
216
|
border: 1px solid var(--line); border-radius: 8px; background: var(--chip); overflow: hidden; font-size: 11px; }
|
|
191
217
|
.pfile img { width: 100%; height: 100%; object-fit: cover; }
|
|
192
|
-
.pfile .pname { padding: 4px 6px;
|
|
218
|
+
.pfile .pname { padding: 4px 6px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
|
193
219
|
.pfile.uploading img, .pfile.uploading .pname { opacity: .55; }
|
|
194
220
|
.pfile .pbar { position: absolute; left: 4px; right: 4px; bottom: 4px; height: 4px; border-radius: 2px; background: color-mix(in srgb, var(--panel) 70%, transparent); }
|
|
195
221
|
.pfile .pbar span { display: block; height: 100%; border-radius: 2px; background: var(--color-info); transition: width .2s; }
|
|
@@ -202,7 +228,7 @@ code { overflow-wrap: anywhere; }
|
|
|
202
228
|
.file-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
|
|
203
229
|
.file-link { display: inline-flex; align-items: center; max-width: 100%; padding: 3px 8px; border-radius: 6px; background: var(--chip);
|
|
204
230
|
font-size: 13px; overflow-wrap: anywhere; }
|
|
205
|
-
.file-link::before { content: "📎"; margin-right:
|
|
231
|
+
.file-link::before { content: "📎"; margin-right: 6px; }
|
|
206
232
|
.msg .body:empty { display: none; }
|
|
207
233
|
.note-tools { display: flex; align-items: flex-start; gap: 6px; }
|
|
208
234
|
.note-tools .pending-files { flex: 1; margin-top: 4px; }
|
|
@@ -210,11 +236,13 @@ code { overflow-wrap: anywhere; }
|
|
|
210
236
|
|
|
211
237
|
/* Compose button and sheet */
|
|
212
238
|
main { padding-bottom: calc(110px + env(safe-area-inset-bottom)); }
|
|
213
|
-
|
|
239
|
+
/* The + sits two thirds of (16px + the safe area) from the corner, and at least 32px where there is no safe area. */
|
|
240
|
+
:root { --fab-edge: max(32px, calc((16px + env(safe-area-inset-bottom)) * 2 / 3)); }
|
|
241
|
+
.fab { position: fixed; z-index: 6; right: max(32px, calc((16px + max(env(safe-area-inset-right), env(safe-area-inset-bottom))) * 2 / 3)); bottom: calc(var(--app-bottom, 0px) + var(--fab-edge));
|
|
214
242
|
width: 75px; height: 75px; padding: 0; border-radius: 50%; border: 0; background: var(--accent); color: var(--on-accent);
|
|
215
243
|
display: inline-flex; align-items: center; justify-content: center; box-shadow: 0 6px 18px rgba(0,0,0,.25); }
|
|
216
244
|
.fab:active { transform: scale(.96); }
|
|
217
|
-
.view-board .toast-stack { bottom: calc(var(--app-bottom, 0px) +
|
|
245
|
+
.view-board .toast-stack { bottom: calc(var(--app-bottom, 0px) + 83px + var(--fab-edge)); }
|
|
218
246
|
/* A phone sheet pads its content above the keyboard (--kb, dialogs.js fitSheet) and stays on the screen's bottom
|
|
219
247
|
edge while the keyboard covers the bar: iOS reports its height late, so moving the sheet up leaves a strip below. */
|
|
220
248
|
.sheet { position: fixed; inset: auto 0 0 0; margin: 0 auto; width: 100%; max-width: 560px;
|
|
@@ -282,19 +310,10 @@ main { padding-bottom: calc(110px + env(safe-area-inset-bottom)); }
|
|
|
282
310
|
.ask-actions .icon:disabled { opacity: .35; }
|
|
283
311
|
.ask-actions .icon.bumped { color: var(--color-notice); opacity: 1; }
|
|
284
312
|
.ask-actions .icon.bumped svg { fill: currentColor; }
|
|
285
|
-
|
|
286
|
-
.ask-actions .icon { --bump-fade: 0ms; }
|
|
287
|
-
@keyframes bump-in { from { color: var(--muted); } }
|
|
288
|
-
@keyframes bump-fill-in { from { fill: transparent; } }
|
|
289
|
-
@keyframes bump-out { from { color: var(--color-notice); opacity: 1; } }
|
|
290
|
-
@keyframes bump-fill-out { from { fill: var(--color-notice); } to { fill: transparent; } }
|
|
291
|
-
.ask-actions .icon.bump-in { animation: bump-in var(--bump-fade) linear; }
|
|
292
|
-
.ask-actions .icon.bump-in svg { animation: bump-fill-in var(--bump-fade) linear; }
|
|
293
|
-
.ask-actions .icon.bump-out { animation: bump-out var(--bump-fade) linear; }
|
|
294
|
-
.ask-actions .icon.bump-out svg { animation: bump-fill-out var(--bump-fade) linear; }
|
|
313
|
+
.ask-actions .icon.owner-done { color: var(--color-notice); }
|
|
295
314
|
/* A work card's empty bump icon always shows on touch screens; with a hover pointer it shows while the card is hovered or holds focus */
|
|
296
315
|
@media (hover: hover) {
|
|
297
|
-
.item button[data-card-bump]:not(.bumped) { opacity: 0; }
|
|
316
|
+
.item button[data-card-bump]:not(.bumped, [aria-busy="true"]) { opacity: 0; }
|
|
298
317
|
.item:hover button[data-card-bump]:not(.bumped), .item:focus-within button[data-card-bump]:not(.bumped) { opacity: 1; }
|
|
299
318
|
}
|
|
300
319
|
.working-dot { display: inline-block; width: 7px; height: 7px; border-radius: 50%; background: var(--color-notice); margin-right: 5px; vertical-align: 1px; }
|
|
@@ -311,23 +330,35 @@ button.attach:disabled { opacity: .35; }
|
|
|
311
330
|
.line2.meta { justify-content: flex-start; margin-top: 4px; }
|
|
312
331
|
.line3 { margin-top: 3px; }
|
|
313
332
|
/* The active bar blinks its fill, not its opacity: an opacity animation gives it its own layer, which Safari can snap a
|
|
314
|
-
pixel off its siblings (docs/adr/
|
|
333
|
+
pixel off its siblings (docs/adr/2026-11-03-1519-a-building-cards-phase-bars-end-its-time-row.md). */
|
|
315
334
|
.card-time .phase-bars { display: inline-flex; gap: 2px; vertical-align: middle; position: relative; top: -1px; }
|
|
316
335
|
.phase-bars i { width: 9px; height: 4px; border-radius: 2px; background: var(--line); }
|
|
317
|
-
|
|
336
|
+
/* A strip dims, and its running bar stops blinking, while the card waits on something other than a builder
|
|
337
|
+
(docs/adr/2026-11-03-2024-every-in-progress-card-shows-its-phase-bars.md). app-cards.js sweeps bars in --bar-fill. */
|
|
338
|
+
.phase-bars { --bar-fill: var(--color-notice); }
|
|
339
|
+
.phase-bars.dim { --bar-fill: color-mix(in srgb, var(--muted) 55%, transparent); }
|
|
340
|
+
.phase-bars i.done, .phase-bars i.now { background: var(--bar-fill); }
|
|
341
|
+
/* A bar part way, to --p: a starting board's clone (ui-sidebar.js). */
|
|
342
|
+
.phase-bars i.fill { background: linear-gradient(to right, var(--bar-fill) var(--p), var(--line) var(--p)); }
|
|
318
343
|
@keyframes pulse-fill { 50% { background-color: color-mix(in srgb, var(--color-notice) 35%, transparent); } }
|
|
319
|
-
@media (prefers-reduced-motion: no-preference) { .phase-bars i.now { animation: pulse-fill 1.4s ease-in-out infinite; } }
|
|
344
|
+
@media (prefers-reduced-motion: no-preference) { .phase-bars:not(.dim) i.now { animation: pulse-fill 1.4s ease-in-out infinite; } }
|
|
345
|
+
/* A stale build's status line, dot included, is the needs-you red, and a tap on it nudges Claude (ui-cards.js builderStatus). */
|
|
346
|
+
button.sub.agent.stalled { display: block; width: 100%; padding: 0; border: 0; border-radius: 0; background: none; text-align: left; color: var(--color-danger); }
|
|
347
|
+
.stalled .working-dot { background: currentColor; }
|
|
320
348
|
.brand { display: grid; grid-template-columns: auto auto minmax(0, 1fr); column-gap: 10px; row-gap: 2px; }
|
|
321
349
|
.brand .hub { grid-row: 1 / span 2; align-self: center; }
|
|
322
|
-
|
|
350
|
+
/* The session's working line, "thinking", is the owner's blue with one font, size, weight and pulse on the card and in the thread. */
|
|
351
|
+
.thinking { color: var(--accent); font-size: 12px; font-weight: 600; }
|
|
352
|
+
.thinking .working-dot { background: currentColor; }
|
|
323
353
|
.msg.link { padding: 0 10px; margin: 4px 0; font-size: 13px; }
|
|
324
354
|
.msg.builder-status { padding: 0 10px; margin: 4px 0; font-size: 12px; color: var(--color-notice); overflow-wrap: anywhere; }
|
|
325
355
|
.msg.builder-status .working-dot { animation: none; }
|
|
356
|
+
.msg.request { padding: 0 10px; margin: 4px 0; font-size: 12px; color: var(--muted); overflow-wrap: anywhere; }
|
|
326
357
|
.msg.agent { padding: 0 10px; margin: 4px 0; font-size: 12px; font-weight: 600; overflow-wrap: anywhere; }
|
|
327
358
|
.msg.agent.started { color: var(--color-notice); } .msg.agent.finished { color: var(--color-success); }
|
|
328
359
|
.msg.agent .muted { font-weight: 400; }
|
|
329
360
|
/* A planner's line, dot included, is the owner's blue, on the card and in the thread; its finish stays green
|
|
330
|
-
(docs/adr/
|
|
361
|
+
(docs/adr/2026-11-03-1551-planners-and-implementers-are-two-kinds-of-agent.md). */
|
|
331
362
|
.sub.agent.planner, .msg.builder-status.planner, .msg.agent.started.planner { color: var(--accent); }
|
|
332
363
|
.planner .working-dot { background: currentColor; }
|
|
333
364
|
.msg.calls { padding: 0 10px; margin: 4px 0; font-size: 12px; overflow-wrap: anywhere; }
|
|
@@ -335,7 +366,6 @@ button.attach:disabled { opacity: .35; }
|
|
|
335
366
|
.msg.calls ol { margin: 4px 0; padding-left: 20px; }
|
|
336
367
|
.agent-dot { display: inline-block; width: 7px; height: 7px; border-radius: 50%; background: currentColor; margin-right: 5px; vertical-align: 1px; }
|
|
337
368
|
/* INT-30: card line order */
|
|
338
|
-
.line5.meta { justify-content: flex-start; margin-top: 4px; }
|
|
339
369
|
.line6 { margin-top: 4px; }
|
|
340
370
|
.card-time time { font-variant-numeric: tabular-nums; }
|
|
341
371
|
.card-unread { color: var(--accent); font-weight: 600; }
|
|
@@ -350,7 +380,7 @@ button.attach:disabled { opacity: .35; }
|
|
|
350
380
|
.lane[open] > summary { border-bottom: 0; border-radius: 10px 10px 0 0; }
|
|
351
381
|
.lane[open] > .list { border-radius: 0 0 10px 10px; }
|
|
352
382
|
.lane > summary .count { color: var(--muted); font-weight: 400; }
|
|
353
|
-
/* Each lane's sort icon and its menu, grey (docs/adr/
|
|
383
|
+
/* Each lane's sort icon and its menu, grey (docs/adr/2026-11-01-1817-colour-says-whos-waiting.md) */
|
|
354
384
|
/* INT-35: offline header */
|
|
355
385
|
.view-board.offline #compose { display: none; }
|
|
356
386
|
.view-board.offline main > * { opacity: .72; }
|
|
@@ -370,6 +400,15 @@ button.attach:disabled { opacity: .35; }
|
|
|
370
400
|
.brand { flex: 1 1 auto; display: flex; align-items: center; gap: 10px; min-width: 0; }
|
|
371
401
|
.brand :is(h1, h2) { min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
|
372
402
|
.top .nav { flex: none; }
|
|
403
|
+
/* The away moon right of the board title (docs/adr/2026-11-04-0226-the-hub-checks-every-minute-while-youre-here-and-every-5-when-away.md)
|
|
404
|
+
fades in and out with the toasts' timings (toasts.js). */
|
|
405
|
+
.away-moon { flex: none; display: inline-flex; color: var(--muted); opacity: 0; visibility: hidden; transition: opacity 200ms ease, visibility 0s linear 200ms; }
|
|
406
|
+
.away-moon.on { opacity: 1; visibility: visible; transition: opacity 150ms ease, visibility 0s; }
|
|
407
|
+
.away-moon svg { display: block; }
|
|
408
|
+
@media (prefers-reduced-motion: reduce) {
|
|
409
|
+
.away-moon { transition: opacity 100ms ease, visibility 0s linear 100ms; }
|
|
410
|
+
.away-moon.on { transition: opacity 80ms ease, visibility 0s; }
|
|
411
|
+
}
|
|
373
412
|
.lane-github { display: inline-flex; align-items: center; gap: 2px; }
|
|
374
413
|
.lane-github .github { display: inline-flex; align-items: center; gap: 4px; }
|
|
375
414
|
.lane-github .gh-mark { flex: none; }
|
|
@@ -391,7 +430,7 @@ button.attach:disabled { opacity: .35; }
|
|
|
391
430
|
.top .nav #refresh, .top .nav a.icon { display: inline-flex; align-items: center; justify-content: center; margin: 0; padding: 4px; border: 0; line-height: 1; }
|
|
392
431
|
.top .nav #status { line-height: 1.1; white-space: nowrap; }
|
|
393
432
|
.top .nav #refresh:disabled, .top .nav a.icon[aria-disabled="true"] { opacity: .35; pointer-events: none; }
|
|
394
|
-
/*
|
|
433
|
+
/* [the bulb runs an architecture review of the board's repo](docs/adr/2026-11-02-1813-the-bulb-runs-an-architecture-review-of-the-boards-repo.md): the bulb sits between refresh and the gear, and glows orange while an architecture review runs */
|
|
395
434
|
.top .nav .arch-bulb { display: inline-flex; align-items: center; justify-content: center; margin: 0; padding: 4px; border: 0; line-height: 1; color: var(--muted); }
|
|
396
435
|
.top .nav .arch-bulb:hover { color: var(--text); }
|
|
397
436
|
.top .nav .arch-bulb[hidden] { display: none; }
|
|
@@ -409,11 +448,12 @@ button.attach:disabled { opacity: .35; }
|
|
|
409
448
|
.view-board.offline .refresh #refresh, .refresh .link-state.offline { color: var(--color-danger); }
|
|
410
449
|
.back { display: inline-flex; align-items: center; justify-content: center; flex: none; width: 32px; height: 32px; color: var(--accent); text-decoration: none; }
|
|
411
450
|
/* The lead slot, logo or back, is one 44px tap box on the page's left edge, so every page's header lines up the same
|
|
412
|
-
(docs/adr/
|
|
451
|
+
(docs/adr/2026-10-29-1639-a-questions-takes-show-inline.md). The brand keeps that height when the rail hides the logo, so the
|
|
413
452
|
board's header and the sidebar's stay level. */
|
|
414
453
|
.top { padding-top: max(4px, env(safe-area-inset-top)); padding-bottom: 4px; }
|
|
415
454
|
.top .brand { gap: 4px; min-height: 44px; }
|
|
416
455
|
.top .hub, .top .back { display: inline-flex; align-items: center; justify-content: center; flex: none; width: 44px; height: 44px; margin-left: -10px; border-radius: 10px; }
|
|
456
|
+
.top .hub + .back { margin-left: 0; }
|
|
417
457
|
.top .back:active { background: var(--accent-soft); }
|
|
418
458
|
.top .brand :is(h1, h2) { font-size: 17px; font-weight: 600; line-height: 22px; }
|
|
419
459
|
/* The last visit paints dimmed until the fresh board lands; the controls ui-snapshot.js liveControls blocks rest meanwhile.
|
|
@@ -427,7 +467,7 @@ main > * { transition: opacity .25s ease; }
|
|
|
427
467
|
.item.tint { animation: card-tint 2.4s ease-out var(--sign-delay, 0s) 1; border-radius: 6px; }
|
|
428
468
|
@keyframes card-tint { 0%, 25% { background: var(--accent-soft); } 100% { background: transparent; } }
|
|
429
469
|
.msg .quote { margin: 4px 0 6px; padding: 2px 0 2px 8px; border-left: 2px solid var(--line); color: var(--muted); white-space: pre-wrap; overflow-wrap: anywhere; }
|
|
430
|
-
/*
|
|
470
|
+
/* [one board registry for every hub feature](docs/adr/2026-10-29-1639-one-board-registry-for-every-hub-feature.md): the GitHub mark opens the Hub links sheet, with a red dot while a link is broken; a new board's setup checklist */
|
|
431
471
|
.lane-github .gh-links { position: relative; display: inline-flex; align-items: center; padding: 4px; margin: -4px -2px -4px -4px; font-size: inherit; line-height: 1; color: inherit; }
|
|
432
472
|
.lane-github .links-dot { position: absolute; top: 1px; right: 0; width: 7px; height: 7px; border-radius: 50%; background: var(--color-danger); box-shadow: 0 0 0 1.5px var(--bg); }
|
|
433
473
|
.hold-sheet .hold-lede { margin: 0 0 2px; font-size: 13.5px; line-height: 1.4; }
|
|
@@ -457,6 +497,15 @@ main > * { transition: opacity .25s ease; }
|
|
|
457
497
|
.view-settings label.who { gap: 12px; cursor: pointer; }
|
|
458
498
|
.view-settings label.who .sub { display: block; margin-top: 2px; }
|
|
459
499
|
.view-settings input.toggle { flex: none; width: 1.4rem; height: 1.4rem; margin: 0; accent-color: var(--accent); }
|
|
500
|
+
.view-settings input.count { flex: none; width: 4.5em; text-align: center; }
|
|
501
|
+
/* A settings switch waiting on the server (ui.js waitOn) keeps its face, disabled, with a spinner beside it
|
|
502
|
+
(docs/adr/2026-11-03-1921-board-settings-grant-a-boards-session-permissions.md) */
|
|
503
|
+
.view-settings .toggle-slot { flex: none; display: inline-flex; align-items: center; gap: 8px; }
|
|
504
|
+
.view-settings .toggle-spin { display: none; color: var(--muted); }
|
|
505
|
+
.view-settings .toggle-slot:has(input.tap-waiting) .toggle-spin { display: inline-block; }
|
|
506
|
+
.view-settings input.toggle.tap-waiting { opacity: 1; cursor: default; }
|
|
507
|
+
.view-settings #permissions code { font-size: 11.5px; overflow-wrap: anywhere; }
|
|
508
|
+
.view-settings #permissions .refused-note { color: var(--color-danger); }
|
|
460
509
|
.view-settings .close-board-row { width: 100%; text-align: left; color: var(--color-danger); }
|
|
461
510
|
.view-settings .repo-row { width: 100%; gap: 12px; text-align: left; }
|
|
462
511
|
.view-settings .repo-row > :first-child { min-width: 0; overflow-wrap: anywhere; }
|
|
@@ -500,18 +549,9 @@ main > * { transition: opacity .25s ease; }
|
|
|
500
549
|
.view-questions .bar #qstatus { min-width: 0; }
|
|
501
550
|
.view-questions .bar #qstatus.sent { color: var(--color-success); font-weight: 600; }
|
|
502
551
|
.view-questions .solo { display: flex; justify-content: space-between; align-items: center; gap: 8px; margin: 4px 0; }
|
|
503
|
-
/* docs/adr/
|
|
552
|
+
/* docs/adr/2026-11-02-1332-a-prototype-round-ends-with-a-one-take-confirm.md */
|
|
504
553
|
.view-questions .topichead { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; }
|
|
505
|
-
.view-questions .topichead .try-spin
|
|
506
|
-
/* A requested question: an accent tint and an accent border drawn inside the card, so the card keeps its size. */
|
|
507
|
-
.view-questions .q.pr-busy { border-color: var(--accent); background: color-mix(in srgb, var(--accent) 9%, var(--panel)); box-shadow: inset 0 0 0 1px var(--accent); }
|
|
508
|
-
.view-questions .q.pr-busy .opt { opacity: .55; cursor: default; }
|
|
509
|
-
.view-questions .q.pr-busy .opt:has(input:checked) { opacity: 1; }
|
|
510
|
-
/* The source line is as tall as the state badge beside it, which a requested card leaves out. */
|
|
511
|
-
.view-questions .q > .row:first-child > .muted { padding: 1px 0; }
|
|
512
|
-
.view-questions .q.pr-busy textarea { opacity: .7; }
|
|
513
|
-
.view-questions .q.pr-busy .proto-ask { color: var(--accent); }
|
|
514
|
-
.view-questions .note-tools .chip { align-self: center; margin-top: 2px; }
|
|
554
|
+
.view-questions .topichead .try-spin { width: 9px; height: 9px; margin-right: 5px; vertical-align: -1px; }
|
|
515
555
|
.view-questions .q .pr-open { display: inline-block; margin: 0 0 8px; }
|
|
516
556
|
.view-questions .pr-rule { display: flex; align-items: center; gap: 6px; margin: 0 0 6px; font-size: 12.5px; color: var(--muted); }
|
|
517
557
|
.view-questions .pr-rule svg { flex: none; }
|
|
@@ -587,7 +627,6 @@ main > * { transition: opacity .25s ease; }
|
|
|
587
627
|
.view-frame > .frame-page { flex: 1 1 auto; display: block; width: 100%; min-height: 0; border: 0; background: var(--bg); }
|
|
588
628
|
.view-frame .alone { white-space: nowrap; font-size: 13px; }
|
|
589
629
|
|
|
590
|
-
.top .phone-logo { display: none; }
|
|
591
630
|
@media (max-width: 899px) {
|
|
592
631
|
:root:has(body > .top, body.has-sidebar > :not(.sidebar) > .top):not(.ps-embed) {
|
|
593
632
|
--app-bottom: calc(49px + max(4px, env(safe-area-inset-bottom)));
|
|
@@ -596,7 +635,6 @@ main > * { transition: opacity .25s ease; }
|
|
|
596
635
|
position: fixed; top: auto; bottom: 0; left: 0; right: 0; z-index: 7;
|
|
597
636
|
border-bottom: 0; border-top: 1px solid var(--line); padding-top: 4px; padding-bottom: max(4px, env(safe-area-inset-bottom));
|
|
598
637
|
}
|
|
599
|
-
.top .phone-logo { display: inline-flex; margin-left: 0; }
|
|
600
638
|
.top .nav #refresh, .top .nav a.icon, .top .nav .arch-bulb { min-width: 44px; min-height: 44px; }
|
|
601
639
|
body > main, body.has-sidebar > :not(.sidebar) > main { padding-top: max(16px, env(safe-area-inset-top)); padding-bottom: calc(96px + var(--app-bottom, 0px) + env(safe-area-inset-bottom)); }
|
|
602
640
|
.view-frame:not(.own-header) { padding-bottom: var(--app-bottom, 0px); }
|
|
@@ -618,15 +656,25 @@ main > * { transition: opacity .25s ease; }
|
|
|
618
656
|
.settings-body { overflow-y: auto; overscroll-behavior: contain; min-height: 0; padding: 0 20px 16px; }
|
|
619
657
|
.settings-body input { font-size: 16px; }
|
|
620
658
|
.settings-footer { display: flex; justify-content: flex-end; padding: 12px 20px; border-top: 1px solid var(--line); }
|
|
621
|
-
.
|
|
622
|
-
.tk-saving, .lk-checking { display: inline-flex; align-items: center; gap: 6px; }
|
|
659
|
+
.lk-checking { display: inline-flex; align-items: center; gap: 6px; }
|
|
623
660
|
/* linear-key.js's modal over a page sits in .hub-view main only for hub.css's selectors. */
|
|
624
661
|
.lk-over, .lk-over > main { display: contents; }
|
|
625
662
|
|
|
626
663
|
.tk-section { margin: 10px 0; }
|
|
664
|
+
/* The Tickets source row's live state, and Hub's key field opened under it (dialogs.js ticketsControl keyState). */
|
|
665
|
+
.tk-status { display: flex; align-items: center; gap: 8px; margin: 8px 0 0; font-size: 13px; color: var(--muted); }
|
|
666
|
+
.tk-status b { font-weight: 600; color: var(--text); }
|
|
667
|
+
.tk-status .dot { width: 8px; height: 8px; border-radius: 50%; background: var(--line); flex: none; }
|
|
668
|
+
.tk-status.on .dot { background: var(--accent); }
|
|
669
|
+
.tk-status.on b { color: var(--accent); }
|
|
670
|
+
.tk-inline { margin: 6px 0 10px; border: 1px solid var(--accent); border-radius: 10px; padding: 8px 10px; background: var(--accent-soft); }
|
|
671
|
+
.tk-inline .tk-ask { margin: 2px 0 6px; font-size: 13px; }
|
|
672
|
+
.tk-inline .hub-view main { padding: 0; }
|
|
627
673
|
.tk-seg { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 4px; padding: 4px; margin: 8px 0; border: 1px solid var(--line); border-radius: 9px; background: var(--chip); }
|
|
628
674
|
.tk-seg button { min-width: 0; min-height: 44px; padding: 6px 4px; border: 1px solid transparent; border-radius: 6px; background: transparent; color: var(--muted); font: inherit; font-size: 13px; cursor: pointer; }
|
|
629
675
|
.tk-seg button[aria-pressed="true"] { border-color: var(--accent); background: var(--accent-soft); color: var(--accent); font-weight: 600; }
|
|
676
|
+
.ask-seg { grid-template-columns: repeat(2, minmax(0, 1fr)); margin: 10px 0 0; }
|
|
677
|
+
.ask-choice-help { margin: 4px 2px 0; }
|
|
630
678
|
.tk-seg button:focus-visible { outline: 2px solid var(--accent); outline-offset: -3px; }
|
|
631
679
|
.tk-grid { display: grid; gap: 8px; grid-template-columns: minmax(0, 1fr); }
|
|
632
680
|
@media (min-width: 560px) { .tk-grid { grid-template-columns: minmax(0, 1fr) minmax(0, 1.4fr); } }
|
|
@@ -646,6 +694,24 @@ main > * { transition: opacity .25s ease; }
|
|
|
646
694
|
.try-spin { display: inline-block; width: 10px; height: 10px; border: 1.5px solid currentColor; border-right-color: transparent; border-radius: 50%; animation: try-spin .8s linear infinite; flex: none; }
|
|
647
695
|
@keyframes try-spin { to { transform: rotate(360deg); } }
|
|
648
696
|
@media (prefers-reduced-motion: reduce) { .try-spin { animation: none; } }
|
|
697
|
+
/* A pending control waits in one style (ui.js waitOn and BUSY, docs/adr/2026-11-03-1850-a-tap-waits-for-the-server-to-record-it.md,
|
|
698
|
+
docs/adr/2026-11-03-1915-every-pending-control-waits-in-one-style.md): a busy button keeps its own colours and width, disabled, and
|
|
699
|
+
its content gives way to a spinner in its text colour; the New version row's spinner sits in its pill; a bump icon keeps
|
|
700
|
+
its arrow and pulses orange until the card moves; a toggle, select or field keeps its face with a spinner beside it */
|
|
701
|
+
button[aria-busy="true"], button[aria-busy="true"]:disabled, .ask-actions .icon[aria-busy="true"]:disabled { cursor: default; opacity: 1; }
|
|
702
|
+
:is(button[aria-busy="true"]:not([data-card-bump], [data-bump], .sb-update-row), .sb-update-row[aria-busy="true"] .sb-go) { position: relative; -webkit-text-fill-color: transparent; }
|
|
703
|
+
:is(button[aria-busy="true"]:not([data-card-bump], [data-bump], .sb-update-row), .sb-update-row[aria-busy="true"] .sb-go) > * { visibility: hidden; }
|
|
704
|
+
:is(button[aria-busy="true"]:not([data-card-bump], [data-bump], .sb-update-row), .sb-update-row[aria-busy="true"] .sb-go)::after { content: ''; position: absolute; inset: 0; margin: auto;
|
|
705
|
+
width: 12px; height: 12px; box-sizing: border-box; border: 2px solid currentColor; border-right-color: transparent; border-radius: 50%; animation: try-spin .8s linear infinite; }
|
|
706
|
+
@keyframes wait-orange { 50% { color: var(--color-notice); opacity: 1; } }
|
|
707
|
+
button[aria-busy="true"]:is([data-card-bump], [data-bump]) { color: var(--muted); animation: wait-orange 1s ease-in-out infinite; }
|
|
708
|
+
button[aria-busy="true"]:is([data-card-bump], [data-bump]) svg { fill: currentColor; }
|
|
709
|
+
.try-spin.tap-beside { width: 12px; height: 12px; border-width: 2px; margin: 0 8px 0 auto; color: var(--muted); }
|
|
710
|
+
.tk-field > span > .try-spin.tap-beside { margin: 0 0 0 6px; vertical-align: -2px; }
|
|
711
|
+
@media (prefers-reduced-motion: reduce) {
|
|
712
|
+
:is(button[aria-busy="true"], .sb-update-row[aria-busy="true"] .sb-go)::after { animation: none; }
|
|
713
|
+
button[aria-busy="true"]:is([data-card-bump], [data-bump]) { animation: none; color: var(--color-notice); }
|
|
714
|
+
}
|
|
649
715
|
.install { display: inline-flex; align-items: center; gap: 4px; }
|
|
650
716
|
.external-links .install.tone-ready { color: var(--color-success); }
|
|
651
717
|
.external-links .install.tone-danger { color: var(--color-danger); }
|
|
@@ -654,12 +720,39 @@ main > * { transition: opacity .25s ease; }
|
|
|
654
720
|
.tb-main > svg { flex: none; color: var(--muted); }
|
|
655
721
|
.tb-main-text { flex: 1 1 200px; min-width: 0; overflow-wrap: anywhere; }
|
|
656
722
|
.tb-main .meta { justify-content: flex-end; margin-left: auto; }
|
|
723
|
+
/* #60: Main's refresh icon right of its timestamp; a failed pull's reason shows on hover, or on a tap on touch */
|
|
724
|
+
.tb-main .main-pull { position: relative; display: inline-flex; align-items: center; vertical-align: middle; margin-left: 6px; }
|
|
725
|
+
.tb-main .gh-refresh { display: inline-flex; align-items: center; justify-content: center; font-size: 15px; line-height: 1; padding: 2px 4px; color: var(--muted); min-width: 28px; min-height: 28px; }
|
|
726
|
+
.tb-main .gh-refresh[aria-disabled="true"] { opacity: .45; cursor: default; }
|
|
727
|
+
.tb-main .gh-refresh.failed { color: var(--color-danger); }
|
|
728
|
+
.main-pull-why { position: absolute; top: calc(100% + 6px); left: 0; z-index: 5; width: max-content; max-width: min(240px, calc(100vw - 32px)); padding: 7px 10px; border: 1px solid var(--line); border-radius: 8px; background: var(--panel); color: var(--text); font-size: 13px; line-height: 1.35; box-shadow: 0 6px 20px rgba(0,0,0,.25); visibility: hidden; pointer-events: none; }
|
|
729
|
+
.main-pull-why.open { visibility: visible; }
|
|
730
|
+
@media (hover: hover) { .main-pull:hover .main-pull-why { visibility: visible; } }
|
|
657
731
|
.main-log-source { margin: 0 0 8px; overflow-wrap: anywhere; }
|
|
658
732
|
.main-log-lines { margin: 0; padding: 8px 10px; border-radius: 8px; background: var(--chip); color: var(--text);
|
|
659
733
|
font-family: ui-monospace, "SF Mono", Menlo, monospace; font-size: 11.5px; line-height: 1.5;
|
|
660
734
|
max-height: calc(12 * 1.5 * 11.5px + 16px); white-space: pre-wrap; overflow-wrap: anywhere; overflow-y: auto; }
|
|
661
735
|
.main-log-actions { display: flex; justify-content: flex-end; margin-top: 12px; }
|
|
662
736
|
.main-log-actions button { display: inline-flex; align-items: center; gap: 7px; min-height: 40px; padding: 6px 18px; }
|
|
663
|
-
.main-log-actions .main-log-going { border-color: color-mix(in srgb, var(--color-notice) 45%, var(--line));
|
|
664
|
-
background: color-mix(in srgb, var(--color-notice) 12%, var(--panel)); color: var(--color-notice); cursor: default; opacity: 1; }
|
|
665
737
|
#mainLogReason { color: var(--color-notice); overflow-wrap: anywhere; }
|
|
738
|
+
|
|
739
|
+
/* The Auto Review lane (ui-cards.js reviewLane): its cards read like the board's, and Posted earlier's lines like a fold's. */
|
|
740
|
+
.rv-card, .rv-line { border-top: 1px solid var(--line); }
|
|
741
|
+
.rv-card:first-child, .rv-line:first-child { border-top: 0; }
|
|
742
|
+
.rv-card > summary, .rv-line > summary { list-style: none; cursor: pointer; }
|
|
743
|
+
.rv-card > summary::-webkit-details-marker, .rv-line > summary::-webkit-details-marker { display: none; }
|
|
744
|
+
.rv-card > summary:hover, .rv-line > summary:hover { background: color-mix(in srgb, var(--chip) 60%, transparent); }
|
|
745
|
+
.rv-card > summary { display: grid; grid-template-columns: 18px 1fr; gap: 8px; align-items: start; padding: 9px 12px; }
|
|
746
|
+
.rv-card > summary .status { margin-top: 2px; }
|
|
747
|
+
.rv-line > summary { padding: 8px 12px; font-size: 13px; }
|
|
748
|
+
.status.rv-needs { border-color: var(--color-danger); background: var(--color-danger); }
|
|
749
|
+
.rv-word.s-needs, .lane-github .rv-late { color: var(--color-danger); font-weight: 600; }
|
|
750
|
+
.rv-detail { display: grid; gap: 10px; padding: 0 12px 12px 38px; font-size: 14px; min-width: 0; }
|
|
751
|
+
.rv-line .rv-detail { padding-left: 12px; }
|
|
752
|
+
.rv-detail p { margin: 0; }
|
|
753
|
+
.rv-review { border: 1px solid var(--line); border-radius: 10px; background: var(--bg); padding: 10px 12px; min-width: 0; overflow-wrap: anywhere; display: grid; gap: 8px; }
|
|
754
|
+
.rv-review > * { margin: 0; }
|
|
755
|
+
.rv-links { display: flex; flex-wrap: wrap; gap: 6px 14px; font-size: 13px; }
|
|
756
|
+
.rv-links a { color: var(--accent); text-decoration: none; }
|
|
757
|
+
.rv-acts { display: flex; flex-wrap: wrap; gap: 8px; }
|
|
758
|
+
.view-questions .bar #qstatus .try-spin { color: var(--accent); margin-right: 6px; }
|
package/board/public/toasts.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
(function () {
|
|
2
|
-
// How long a toast fades in and out
|
|
2
|
+
// How long a toast fades in and out.
|
|
3
3
|
const reduced = () => matchMedia('(prefers-reduced-motion: reduce)').matches;
|
|
4
4
|
const enterTime = () => reduced() ? 80 : 150;
|
|
5
5
|
const exitTime = () => reduced() ? 100 : 200;
|
|
@@ -177,5 +177,5 @@
|
|
|
177
177
|
}
|
|
178
178
|
return { toast, destroy };
|
|
179
179
|
}
|
|
180
|
-
globalThis.BoardToasts = { create
|
|
180
|
+
globalThis.BoardToasts = { create };
|
|
181
181
|
})();
|