@gotcos/glasses-server 6.99.16 → 6.99.25

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/CHANGELOG.md +137 -0
  2. package/docs/work-orchestrator.md +20 -0
  3. package/package.json +1 -1
  4. package/server/index.ts +23 -1
  5. package/server/lib/ask-work-plan.ts +116 -0
  6. package/server/lib/batch-transcript-quality.ts +2 -0
  7. package/server/lib/drop-store.ts +16 -2
  8. package/server/lib/meeting-ask-runtime.ts +1 -1
  9. package/server/lib/meeting-batch-transcribe.ts +40 -1
  10. package/server/lib/ping-sources.ts +6 -2
  11. package/server/lib/prep-runtime.ts +915 -0
  12. package/server/lib/prep-store.ts +226 -0
  13. package/server/lib/stt-resolver.ts +26 -2
  14. package/server/lib/transcript-cleanup.ts +11 -2
  15. package/server/lib/web-control-static.ts +226 -0
  16. package/server/lib/web-memories-bridge.ts +9 -8
  17. package/server/lib/web-pet-choice.ts +225 -0
  18. package/server/lib/web-pet.ts +226 -0
  19. package/server/lib/work-lens-rounds.ts +29 -4
  20. package/server/lib/work-orchestrator/runtime.ts +8 -2
  21. package/server/routes/ask-work-plan.ts +114 -0
  22. package/server/routes/health.ts +8 -0
  23. package/server/routes/prep.ts +81 -0
  24. package/server/routes/web-control.ts +110 -7
  25. package/server/routes/welcome-context.ts +29 -1
  26. package/server/routes/work-lens-rounds.ts +19 -5
  27. package/server/routes/work-orchestrator.ts +57 -0
  28. package/server/web-control/app.css +24 -5
  29. package/server/web-control/app.js +646 -108
  30. package/server/web-control/control.css +1 -1
  31. package/server/web-control/index.html +27 -13
  32. package/server/web-control/memories/memory-workspace.js +1 -1
  33. package/server/web-control/panes/cos-chat.css +26 -0
  34. package/server/web-control/panes/cos-chat.js +641 -6
  35. package/server/web-control/panes/meetings.css +45 -2
  36. package/server/web-control/panes/meetings.js +230 -7
  37. package/server/web-control/panes/memories.css +291 -0
  38. package/server/web-control/panes/memories.js +2208 -0
  39. package/server/web-control/panes/questions.js +59 -21
  40. package/server/web-control/panes/settings.js +102 -4
  41. package/server/web-control/panes/today-actions.css +109 -0
  42. package/server/web-control/panes/today-actions.js +972 -0
  43. package/server/web-control/panes/work.css +54 -0
  44. package/server/web-control/panes/work.js +1037 -18
  45. package/server/web-control/shell.js +6 -2
  46. package/server/web-control/theme.js +0 -2
  47. package/shared/meeting-ask.ts +6 -2
  48. package/shared/prep.ts +317 -0
  49. package/server/web-control/memories/memories-app.js +0 -1561
  50. package/server/web-control/memories/memories-theme.css +0 -73
  51. package/server/web-control/memories/memories.html +0 -72
  52. package/server/web-control/memories/memory-stewardship.js +0 -63
@@ -0,0 +1,291 @@
1
+ /* COS Control Web: Memories pane styles, on top of control.css. Control's Memories page in the app's own tokens: a
2
+ list of learning beside a reader from 760px (the split in app.css), a pushed reader below it, a text switch with a
3
+ gold rule for the views, and the timeline Control draws down the left of a lesson. Nothing here is fixed to the
4
+ bottom of the screen, and nothing is wider than the screen. */
5
+
6
+ #pane-memories { max-width: 1240px; }
7
+ .mm { min-width: 0; }
8
+ .mm-controls { margin: 12px 0 6px; }
9
+ .mm-tabs { display: flex; flex-wrap: wrap; gap: 2px 18px; }
10
+ .mm-counts { display: flex; flex-wrap: wrap; align-items: baseline; gap: 2px 6px; margin: 4px 2px 12px; font-size: 13px; line-height: 1.5; color: var(--sub); }
11
+ .mm-counts b { color: var(--ink); font-weight: 600; }
12
+ .mm-dot { color: var(--tertiary); }
13
+ .mm-foot { margin: 18px 2px 0; font-size: 12px; color: var(--tertiary); overflow-wrap: anywhere; }
14
+ .mm-icon-btn { width: 36px; justify-content: center; padding: 0; }
15
+ /* On a phone the top bar already says Memories, and the counts line carries Memory settings and Refresh, so the
16
+ hero steps aside and the list starts higher on the closed Duo (Control's page did the same for web phones). */
17
+ .mm-phone-only { display: none; }
18
+ @media (max-width: 599px) {
19
+ .mm-hero { display: none; }
20
+ .mm-phone-only { display: inline; }
21
+ .mm-controls { margin-top: 2px; }
22
+ }
23
+ .mm-link { display: inline; padding: 0; font: inherit; font-weight: 600; color: var(--accent); text-align: left; }
24
+ .mm-link:disabled { opacity: 0.45; }
25
+ .mm-muted { color: var(--sub); font-size: 13px; line-height: 1.45; overflow-wrap: anywhere; }
26
+ .mm-bad { color: var(--hot); font-size: 13.5px; overflow-wrap: anywhere; }
27
+ .mm-ok { color: var(--green); }
28
+ .mm-warn { color: var(--amber); font-size: 13px; }
29
+ .mm-split { margin-top: 2px; }
30
+ .mm-split, .mm-list, .mm-reader { min-width: 0; }
31
+
32
+ /* A reader on a narrow screen is a pushed page: the header, views and counts step aside. */
33
+ @media (max-width: 759px) {
34
+ #pane-memories.reading .mm-hero, #pane-memories.reading .mm-controls, #pane-memories.reading .mm-counts { display: none; }
35
+ }
36
+
37
+ /* ── list ─────────────────────────────────────────────── */
38
+ .mm-group { margin: 14px 4px 8px; align-items: baseline; }
39
+ .mm-group:first-child { margin-top: 4px; }
40
+ .mm-group span:last-child { font-weight: 500; font-size: 13px; }
41
+ .mm-group .mm-link { font-size: 13px; }
42
+ .mm-group-note { margin: -2px 4px 8px; font-size: 12.5px; line-height: 1.45; color: var(--sub); }
43
+ .mm-row { display: grid; grid-template-columns: minmax(0, 1fr) 12px; gap: 10px; align-items: center; width: 100%; padding: 12px 14px; text-align: left; color: inherit; position: relative; }
44
+ .mm-row + .mm-row::before { content: ''; position: absolute; top: 0; left: 14px; right: 0; height: 1px; background: var(--hairline); }
45
+ .mm-row:hover { background: var(--qopen); }
46
+ .mm-row:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
47
+ .mm-row[aria-selected='true'] { background: var(--qopen); box-shadow: inset 3px 0 0 var(--gold); }
48
+ .mm-row-body { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
49
+ .mm-row-title { font: 600 15px/1.35 var(--body); color: var(--ink); display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; overflow-wrap: anywhere; }
50
+ .mm-row-what { font-size: 12.5px; color: var(--sub); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
51
+ .mm-facts { font-size: 12px; line-height: 1.35; color: var(--tertiary); overflow-wrap: anywhere; }
52
+ .mm-kind { color: var(--tint); font-weight: 600; }
53
+ .mm-status { font-size: 12.5px; line-height: 1.4; color: var(--sub); display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; overflow-wrap: anywhere; }
54
+ .mm-status.ok { color: var(--green); }
55
+ .mm-status.warn { color: var(--amber); }
56
+ .mm-status.bad { color: var(--hot); }
57
+ .mm-state { display: flex; flex-direction: column; gap: 4px; padding: 18px 16px; font-size: 14px; line-height: 1.45; color: var(--sub); }
58
+ .mm-state strong { color: var(--ink); font-size: 15px; }
59
+ .mm-state-act { margin-top: 8px; }
60
+ .mm-list .skel-row:first-of-type { border-top: 1px solid var(--row-border); }
61
+ .mm-more { margin: 10px 0 4px; }
62
+ .mm-more-top { margin: 0 0 8px; }
63
+ .mm-search { max-width: none; margin: 4px 0 8px; }
64
+ .mm-search .field { width: 100%; }
65
+ .mm-aside-note { margin: 14px 4px 0; font-size: 13px; color: var(--sub); line-height: 1.45; }
66
+ .mm-aside-note h3 { margin: 0 0 4px; font: 600 14px/1.3 var(--body); color: var(--ink); overflow-wrap: anywhere; }
67
+ .mm-aside-note p { margin: 0 0 6px; }
68
+ @media (min-width: 760px) {
69
+ .mm-row-title { font-size: 13.5px; }
70
+ .mm-row { padding: 10px 12px; }
71
+ .mm-list .mm-group:first-child { margin-top: 0; }
72
+ }
73
+
74
+ /* ── reader ───────────────────────────────────────────── */
75
+ .mm-reader-head { padding: 4px 0 12px; border-bottom: 1px solid var(--hairline); margin-bottom: 14px; }
76
+ .mm-title { font: 500 23px/1.22 var(--display); letter-spacing: -0.005em; margin: 0; color: var(--ink); overflow-wrap: anywhere; }
77
+ .mm-sub { margin: 6px 0 0; font-size: 12.5px; line-height: 1.45; color: var(--sub); overflow-wrap: anywhere; }
78
+ .mm-actions { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 10px; align-items: center; }
79
+ .mm-actions:first-child { margin-top: 0; }
80
+ .mm-reader-state { display: flex; flex-direction: column; gap: 4px; padding: 26px 4px; color: var(--sub); font-size: 14.5px; }
81
+ .mm-reader-state strong { color: var(--ink); font-size: 16px; }
82
+ .mm-reader .cx-notice { margin: 0 0 12px; overflow-wrap: anywhere; }
83
+ .mm-timeline { position: relative; padding-left: 22px; }
84
+ .mm-timeline::before { content: ''; position: absolute; left: 5px; top: 8px; bottom: 8px; width: 2px; border-radius: 1px; background: var(--hairline); }
85
+ .mm-step { position: relative; padding: 0 0 18px; min-width: 0; }
86
+ .mm-step::before { content: ''; position: absolute; left: -21px; top: 5px; width: 10px; height: 10px; border-radius: 50%; background: var(--panel); border: 2px solid var(--tint); }
87
+ .mm-step.last { padding-bottom: 4px; }
88
+ .mm-step-head { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 2px 12px; margin-bottom: 6px; }
89
+ .mm-step-head h3 { margin: 0; font: 600 15px/1.3 var(--body); color: var(--ink); }
90
+ .mm-step-meta { font-size: 12px; color: var(--tertiary); overflow-wrap: anywhere; }
91
+ .mm-step-body { font-size: 14.5px; line-height: 1.5; color: var(--ink); overflow-wrap: anywhere; min-width: 0; }
92
+ .mm-step-body p { margin: 0 0 8px; }
93
+ .mm-step-body p:last-child { margin-bottom: 0; }
94
+ .mm-quote { margin: 0 0 8px; padding: 10px 12px; border-left: 3px solid var(--tint); border-radius: 0 10px 10px 0; background: var(--qopen); font-size: 14px; line-height: 1.5; white-space: pre-wrap; overflow-wrap: anywhere; color: var(--ink); }
95
+ .mm-label { display: block; font: 600 12px/1.3 var(--body); color: var(--sub); margin-bottom: 3px; }
96
+ .mm-change { display: grid; gap: 8px; margin-bottom: 8px; }
97
+ .mm-change > div { padding: 10px 12px; border-radius: 10px; background: var(--qopen); white-space: pre-wrap; }
98
+ .mm-change .after { background: var(--green-bg); }
99
+ .mm-effect { margin-top: 8px; padding: 10px 12px; border-radius: 10px; border: 1px solid var(--panel-border); }
100
+ .mm-effect ul { margin: 0; padding: 0; list-style: none; display: grid; gap: 6px; font-size: 13.5px; }
101
+ .mm-effect li b { display: block; font: 600 12px/1.3 var(--body); color: var(--sub); }
102
+ .mm-check { font-weight: 600; color: var(--green); }
103
+ @media (max-width: 599px) { .mm-title { font-size: 21px; line-height: 1.25; } }
104
+ @media (min-width: 1100px) { .mm-title { font-size: 26px; } }
105
+
106
+ /* ── Knowledge ────────────────────────────────────────── */
107
+ .mm-card { margin: 0 0 12px; }
108
+ .mm-card-head { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 2px 12px; margin-bottom: 6px; }
109
+ .mm-card-title { margin: 0; font: 600 15.5px/1.3 var(--body); color: var(--ink); overflow-wrap: anywhere; }
110
+ .mm-card p { margin: 6px 0; font-size: 14px; line-height: 1.5; overflow-wrap: anywhere; }
111
+ .mm-card h4 { margin: 0 0 4px; font: 600 14px/1.35 var(--body); overflow-wrap: anywhere; }
112
+ .mm-sub-title { margin: 16px 0 6px; font: 600 14px/1.3 var(--body); color: var(--ink); }
113
+ .mm-inline { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin: 8px 0; }
114
+ .mm-inline > .field { flex: 1 1 200px; min-width: 0; min-height: 40px; padding: 0 12px; font-size: 16px; border-radius: 9px; }
115
+ .mm-inline > .cx-btn { min-height: 40px; height: 40px; }
116
+ .mm-wrap { align-items: flex-end; }
117
+ .mm-pick { display: inline-flex; flex-direction: column; gap: 4px; font-size: 12.5px; color: var(--sub); min-width: 0; }
118
+ .mm-pick > span { white-space: nowrap; }
119
+ .mm-block > span { white-space: normal; }
120
+ .mm-pick > .field { min-height: 40px; padding: 0 12px; font-size: 16px; border-radius: 9px; color: var(--ink); }
121
+ .mm-pick > select.field { padding-right: 34px; background-position: calc(100% - 18px) 17px, calc(100% - 13px) 17px; }
122
+ .mm-pick > textarea.field { padding: 10px 12px; min-height: 80px; }
123
+ .mm-block { display: flex; margin: 8px 0; }
124
+ .mm-num { width: 120px; }
125
+ .mm-progress { margin: 10px 0; padding: 10px 12px; border-radius: 10px; background: var(--qopen); border: 1px solid var(--panel-border); font-size: 13.5px; color: var(--ink); overflow-wrap: anywhere; }
126
+ .mm-progress ul { margin: 6px 0; padding-left: 18px; font-size: 12.5px; }
127
+ .mm-progress pre, .mm-pre { white-space: pre-wrap; overflow-wrap: anywhere; font: 400 11.5px/1.45 var(--mono); background: var(--qopen); padding: 10px; border-radius: 8px; max-height: 240px; overflow: auto; }
128
+ .mm-try { margin: 8px 0 2px; }
129
+ .mm-tries { margin: 0; padding: 0; list-style: none; display: grid; gap: 4px; }
130
+ .mm-tries .mm-link { font-size: 13.5px; overflow-wrap: anywhere; }
131
+ .mm-answer { margin: 12px 0 8px; padding: 12px 14px; border-radius: 10px; background: var(--qopen); font-size: 14.5px; line-height: 1.55; overflow-wrap: anywhere; max-height: 60vh; overflow-y: auto; }
132
+ .mm-answer h4 { margin: 10px 0 4px; font: 600 14.5px/1.3 var(--body); }
133
+ .mm-answer p { margin: 0 0 8px; }
134
+ .mm-answer ul { margin: 0 0 8px; padding-left: 1.2em; }
135
+ .mm-answer code { font: 400 13px/1.4 var(--mono); background: var(--panel); padding: 0 3px; border-radius: 4px; }
136
+ .mm-table { overflow-x: auto; max-width: 100%; }
137
+ .mm-answer table { border-collapse: collapse; font-size: 13px; }
138
+ .mm-answer th, .mm-answer td { border: 1px solid var(--panel-border); padding: 4px 8px; text-align: left; vertical-align: top; }
139
+ .mm-refs ol { margin: 0; padding-left: 1.4em; font-size: 13px; line-height: 1.45; }
140
+ .mm-refs li { margin-bottom: 4px; overflow-wrap: anywhere; }
141
+ .mm-ref { color: var(--accent); font-variant-numeric: tabular-nums; }
142
+ .mm-entity { margin-top: 10px; padding: 10px 12px; border-radius: 10px; border: 1px solid var(--panel-border); }
143
+ .mm-rels { margin: 6px 0; padding-left: 1.1em; font-size: 13px; line-height: 1.45; overflow-wrap: anywhere; }
144
+ .mm-health { margin: 14px 0 0; }
145
+ .mm-health > summary { cursor: pointer; padding: 12px 2px; font: 600 14px/1.3 var(--body); color: var(--ink); }
146
+ .mm-grid { display: grid; grid-template-columns: max-content minmax(0, 1fr); gap: 6px 14px; margin: 8px 0; font-size: 13.5px; }
147
+ .mm-grid dt { color: var(--sub); }
148
+ .mm-grid dd { margin: 0; overflow-wrap: anywhere; min-width: 0; }
149
+ .mm-ingest { margin-top: 8px; }
150
+ .mm-ingest .mm-pick { flex-direction: row; align-items: center; gap: 8px; flex: none; }
151
+ .mm-ingest select.field { width: auto; min-width: 96px; }
152
+ .mm-dup { padding: 10px 0; border-top: 1px solid var(--hairline); }
153
+ .mm-dup-member { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 6px 12px; padding: 6px 0; font-size: 13.5px; overflow-wrap: anywhere; }
154
+ .mm-dup-member > span { min-width: 0; flex: 1 1 200px; }
155
+ @media (max-width: 599px) {
156
+ .mm-grid { grid-template-columns: minmax(0, 1fr); gap: 0; }
157
+ .mm-grid dt { margin-top: 8px; font-size: 12.5px; }
158
+ }
159
+
160
+ /* Set up Knowledge */
161
+ .mm-setup { list-style: none; margin: 12px 0 8px; padding: 0; display: grid; gap: 14px; }
162
+ .mm-setup-step { display: grid; grid-template-columns: 28px minmax(0, 1fr); gap: 12px; }
163
+ .mm-setup-mark { width: 28px; height: 28px; border-radius: 50%; display: grid; place-items: center; font: 600 13px/1 var(--body); color: var(--sub); border: 1.5px solid var(--panel-border); background: var(--panel); }
164
+ .mm-setup-step.done .mm-setup-mark { color: var(--green); border-color: var(--green); background: var(--green-bg); }
165
+ .mm-setup-step.blocked .mm-setup-mark { color: var(--amber); border-color: var(--amber); }
166
+ .mm-setup-body { min-width: 0; }
167
+ .mm-setup-body h4 { margin: 3px 0 4px; font: 600 14.5px/1.3 var(--body); }
168
+ .mm-setup-body p { margin: 4px 0; font-size: 13.5px; line-height: 1.45; overflow-wrap: anywhere; }
169
+ .mm-checks, .mm-sources { list-style: none; margin: 6px 0; padding: 0; display: grid; gap: 6px; font-size: 13px; }
170
+ .mm-checks li { overflow-wrap: anywhere; }
171
+ .mm-checks li.ok { color: var(--ink); }
172
+ .mm-checks li.ok span { color: var(--green); }
173
+ .mm-sources li { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px; }
174
+ .mm-sources code { font: 400 12px/1.3 var(--mono); overflow-wrap: anywhere; min-width: 0; }
175
+ .mm-picks { display: grid; gap: 8px; margin: 8px 0; }
176
+ @media (min-width: 900px) { .mm-picks { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
177
+ .mm-pick-card { display: grid; grid-template-columns: 18px minmax(0, 1fr); gap: 10px; padding: 10px 12px; border-radius: 10px; border: 1px solid var(--panel-border); background: var(--panel); cursor: pointer; font-size: 13px; line-height: 1.4; }
178
+ .mm-pick-card > span { display: flex; flex-direction: column; gap: 3px; min-width: 0; overflow-wrap: anywhere; }
179
+ .mm-pick-card.on { border-color: var(--gold); box-shadow: inset 0 0 0 1px var(--gold); }
180
+ .mm-pick-card.off { opacity: 0.6; cursor: default; }
181
+ .mm-pick-card input { margin-top: 2px; accent-color: var(--gold); }
182
+ .mm-pick-card .cx-btn { align-self: flex-start; margin-top: 4px; }
183
+ .mm-ask-strip { gap: 6px 16px; font-size: 13.5px; }
184
+
185
+ /* ── the graph explorer, inside the reader and full screen ── */
186
+ .mm-graph { margin: 14px 0 0; min-width: 0; }
187
+ .mm-graph-head { display: flex; flex-wrap: wrap; align-items: flex-start; justify-content: space-between; gap: 6px 12px; margin-bottom: 8px; }
188
+ .mm-graph-text { min-width: 0; flex: 1 1 220px; }
189
+ .mm-graph-text p { margin: 2px 0 0; }
190
+ .mm-graph-host { min-width: 0; }
191
+ .mm-graph-wait { padding: 30px 4px; }
192
+ .mm-graph.full { position: fixed; inset: 0; z-index: 45; margin: 0; overflow-y: auto; overscroll-behavior: contain; background: var(--page);
193
+ padding: calc(var(--safe-top) + 10px) calc(var(--gutter) + var(--safe-right)) calc(var(--safe-bottom) + 16px) calc(var(--gutter) + var(--safe-left)); }
194
+ body.mm-graph-open { overflow: hidden; }
195
+ /* The explorer's own palette (graph-explorer.css reads these), in the app's light and dark. */
196
+ .mm-graph { --card: #ffffff; --raised: #eee8dd; --fg: #30312e; --muted: #74726d; --line: #ded6c8; --accent: #89662d; --green: #2f7952; --red: #a54732; --graph-bg: #faf8f3; }
197
+ :root[data-theme='dark'] .mm-graph { --card: #261d16; --raised: #30271f; --fg: #f5f0e6; --muted: #bbae9a; --line: #473a2c; --accent: #c9a86e; --green: #92c6a1; --red: #e8a494; --graph-bg: #14100c; }
198
+ /* The explorer sets its own stage height (and a smaller one when narrow); the pane decides it here instead. */
199
+ .mm-graph { --mm-graph-h: min(64dvh, 560px); }
200
+ .mm-graph.full { --mm-graph-h: max(320px, calc(100dvh - var(--safe-top) - var(--safe-bottom) - 230px)); }
201
+ .mm-graph .cgx .cgx-stage { height: var(--mm-graph-h); min-height: 320px; isolation: isolate; }
202
+ :root:not([data-theme='dark']) .mm-graph .cgx-panel { box-shadow: 0 4px 14px rgba(31, 23, 18, 0.08); }
203
+ :root:not([data-theme='dark']) .mm-graph .cgx-result { border-bottom-color: var(--line); }
204
+ /* The explorer and its investigation tools were drawn for Control's page, whose plain buttons, rows and fields had a
205
+ look of their own. The same base, at the lowest weight, so every explorer class still wins. */
206
+ :where(.mm-graph) button { border: 1px solid var(--line); background: var(--card); color: var(--fg); border-radius: 7px; padding: 7px 12px; font: 500 13px/1.2 var(--body); }
207
+ :where(.mm-graph) button:disabled { opacity: 0.45; }
208
+ :where(.mm-graph) input, :where(.mm-graph) select { color: var(--fg); background: var(--card); border: 1px solid var(--line); border-radius: 7px; padding: 7px 9px; font: 400 14px/1.3 var(--body); max-width: 100%; }
209
+ .mm-graph .memory-investigation .row { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; width: auto; min-height: 0; padding: 0; margin: 8px 0; border: 0; grid-template-columns: none; }
210
+ .mm-graph .memory-investigation .row:active { background: none; }
211
+ .mm-graph .memory-investigation .row input { flex: 1 1 160px; min-width: 0; }
212
+ .mm-graph .memory-investigation .muted { color: var(--muted); font-size: 12.5px; }
213
+ .mm-graph .memory-investigation .source-card { margin: 8px 0; padding: 10px 12px; border: 1px solid var(--line); border-radius: 10px; background: var(--card); }
214
+ .mm-graph .memory-investigation > [data-role='overview-status'] { margin: 8px 2px; font-size: 12.5px; color: var(--sub); }
215
+ .mm-graph .investigation-tools { border-top: 1px solid var(--hairline); margin-top: 10px; }
216
+ .mm-graph .investigation-tools > summary { cursor: pointer; padding: 12px 2px; font: 600 13.5px/1.3 var(--body); color: var(--ink); }
217
+ .mm-graph .investigation-tools details summary { cursor: pointer; font-size: 13px; overflow-wrap: anywhere; }
218
+ .mm-graph .investigation-tools p { font-size: 12.5px; overflow-wrap: anywhere; }
219
+ body.mm-modal-open .cgx-rail, body.mm-modal-open .cgx-railtoggle, body.mm-modal-open .cgx-pinned, body.mm-modal-open .cgx-dp, body.mm-modal-open .cgx-tip, body.mm-modal-open .cgx-hint { visibility: hidden; pointer-events: none; }
220
+
221
+ /* ── sheets ───────────────────────────────────────────── */
222
+ body.mm-modal-open { overflow: hidden; }
223
+ .mm-backdrop { position: fixed; inset: 0; z-index: 70; background: rgba(23, 18, 14, 0.5); display: flex; align-items: stretch; justify-content: center; }
224
+ .mm-backdrop.mm-enter { animation: fade 160ms ease; }
225
+ .mm-modal { position: relative; width: 100%; display: flex; flex-direction: column; background: var(--page); color: var(--ink); min-height: 0; }
226
+ .mm-modal-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: calc(var(--safe-top) + 10px) calc(var(--gutter) + var(--safe-right)) 10px calc(var(--gutter) + var(--safe-left)); border-bottom: 1px solid var(--hairline); flex: none; }
227
+ .mm-modal-head h2 { margin: 0; font: 500 21px/1.2 var(--display); min-width: 0; overflow-wrap: anywhere; }
228
+ .mm-modal-body { flex: 1 1 auto; min-height: 0; overflow-y: auto; overscroll-behavior: contain; padding: 14px calc(var(--gutter) + var(--safe-right)) calc(var(--safe-bottom) + 24px) calc(var(--gutter) + var(--safe-left)); font-size: 14.5px; line-height: 1.5; overflow-wrap: anywhere; }
229
+ .mm-modal-body > p { margin: 0 0 10px; }
230
+ .mm-set { margin: 0 0 18px; }
231
+ .mm-set .cx-list { margin: 8px 0; }
232
+ .mm-set .cx-set-row .switch { grid-row: auto; grid-column: auto; flex: none; }
233
+ .mm-set .switch:disabled { opacity: 0.5; }
234
+ .mm-checkrow { display: flex; flex-wrap: wrap; gap: 8px 18px; margin: 0 0 10px; }
235
+ .mm-checkrow .cx-check { margin: 0; font-size: 14px; }
236
+ .mm-preview { min-height: 220px; font: 400 13px/1.5 var(--mono); padding: 12px; white-space: pre-wrap; }
237
+ .mm-log { list-style: none; margin: 0 0 8px; padding: 0; display: grid; gap: 0; }
238
+ .mm-log li { display: flex; flex-direction: column; gap: 2px; padding: 8px 0; border-top: 1px solid var(--hairline); font-size: 13.5px; overflow-wrap: anywhere; }
239
+ .mm-log li:first-child { border-top: 0; }
240
+ .mm-merge { display: grid; gap: 10px; margin: 10px 0; }
241
+ @media (min-width: 600px) { .mm-merge { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); } }
242
+ .mm-merge-col { border: 1px solid var(--panel-border); border-radius: 10px; padding: 10px 12px; min-width: 0; font-size: 13.5px; }
243
+ .mm-merge-col.keep { border-color: var(--gold); box-shadow: inset 0 0 0 1px var(--gold-bg); }
244
+ .mm-merge-col h4 { margin: 0 0 2px; }
245
+ .mm-merge-col p { margin: 6px 0; }
246
+ .mm-merge-steps { margin: 8px 0; padding-left: 20px; font-size: 13.5px; }
247
+ .mm-merge-steps li { opacity: 0.55; margin: 2px 0; }
248
+ .mm-merge-steps li.done { opacity: 0.8; text-decoration: line-through; }
249
+ .mm-merge-steps li.now { opacity: 1; font-weight: 600; }
250
+ @media (min-width: 600px) {
251
+ .mm-backdrop { align-items: center; padding: 24px; }
252
+ .mm-modal { max-width: 680px; max-height: 86dvh; border-radius: 16px; border: 1px solid var(--panel-border); box-shadow: 0 24px 60px rgba(0, 0, 0, 0.28); overflow: hidden; }
253
+ .mm-modal-head { padding: 14px 20px 12px; }
254
+ .mm-modal-body { padding: 16px 20px 22px; }
255
+ }
256
+ @media (prefers-reduced-motion: reduce) { .mm-backdrop.mm-enter { animation: none; } }
257
+
258
+ /* ── Cues to rate and Rated cues (Control's cue review: one card at a time, then the rated list) ── */
259
+ .split.mm-split.solo { display: block; }
260
+ .split.mm-split.solo .split-list { position: static; max-height: none; overflow: visible; max-width: 820px; }
261
+ .split.mm-split.solo .reader { display: none; }
262
+ .mm-cue-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; margin: 6px 2px 12px; }
263
+ .mm-cue-head p { margin: 3px 0 0; }
264
+ .mm-cue-title { margin: 0; font: 500 24px/1.15 var(--display); color: var(--ink); letter-spacing: -0.01em; }
265
+ .mm-cue { padding: 16px 18px; outline: none; }
266
+ .mm-cue:focus-visible { box-shadow: 0 0 0 2px var(--accent); }
267
+ .mm-cue-meta { display: flex; flex-wrap: wrap; align-items: baseline; gap: 2px 10px; margin: 0 0 10px; font-size: 12.5px; color: var(--sub); overflow-wrap: anywhere; }
268
+ .mm-cue-meta b { color: var(--ink); font-weight: 600; }
269
+ .mm-cue-left { margin-left: auto; }
270
+ .mm-mono { font: 400 11.5px/1.3 var(--mono); }
271
+ .mm-cue-text { margin: 0 0 10px; font-size: 17px; line-height: 1.5; color: var(--ink); overflow-wrap: anywhere; }
272
+ .mm-cue-text.small { font-size: 14.5px; }
273
+ .mm-cue-sources { margin: 0 0 8px; font-size: 13px; }
274
+ .mm-cue-sources ul { margin: 2px 0 0; padding-left: 1.1em; }
275
+ .mm-cue-sources li { margin: 2px 0; overflow-wrap: anywhere; }
276
+ .mm-cue-before { margin: 8px 0; padding: 10px 14px; border-radius: 9px; background: var(--qopen); font-size: 13.5px; line-height: 1.45; overflow-wrap: anywhere; }
277
+ .mm-cue-before p { margin: 4px 0 0; color: var(--ink); }
278
+ .mm-verdicts { display: flex; flex-wrap: wrap; gap: 8px; margin: 12px 0 4px; }
279
+ .mm-verdicts .cx-btn { min-width: 0; }
280
+ .mm-key { font: 400 10.5px/1 var(--mono); opacity: 0.7; margin-right: 6px; }
281
+ .mm-cue .mm-block { margin-top: 12px; }
282
+ .mm-cue-next { margin: 10px 4px 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
283
+ .mm-cue-row { margin: 0 0 10px; padding: 12px 14px; }
284
+ .mm-cue-row .mm-verdicts { margin: 0; }
285
+ .mm-cue-rated { margin: 0 0 8px; font-size: 12.5px; font-weight: 600; color: var(--accent); overflow-wrap: anywhere; }
286
+ @media (max-width: 599px) {
287
+ .mm-keys-hint, .mm-key { display: none; }
288
+ .mm-cue { padding: 14px; }
289
+ .mm-cue-text { font-size: 16px; }
290
+ .mm-cue-title { font-size: 21px; }
291
+ }