@gotcos/glasses-server 6.98.1 → 6.99.16
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/CHANGELOG.md +227 -0
- package/package.json +2 -1
- package/server/index.ts +170 -11
- package/server/lib/api-auth.ts +31 -14
- package/server/lib/claude-bridge.ts +21 -2
- package/server/lib/codex-bridge.ts +21 -2
- package/server/lib/cos-thread.ts +582 -0
- package/server/lib/display-bus.ts +3 -0
- package/server/lib/drop-attachments.ts +55 -0
- package/server/lib/drop-destinations.ts +134 -0
- package/server/lib/drop-history-search.ts +97 -0
- package/server/lib/drop-p2-boot.ts +60 -0
- package/server/lib/drop-p2-runtime.ts +237 -0
- package/server/lib/drop-p2-settings.ts +174 -0
- package/server/lib/drop-resolution.ts +168 -0
- package/server/lib/drop-router.ts +325 -0
- package/server/lib/drop-service.ts +830 -0
- package/server/lib/drop-settings.ts +56 -0
- package/server/lib/drop-store.ts +450 -0
- package/server/lib/drop-when.ts +265 -0
- package/server/lib/glasses-pairing.ts +15 -0
- package/server/lib/learning-needs-you.ts +111 -0
- package/server/lib/live-cues-v2-settings.ts +2 -1
- package/server/lib/live-cues-v2.ts +6 -4
- package/server/lib/media-store.ts +80 -0
- package/server/lib/meeting-batch-transcribe.ts +15 -2
- package/server/lib/meeting-consolidation-run.ts +169 -0
- package/server/lib/meeting-store.ts +61 -0
- package/server/lib/meeting-title-steer.ts +200 -0
- package/server/lib/network-policy.ts +84 -6
- package/server/lib/permission-broker.ts +13 -0
- package/server/lib/phone-recording.ts +1 -1
- package/server/lib/ping-budget.ts +149 -0
- package/server/lib/ping-engine.ts +245 -0
- package/server/lib/ping-feed-sink.ts +33 -0
- package/server/lib/ping-sources.ts +192 -0
- package/server/lib/query-job-coordinator.ts +5 -2
- package/server/lib/query-job-runtime.ts +45 -4
- package/server/lib/query-job-types.ts +10 -1
- package/server/lib/reminder-scheduler.ts +153 -0
- package/server/lib/tailnet-self-name.ts +103 -0
- package/server/lib/tailscale-nudge.ts +40 -2
- package/server/lib/task-store.ts +32 -0
- package/server/lib/web-ask-admission.ts +56 -0
- package/server/lib/web-live-chunks.ts +273 -0
- package/server/lib/web-memories-bridge.ts +323 -0
- package/server/lib/web-session-auth.ts +492 -0
- package/server/lib/web-usage-bridge.ts +154 -0
- package/server/lib/work-search.ts +14 -1
- package/server/lib/your-move-count.ts +58 -0
- package/server/routes/cos-thread.ts +79 -0
- package/server/routes/display.ts +11 -1
- package/server/routes/drops.ts +262 -0
- package/server/routes/health.ts +16 -0
- package/server/routes/live-cues.ts +5 -4
- package/server/routes/meeting.ts +61 -5
- package/server/routes/permission-broker.ts +23 -3
- package/server/routes/transcribe-stream.ts +43 -4
- package/server/routes/web-control.ts +569 -0
- package/server/routes/welcome-context.ts +2 -1
- package/server/scripts/web-live-cls/cdp.mjs +57 -0
- package/server/scripts/web-live-cls/measure.mjs +80 -0
- package/server/scripts/web-live-cls/mock.mjs +97 -0
- package/server/scripts/web-live-cls/render.mjs +26 -0
- package/server/web-control/app.css +519 -0
- package/server/web-control/app.js +3643 -0
- package/server/web-control/control.css +325 -0
- package/server/web-control/fonts/DMSans.ttf +0 -0
- package/server/web-control/fonts/Fraunces.ttf +0 -0
- package/server/web-control/fonts/JetBrainsMono.ttf +0 -0
- package/server/web-control/index.html +275 -0
- package/server/web-control/mark.svg +1 -0
- package/server/web-control/memories/d3.min.js +2 -0
- package/server/web-control/memories/graph-explorer.css +200 -0
- package/server/web-control/memories/graph-explorer.js +748 -0
- package/server/web-control/memories/memories-app.js +1561 -0
- package/server/web-control/memories/memories-theme.css +73 -0
- package/server/web-control/memories/memories.html +72 -0
- package/server/web-control/memories/memory-stewardship.js +63 -0
- package/server/web-control/memories/memory-workspace.js +216 -0
- package/server/web-control/panes/cos-chat.css +174 -0
- package/server/web-control/panes/cos-chat.js +1118 -0
- package/server/web-control/panes/dictation.js +173 -0
- package/server/web-control/panes/meetings.css +314 -0
- package/server/web-control/panes/meetings.js +2568 -0
- package/server/web-control/panes/messages.js +718 -0
- package/server/web-control/panes/questions.css +32 -0
- package/server/web-control/panes/questions.js +275 -0
- package/server/web-control/panes/sessions.css +452 -0
- package/server/web-control/panes/settings.js +292 -0
- package/server/web-control/panes/speakers.css +269 -0
- package/server/web-control/panes/speakers.js +2755 -0
- package/server/web-control/panes/threads.js +200 -0
- package/server/web-control/panes/work.css +261 -0
- package/server/web-control/panes/work.js +1667 -0
- package/server/web-control/shell.js +294 -0
- package/server/web-control/theme.js +25 -0
- package/server/web-control/vendor/qrcode-encoder.js +10 -0
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
/* COS Control Web: Threads, the same pane as Control's (ActivityWindow.swift contextList(kind: "thread")
|
|
2
|
+
4841-4897, sectionHeader 5065-5123, contextRow 5007-5034; ContextDetailPane in Views.swift 6112-6189;
|
|
3
|
+
Models.swift thread() and threadBody() 620-690). Read only, as in Control.
|
|
4
|
+
Data: GET /api/threads?limit=50, /api/threads/:id, /api/threads/search?q=&limit=20, /api/context/status.
|
|
5
|
+
Routes: #/threads, #/threads/<id>. */
|
|
6
|
+
(function () {
|
|
7
|
+
'use strict';
|
|
8
|
+
var W = window.COSWeb;
|
|
9
|
+
var $ = W.$, esc = W.esc, api = W.api;
|
|
10
|
+
var pane = $('pane-threads');
|
|
11
|
+
|
|
12
|
+
var S = { rows: null, state: 'idle', error: '', status: null, q: '', hits: null, searching: false, ranFor: '', semantic: null, details: {} };
|
|
13
|
+
|
|
14
|
+
function trimmed(v) { var s = typeof v === 'string' ? v.trim() : ''; return s || null; }
|
|
15
|
+
function subtitle(t) {
|
|
16
|
+
var meetings = Number(t.meeting_count) || 0;
|
|
17
|
+
var topics = Array.isArray(t.topics) ? t.topics.filter(function (x) { return typeof x === 'string'; }) : [];
|
|
18
|
+
return [meetings > 0 ? meetings + ' meeting' + (meetings === 1 ? '' : 's') : null,
|
|
19
|
+
topics.length ? topics.slice(0, 3).join(', ') : null,
|
|
20
|
+
t.is_resolved === true ? 'resolved' : null].filter(Boolean).join(' · ');
|
|
21
|
+
}
|
|
22
|
+
// threadBody: notes, then facts, then Stakeholders / Meetings / Milestones / Sources.
|
|
23
|
+
function body(t) {
|
|
24
|
+
var sections = [];
|
|
25
|
+
var notes = (t.manual_updates || []).map(function (u) { return trimmed(u && u.content); }).filter(Boolean);
|
|
26
|
+
if (notes.length) sections.push(notes.join('\n\n'));
|
|
27
|
+
var facts = [];
|
|
28
|
+
var topics = (t.topics || []).filter(function (x) { return typeof x === 'string'; });
|
|
29
|
+
if (trimmed(t.target_date)) facts.push('Target: ' + trimmed(t.target_date));
|
|
30
|
+
if (trimmed(t.serves_goal)) facts.push('Goal: ' + trimmed(t.serves_goal));
|
|
31
|
+
var first = trimmed(t.first_seen), last = trimmed(t.last_seen);
|
|
32
|
+
if (first || last) facts.push('Seen: ' + (first || '?') + ' to ' + (last || '?'));
|
|
33
|
+
if (topics.length) facts.push('Topics: ' + topics.join(', '));
|
|
34
|
+
if (facts.length) sections.push(facts.join('\n'));
|
|
35
|
+
function section(title, items, total) {
|
|
36
|
+
if (!items.length) return;
|
|
37
|
+
var count = total > items.length ? items.length + ' of ' + total : String(items.length);
|
|
38
|
+
sections.push(title + ' (' + count + ')\n' + items.map(function (i) { return '- ' + i; }).join('\n'));
|
|
39
|
+
}
|
|
40
|
+
function strings(key) { return (t[key] || []).map(function (x) { return trimmed(x); }).filter(Boolean); }
|
|
41
|
+
section('Stakeholders', strings('stakeholders'));
|
|
42
|
+
var meetings = (t.meetings || []).map(function (m) {
|
|
43
|
+
var name = trimmed(m && m.name); if (!name) return null;
|
|
44
|
+
var date = trimmed(m.date); return date ? date + ' ' + name : name;
|
|
45
|
+
}).filter(Boolean);
|
|
46
|
+
section('Meetings', meetings, Number(t.meeting_count) || 0);
|
|
47
|
+
section('Milestones', strings('milestones'));
|
|
48
|
+
section('Sources', strings('sources'));
|
|
49
|
+
return sections.join('\n\n');
|
|
50
|
+
}
|
|
51
|
+
function copyFormat(t) {
|
|
52
|
+
var text = body(t) || t.name || '';
|
|
53
|
+
return 'Thread ' + t.id + ' (' + subtitle(t) + ')\n\n"""\n' + text + '\n"""';
|
|
54
|
+
}
|
|
55
|
+
function matchLabel(m) { return m === 'both' ? 'Keyword + meaning' : m === 'semantic' || m === 'meaning' ? 'Meaning' : 'Keyword'; }
|
|
56
|
+
|
|
57
|
+
function load(force) {
|
|
58
|
+
if (S.state === 'loading' || (S.rows && !force)) return;
|
|
59
|
+
S.state = 'loading';
|
|
60
|
+
render();
|
|
61
|
+
Promise.all([
|
|
62
|
+
api('/api/threads?limit=50'),
|
|
63
|
+
api('/api/context/status').then(function (d) { return d; }, function () { return null; })
|
|
64
|
+
]).then(function (res) {
|
|
65
|
+
S.rows = (res[0] && res[0].threads) || [];
|
|
66
|
+
S.status = res[1] && res[1].threads ? res[1].threads : null;
|
|
67
|
+
S.state = 'ready';
|
|
68
|
+
render();
|
|
69
|
+
}, function (err) {
|
|
70
|
+
S.state = 'error';
|
|
71
|
+
S.error = err && err.status === 404 ? 'Update the server to search threads from this panel.' : (err.message || 'Threads could not be loaded.');
|
|
72
|
+
render();
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
function search() {
|
|
76
|
+
var q = S.q.trim();
|
|
77
|
+
if (q.length < 2) { S.hits = null; S.ranFor = ''; render(); return; }
|
|
78
|
+
S.searching = true;
|
|
79
|
+
render();
|
|
80
|
+
api('/api/threads/search?q=' + encodeURIComponent(q) + '&limit=20').then(function (d) {
|
|
81
|
+
if (S.q.trim() !== q) return;
|
|
82
|
+
S.searching = false; S.ranFor = q;
|
|
83
|
+
S.hits = (d && d.hits) || [];
|
|
84
|
+
S.semantic = d ? d.semanticAvailable === true : null;
|
|
85
|
+
render();
|
|
86
|
+
}, function (err) {
|
|
87
|
+
S.searching = false; S.ranFor = q; S.hits = [];
|
|
88
|
+
S.error = err.message || 'The lookup failed.';
|
|
89
|
+
render();
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
function hero() {
|
|
94
|
+
var q = S.q.trim();
|
|
95
|
+
var active = S.status && S.status.available ? Number(S.status.active) || 0 : null;
|
|
96
|
+
var detail;
|
|
97
|
+
if (q.length >= 2) detail = S.searching ? 'Looking up…' : 'Lookup across stored threads';
|
|
98
|
+
else if (S.rows && active != null) detail = S.rows.length + ' shown · ' + active + ' active';
|
|
99
|
+
else detail = 'Follow work that develops across meetings and time.';
|
|
100
|
+
var stats = S.status && S.status.available
|
|
101
|
+
? '<div class="cx-stats"><span class="cx-stat"><b>' + (Number(S.status.total) || 0).toLocaleString() + '</b><span>TRACKED</span></span>' +
|
|
102
|
+
'<span class="cx-stat"><b>' + (S.rows ? S.rows.length : 0).toLocaleString() + '</b><span>SHOWN</span></span></div>'
|
|
103
|
+
: '';
|
|
104
|
+
return '<header class="cx-hero" data-tint="threads"><span class="cx-glyph"><svg class="icon"><use href="#i-threads"/></svg></span>' +
|
|
105
|
+
'<div class="cx-hero-text"><h1 class="cx-title">Review threads</h1><p class="cx-detail-line">' + esc(detail) + '</p></div>' +
|
|
106
|
+
'<div class="cx-actions"><button type="button" class="cx-btn quiet" data-th="refresh"><svg class="icon"><use href="#i-refresh"/></svg>Refresh</button></div>' +
|
|
107
|
+
stats + '</header>';
|
|
108
|
+
}
|
|
109
|
+
function searchBar() {
|
|
110
|
+
var q = S.q.trim();
|
|
111
|
+
var note = q.length >= 2 && S.ranFor === q && S.semantic === false ? '<p class="cx-note" style="margin:-4px 2px 10px">Keyword only. Threads have no meaning index.</p>' : '';
|
|
112
|
+
return '<div class="cx-controls"><form class="cx-search" data-th-form role="search" style="max-width:420px">' +
|
|
113
|
+
'<input class="field" type="search" id="th-q" placeholder="Search topics, ideas…" value="' + esc(S.q) + '" autocomplete="off" aria-label="Search topics, ideas">' +
|
|
114
|
+
(S.q ? '<button type="button" class="cx-clear" data-th="clear">Clear</button>' : '') + '</form></div>' + note;
|
|
115
|
+
}
|
|
116
|
+
function row(t) {
|
|
117
|
+
return '<button type="button" class="cx-row" data-th="open" data-id="' + esc(t.id) + '">' +
|
|
118
|
+
'<span class="cx-row-glyph"><svg class="icon"><use href="#i-threads"/></svg></span><span class="cx-row-body">' +
|
|
119
|
+
'<span class="cx-row-title strong">' + esc(t.name || '(untitled)') + '</span>' +
|
|
120
|
+
(subtitle(t) ? '<span class="cx-row-sub">' + esc(subtitle(t)) + '</span>' : '') +
|
|
121
|
+
'<span class="cx-id">' + esc(t.id) + '</span></span><span class="chev"></span></button>';
|
|
122
|
+
}
|
|
123
|
+
function hitRow(h) {
|
|
124
|
+
return '<button type="button" class="cx-row" data-th="open" data-id="' + esc(h.id) + '">' +
|
|
125
|
+
'<span class="cx-row-glyph"><svg class="icon"><use href="#i-threads"/></svg></span><span class="cx-row-body">' +
|
|
126
|
+
'<span class="cx-row-title strong">' + esc(h.title || h.name || '(untitled)') + '</span>' +
|
|
127
|
+
(h.snippet ? '<span class="cx-row-sub">' + esc(h.snippet) + '</span>' : '') +
|
|
128
|
+
'<span class="cx-meta" style="margin-top:4px"><span class="cx-id" style="margin:0">' + esc(h.id) + '</span><span class="cx-cap">' + esc(matchLabel(h.match)) + '</span></span>' +
|
|
129
|
+
'</span><span class="chev"></span></button>';
|
|
130
|
+
}
|
|
131
|
+
function list() {
|
|
132
|
+
var q = S.q.trim();
|
|
133
|
+
if (q.length >= 2 && S.ranFor === q) {
|
|
134
|
+
if (!S.hits.length) return '<div class="cx-list"><p class="cx-empty">No threads match that lookup.</p></div>';
|
|
135
|
+
return '<div class="cx-list">' + S.hits.map(hitRow).join('') + '</div>';
|
|
136
|
+
}
|
|
137
|
+
if (S.state === 'error') return '<div class="cx-notice warn">' + esc(S.error) + '</div>';
|
|
138
|
+
if (!S.rows) return '<p class="cx-note">Loading threads…</p>';
|
|
139
|
+
if (!S.rows.length) return '<div class="cx-list"><p class="cx-empty">No threads yet. Threads are markdown files in threads/, or tracked automatically with a bridge.</p></div>';
|
|
140
|
+
return '<div class="cx-list">' + S.rows.map(row).join('') + '</div>';
|
|
141
|
+
}
|
|
142
|
+
function renderList() {
|
|
143
|
+
var focus = document.activeElement && document.activeElement.id === 'th-q';
|
|
144
|
+
var caret = focus ? document.activeElement.selectionStart : null;
|
|
145
|
+
pane.innerHTML = '<div class="cx" data-tint="threads">' + hero() + searchBar() + list() + '</div>';
|
|
146
|
+
if (focus) { var input = $('th-q'); if (input) { input.focus(); try { input.setSelectionRange(caret, caret); } catch (_e) {} } }
|
|
147
|
+
}
|
|
148
|
+
function renderDetail(id) {
|
|
149
|
+
var cached = S.details[id] || (S.rows || []).filter(function (t) { return t.id === id; })[0];
|
|
150
|
+
if (cached) W.setCrumb(cached.name || id);
|
|
151
|
+
pane.innerHTML = '<div class="cx">' + W.skeletonRows(4) + '</div>';
|
|
152
|
+
api('/api/threads/' + encodeURIComponent(id)).then(function (t) {
|
|
153
|
+
var rt = W.parseRoute(); if (rt.pane !== 'threads' || rt.args[0] !== id) return;
|
|
154
|
+
t = t && t.thread ? t.thread : t;
|
|
155
|
+
S.details[id] = t;
|
|
156
|
+
W.setCrumb(t.name || id);
|
|
157
|
+
var text = body(t);
|
|
158
|
+
pane.innerHTML = '<div class="cx" data-tint="threads"><div class="cx-detail-head"><div style="min-width:0">' +
|
|
159
|
+
'<h2 class="cx-detail-title" style="font:500 22px/1.2 var(--display)">' + esc(t.name || '(untitled)') + '</h2>' +
|
|
160
|
+
(subtitle(t) ? '<p class="cx-detail-meta">' + esc(subtitle(t)) + '</p>' : '') +
|
|
161
|
+
'<p class="cx-id" style="user-select:all">' + esc(t.id) + '</p></div>' +
|
|
162
|
+
'<div class="cx-actions"><button type="button" class="cx-btn primary" data-th="copy">Copy as Context</button></div></div>' +
|
|
163
|
+
'<div class="cx-card"><div class="cx-card-body md">' + (text ? W.md(text) : '<p style="color:var(--sub)">(no stored body)</p>') + '</div></div></div>';
|
|
164
|
+
}, function (err) {
|
|
165
|
+
var r = W.parseRoute(); if (r.pane !== 'threads' || r.args[0] !== id) return;
|
|
166
|
+
pane.innerHTML = '<div class="cx"><div class="cx-notice warn">' + esc(err && err.status === 404 ? 'That thread is no longer stored.' : (err.message || 'The thread could not be read.')) + '</div>' +
|
|
167
|
+
(err && err.status === 404 ? '' : '<button type="button" class="cx-btn quiet" data-th="retry">Try again</button>') + '</div>';
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
function render() { var a = W.parseRoute(); if (a.pane === 'threads' && !a.args.length) renderList(); }
|
|
171
|
+
|
|
172
|
+
pane.addEventListener('click', function (e) {
|
|
173
|
+
var t = e.target.closest('[data-th]');
|
|
174
|
+
if (!t) return;
|
|
175
|
+
var act = t.getAttribute('data-th');
|
|
176
|
+
if (act === 'refresh') { S.rows = null; S.state = 'idle'; load(true); if (S.q.trim().length >= 2) search(); return; }
|
|
177
|
+
if (act === 'clear') { S.q = ''; S.hits = null; S.ranFor = ''; return renderList(); }
|
|
178
|
+
if (act === 'open') return W.go('threads', [t.getAttribute('data-id')]);
|
|
179
|
+
if (act === 'retry') { var cur = W.parseRoute().args[0]; if (cur) renderDetail(cur); return; }
|
|
180
|
+
if (act === 'copy') {
|
|
181
|
+
var id = W.parseRoute().args[0], th = S.details[id];
|
|
182
|
+
if (th) W.copyText(copyFormat(th)).then(function () { W.toast('Copied as grounded context'); }, function (err) { W.toast(err.message); });
|
|
183
|
+
}
|
|
184
|
+
});
|
|
185
|
+
pane.addEventListener('input', function (e) {
|
|
186
|
+
if (e.target.id !== 'th-q') return;
|
|
187
|
+
S.q = e.target.value;
|
|
188
|
+
clearTimeout(pane._t);
|
|
189
|
+
if (S.q.trim().length < 2) { S.hits = null; S.ranFor = ''; renderList(); return; }
|
|
190
|
+
pane._t = setTimeout(search, 350);
|
|
191
|
+
});
|
|
192
|
+
pane.addEventListener('submit', function (e) { if (e.target.matches('[data-th-form]')) { e.preventDefault(); clearTimeout(pane._t); search(); } });
|
|
193
|
+
|
|
194
|
+
W.registerPane('threads', {
|
|
195
|
+
load: function (args) {
|
|
196
|
+
if (args && args.length) renderDetail(args[0]);
|
|
197
|
+
else { load(false); renderList(); }
|
|
198
|
+
}
|
|
199
|
+
});
|
|
200
|
+
})();
|
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
/* COS Control Web: Work pane styles, on top of control.css. Control's board: columns 234pt wide on a raised ground,
|
|
2
|
+
cards on the panel with a 7pt radius, a gold rule for the chosen text switch, amber for a card asking for you,
|
|
3
|
+
green for one running. Below 600px the stages stack, one under another, with no sideways page scroll. */
|
|
4
|
+
|
|
5
|
+
#pane-work { max-width: 1400px; }
|
|
6
|
+
.wk { --danger: var(--rec, #c8452f); }
|
|
7
|
+
.wk [data-tone='green'] { --tone: var(--green); }
|
|
8
|
+
.wk [data-tone='amber'] { --tone: var(--amber); }
|
|
9
|
+
.wk [data-tone='danger'] { --tone: var(--danger); }
|
|
10
|
+
.wk [data-tone='accent'] { --tone: var(--accent); }
|
|
11
|
+
.wk [data-tone='muted'] { --tone: var(--sub); }
|
|
12
|
+
|
|
13
|
+
.wk-row { display: flex; align-items: center; gap: 8px; min-width: 0; }
|
|
14
|
+
.wk-row.wk-top { align-items: flex-start; }
|
|
15
|
+
.wk-wrap { flex-wrap: wrap; }
|
|
16
|
+
.wk-grow { flex: 1; min-width: 0; }
|
|
17
|
+
.wk-push { margin-left: auto; }
|
|
18
|
+
.wk-muted { color: var(--sub); font-size: 13px; line-height: 1.4; overflow-wrap: anywhere; }
|
|
19
|
+
.wk-small { font-size: 12.5px; line-height: 1.45; overflow-wrap: anywhere; }
|
|
20
|
+
.wk-fine { font-size: 11.5px; line-height: 1.45; color: var(--tertiary); margin: 10px 0 0; }
|
|
21
|
+
.wk-mono { font: 400 11px/1.3 var(--mono); color: var(--sub); white-space: nowrap; }
|
|
22
|
+
.wk-error { color: var(--danger); font-size: 13px; margin: 6px 0; overflow-wrap: anywhere; }
|
|
23
|
+
.wk-pad { padding: 12px; margin: 0; }
|
|
24
|
+
.wk-pad-x { padding: 0 2px; margin: 0 0 10px; }
|
|
25
|
+
.wk-clamp2, .wk-clamp3 { display: -webkit-box; -webkit-box-orient: vertical; overflow: hidden; }
|
|
26
|
+
.wk-clamp2 { -webkit-line-clamp: 2; }
|
|
27
|
+
.wk-clamp3 { -webkit-line-clamp: 3; }
|
|
28
|
+
.wk-h2 { font: 500 22px/1.2 var(--display); margin: 0; color: var(--ink); }
|
|
29
|
+
.wk code { font: 400 0.92em/1.3 var(--mono); background: var(--qopen); padding: 0 3px; border-radius: 4px; }
|
|
30
|
+
.wk-u { text-decoration: underline; text-decoration-color: var(--gold); text-decoration-thickness: 2px; text-underline-offset: 2px; }
|
|
31
|
+
|
|
32
|
+
.wk-text-btn { display: inline-flex; align-items: center; min-height: 30px; padding: 0 2px; font: 600 13px/1.2 var(--body); color: var(--accent); white-space: nowrap; }
|
|
33
|
+
.wk-text-btn:disabled { opacity: 0.45; }
|
|
34
|
+
.wk-link { text-align: left; color: var(--accent); font: 600 14px/1.35 var(--body); padding: 0; }
|
|
35
|
+
.wk-decision-title { max-width: 100%; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
|
36
|
+
@media (max-width: 599px) { .wk-decision-title { white-space: normal; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; } }
|
|
37
|
+
.wk-icon-btn { width: 36px; justify-content: center; padding: 0; }
|
|
38
|
+
.wk-caret { display: inline-block; width: 0; height: 0; margin-left: 6px; border-left: 4px solid transparent; border-right: 4px solid transparent; border-top: 5px solid currentColor; vertical-align: 2px; opacity: 0.7; }
|
|
39
|
+
.wk-note { justify-content: space-between; align-items: center; }
|
|
40
|
+
|
|
41
|
+
/* ── tabs and filters ───────────────────────────────────── */
|
|
42
|
+
.wk-controls { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 10px 18px; margin: 12px 0 14px; }
|
|
43
|
+
.wk-tabs { flex-wrap: wrap; row-gap: 0; }
|
|
44
|
+
.wk-more { position: relative; display: inline-flex; }
|
|
45
|
+
.wk-menu { position: absolute; top: calc(100% + 6px); right: 0; left: auto; max-width: calc(100vw - 32px); z-index: 30; min-width: 200px; padding: 6px; border-radius: 10px; background: var(--panel); border: 1px solid var(--panel-border); box-shadow: var(--shadow); display: flex; flex-direction: column; }
|
|
46
|
+
.wk-tabs .wk-menu button { padding: 10px 10px; text-align: left; border-radius: 7px; font: 500 14px/1.2 var(--body); color: var(--ink); }
|
|
47
|
+
.wk-tabs .wk-menu button::after { display: none; }
|
|
48
|
+
.wk-menu button:hover { background: var(--qopen); }
|
|
49
|
+
.wk-filters { display: flex; flex-wrap: wrap; align-items: center; justify-content: flex-end; gap: 8px 12px; min-width: 0; flex: 1 1 auto; }
|
|
50
|
+
.wk-filters .cx-search { flex: 1 1 200px; max-width: 280px; }
|
|
51
|
+
.wk-pick { display: inline-flex; align-items: center; gap: 7px; font-size: 12.5px; color: var(--sub); min-width: 0; }
|
|
52
|
+
.wk-pick select.field, .wk-pick input.field { width: auto; min-height: 34px; padding: 0 30px 0 10px; font-size: 13.5px; border-radius: 8px; color: var(--ink); background-position: calc(100% - 16px) 15px, calc(100% - 11px) 15px; }
|
|
53
|
+
.wk-pick input.field { padding: 0 10px; }
|
|
54
|
+
.wk-pick-wide { display: flex; flex-direction: column; align-items: stretch; gap: 6px; margin: 10px 0; }
|
|
55
|
+
.wk-pick-wide span { font: 600 12px/1.2 var(--body); color: var(--sub); }
|
|
56
|
+
.wk-pick-wide select.field { width: 100%; max-width: 520px; min-height: 40px; }
|
|
57
|
+
@media (max-width: 599px) {
|
|
58
|
+
.wk-controls { margin: 10px 0 12px; }
|
|
59
|
+
.wk-filters { width: 100%; justify-content: flex-start; }
|
|
60
|
+
.wk-filters .cx-search { max-width: none; flex-basis: 100%; }
|
|
61
|
+
.wk-pick { flex: 1 1 140px; flex-direction: column; align-items: stretch; gap: 4px; font-size: 11.5px; }
|
|
62
|
+
.wk-pick select.field { min-height: 38px; font-size: 15px; width: 100%; background-position: calc(100% - 16px) 17px, calc(100% - 11px) 17px; }
|
|
63
|
+
.wk-text-btn { min-height: 36px; font-size: 14px; }
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/* ── capture ────────────────────────────────────────────── */
|
|
67
|
+
.wk-capture { margin: 12px 0 0; display: flex; flex-direction: column; gap: 8px; }
|
|
68
|
+
.wk-capture .field { min-height: 40px; font-size: 15px; padding: 8px 12px; border-radius: 9px; }
|
|
69
|
+
.wk-capture-row { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; justify-content: flex-end; }
|
|
70
|
+
.wk-capture-row select.field { width: auto; min-width: 180px; padding-right: 32px; background-position: calc(100% - 17px) 18px, calc(100% - 12px) 18px; }
|
|
71
|
+
|
|
72
|
+
/* ── Your move ──────────────────────────────────────────── */
|
|
73
|
+
.wk-queue { padding-top: 6px; }
|
|
74
|
+
.wk-queue-head { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 12px; margin-bottom: 4px; }
|
|
75
|
+
.wk-decision { display: flex; gap: 12px; align-items: flex-start; padding: 16px 0; border-bottom: 1px solid var(--hairline); }
|
|
76
|
+
.wk-decision-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 5px; }
|
|
77
|
+
.wk-decision-main p { margin: 0; }
|
|
78
|
+
.wk-decision-actions { display: flex; flex-direction: column; align-items: flex-end; gap: 4px; flex: none; }
|
|
79
|
+
.wk-state { margin: 0; font: 500 12.5px/1.35 var(--body); color: var(--tone, var(--sub)); }
|
|
80
|
+
@media (max-width: 599px) {
|
|
81
|
+
.wk-decision { flex-direction: column; gap: 8px; }
|
|
82
|
+
.wk-decision-actions { flex-direction: row; align-items: center; gap: 12px; }
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/* ── board ──────────────────────────────────────────────── */
|
|
86
|
+
.wk-board-head { display: flex; flex-wrap: wrap; align-items: flex-start; justify-content: space-between; gap: 8px 16px; margin: 4px 0 12px; }
|
|
87
|
+
.wk-board-head .wk-muted { margin: 4px 0 0; font-size: 12.5px; }
|
|
88
|
+
.wk-results { margin: 0 0 12px; display: flex; flex-direction: column; gap: 8px; }
|
|
89
|
+
.wk-band { border-top: 1px solid var(--hairline); border-bottom: 1px solid var(--hairline); }
|
|
90
|
+
.wk-band-row { display: grid; grid-template-columns: 70px minmax(0, 1fr) auto; gap: 12px; align-items: baseline; width: 100%; padding: 9px 6px; text-align: left; }
|
|
91
|
+
.wk-band-row + .wk-band-row { border-top: 1px solid var(--hairline); }
|
|
92
|
+
.wk-band-row:hover { background: var(--gold-bg); }
|
|
93
|
+
.wk-band-stage { font: 400 10.5px/1.3 var(--mono); color: var(--sub); }
|
|
94
|
+
.wk-band-title { font-size: 13.5px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
|
95
|
+
.wk-band-why { font-size: 12px; color: var(--accent); white-space: nowrap; }
|
|
96
|
+
.wk-band-why.meaning { color: var(--gold); font-style: italic; }
|
|
97
|
+
@media (max-width: 599px) { .wk-band-row { grid-template-columns: minmax(0, 1fr); gap: 2px; } .wk-band-title { white-space: normal; } }
|
|
98
|
+
|
|
99
|
+
.wk-mentioned { margin: 0 0 12px; }
|
|
100
|
+
.wk-menu-label { display: inline-flex; align-items: center; min-height: 32px; padding: 0 10px; border-radius: 8px; border: 1px solid var(--panel-border); background: var(--btn-bg); font: 500 13px/1 var(--body); color: var(--ink); }
|
|
101
|
+
.wk-mentioned-list { margin-top: 8px; max-height: 420px; overflow-y: auto; }
|
|
102
|
+
.wk-mrow { display: flex; align-items: center; justify-content: space-between; gap: 12px; width: 100%; padding: 10px 14px; text-align: left; font-size: 13.5px; line-height: 1.35; border-top: 1px solid var(--hairline); }
|
|
103
|
+
.wk-mrow:first-child { border-top: 0; }
|
|
104
|
+
.wk-mrow span:first-child { min-width: 0; overflow-wrap: anywhere; }
|
|
105
|
+
.wk-more-row { display: block; width: 100%; padding: 11px 14px; text-align: left; font: 600 13px/1.2 var(--body); color: var(--accent); }
|
|
106
|
+
|
|
107
|
+
/* Columns: stacked on the closed Duo; side by side from 600px, scrolling sideways inside the board as Control's does. */
|
|
108
|
+
.wk-columns { display: flex; flex-direction: column; gap: 14px; }
|
|
109
|
+
.wk-col { background: color-mix(in srgb, var(--qopen) 70%, transparent); border: 1px solid var(--panel-border); border-radius: 9px; min-width: 0; }
|
|
110
|
+
.wk-col-head { padding: 12px 12px 11px; border-bottom: 1px solid var(--panel-border); }
|
|
111
|
+
.wk-col-head h3 { margin: 0; font: 600 14px/1.2 var(--body); color: var(--ink); }
|
|
112
|
+
.wk-col-head .wk-row { justify-content: space-between; }
|
|
113
|
+
.wk-col-head p { margin: 5px 0 0; font-size: 11.5px; color: var(--sub); }
|
|
114
|
+
.wk-count { font: 400 11.5px/1 var(--mono); color: var(--sub); }
|
|
115
|
+
.wk-col-body { padding: 10px; display: flex; flex-direction: column; gap: 10px; }
|
|
116
|
+
.wk-col-body > * { flex: none; }
|
|
117
|
+
@media (min-width: 600px) {
|
|
118
|
+
.wk-columns { display: grid; grid-auto-flow: column; grid-auto-columns: minmax(206px, 1fr); overflow-x: auto; gap: 12px; padding-bottom: 6px; scroll-snap-type: x proximity; overscroll-behavior-x: contain; }
|
|
119
|
+
.wk-col { scroll-snap-align: start; display: flex; flex-direction: column; max-height: calc(100dvh - 150px); }
|
|
120
|
+
.wk-col-body { overflow-y: auto; flex: 1; min-height: 120px; }
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
.wk-card { position: relative; background: var(--panel); border: 1px solid var(--panel-border); border-radius: 7px; overflow: hidden; }
|
|
124
|
+
.wk-card[data-tone='asking'] { border-color: color-mix(in srgb, var(--amber) 60%, transparent); }
|
|
125
|
+
.wk-card[data-tone='running'] { border-color: color-mix(in srgb, var(--green) 60%, transparent); }
|
|
126
|
+
.wk-card[data-tone='matched'] { border-color: color-mix(in srgb, var(--gold) 50%, transparent); }
|
|
127
|
+
.wk-card[data-tone='asking']::before, .wk-card[data-tone='running']::before { content: ''; position: absolute; left: 0; top: 0; bottom: 0; width: 3px; border-radius: 2px; background: var(--amber); }
|
|
128
|
+
.wk-card[data-tone='running']::before { background: var(--green); }
|
|
129
|
+
.wk-card-tap { display: flex; flex-direction: column; gap: 9px; width: 100%; padding: 12px; text-align: left; color: inherit; }
|
|
130
|
+
.wk-card-tap:hover { background: var(--qopen); }
|
|
131
|
+
.wk-card-tap:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
|
|
132
|
+
.wk-card-title { font: 500 13.5px/1.38 var(--body); color: var(--ink); display: -webkit-box; -webkit-line-clamp: 5; -webkit-box-orient: vertical; overflow: hidden; overflow-wrap: anywhere; }
|
|
133
|
+
.wk-card-source { font-size: 11.5px; line-height: 1.35; color: var(--sub); display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; overflow-wrap: anywhere; }
|
|
134
|
+
.wk-status { display: flex; align-items: baseline; gap: 6px; margin: 0; font: 600 11.5px/1.35 var(--body); color: var(--tone, var(--accent)); overflow-wrap: anywhere; }
|
|
135
|
+
.wk-status .icon { width: 12px; height: 12px; align-self: center; }
|
|
136
|
+
.wk-dot { flex: none; width: 7px; height: 7px; border-radius: 50%; background: currentColor; transform: translateY(-1px); }
|
|
137
|
+
.wk-dot.hollow { background: transparent; box-shadow: inset 0 0 0 1.5px currentColor; }
|
|
138
|
+
.wk-dot.live { animation: wk-pulse 1.6s ease-in-out infinite; }
|
|
139
|
+
@keyframes wk-pulse { 50% { opacity: 0.35; } }
|
|
140
|
+
@media (prefers-reduced-motion: reduce) { .wk-dot.live { animation: none; } }
|
|
141
|
+
.wk-quote { margin: 0; font-size: 12px; font-style: italic; line-height: 1.4; color: var(--ink); display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; }
|
|
142
|
+
.wk-meeting { display: flex; align-items: flex-start; gap: 6px; width: 100%; padding: 0 12px 10px; text-align: left; font-size: 11.5px; line-height: 1.35; color: var(--accent); }
|
|
143
|
+
.wk-meeting .icon { width: 13px; height: 13px; flex: none; margin-top: 1px; }
|
|
144
|
+
.wk-meeting span { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; overflow-wrap: anywhere; }
|
|
145
|
+
.wk-date { margin: -4px 0 0; padding: 0 12px 9px; text-align: right; font: 400 10.5px/1.3 var(--mono); color: var(--sub); }
|
|
146
|
+
.wk-card-foot { display: flex; align-items: center; gap: 10px; padding: 6px 10px; border-top: 1px solid var(--hairline); }
|
|
147
|
+
.wk-card-foot .wk-text-btn { flex: none; }
|
|
148
|
+
.wk-stage-lg { max-width: 200px; }
|
|
149
|
+
.wk-stage { flex: 0 1 auto; width: auto; max-width: 132px; field-sizing: content; min-height: 28px; padding: 0 24px 0 9px; border-radius: 7px; border: 1px solid var(--panel-border); background: var(--btn-bg); color: var(--ink); font: 500 12.5px/1 var(--body);
|
|
150
|
+
appearance: none; -webkit-appearance: none; cursor: pointer;
|
|
151
|
+
background-image: linear-gradient(45deg, transparent 50%, var(--sub) 50%), linear-gradient(135deg, var(--sub) 50%, transparent 50%);
|
|
152
|
+
background-position: calc(100% - 13px) 12px, calc(100% - 9px) 12px; background-size: 4px 4px; background-repeat: no-repeat; }
|
|
153
|
+
.wk-stage:disabled { opacity: 0.5; cursor: default; }
|
|
154
|
+
.wk-stage-lg { min-height: 32px; font-size: 13.5px; background-position: calc(100% - 13px) 14px, calc(100% - 9px) 14px; }
|
|
155
|
+
.wk-confirm { margin: 8px 10px 10px; padding: 10px 12px; border-radius: 8px; background: var(--gold-bg); font-size: 13px; }
|
|
156
|
+
.wk-confirm p { margin: 0 0 8px; overflow-wrap: anywhere; }
|
|
157
|
+
@media (max-width: 599px) {
|
|
158
|
+
.wk-stage { min-height: 36px; font-size: 14px; background-position: calc(100% - 13px) 16px, calc(100% - 9px) 16px; }
|
|
159
|
+
.wk-card-title { font-size: 15px; }
|
|
160
|
+
.wk-card-source, .wk-meeting { font-size: 12.5px; }
|
|
161
|
+
.wk-status { font-size: 12.5px; }
|
|
162
|
+
.wk-meeting { min-height: 28px; }
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/* ── Focus ──────────────────────────────────────────────── */
|
|
166
|
+
.wk-focus-counts { margin: 0 0 10px; gap: 6px 16px; }
|
|
167
|
+
.wk-count-link { display: inline-flex; align-items: center; gap: 5px; min-height: 30px; font: 500 13px/1.2 var(--body); color: var(--accent); border-bottom: 1px dashed color-mix(in srgb, var(--accent) 55%, transparent); }
|
|
168
|
+
.wk-count-link .chev { width: 6px; height: 6px; }
|
|
169
|
+
.wk-count-link:disabled { color: var(--sub); border-bottom-color: transparent; }
|
|
170
|
+
.wk-frow { display: flex; flex-direction: column; gap: 5px; width: 100%; padding: 14px 16px; text-align: left; border-top: 1px solid var(--hairline); }
|
|
171
|
+
.wk-frow:first-child { border-top: 0; }
|
|
172
|
+
.wk-frow:hover { background: var(--qopen); }
|
|
173
|
+
.wk-frow-title { font: 500 14px/1.38 var(--body); color: var(--ink); overflow-wrap: anywhere; }
|
|
174
|
+
|
|
175
|
+
/* ── Sort ───────────────────────────────────────────────── */
|
|
176
|
+
.wk-sort { display: flex; flex-direction: column; gap: 10px; }
|
|
177
|
+
.wk-sort-head { gap: 6px 12px; }
|
|
178
|
+
.wk-sort-head .wk-muted { font-size: 12.5px; }
|
|
179
|
+
.wk-sort-body { display: flex; flex-direction: column; gap: 14px; border-top: 1px solid var(--hairline); padding-top: 14px; }
|
|
180
|
+
.wk-sort-group h3 { margin: 0; font: 600 15px/1.3 var(--body); min-width: 0; overflow-wrap: anywhere; }
|
|
181
|
+
.wk-keys { margin: -6px 0 0; }
|
|
182
|
+
.wk-sort-note { margin: -8px 0 0; }
|
|
183
|
+
@media (hover: none) { .wk-keys { display: none; } }
|
|
184
|
+
@media (max-width: 599px) { .wk-sort-head .wk-muted { order: 3; flex-basis: 100%; } }
|
|
185
|
+
.wk-sort-card { padding: 12px; border-radius: 9px; background: var(--qopen); border: 1px solid var(--panel-border); display: flex; flex-direction: column; gap: 7px; }
|
|
186
|
+
.wk-sort-card p { margin: 0; }
|
|
187
|
+
.wk-items h4 { margin: 0; font: 600 14px/1.2 var(--body); }
|
|
188
|
+
.wk-items > .wk-muted { margin: 4px 0 8px; font-size: 12.5px; }
|
|
189
|
+
.wk-items-list { padding: 0 12px; border-radius: 9px; background: color-mix(in srgb, var(--qopen) 60%, transparent); border: 1px solid var(--panel-border); }
|
|
190
|
+
.wk-intake-row { padding: 12px 0; display: flex; flex-direction: column; gap: 6px; }
|
|
191
|
+
.wk-intake-row + .wk-intake-row { border-top: 1px solid var(--hairline); }
|
|
192
|
+
.wk-intake-text { margin: 0; font: 500 14px/1.42 var(--body); color: var(--ink); overflow-wrap: anywhere; }
|
|
193
|
+
.wk-intake-foot { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 6px 12px; }
|
|
194
|
+
.wk-intake-meta { display: flex; align-items: baseline; gap: 4px; min-width: 0; flex: 1 1 220px; }
|
|
195
|
+
.wk-intake-meta .wk-meeting { padding: 0; width: auto; color: var(--sub); }
|
|
196
|
+
.wk-intake-meta .wk-muted { font-size: 11.5px; white-space: nowrap; }
|
|
197
|
+
.wk-evidence summary { cursor: pointer; font-size: 12.5px; color: var(--accent); min-height: 28px; }
|
|
198
|
+
.wk-evidence p { white-space: pre-wrap; font-size: 12px; color: var(--sub); margin: 6px 0 0; }
|
|
199
|
+
.wk-sort-nav { gap: 18px; padding-top: 4px; }
|
|
200
|
+
.wk-undo { justify-content: flex-end; }
|
|
201
|
+
|
|
202
|
+
/* ── detail ─────────────────────────────────────────────── */
|
|
203
|
+
.wk-backbar { margin: 4px 0 10px; }
|
|
204
|
+
.wk-backbar .icon { width: 14px; height: 14px; }
|
|
205
|
+
@media (max-width: 599px) { .wk-backbar { display: none; } }
|
|
206
|
+
.wk-detail { display: flex; flex-direction: column; gap: 18px; }
|
|
207
|
+
.wk-detail-main, .wk-detail-side { min-width: 0; display: flex; flex-direction: column; gap: 18px; }
|
|
208
|
+
@media (min-width: 900px) {
|
|
209
|
+
.wk-detail { display: grid; grid-template-columns: minmax(0, 1fr) minmax(320px, 400px); gap: 22px; align-items: start; }
|
|
210
|
+
.wk-detail-side { padding: 16px; border-radius: 12px; background: color-mix(in srgb, var(--qopen) 60%, transparent); border: 1px solid var(--panel-border); }
|
|
211
|
+
}
|
|
212
|
+
@media (min-width: 1300px) { .wk-detail { grid-template-columns: minmax(0, 1fr) 452px; } }
|
|
213
|
+
.wk-detail-head { display: flex; flex-direction: column; gap: 10px; padding-bottom: 14px; border-bottom: 1px solid var(--hairline); }
|
|
214
|
+
.wk-detail-head p { margin: 0; }
|
|
215
|
+
.wk-detail-title { font: 500 24px/1.22 var(--display); margin: 0; color: var(--ink); min-width: 0; overflow-wrap: anywhere; }
|
|
216
|
+
.wk-detail-head .wk-detail-title { flex: 1 1 300px; }
|
|
217
|
+
.wk-actions { flex: none; }
|
|
218
|
+
.wk-section { display: flex; flex-direction: column; gap: 10px; }
|
|
219
|
+
.wk-section > p { margin: 0; }
|
|
220
|
+
.wk-fact h3 { margin: 0 0 6px; font: 600 12px/1.2 var(--body); color: var(--sub); }
|
|
221
|
+
.wk-fact .cx-card-body { font-size: 14.5px; }
|
|
222
|
+
.wk-contrib { padding: 12px; border-radius: 8px; background: var(--panel); border: 1px solid var(--panel-border); display: flex; flex-direction: column; gap: 6px; }
|
|
223
|
+
.wk-contrib p { margin: 0; }
|
|
224
|
+
.wk-contrib strong { font-size: 13.5px; }
|
|
225
|
+
.wk-sub { display: flex; flex-direction: column; gap: 8px; padding-top: 6px; }
|
|
226
|
+
.wk-sub .wk-meeting { padding: 8px 10px; border-radius: 8px; border: 1px solid var(--panel-border); background: var(--btn-bg); font-size: 13px; }
|
|
227
|
+
.wk-sub .wk-muted, .wk-sub p { margin: 0; }
|
|
228
|
+
.wk-handoff { padding: 12px; border-radius: 9px; background: var(--panel); border: 1px solid color-mix(in srgb, var(--tone, var(--panel-border)) 45%, transparent); display: flex; flex-direction: column; gap: 6px; }
|
|
229
|
+
.wk-handoff p { margin: 0; }
|
|
230
|
+
.wk-handoff .wk-state { color: var(--tone); }
|
|
231
|
+
.wk-section .cx-btn.primary { align-self: flex-start; }
|
|
232
|
+
.wk-section > .cx-btn { align-self: flex-start; }
|
|
233
|
+
.wk-reply { display: flex; flex-direction: column; gap: 8px; }
|
|
234
|
+
.wk-reply p { margin: 0; }
|
|
235
|
+
.wk-reply .field { min-height: 80px; font-size: 15px; padding: 9px 12px; border-radius: 9px; }
|
|
236
|
+
.wk-missing { padding: 20px 0; }
|
|
237
|
+
|
|
238
|
+
/* ── Start work and Edit task ───────────────────────────── */
|
|
239
|
+
.wk-start, .wk-edit { max-width: 640px; display: flex; flex-direction: column; gap: 12px; }
|
|
240
|
+
.wk-start p, .wk-edit p { margin: 0; }
|
|
241
|
+
.wk-start > *, .wk-edit > *, .wk-section > *, .wk-sort > * { flex: none; }
|
|
242
|
+
.wk-start-task { font-size: 15px; line-height: 1.45; overflow-wrap: anywhere; }
|
|
243
|
+
.wk-field { display: flex; flex-direction: column; gap: 6px; }
|
|
244
|
+
.wk-label { font: 600 12px/1.2 var(--body); color: var(--sub); }
|
|
245
|
+
.wk-field .field { min-height: 42px; font-size: 15px; padding: 9px 12px; border-radius: 9px; }
|
|
246
|
+
.wk-choices { border: 1px solid var(--panel-border); border-radius: 9px; overflow: hidden; background: var(--panel); }
|
|
247
|
+
.wk-choice { display: flex; gap: 10px; align-items: flex-start; padding: 12px; cursor: pointer; }
|
|
248
|
+
.wk-choice + .wk-choice { border-top: 1px solid var(--hairline); }
|
|
249
|
+
.wk-choice input { margin-top: 3px; accent-color: var(--gold); width: 16px; height: 16px; flex: none; }
|
|
250
|
+
.wk-choice > span { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
|
|
251
|
+
.wk-choice strong { font-size: 14px; }
|
|
252
|
+
.wk-choice.off { opacity: 0.5; cursor: default; }
|
|
253
|
+
.wk-lines { display: flex; flex-direction: column; gap: 4px; }
|
|
254
|
+
.wk-line { display: grid; grid-template-columns: 70px minmax(0, 1fr); gap: 8px; font-size: 12.5px; }
|
|
255
|
+
.wk-line span:first-child { color: var(--sub); }
|
|
256
|
+
.wk-line span:last-child { overflow-wrap: anywhere; }
|
|
257
|
+
.wk-more-actions { border-top: 1px solid var(--hairline); padding-top: 10px; }
|
|
258
|
+
.wk-more-actions summary { cursor: pointer; font: 600 13px/1.2 var(--body); min-height: 32px; display: flex; align-items: center; }
|
|
259
|
+
.wk-more-body { display: flex; flex-direction: column; gap: 10px; padding-top: 8px; }
|
|
260
|
+
.wk-edit-foot { display: flex; flex-direction: column; gap: 8px; padding-top: 12px; border-top: 1px solid var(--hairline); }
|
|
261
|
+
.wk-edit-foot .wk-confirm { margin: 0; }
|