nlm-memory 0.5.0 → 0.5.1

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 (247) hide show
  1. package/README.md +72 -34
  2. package/dist/cli/nlm.js +2 -1
  3. package/dist/cli/nlm.js.map +1 -1
  4. package/dist/http/app.js +2 -1
  5. package/dist/http/app.js.map +1 -1
  6. package/dist/mcp/server.js +20 -1
  7. package/dist/mcp/server.js.map +1 -1
  8. package/dist/ui/assets/{index-C8cpwbYJ.css → index-Beo8psd-.css} +1 -1
  9. package/dist/ui/assets/{index-CB50QnL-.js → index-CSPTTeeM.js} +8 -8
  10. package/dist/ui/index.html +2 -2
  11. package/package.json +26 -1
  12. package/.agents/plugins/marketplace.json +0 -20
  13. package/.github/workflows/ci.yml +0 -30
  14. package/docs/methodology/re-derivation-rate.md +0 -112
  15. package/docs/methodology/useful-hit-rate.md +0 -79
  16. package/docs/plans/2026-05-20-fts5-lexical-recall.md +0 -1088
  17. package/docs/plans/2026-05-20-recall-daemon-wedge-fix.md +0 -662
  18. package/docs/plans/2026-05-20-recall-hook-design.md +0 -131
  19. package/docs/plans/2026-05-20-recall-hook-implementation.md +0 -1222
  20. package/docs/plans/desktop-product.md +0 -69
  21. package/docs/plans/factstore-design.md +0 -236
  22. package/logs/CHANGELOG/CHANGELOG-2026.md +0 -1575
  23. package/logs/CHANGELOG/CHANGELOG.md +0 -209
  24. package/migrations/000_initial_schema.sql +0 -174
  25. package/migrations/001_entity_type_rename.sql +0 -17
  26. package/migrations/002_adapter_state_extend.sql +0 -12
  27. package/migrations/003_session_embeddings.sql +0 -11
  28. package/migrations/004_facts.sql +0 -46
  29. package/migrations/005_sources.sql +0 -31
  30. package/migrations/006_providers.sql +0 -33
  31. package/migrations/007_source_tokens.sql +0 -17
  32. package/migrations/008_fts_rebuild.sql +0 -9
  33. package/migrations/009_session_embedding_chunks.sql +0 -46
  34. package/migrations/010_sources_opencode.sql +0 -30
  35. package/migrations/011_sources_hermes_agent.sql +0 -30
  36. package/migrations/012_sources_aider.sql +0 -30
  37. package/migrations/013_adapter_state_failure_count.sql +0 -12
  38. package/migrations/014_sources_cursor.sql +0 -30
  39. package/migrations/015_sources_windsurf.sql +0 -30
  40. package/plugin-hermes-agent/README.md +0 -49
  41. package/plugin-hermes-agent/__init__.py +0 -75
  42. package/plugin-hermes-agent/plugin.yaml +0 -15
  43. package/scripts/backfill-citations.mjs +0 -0
  44. package/scripts/build-codex-plugin.mjs +0 -61
  45. package/scripts/deepseek-probe.mjs +0 -67
  46. package/scripts/extract-triples.mjs +0 -207
  47. package/scripts/longmemeval/embedding-cache.ts +0 -77
  48. package/scripts/longmemeval/fetch-dataset.sh +0 -25
  49. package/scripts/longmemeval/run-harness.ts +0 -315
  50. package/scripts/longmemeval/scorer.ts +0 -99
  51. package/scripts/longmemeval/tsconfig.json +0 -9
  52. package/scripts/longmemeval/types.ts +0 -35
  53. package/scripts/nlm-daily-digest.py +0 -239
  54. package/scripts/nlm-daily-digest.sh +0 -28
  55. package/src/cli/classify-parity.ts +0 -257
  56. package/src/cli/launchctl-helpers.ts +0 -49
  57. package/src/cli/nlm.ts +0 -1078
  58. package/src/core/actions/actions-log.ts +0 -118
  59. package/src/core/actions/overlay.ts +0 -117
  60. package/src/core/adapters/aider.ts +0 -205
  61. package/src/core/adapters/claude-code.ts +0 -293
  62. package/src/core/adapters/common.ts +0 -54
  63. package/src/core/adapters/cursor.ts +0 -486
  64. package/src/core/adapters/from-source.ts +0 -67
  65. package/src/core/adapters/hermes-agent.ts +0 -240
  66. package/src/core/adapters/hermes.ts +0 -277
  67. package/src/core/adapters/jsonl-generic.ts +0 -208
  68. package/src/core/adapters/opencode.ts +0 -281
  69. package/src/core/adapters/pi.ts +0 -264
  70. package/src/core/adapters/windsurf.ts +0 -386
  71. package/src/core/classifier/prompt.ts +0 -200
  72. package/src/core/dataset/build-dataset.ts +0 -463
  73. package/src/core/embedding/chunk-body.ts +0 -76
  74. package/src/core/embedding/embed-backfill.ts +0 -210
  75. package/src/core/embedding/embed-normalize.ts +0 -135
  76. package/src/core/facts/backfill-facts.ts +0 -254
  77. package/src/core/facts/extract-facts.ts +0 -50
  78. package/src/core/hook/citation-detect.ts +0 -124
  79. package/src/core/hook/cite-memo.ts +0 -68
  80. package/src/core/hook/claude-settings.ts +0 -187
  81. package/src/core/hook/gate.ts +0 -25
  82. package/src/core/hook/hook-log.ts +0 -41
  83. package/src/core/hook/memo-sweep.ts +0 -164
  84. package/src/core/hook/memo.ts +0 -67
  85. package/src/core/hook/pointer-block.ts +0 -26
  86. package/src/core/hook/select.ts +0 -32
  87. package/src/core/hook/transcript.ts +0 -121
  88. package/src/core/ingest/ingest-session.ts +0 -111
  89. package/src/core/providers/provider-models.ts +0 -100
  90. package/src/core/providers/provider-registry.ts +0 -196
  91. package/src/core/recall/citation-log.ts +0 -108
  92. package/src/core/recall/filter.ts +0 -27
  93. package/src/core/recall/index.ts +0 -6
  94. package/src/core/recall/match-fields.ts +0 -40
  95. package/src/core/recall/query-log.ts +0 -149
  96. package/src/core/recall/query-shape.ts +0 -66
  97. package/src/core/recall/recall-service.ts +0 -320
  98. package/src/core/recall/recent-log.ts +0 -59
  99. package/src/core/recall/tokenize.ts +0 -18
  100. package/src/core/recall/useful-scan.ts +0 -336
  101. package/src/core/recall-facts/fact-query-log.ts +0 -150
  102. package/src/core/recall-facts/fact-recall-service.ts +0 -327
  103. package/src/core/scheduler/scan-once.ts +0 -142
  104. package/src/core/scheduler/scheduler.ts +0 -225
  105. package/src/core/sources/source-registry.ts +0 -278
  106. package/src/core/storage/db-restore.ts +0 -133
  107. package/src/core/storage/live-status.ts +0 -45
  108. package/src/core/storage/migrate.ts +0 -72
  109. package/src/core/storage/sqlite-fact-store.ts +0 -304
  110. package/src/core/storage/sqlite-session-store.ts +0 -810
  111. package/src/hook/hook-auth.ts +0 -18
  112. package/src/hook/prompt-recall-hook.ts +0 -180
  113. package/src/hook/session-end-hook.ts +0 -81
  114. package/src/hook/session-start-hook.ts +0 -168
  115. package/src/hook/stop-hook.ts +0 -239
  116. package/src/http/app.ts +0 -1215
  117. package/src/install/claude-code.ts +0 -128
  118. package/src/install/codex.ts +0 -367
  119. package/src/install/cursor.ts +0 -68
  120. package/src/install/hermes-agent.ts +0 -76
  121. package/src/install/hermes.ts +0 -78
  122. package/src/install/nlm-dir-perms.ts +0 -55
  123. package/src/install/ollama.ts +0 -284
  124. package/src/install/setup.ts +0 -489
  125. package/src/install/windsurf.ts +0 -68
  126. package/src/llm/classifier-box.ts +0 -64
  127. package/src/llm/deepseek-client.ts +0 -150
  128. package/src/llm/env-autoload.ts +0 -55
  129. package/src/llm/ollama-client.ts +0 -189
  130. package/src/mcp/server.ts +0 -534
  131. package/src/ports/fact-store.ts +0 -102
  132. package/src/ports/llm-client.ts +0 -52
  133. package/src/ports/logger.ts +0 -16
  134. package/src/ports/session-store.ts +0 -45
  135. package/src/ports/transcript-adapter.ts +0 -55
  136. package/src/shared/types.ts +0 -149
  137. package/src/ui/App.tsx +0 -58
  138. package/src/ui/components/PromoteOpenButton.tsx +0 -65
  139. package/src/ui/components/SessionDrawer.tsx +0 -199
  140. package/src/ui/components/SideNav.tsx +0 -162
  141. package/src/ui/components/Skeleton.tsx +0 -107
  142. package/src/ui/index.html +0 -13
  143. package/src/ui/lib/actions.ts +0 -30
  144. package/src/ui/lib/api.ts +0 -92
  145. package/src/ui/lib/dataset.ts +0 -141
  146. package/src/ui/lib/registries.ts +0 -155
  147. package/src/ui/lib/view-settings.ts +0 -41
  148. package/src/ui/main.tsx +0 -15
  149. package/src/ui/pages/Live.tsx +0 -229
  150. package/src/ui/pages/Pulse.tsx +0 -415
  151. package/src/ui/pages/Recall.tsx +0 -190
  152. package/src/ui/pages/River.tsx +0 -354
  153. package/src/ui/pages/Search.tsx +0 -386
  154. package/src/ui/pages/Stub.tsx +0 -9
  155. package/src/ui/pages/Thread.tsx +0 -473
  156. package/src/ui/pages/settings/Classifier.tsx +0 -227
  157. package/src/ui/pages/settings/Data.tsx +0 -190
  158. package/src/ui/pages/settings/Index.tsx +0 -65
  159. package/src/ui/pages/settings/Labels.tsx +0 -224
  160. package/src/ui/pages/settings/Providers.tsx +0 -305
  161. package/src/ui/pages/settings/SettingsSubnav.tsx +0 -28
  162. package/src/ui/pages/settings/Sources.tsx +0 -326
  163. package/src/ui/pages/settings/Views.tsx +0 -96
  164. package/src/ui/styles.css +0 -1890
  165. package/src/ui/tsconfig.json +0 -21
  166. package/src/ui/vite.config.ts +0 -19
  167. package/tests/fixtures/claude_code/short_session.jsonl +0 -2
  168. package/tests/fixtures/claude_code/standard_iso.jsonl +0 -4
  169. package/tests/fixtures/claude_code/tool_heavy.jsonl +0 -8
  170. package/tests/fixtures/claude_code/with_subagent.jsonl +0 -7
  171. package/tests/fixtures/facts.ts +0 -17
  172. package/tests/fixtures/golden-corpus.ts +0 -85
  173. package/tests/fixtures/hermes/paired_request_dump.json +0 -24
  174. package/tests/fixtures/hermes/paired_session.json +0 -23
  175. package/tests/fixtures/hermes/request_dump.json +0 -28
  176. package/tests/fixtures/hermes/session_iso.json +0 -38
  177. package/tests/fixtures/hermes/session_unix.json +0 -38
  178. package/tests/fixtures/hermes/system_only.json +0 -18
  179. package/tests/fixtures/pi/error-connection-abort.jsonl +0 -8
  180. package/tests/fixtures/pi/short-successful.jsonl +0 -5
  181. package/tests/fixtures/pi/with-custom-message.jsonl +0 -6
  182. package/tests/fixtures/sessions.ts +0 -22
  183. package/tests/integration/backfill-facts.test.ts +0 -362
  184. package/tests/integration/citation-explicit.test.ts +0 -111
  185. package/tests/integration/cite-event.test.ts +0 -169
  186. package/tests/integration/cite-memo.test.ts +0 -87
  187. package/tests/integration/db-restore.test.ts +0 -153
  188. package/tests/integration/embed-backfill.test.ts +0 -176
  189. package/tests/integration/fact-supersedence.test.ts +0 -313
  190. package/tests/integration/fts-index.test.ts +0 -60
  191. package/tests/integration/getbyids-sqlite.test.ts +0 -100
  192. package/tests/integration/hermes-agent-hooks.test.ts +0 -248
  193. package/tests/integration/hook-claude-settings.test.ts +0 -218
  194. package/tests/integration/hook-log.test.ts +0 -54
  195. package/tests/integration/hook-memo.test.ts +0 -68
  196. package/tests/integration/hook-pre-compact.test.ts +0 -105
  197. package/tests/integration/hook-subagent-start.test.ts +0 -102
  198. package/tests/integration/http.test.ts +0 -401
  199. package/tests/integration/keyword-search-fts.test.ts +0 -66
  200. package/tests/integration/mcp-recall-logging.test.ts +0 -88
  201. package/tests/integration/mcp.test.ts +0 -260
  202. package/tests/integration/memo-sweep.test.ts +0 -91
  203. package/tests/integration/prompt-recall-hook.test.ts +0 -88
  204. package/tests/integration/provider-registry.test.ts +0 -107
  205. package/tests/integration/recall-golden.test.ts +0 -59
  206. package/tests/integration/recall-sqlite.test.ts +0 -169
  207. package/tests/integration/scheduler.test.ts +0 -391
  208. package/tests/integration/session-end-hook.test.ts +0 -48
  209. package/tests/integration/session-start-hook.test.ts +0 -126
  210. package/tests/integration/source-registry.test.ts +0 -122
  211. package/tests/integration/sqlite-fact-store.test.ts +0 -346
  212. package/tests/integration/stop-hook.test.ts +0 -560
  213. package/tests/integration/wal-checkpoint.test.ts +0 -49
  214. package/tests/unit/cli/launchctl-helpers.test.ts +0 -60
  215. package/tests/unit/core/adapters/aider.test.ts +0 -230
  216. package/tests/unit/core/adapters/claude-code.test.ts +0 -118
  217. package/tests/unit/core/adapters/cursor.test.ts +0 -485
  218. package/tests/unit/core/adapters/hermes-agent.test.ts +0 -329
  219. package/tests/unit/core/adapters/hermes.test.ts +0 -81
  220. package/tests/unit/core/adapters/jsonl-generic.test.ts +0 -142
  221. package/tests/unit/core/adapters/opencode.test.ts +0 -354
  222. package/tests/unit/core/adapters/pi.test.ts +0 -110
  223. package/tests/unit/core/adapters/windsurf.test.ts +0 -416
  224. package/tests/unit/core/classifier/prompt.test.ts +0 -126
  225. package/tests/unit/core/embedding/chunk-body.test.ts +0 -100
  226. package/tests/unit/core/facts/extract-facts.test.ts +0 -117
  227. package/tests/unit/core/filter.test.ts +0 -40
  228. package/tests/unit/core/hook/citation-detect-cite-session.test.ts +0 -96
  229. package/tests/unit/core/hook/citation-detect.test.ts +0 -124
  230. package/tests/unit/core/hook/gate.test.ts +0 -29
  231. package/tests/unit/core/hook/pointer-block.test.ts +0 -22
  232. package/tests/unit/core/hook/select.test.ts +0 -66
  233. package/tests/unit/core/match-fields.test.ts +0 -39
  234. package/tests/unit/core/mcp-cite-session.test.ts +0 -51
  235. package/tests/unit/core/providers/provider-models.test.ts +0 -101
  236. package/tests/unit/core/query-shape.test.ts +0 -92
  237. package/tests/unit/core/recall-facts/fact-recall-service.test.ts +0 -258
  238. package/tests/unit/core/recall-service.test.ts +0 -200
  239. package/tests/unit/core/storage/live-status.test.ts +0 -54
  240. package/tests/unit/core/tokenize.test.ts +0 -32
  241. package/tests/unit/core/useful-scan.test.ts +0 -537
  242. package/tests/unit/llm/embed.test.ts +0 -93
  243. package/tests/unit/llm/ollama-client.test.ts +0 -124
  244. package/tests/unit/scripts/longmemeval-scorer.test.ts +0 -114
  245. package/tsconfig.json +0 -31
  246. package/tsconfig.test.json +0 -11
  247. package/vitest.config.ts +0 -22
package/src/ui/styles.css DELETED
@@ -1,1890 +0,0 @@
1
- /* NLM — Design system v2
2
- Single source of truth for all tokens, surfaces, and shared components.
3
- All pages import this via BaseLayout. No :global() needed — .css is always global. */
4
-
5
- /* ── Tokens ──────────────────────────────────────────────────────────────── */
6
- :root {
7
- /* Surface scale — 4 clean steps (dark-gray, not near-black) */
8
- --surface-0: #161616; /* page background */
9
- --surface-1: #1d1d1d; /* card / tile */
10
- --surface-2: #242424; /* card hover / raised input */
11
- --surface-float: #2c2c2c; /* floating panel (dropdowns, modals) */
12
-
13
- /* Border scale — 4 levels (bumped to stay visible on lighter surfaces) */
14
- --border-1: #262626; /* hairline / divider */
15
- --border-2: #303030; /* card border */
16
- --border-3: #3d3d3d; /* hover / active border */
17
- --border-4: #525252; /* focused / bright */
18
-
19
- /* Text scale — 4 semantic levels */
20
- --text-1: #e8e8e8; /* primary — body, values */
21
- --text-2: #b0b0b0; /* secondary — labels, subtitles */
22
- --text-3: #686868; /* muted — timestamps, section headers */
23
- --text-4: #383838; /* disabled / placeholder */
24
-
25
- /* Legacy text aliases — TODO: migrate .astro call sites to --text-1/2/3/4 */
26
- --text-primary: #e8e8e8;
27
- --text-dim: #b8b8b8; /* TODO: migrate */
28
- --text-muted: #888; /* TODO: migrate */
29
- --text-faint: #777; /* TODO: migrate */
30
- --text-ghost: #666; /* TODO: migrate */
31
- --text-dead: #555; /* TODO: migrate */
32
- --text-void: #444; /* TODO: migrate */
33
-
34
- /* Signal colors */
35
- --accent: #e8ff6e;
36
- --accent-dim: rgba(232, 255, 110, 0.12);
37
- --accent-glow: rgba(232, 255, 110, 0.06);
38
- --warn: #ff9933;
39
- --warn-dim: rgba(255, 153, 51, 0.12);
40
- --danger: #ff6b35;
41
- --danger-dim: rgba(255, 107, 53, 0.07);
42
- --danger-glow: rgba(255, 107, 53, 0.12);
43
-
44
- /* Typography — type scale */
45
- --font-mono: 'IBM Plex Mono', 'Fira Code', ui-monospace, monospace;
46
-
47
- --text-xs: 10px;
48
- --text-sm: 11px;
49
- --text-base: 13px;
50
- --text-md: 15px;
51
- --text-lg: 18px;
52
- --text-xl: 22px;
53
- --text-stat: 36px;
54
-
55
- --lh-tight: 1.3;
56
- --lh-base: 1.5;
57
- --lh-loose: 1.7;
58
-
59
- /* Spacing */
60
- --page-x: 28px;
61
- --section-gap: 24px;
62
-
63
- /* Shape */
64
- --r-sm: 3px;
65
- --r-md: 5px;
66
- --r-lg: 7px;
67
-
68
- /* Motion */
69
- --ease: 0.15s ease;
70
- --ease-fast: 0.1s ease;
71
- }
72
-
73
- /* ── Reset ───────────────────────────────────────────────────────────────── */
74
- *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
75
-
76
- html {
77
- background-color: var(--surface-0);
78
- }
79
-
80
- body {
81
- /* Subtle accent radial at top — the one atmospheric element.
82
- Reads as a ceiling light above a dark instrument panel. */
83
- background-image: radial-gradient(
84
- ellipse 100% 40% at 50% -8%,
85
- rgba(232, 255, 110, 0.032) 0%,
86
- transparent 100%
87
- );
88
- background-attachment: fixed;
89
- color: var(--text-1);
90
- font-family: var(--font-mono);
91
- min-height: 100vh;
92
- -webkit-font-smoothing: antialiased;
93
- -moz-osx-font-smoothing: grayscale;
94
- }
95
-
96
- /* ── Scrollbar ───────────────────────────────────────────────────────────── */
97
- ::-webkit-scrollbar { width: 4px; height: 4px; }
98
- ::-webkit-scrollbar-track { background: var(--surface-1); }
99
- ::-webkit-scrollbar-thumb { background: var(--border-3); border-radius: 2px; }
100
-
101
- /* ── Animation ───────────────────────────────────────────────────────────── */
102
- @keyframes fadeSlideIn {
103
- from { opacity: 0; transform: translateY(6px); }
104
- to { opacity: 1; transform: translateY(0); }
105
- }
106
-
107
- @media (prefers-reduced-motion: reduce) {
108
- *, *::before, *::after {
109
- animation-duration: 0.01ms !important;
110
- animation-delay: 0ms !important;
111
- transition-duration: 0.01ms !important;
112
- }
113
- }
114
-
115
- /* ── Skeleton ────────────────────────────────────────────────────────────── */
116
- .skeleton {
117
- display: inline-block;
118
- background: linear-gradient(
119
- 90deg,
120
- var(--surface-1) 0%,
121
- var(--surface-2) 50%,
122
- var(--surface-1) 100%
123
- );
124
- background-size: 200% 100%;
125
- animation: skeleton-shimmer 1.2s ease-in-out infinite;
126
- vertical-align: middle;
127
- }
128
- @keyframes skeleton-shimmer {
129
- 0% { background-position: 200% 0; }
130
- 100% { background-position: -200% 0; }
131
- }
132
- @media (prefers-reduced-motion: reduce) {
133
- .skeleton { animation: none; background: var(--surface-2); }
134
- }
135
-
136
- /* ── Card ────────────────────────────────────────────────────────────────── */
137
- /* Base surface. Combine with .card-lift for interactive tiles. */
138
- .card {
139
- background: var(--surface-1);
140
- border: 1px solid var(--border-2);
141
- border-radius: var(--r-md);
142
- }
143
- .card-lift {
144
- transition: border-color var(--ease), background var(--ease);
145
- }
146
- .card-lift:hover {
147
- background: var(--surface-2);
148
- border-color: var(--border-3);
149
- }
150
-
151
- /* ── Button ──────────────────────────────────────────────────────────────── */
152
- /* Canonical button. All interactive controls should use this or a variant. */
153
- .btn {
154
- display: inline-flex;
155
- align-items: center;
156
- gap: 5px;
157
- font-family: var(--font-mono);
158
- font-size: var(--text-sm);
159
- letter-spacing: 0.06em;
160
- text-transform: uppercase;
161
- padding: 5px 12px;
162
- border-radius: var(--r-sm);
163
- border: 1px solid var(--border-3);
164
- background: transparent;
165
- color: var(--text-2);
166
- cursor: pointer;
167
- white-space: nowrap;
168
- text-decoration: none;
169
- user-select: none;
170
- transition: border-color var(--ease), color var(--ease), background var(--ease);
171
- }
172
- .btn:hover { border-color: var(--border-4); color: var(--text-1); }
173
- .btn:active { background: var(--surface-2); }
174
- .btn.active { background: var(--surface-2); border-color: var(--border-3); color: var(--text-1); }
175
- .btn-primary { background: var(--accent); border-color: var(--accent); color: #080808; font-weight: 600; }
176
- .btn-primary:hover { background: #d4eb5e; border-color: #d4eb5e; color: #080808; }
177
- .btn-accent { color: var(--accent); border-color: rgba(232,255,110,0.25); }
178
- .btn-accent:hover { background: var(--accent-glow); border-color: rgba(232,255,110,0.4); }
179
-
180
- .form-row {
181
- display: flex;
182
- align-items: center;
183
- gap: 12px;
184
- flex-wrap: wrap;
185
- margin: 12px 0;
186
- }
187
- .form-row .form-label { color: var(--text-3); font-size: var(--text-xs); }
188
- .btn-danger:hover { border-color: var(--danger); color: var(--danger); }
189
-
190
- /* File input — restyle the native picker button to match .btn; the
191
- filename text stays native but tuned to the app's muted mono. */
192
- input[type="file"].file-input {
193
- font-family: var(--font-mono);
194
- font-size: var(--text-xs);
195
- color: var(--text-3);
196
- max-width: 24rem;
197
- }
198
- input[type="file"].file-input::file-selector-button {
199
- display: inline-flex;
200
- align-items: center;
201
- font-family: var(--font-mono);
202
- font-size: var(--text-sm);
203
- letter-spacing: 0.06em;
204
- text-transform: uppercase;
205
- padding: 5px 12px;
206
- margin-right: 10px;
207
- border-radius: var(--r-sm);
208
- border: 1px solid var(--border-3);
209
- background: transparent;
210
- color: var(--text-2);
211
- cursor: pointer;
212
- transition: border-color var(--ease), color var(--ease), background var(--ease);
213
- }
214
- input[type="file"].file-input::file-selector-button:hover {
215
- border-color: var(--border-4);
216
- color: var(--text-1);
217
- }
218
- input[type="file"].file-input:disabled {
219
- cursor: not-allowed;
220
- }
221
- input[type="file"].file-input:disabled::file-selector-button {
222
- opacity: 0.5;
223
- cursor: not-allowed;
224
- }
225
-
226
- /* ── Chip ────────────────────────────────────────────────────────────────── */
227
- /* Filter / state toggles. Lowercase, smaller presence than .btn. */
228
- .chip {
229
- display: inline-flex;
230
- align-items: center;
231
- gap: 4px;
232
- font-family: var(--font-mono);
233
- font-size: var(--text-sm);
234
- letter-spacing: 0.06em;
235
- text-transform: lowercase;
236
- padding: 3px 9px;
237
- border-radius: var(--r-sm);
238
- border: 1px solid var(--border-1);
239
- background: transparent;
240
- color: var(--text-3);
241
- cursor: pointer;
242
- user-select: none;
243
- white-space: nowrap;
244
- transition: border-color var(--ease), color var(--ease), background var(--ease);
245
- }
246
- .chip:hover { border-color: var(--border-3); color: var(--text-2); }
247
- .chip.active { border-color: var(--border-3); color: var(--text-1); background: var(--surface-2); }
248
-
249
- /* Semantic chip tints — opt-in via data attributes */
250
- .chip[data-severity="critical"].active { border-color: rgba(255,107,53,0.4); color: var(--danger); background: var(--danger-dim); }
251
- .chip[data-severity="high"].active { border-color: rgba(204,68,34,0.35); color: #cc4422; background: rgba(204,68,34,0.06); }
252
- .chip[data-severity="medium"].active { border-color: rgba(255,153,51,0.35); color: var(--warn); background: var(--warn-dim); }
253
- .chip[data-severity="low"].active { border-color: var(--border-3); color: var(--text-2); background: var(--surface-2); }
254
- .chip[data-status="active"].active { color: var(--accent); border-color: rgba(232,255,110,0.3); background: var(--accent-glow); }
255
- .chip[data-status="idle"].active { color: #ffcc80; }
256
- .chip[data-length].active { color: var(--text-1); }
257
- .chip[data-marker].active { color: var(--accent); border-color: rgba(232,255,110,0.3); background: var(--accent-glow); }
258
-
259
- /* ── Floating panel ──────────────────────────────────────────────────────── */
260
- /* Glass treatment — ONLY for elements that genuinely overlay scrolled content
261
- (dropdowns, session preview, sticky bulk toolbar, KB legend). */
262
- .panel-float {
263
- background: rgba(16, 16, 16, 0.96);
264
- backdrop-filter: blur(18px);
265
- -webkit-backdrop-filter: blur(18px);
266
- border: 1px solid var(--border-3);
267
- border-radius: var(--r-md);
268
- box-shadow: 0 12px 40px rgba(0,0,0,0.65), 0 0 0 1px rgba(255,255,255,0.03);
269
- }
270
-
271
- /* ── Navigation pills ────────────────────────────────────────────────────── */
272
- .nav-link {
273
- display: inline-flex;
274
- align-items: center;
275
- background: transparent;
276
- border: 1px solid transparent;
277
- color: var(--text-3);
278
- border-radius: var(--r-sm);
279
- padding: 4px 10px;
280
- font-size: var(--text-sm);
281
- font-family: var(--font-mono);
282
- letter-spacing: 0.06em;
283
- text-transform: uppercase;
284
- text-decoration: none;
285
- transition: color var(--ease), border-color var(--ease), background var(--ease);
286
- }
287
- .nav-link:hover { color: var(--text-2); border-color: var(--border-3); }
288
- .nav-link.active {
289
- background: var(--surface-2);
290
- border-color: var(--border-3);
291
- color: var(--text-1);
292
- }
293
-
294
- /* ── Inputs ──────────────────────────────────────────────────────────────── */
295
- .search-input {
296
- background: var(--surface-1);
297
- border: 1px solid var(--border-2);
298
- color: var(--text-1);
299
- font-family: var(--font-mono);
300
- font-size: var(--text-xs);
301
- padding: 5px 10px;
302
- border-radius: var(--r-sm);
303
- letter-spacing: 0.04em;
304
- outline: none;
305
- transition: border-color var(--ease);
306
- }
307
- .search-input:focus { border-color: var(--border-3); }
308
- .search-input::placeholder { color: var(--text-4); letter-spacing: 0.06em; }
309
-
310
- /* ── Control buttons (River toolbar: zoom, axis, entity pickers) ─────────── */
311
- .ctrl-btn {
312
- background: var(--surface-1);
313
- border: 1px solid var(--border-2);
314
- color: var(--text-2);
315
- font-family: var(--font-mono);
316
- font-size: var(--text-sm);
317
- letter-spacing: 0.06em;
318
- text-transform: uppercase;
319
- padding: 4px 10px;
320
- border-radius: var(--r-sm);
321
- cursor: pointer;
322
- white-space: nowrap;
323
- transition: border-color var(--ease), color var(--ease), background var(--ease);
324
- }
325
- .ctrl-btn:hover { border-color: var(--border-3); color: var(--text-1); }
326
- .ctrl-btn.active { background: var(--surface-2); border-color: var(--border-3); color: var(--accent); }
327
- .ctrl-btn[data-active="1"] { color: var(--accent); border-color: rgba(232,255,110,0.25); }
328
-
329
- .ctrl-label {
330
- font-size: var(--text-sm);
331
- color: var(--text-3);
332
- letter-spacing: 0.06em;
333
- text-transform: uppercase;
334
- flex-shrink: 0;
335
- }
336
-
337
- /* ── Settings subnav ─────────────────────────────────────────────────────── */
338
- .subnav {
339
- padding: 0 28px;
340
- border-bottom: 1px solid var(--border-1);
341
- display: flex;
342
- gap: 0;
343
- }
344
- .subnav-link {
345
- font-size: var(--text-sm);
346
- font-family: var(--font-mono);
347
- letter-spacing: 0.06em;
348
- text-transform: uppercase;
349
- color: var(--text-3);
350
- text-decoration: none;
351
- padding: 10px 14px;
352
- border-bottom: 2px solid transparent;
353
- margin-bottom: -1px;
354
- transition: color var(--ease), border-color var(--ease);
355
- }
356
- .subnav-link:hover { color: var(--text-2); }
357
- .subnav-link.active { color: var(--accent); border-bottom-color: var(--accent); }
358
-
359
- /* ── App shell ────────────────────────────────────────────────────────────
360
- Ported from BaseLayout.astro. Side-nav is sticky inside the flex row,
361
- so the main panel doesn't need a margin offset. */
362
- .page-shell {
363
- display: flex;
364
- min-height: 100vh;
365
- background: var(--surface-0);
366
- }
367
-
368
- .page-main {
369
- flex: 1;
370
- min-width: 0;
371
- display: flex;
372
- flex-direction: column;
373
- }
374
-
375
- /* ── AppHeader (slim top bar) ─────────────────────────────────────────── */
376
- .app-header {
377
- position: sticky;
378
- top: 0;
379
- z-index: 50;
380
- height: 52px;
381
- padding: 0 var(--page-x);
382
- display: flex;
383
- align-items: center;
384
- gap: 20px;
385
- background: rgba(22, 22, 22, 0.9);
386
- backdrop-filter: blur(12px);
387
- -webkit-backdrop-filter: blur(12px);
388
- border-bottom: 1px solid var(--border-1);
389
- }
390
-
391
- .app-header .wordmark-page {
392
- font-size: var(--text-sm);
393
- color: var(--text-3);
394
- letter-spacing: 0.04em;
395
- text-transform: lowercase;
396
- }
397
-
398
- .app-header .header-spacer { flex: 1; }
399
-
400
- .app-header .status-dot {
401
- width: 7px;
402
- height: 7px;
403
- border-radius: 50%;
404
- background: var(--accent);
405
- box-shadow: 0 0 6px var(--accent-dim);
406
- animation: pulse-dot 2s ease-in-out infinite;
407
- }
408
-
409
- @keyframes pulse-dot {
410
- 0%, 100% { opacity: 1; }
411
- 50% { opacity: 0.4; }
412
- }
413
-
414
- .app-header .header-info {
415
- font-size: var(--text-xs);
416
- color: var(--text-3);
417
- letter-spacing: 0.04em;
418
- }
419
-
420
- /* ── SideNav (ported from SideNav.astro <style> block) ─────────────────── */
421
- .sidenav {
422
- width: 180px;
423
- flex-shrink: 0;
424
- display: flex;
425
- flex-direction: column;
426
- background: var(--surface-1);
427
- border-right: 1px solid var(--border-1);
428
- position: sticky;
429
- top: 0;
430
- height: 100vh;
431
- overflow: hidden;
432
- transition: width 150ms ease;
433
- z-index: 100;
434
- }
435
-
436
- .sidenav.collapsed { width: 52px; }
437
-
438
- .sidenav-header {
439
- padding: 0 8px 0 16px;
440
- height: 52px;
441
- display: flex;
442
- align-items: center;
443
- justify-content: space-between;
444
- border-bottom: 1px solid var(--border-1);
445
- flex-shrink: 0;
446
- }
447
-
448
- .sidenav-wordmark {
449
- font-size: 11px;
450
- font-family: var(--font-mono);
451
- letter-spacing: 0.2em;
452
- text-transform: uppercase;
453
- color: var(--accent);
454
- user-select: none;
455
- white-space: nowrap;
456
- overflow: hidden;
457
- transition: opacity 100ms ease, width 100ms ease;
458
- }
459
-
460
- .sidenav.collapsed .sidenav-wordmark { opacity: 0; width: 0; padding: 0; }
461
-
462
- .sidenav-toggle {
463
- background: none;
464
- border: none;
465
- color: var(--text-3);
466
- cursor: pointer;
467
- padding: 5px;
468
- border-radius: var(--r-sm);
469
- display: flex;
470
- align-items: center;
471
- justify-content: center;
472
- flex-shrink: 0;
473
- transition: color var(--ease), background var(--ease);
474
- }
475
-
476
- .sidenav-toggle:hover { color: var(--text-1); background: var(--surface-2); }
477
-
478
- .sidenav.collapsed .sidenav-header { justify-content: center; padding: 0 8px; }
479
-
480
- .sidenav-items {
481
- flex: 1;
482
- padding: 10px 8px;
483
- display: flex;
484
- flex-direction: column;
485
- gap: 2px;
486
- overflow: hidden;
487
- }
488
-
489
- .sidenav-item {
490
- display: flex;
491
- align-items: center;
492
- gap: 9px;
493
- padding: 8px 10px;
494
- border-radius: var(--r-sm);
495
- font-size: 11px;
496
- font-family: var(--font-mono);
497
- letter-spacing: 0.06em;
498
- text-transform: uppercase;
499
- color: var(--text-3);
500
- text-decoration: none;
501
- border-left: 3px solid transparent;
502
- transition: color var(--ease), background var(--ease), border-color var(--ease);
503
- user-select: none;
504
- white-space: nowrap;
505
- overflow: hidden;
506
- position: relative;
507
- }
508
-
509
- .sidenav-item:hover { color: var(--text-1); background: var(--surface-2); }
510
- .sidenav-item.active {
511
- color: var(--text-1);
512
- border-left-color: var(--accent);
513
- background: var(--accent-glow);
514
- }
515
-
516
- .item-icon { flex-shrink: 0; display: flex; align-items: center; opacity: 0.7; }
517
- .sidenav-item.active .item-icon { opacity: 1; }
518
- .item-label { transition: opacity 100ms ease; }
519
-
520
- .sidenav.collapsed .item-label { display: none; }
521
- .sidenav.collapsed .sidenav-item {
522
- gap: 0;
523
- padding: 8px;
524
- justify-content: center;
525
- border-left: 3px solid transparent;
526
- }
527
- .sidenav.collapsed .sidenav-item.active { border-left-color: var(--accent); }
528
-
529
- .sidenav.collapsed .sidenav-item::after {
530
- content: attr(data-label);
531
- position: absolute;
532
- left: calc(100% + 8px);
533
- top: 50%;
534
- transform: translateY(-50%);
535
- background: var(--surface-float);
536
- color: var(--text-1);
537
- font-size: 10px;
538
- font-family: var(--font-mono);
539
- letter-spacing: 0.06em;
540
- text-transform: uppercase;
541
- padding: 4px 8px;
542
- border-radius: var(--r-sm);
543
- border: 1px solid var(--border-2);
544
- white-space: nowrap;
545
- pointer-events: none;
546
- opacity: 0;
547
- transition: opacity 100ms ease;
548
- z-index: 200;
549
- }
550
-
551
- .sidenav.collapsed .sidenav-item:hover::after { opacity: 1; }
552
-
553
- .sidenav-footer {
554
- padding: 8px;
555
- border-top: 1px solid var(--border-1);
556
- flex-shrink: 0;
557
- }
558
-
559
- .sidenav-data { font-size: 10px; }
560
-
561
- /* ── Live page — three-column board ───────────────────────────────────── */
562
- .live-page {
563
- display: flex;
564
- flex-direction: column;
565
- flex: 1;
566
- min-height: 0;
567
- }
568
-
569
- .live-status {
570
- display: flex;
571
- align-items: center;
572
- gap: 8px;
573
- padding: 12px var(--page-x) 4px;
574
- }
575
-
576
- .live-status-dot {
577
- width: 7px;
578
- height: 7px;
579
- border-radius: 50%;
580
- flex-shrink: 0;
581
- }
582
- .live-status-live {
583
- background: var(--accent);
584
- box-shadow: 0 0 6px var(--accent);
585
- }
586
- .live-status-connecting { background: var(--text-3); }
587
- .live-status-reconnecting {
588
- background: var(--warn);
589
- animation: pulse-dot 1.2s ease-in-out infinite;
590
- }
591
-
592
- .live-status-label {
593
- font-family: var(--font-mono);
594
- font-size: var(--text-sm);
595
- letter-spacing: 0.06em;
596
- text-transform: uppercase;
597
- color: var(--text-2);
598
- }
599
-
600
- .live-board {
601
- padding: 4px var(--page-x) 0;
602
- display: grid;
603
- grid-template-columns: repeat(3, 1fr);
604
- gap: 16px;
605
- flex: 1;
606
- min-height: 0;
607
- }
608
-
609
- .live-col {
610
- background: var(--surface-1);
611
- border: 1px solid var(--border-2);
612
- border-radius: var(--r-md);
613
- display: flex;
614
- flex-direction: column;
615
- overflow: hidden;
616
- min-height: 0;
617
- }
618
-
619
- .live-col-head {
620
- padding: 10px 14px;
621
- border-bottom: 1px solid var(--border-1);
622
- display: flex;
623
- align-items: baseline;
624
- justify-content: space-between;
625
- }
626
-
627
- .live-col-title {
628
- font-size: var(--text-sm);
629
- font-family: var(--font-mono);
630
- letter-spacing: 0.06em;
631
- text-transform: uppercase;
632
- color: var(--text-2);
633
- }
634
-
635
- .live-col-count {
636
- font-size: var(--text-xs);
637
- color: var(--text-3);
638
- font-family: var(--font-mono);
639
- }
640
-
641
- .live-col-body { overflow-y: auto; flex: 1; }
642
-
643
- .live-row {
644
- padding: 8px 14px;
645
- border-bottom: 1px solid var(--border-1);
646
- animation: fadeSlideIn 200ms ease-out;
647
- }
648
-
649
- .live-row:last-child { border-bottom: none; }
650
-
651
- .live-row.clickable {
652
- cursor: pointer;
653
- transition: background var(--ease);
654
- }
655
- .live-row.clickable:hover { background: var(--surface-2); }
656
- .live-row.clickable:focus-visible {
657
- outline: 1px solid rgba(255, 255, 255, 0.5);
658
- outline-offset: -1px;
659
- }
660
-
661
- /* Newly arrived rows flash once so the feed reads as live. */
662
- .live-row.is-new { animation: fadeSlideIn 200ms ease-out, liveFlash 1200ms ease-out; }
663
-
664
- @keyframes liveFlash {
665
- 0% { background: var(--accent-glow); }
666
- 100% { background: transparent; }
667
- }
668
-
669
- .live-row .label { color: var(--text-1); font-size: var(--text-base); line-height: var(--lh-tight); }
670
- .live-row .body { color: var(--text-3); font-size: var(--text-sm); margin-top: 3px; line-height: var(--lh-tight); }
671
- .live-row .meta { color: var(--text-3); font-size: var(--text-xs); margin-top: 4px; letter-spacing: 0.04em; }
672
-
673
- .live-tag {
674
- display: inline-block;
675
- font-size: var(--text-xs);
676
- font-family: var(--font-mono);
677
- letter-spacing: 0.06em;
678
- text-transform: uppercase;
679
- padding: 1px 6px;
680
- margin-right: 6px;
681
- border-radius: var(--r-sm);
682
- background: var(--surface-2);
683
- color: var(--text-2);
684
- border: 1px solid var(--border-2);
685
- }
686
-
687
- .live-tag[data-kind="decision"] {
688
- background: var(--accent-glow);
689
- border-color: rgba(232,255,110,0.25);
690
- color: var(--accent);
691
- }
692
-
693
- .live-tag[data-kind="open"] {
694
- background: var(--warn-dim);
695
- border-color: rgba(255,153,51,0.25);
696
- color: var(--warn);
697
- }
698
-
699
- .live-empty {
700
- padding: 32px 16px;
701
- text-align: center;
702
- color: var(--text-3);
703
- font-size: var(--text-xs);
704
- letter-spacing: 0.06em;
705
- text-transform: uppercase;
706
- }
707
-
708
- /* ── Stub page (placeholder for unported routes) ───────────────────────── */
709
- .stub-shell {
710
- padding: 80px var(--page-x);
711
- text-align: center;
712
- color: var(--text-3);
713
- font-size: var(--text-base);
714
- line-height: var(--lh-loose);
715
- }
716
- .stub-shell .stub-name {
717
- color: var(--accent);
718
- font-size: var(--text-md);
719
- text-transform: lowercase;
720
- letter-spacing: 0.04em;
721
- display: block;
722
- margin-bottom: 12px;
723
- }
724
- .stub-shell .stub-hint { color: var(--text-4); font-size: var(--text-sm); }
725
-
726
- /* ── Page chrome shared across all routes ───────────────────────────────── */
727
- .page-pad {
728
- padding: 20px var(--page-x) 60px;
729
- flex: 1;
730
- min-width: 0;
731
- }
732
-
733
- .page-title {
734
- font-size: var(--text-lg);
735
- font-family: var(--font-mono);
736
- font-weight: 500;
737
- color: var(--text-1);
738
- margin-bottom: 16px;
739
- }
740
-
741
- .page-header {
742
- display: flex;
743
- align-items: center;
744
- gap: 24px;
745
- margin-bottom: 24px;
746
- padding-top: 8px;
747
- }
748
-
749
- .subnav + .page-header,
750
- .subnav + .page-title {
751
- gap: 28px;
752
- margin-top: 28px;
753
- margin-bottom: 28px;
754
- padding-top: 0;
755
- }
756
-
757
- .page-header .page-title { margin-bottom: 0; }
758
- .page-header .header-spacer,
759
- .thread-header .header-spacer,
760
- .river-toolbar .header-spacer { flex: 1; }
761
-
762
- .section-title {
763
- font-size: var(--text-sm);
764
- text-transform: uppercase;
765
- letter-spacing: 0.06em;
766
- color: var(--text-3);
767
- margin: 24px 0 8px;
768
- font-weight: 500;
769
- }
770
-
771
- .muted { color: var(--text-3); }
772
- .muted.small { font-size: var(--text-xs); letter-spacing: 0.04em; }
773
- .muted.error { color: var(--danger); }
774
- .right { text-align: right; }
775
- .mono { font-family: var(--font-mono); }
776
- .small { font-size: var(--text-xs); }
777
-
778
- code, .code-block {
779
- font-family: var(--font-mono);
780
- font-size: var(--text-sm);
781
- background: var(--surface-2);
782
- border: 1px solid var(--border-2);
783
- padding: 2px 6px;
784
- border-radius: var(--r-sm);
785
- color: var(--text-1);
786
- }
787
- .code-block { display: block; padding: 10px 14px; margin: 8px 0; }
788
-
789
- /* ── Settings ───────────────────────────────────────────────────────────── */
790
- .settings-grid {
791
- display: grid;
792
- grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
793
- gap: 12px;
794
- margin-top: 16px;
795
- }
796
-
797
- .settings-card {
798
- padding: 14px;
799
- text-decoration: none;
800
- display: flex;
801
- flex-direction: column;
802
- gap: 6px;
803
- color: var(--text-1);
804
- }
805
-
806
- .settings-card-title {
807
- font-size: var(--text-sm);
808
- letter-spacing: 0.06em;
809
- text-transform: uppercase;
810
- color: var(--accent);
811
- font-weight: 500;
812
- }
813
-
814
- .settings-card-body { color: var(--text-2); font-size: var(--text-sm); }
815
-
816
- .kv-list {
817
- display: grid;
818
- grid-template-columns: max-content 1fr;
819
- gap: 6px 16px;
820
- margin-top: 12px;
821
- }
822
-
823
- .kv-label {
824
- color: var(--text-3);
825
- font-size: var(--text-sm);
826
- letter-spacing: 0.04em;
827
- }
828
-
829
- .kv-value { color: var(--text-1); font-size: var(--text-sm); }
830
- .kv-value.mono { font-family: var(--font-mono); word-break: break-all; }
831
-
832
- .form-grid {
833
- display: grid;
834
- gap: 12px;
835
- margin-top: 12px;
836
- max-width: 420px;
837
- }
838
-
839
- .form-field {
840
- display: flex;
841
- flex-direction: column;
842
- gap: 4px;
843
- }
844
-
845
- .form-label {
846
- font-size: var(--text-xs);
847
- color: var(--text-3);
848
- letter-spacing: 0.06em;
849
- text-transform: uppercase;
850
- }
851
-
852
- .form-input {
853
- background: var(--surface-1);
854
- border: 1px solid var(--border-2);
855
- color: var(--text-1);
856
- padding: 6px 10px;
857
- font-family: var(--font-mono);
858
- font-size: var(--text-sm);
859
- border-radius: var(--r-sm);
860
- }
861
- .form-input:focus { border-color: var(--border-4); outline: none; }
862
-
863
- /* ── Data table (labels page) ───────────────────────────────────────────── */
864
- .data-table {
865
- width: 100%;
866
- border-collapse: collapse;
867
- margin-top: 12px;
868
- font-size: var(--text-sm);
869
- }
870
-
871
- .data-table th {
872
- text-align: left;
873
- font-weight: 500;
874
- font-size: var(--text-xs);
875
- letter-spacing: 0.06em;
876
- text-transform: uppercase;
877
- color: var(--text-3);
878
- padding: 8px 10px;
879
- border-bottom: 1px solid var(--border-2);
880
- }
881
-
882
- .data-table th.right { text-align: right; }
883
-
884
- .data-table td {
885
- padding: 7px 10px;
886
- border-bottom: 1px solid var(--border-1);
887
- color: var(--text-1);
888
- vertical-align: middle;
889
- }
890
-
891
- .data-table tr:hover td { background: var(--surface-1); }
892
-
893
- .canonical .dot { margin-right: 8px; vertical-align: middle; }
894
-
895
- .dot {
896
- display: inline-block;
897
- width: 8px;
898
- height: 8px;
899
- border-radius: 50%;
900
- flex-shrink: 0;
901
- }
902
- .dot.lg { width: 14px; height: 14px; }
903
-
904
- .chip-inline {
905
- display: inline-flex;
906
- align-items: center;
907
- gap: 4px;
908
- padding: 2px 8px;
909
- border-radius: var(--r-sm);
910
- border: 1px solid var(--border-2);
911
- background: var(--surface-2);
912
- color: var(--text-2);
913
- font-family: var(--font-mono);
914
- font-size: var(--text-xs);
915
- letter-spacing: 0.04em;
916
- text-transform: lowercase;
917
- }
918
-
919
- .chip-inline.status-active { color: var(--accent); border-color: rgba(232,255,110,0.25); background: var(--accent-glow); }
920
- .chip-inline.status-idle { color: #ffcc80; border-color: rgba(255,204,128,0.25); }
921
- .chip-inline.status-closed { color: var(--text-2); }
922
- .chip-inline.status-superseded { color: var(--text-3); text-decoration: line-through; }
923
- .chip-inline.status-retired { color: var(--danger); border-color: rgba(255,107,53,0.25); background: var(--danger-dim); }
924
- .chip-inline.status-stale { color: var(--warn); border-color: rgba(255,153,51,0.25); background: var(--warn-dim); }
925
- .chip-inline.severity-high { color: var(--danger); border-color: rgba(255,107,53,0.35); background: var(--danger-dim); }
926
- .chip-inline.severity-medium { color: var(--warn); border-color: rgba(255,153,51,0.35); background: var(--warn-dim); }
927
-
928
- .chip-x {
929
- background: none;
930
- border: none;
931
- color: inherit;
932
- cursor: pointer;
933
- font-size: 12px;
934
- padding: 0 0 0 4px;
935
- line-height: 1;
936
- }
937
-
938
- /* ── Pulse ──────────────────────────────────────────────────────────────── */
939
- .kpi-row {
940
- display: grid;
941
- grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
942
- gap: 12px;
943
- margin-bottom: 18px;
944
- }
945
-
946
- .kpi {
947
- background: var(--surface-1);
948
- border: 1px solid var(--border-2);
949
- border-radius: var(--r-md);
950
- padding: 14px 16px;
951
- display: flex;
952
- flex-direction: column;
953
- gap: 4px;
954
- }
955
-
956
- .kpi-label {
957
- font-size: var(--text-xs);
958
- letter-spacing: 0.06em;
959
- text-transform: uppercase;
960
- color: var(--text-3);
961
- }
962
-
963
- .kpi-value {
964
- font-size: var(--text-stat);
965
- font-family: var(--font-mono);
966
- color: var(--text-1);
967
- line-height: 1;
968
- }
969
-
970
- .kpi-hint { font-size: var(--text-xs); color: var(--text-3); }
971
-
972
- .kpi-sparkline { gap: 8px; }
973
-
974
- .sparkline {
975
- display: flex;
976
- align-items: flex-end;
977
- gap: 4px;
978
- height: 40px;
979
- }
980
-
981
- .spark-bar {
982
- flex: 1;
983
- background: var(--accent);
984
- opacity: 0.7;
985
- border-radius: 1px;
986
- min-height: 2px;
987
- }
988
-
989
- .pulse-grid {
990
- display: grid;
991
- grid-template-columns: 1fr 1fr 1fr;
992
- grid-template-rows: 1fr 1fr;
993
- grid-template-areas:
994
- "coherence recent stale"
995
- "runtimes recent stale";
996
- gap: 12px;
997
- margin-top: 6px;
998
- /* Bound the grid to viewport-minus-chrome so cards have a real bounding box
999
- and their bodies scroll instead of stretching the page. */
1000
- height: calc(100vh - 280px);
1001
- min-height: 360px;
1002
- }
1003
-
1004
- .pulse-area-coherence { grid-area: coherence; }
1005
- .pulse-area-runtimes { grid-area: runtimes; }
1006
- .pulse-area-recent { grid-area: recent; }
1007
- .pulse-area-stale { grid-area: stale; }
1008
-
1009
- /* Scroll containers (Stale alerts, Recent sessions). Card lays out as a
1010
- flex column with header fixed and body filling the remainder. */
1011
- .pulse-scroll-card {
1012
- display: flex;
1013
- flex-direction: column;
1014
- min-height: 0;
1015
- overflow: hidden;
1016
- }
1017
-
1018
- .pulse-scroll-card .card-head { flex-shrink: 0; }
1019
-
1020
- /* Hover affordance for the major blocks on the Pulse view — KPI tiles
1021
- and the three pulse-grid cards get a clean white outline so it's
1022
- obvious they're interactive zones. */
1023
- .kpi,
1024
- .pulse-grid > .card {
1025
- transition: outline-color var(--ease), border-color var(--ease);
1026
- outline: 1px solid transparent;
1027
- outline-offset: -1px;
1028
- }
1029
-
1030
- .kpi:hover,
1031
- .pulse-grid > .card:hover {
1032
- outline-color: rgba(255, 255, 255, 0.55);
1033
- }
1034
-
1035
- .pulse-scroll-body {
1036
- flex: 1;
1037
- min-height: 0;
1038
- overflow-y: auto;
1039
- }
1040
-
1041
- .card-head {
1042
- display: flex;
1043
- align-items: baseline;
1044
- justify-content: space-between;
1045
- padding: 10px 14px;
1046
- border-bottom: 1px solid var(--border-1);
1047
- }
1048
-
1049
- .card-head h3 {
1050
- font-size: var(--text-sm);
1051
- letter-spacing: 0.06em;
1052
- text-transform: uppercase;
1053
- color: var(--text-2);
1054
- font-weight: 500;
1055
- }
1056
-
1057
- .bar-stack { padding: 14px; display: flex; flex-direction: column; gap: 10px; }
1058
- .bar-item { display: grid; grid-template-columns: 80px 1fr auto; gap: 10px; align-items: center; }
1059
- .bar-label { font-size: var(--text-sm); color: var(--text-2); }
1060
- .bar-track { height: 8px; background: var(--surface-2); border-radius: 4px; overflow: hidden; }
1061
- .bar-fill { height: 100%; transition: width 0.3s ease; }
1062
- .bar-fill.tone-active { background: var(--accent); }
1063
- .bar-fill.tone-warn { background: var(--warn); }
1064
- .bar-fill.tone-danger { background: var(--danger); }
1065
- .bar-value { font-size: var(--text-sm); color: var(--text-1); min-width: 96px; text-align: right; white-space: nowrap; }
1066
- .bar-pct { margin-left: 2px; }
1067
-
1068
- /* Recall — adoption + coverage telemetry */
1069
- .recall-head {
1070
- display: flex;
1071
- justify-content: space-between;
1072
- align-items: flex-start;
1073
- gap: 24px;
1074
- margin-bottom: 20px;
1075
- }
1076
- .recall-note { max-width: 60ch; margin: 0; line-height: 1.5; }
1077
- .recall-block { margin-bottom: 28px; }
1078
- .recall-block-head { margin-bottom: 14px; }
1079
- .recall-block-head .page-title { margin-bottom: 2px; }
1080
- .recall-block-head p { margin: 0; max-width: 70ch; }
1081
- .recall-empty { padding: 18px; font-size: var(--text-sm); }
1082
- .recall-cards {
1083
- display: grid;
1084
- grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
1085
- gap: 14px;
1086
- margin-top: 14px;
1087
- }
1088
- .recall-bars .bar-item { grid-template-columns: 140px 1fr auto; }
1089
- .recall-bar-label {
1090
- overflow: hidden;
1091
- text-overflow: ellipsis;
1092
- white-space: nowrap;
1093
- }
1094
- .recall-bars .bar-value { min-width: 0; }
1095
- .recall-bars-empty { padding: 4px 0; }
1096
-
1097
- @media (max-width: 720px) {
1098
- .recall-head { flex-direction: column; gap: 12px; }
1099
- }
1100
-
1101
- /* Runtimes panel (Pulse) */
1102
- .runtime-list { list-style: none; padding: 4px 0; margin: 0; }
1103
- .runtime-row {
1104
- display: grid;
1105
- grid-template-columns: 12px 1fr auto auto;
1106
- align-items: center;
1107
- gap: 10px;
1108
- padding: 8px 12px;
1109
- border-bottom: 1px solid var(--border-1);
1110
- }
1111
- .runtime-row:last-child { border-bottom: none; }
1112
- .runtime-dot {
1113
- width: 8px; height: 8px; border-radius: 50%;
1114
- background: var(--text-3);
1115
- box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.04);
1116
- }
1117
- .runtime-dot.runtime-active { background: var(--accent); box-shadow: 0 0 6px rgba(232,255,110,0.6); }
1118
- .runtime-dot.runtime-idle { background: var(--warn); }
1119
- .runtime-dot.runtime-dormant { background: var(--text-3); opacity: 0.5; }
1120
- .runtime-name { color: var(--text-1); font-size: var(--text-sm); }
1121
- .runtime-counts { white-space: nowrap; }
1122
- .runtime-counts-sep { margin: 0 6px; opacity: 0.5; }
1123
- .runtime-counts-prev { opacity: 0.7; }
1124
- .runtime-age { min-width: 60px; text-align: right; }
1125
-
1126
- .alert-list { list-style: none; padding: 4px 0; }
1127
- .alert-row-empty { padding: 16px 14px; }
1128
-
1129
- .alert-row {
1130
- display: grid;
1131
- grid-template-columns: auto auto 1fr;
1132
- gap: 10px;
1133
- align-items: center;
1134
- padding: 7px 14px;
1135
- border-bottom: 1px solid var(--border-1);
1136
- }
1137
-
1138
- .alert-entity { color: var(--text-1); font-size: var(--text-sm); }
1139
-
1140
- .alert-summary {
1141
- display: -webkit-box;
1142
- -webkit-line-clamp: 1;
1143
- -webkit-box-orient: vertical;
1144
- overflow: hidden;
1145
- text-overflow: ellipsis;
1146
- color: var(--text-3);
1147
- font-size: var(--text-xs);
1148
- letter-spacing: 0.04em;
1149
- min-width: 0;
1150
- line-height: var(--lh-base);
1151
- }
1152
-
1153
- .alert-row.clickable { cursor: pointer; transition: background var(--ease); }
1154
- .alert-row.clickable:hover { background: var(--surface-2); }
1155
- .alert-row.clickable:focus-visible { outline: 1px solid var(--border-4); outline-offset: -2px; }
1156
- .alert-row.clickable:hover .alert-entity { color: var(--accent); }
1157
-
1158
- .drawer-actions {
1159
- display: flex;
1160
- flex-wrap: wrap;
1161
- gap: 6px;
1162
- margin: 14px 0 6px;
1163
- }
1164
-
1165
- .session-list { list-style: none; }
1166
- .session-list.compact .session-row { padding: 6px 0; border-bottom: 1px solid var(--border-1); }
1167
-
1168
- .session-row {
1169
- display: grid;
1170
- grid-template-columns: auto 1fr auto;
1171
- gap: 10px;
1172
- align-items: center;
1173
- padding: 8px 14px;
1174
- border-bottom: 1px solid var(--border-1);
1175
- }
1176
-
1177
- .session-row-detail {
1178
- grid-template-columns: auto 1fr auto;
1179
- }
1180
-
1181
- .session-row-main {
1182
- display: flex;
1183
- flex-direction: column;
1184
- gap: 2px;
1185
- min-width: 0;
1186
- }
1187
-
1188
- .session-label {
1189
- color: var(--text-1);
1190
- font-size: var(--text-sm);
1191
- text-decoration: none;
1192
- white-space: nowrap;
1193
- overflow: hidden;
1194
- text-overflow: ellipsis;
1195
- }
1196
- a.session-label:hover { color: var(--accent); }
1197
-
1198
- .session-meta {
1199
- color: var(--text-3);
1200
- font-size: var(--text-xs);
1201
- letter-spacing: 0.04em;
1202
- }
1203
-
1204
- @media (max-width: 1100px) {
1205
- .pulse-grid {
1206
- grid-template-columns: 1fr 1fr;
1207
- grid-template-rows: auto;
1208
- grid-template-areas:
1209
- "coherence runtimes"
1210
- "recent recent"
1211
- "stale stale";
1212
- height: auto;
1213
- min-height: 0;
1214
- }
1215
- .pulse-scroll-body { max-height: 360px; }
1216
- }
1217
-
1218
- @media (max-width: 700px) {
1219
- .pulse-grid {
1220
- grid-template-columns: 1fr;
1221
- grid-template-areas:
1222
- "coherence"
1223
- "runtimes"
1224
- "recent"
1225
- "stale";
1226
- }
1227
- }
1228
-
1229
- /* ── Search ─────────────────────────────────────────────────────────────── */
1230
- .search-bar {
1231
- display: flex;
1232
- gap: 10px;
1233
- align-items: center;
1234
- margin-bottom: 12px;
1235
- }
1236
-
1237
- .search-input.search-big {
1238
- flex: 1;
1239
- padding: 10px 14px;
1240
- font-size: var(--text-md);
1241
- }
1242
-
1243
- .search-meta { margin: 8px 0; }
1244
-
1245
- /* ── Thread ─────────────────────────────────────────────────────────────── */
1246
- .thread-header {
1247
- display: flex;
1248
- align-items: center;
1249
- gap: 14px;
1250
- margin-bottom: 16px;
1251
- }
1252
-
1253
- .thread-header .page-title { margin-bottom: 0; }
1254
-
1255
- .thread-grid {
1256
- display: grid;
1257
- grid-template-columns: 1fr 1fr;
1258
- gap: 12px;
1259
- margin-bottom: 18px;
1260
- }
1261
-
1262
- .marker-list { list-style: none; max-height: 360px; overflow-y: auto; }
1263
- .marker-row {
1264
- display: grid;
1265
- grid-template-columns: auto 1fr auto;
1266
- gap: 10px;
1267
- padding: 7px 14px;
1268
- border-bottom: 1px solid var(--border-1);
1269
- align-items: baseline;
1270
- }
1271
-
1272
- .marker-text { color: var(--text-1); font-size: var(--text-sm); }
1273
-
1274
- .entity-grid {
1275
- list-style: none;
1276
- display: grid;
1277
- grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
1278
- gap: 10px;
1279
- margin-top: 16px;
1280
- }
1281
-
1282
- .entity-card {
1283
- padding: 10px 12px;
1284
- text-decoration: none;
1285
- color: var(--text-1);
1286
- display: flex;
1287
- align-items: center;
1288
- gap: 8px;
1289
- }
1290
-
1291
- .entity-name {
1292
- flex: 1;
1293
- font-size: var(--text-sm);
1294
- overflow: hidden;
1295
- text-overflow: ellipsis;
1296
- white-space: nowrap;
1297
- }
1298
-
1299
- @media (max-width: 800px) {
1300
- .thread-grid { grid-template-columns: 1fr; }
1301
- }
1302
-
1303
- /* ── River ──────────────────────────────────────────────────────────────── */
1304
- .river-toolbar {
1305
- display: flex;
1306
- align-items: center;
1307
- gap: 12px;
1308
- margin-bottom: 16px;
1309
- }
1310
-
1311
- .river-toolbar .page-title { margin-bottom: 0; font-size: var(--text-lg); }
1312
-
1313
- .river-grid {
1314
- --river-label-w: 200px;
1315
- --river-row-gap: 3px;
1316
- --river-cell-gap: 2px;
1317
- --river-cell-h: 20px;
1318
- padding: 12px;
1319
- width: 100%;
1320
- display: flex;
1321
- flex-direction: column;
1322
- gap: var(--river-row-gap);
1323
- }
1324
-
1325
- /* Density tiers — Settings → Views. Comfortable matches the base values
1326
- above; compact and spacious retune row gap, cell gap, and cell height. */
1327
- .river-grid.river-density-compact {
1328
- --river-row-gap: 1px;
1329
- --river-cell-gap: 1px;
1330
- --river-cell-h: 10px;
1331
- }
1332
- .river-grid.river-density-spacious {
1333
- --river-row-gap: 6px;
1334
- --river-cell-gap: 4px;
1335
- --river-cell-h: 24px;
1336
- }
1337
-
1338
- .river-row {
1339
- display: grid;
1340
- grid-template-columns: var(--river-label-w) 1fr;
1341
- gap: 6px;
1342
- align-items: center;
1343
- width: 100%;
1344
- min-width: 0;
1345
- }
1346
-
1347
- .river-row-dates {
1348
- margin-bottom: 2px;
1349
- }
1350
-
1351
- .river-lane-label {
1352
- display: flex;
1353
- align-items: center;
1354
- gap: 6px;
1355
- padding: 2px 6px;
1356
- border-radius: var(--r-sm);
1357
- text-decoration: none;
1358
- color: var(--text-2);
1359
- font-size: var(--text-sm);
1360
- white-space: nowrap;
1361
- overflow: hidden;
1362
- width: 100%;
1363
- min-width: 0;
1364
- }
1365
- .river-lane-label:hover { background: var(--surface-2); color: var(--text-1); }
1366
-
1367
- .river-lane-label--header {
1368
- padding: 0;
1369
- background: none;
1370
- }
1371
-
1372
- .river-lane-name { flex: 1; overflow: hidden; text-overflow: ellipsis; min-width: 0; }
1373
-
1374
- .river-cells {
1375
- display: grid;
1376
- grid-template-columns: repeat(var(--cells, 1), minmax(0, 1fr));
1377
- gap: var(--river-cell-gap);
1378
- width: 100%;
1379
- min-width: 0;
1380
- }
1381
-
1382
- .river-date-cell {
1383
- font-size: var(--text-xs);
1384
- color: var(--text-2);
1385
- letter-spacing: 0.04em;
1386
- text-align: center;
1387
- overflow: hidden;
1388
- text-overflow: ellipsis;
1389
- white-space: nowrap;
1390
- }
1391
-
1392
- .river-cell {
1393
- height: var(--river-cell-h);
1394
- border-radius: 2px;
1395
- background: var(--surface-2);
1396
- min-width: 0;
1397
- }
1398
-
1399
- .river-cell.tier-1 { background: rgba(232,255,110,0.20); }
1400
- .river-cell.tier-2 { background: rgba(232,255,110,0.40); }
1401
- .river-cell.tier-3 { background: rgba(232,255,110,0.65); }
1402
- .river-cell.tier-4 { background: var(--accent); }
1403
-
1404
- /* ── Inline action buttons (Pulse alerts, Labels rows) ─────────────────── */
1405
- .alert-row {
1406
- grid-template-columns: auto auto 1fr auto;
1407
- }
1408
-
1409
- .alert-actions {
1410
- display: flex;
1411
- gap: 6px;
1412
- align-items: center;
1413
- }
1414
-
1415
- .alert-actions .chip {
1416
- font-size: var(--text-xs);
1417
- padding: 2px 8px;
1418
- }
1419
-
1420
- .row-actions {
1421
- display: flex;
1422
- gap: 6px;
1423
- }
1424
-
1425
- .row-actions .chip {
1426
- font-size: var(--text-xs);
1427
- padding: 2px 8px;
1428
- }
1429
-
1430
- .row-busy { opacity: 0.5; pointer-events: none; transition: opacity 0.15s ease; }
1431
-
1432
- .form-input-inline {
1433
- padding: 3px 8px;
1434
- font-size: var(--text-xs);
1435
- letter-spacing: 0.04em;
1436
- }
1437
-
1438
- /* ── River interactivity ───────────────────────────────────────────────── */
1439
- .river-grid {
1440
- position: relative;
1441
- user-select: none;
1442
- }
1443
-
1444
- .river-drag-rect {
1445
- position: absolute;
1446
- top: 0;
1447
- bottom: 0;
1448
- background: var(--accent-glow);
1449
- border-left: 1px dashed var(--accent);
1450
- border-right: 1px dashed var(--accent);
1451
- pointer-events: none;
1452
- z-index: 1;
1453
- }
1454
-
1455
- .river-lane-label {
1456
- background: none;
1457
- border: none;
1458
- text-align: left;
1459
- cursor: pointer;
1460
- font-family: var(--font-mono);
1461
- }
1462
-
1463
- .river-cell {
1464
- transition: outline-color var(--ease);
1465
- outline: 1px solid transparent;
1466
- outline-offset: 1px;
1467
- position: relative;
1468
- z-index: 0;
1469
- }
1470
-
1471
- .river-cell:hover {
1472
- outline-color: rgba(255, 255, 255, 0.7);
1473
- z-index: 1;
1474
- }
1475
-
1476
- .river-hover {
1477
- position: fixed;
1478
- display: flex;
1479
- align-items: center;
1480
- gap: 8px;
1481
- background: var(--surface-float);
1482
- border: 1px solid var(--border-3);
1483
- border-radius: var(--r-sm);
1484
- padding: 6px 10px;
1485
- font-size: var(--text-xs);
1486
- pointer-events: none;
1487
- z-index: 200;
1488
- box-shadow: 0 6px 20px rgba(0, 0, 0, 0.5);
1489
- }
1490
-
1491
- .river-hover-name {
1492
- color: var(--text-1);
1493
- font-size: var(--text-sm);
1494
- }
1495
-
1496
- /* ── Thread drawer ─────────────────────────────────────────────────────── */
1497
- .session-row.clickable { cursor: pointer; }
1498
- .session-row.clickable:hover { background: var(--surface-1); }
1499
-
1500
- .link-button {
1501
- background: none;
1502
- border: none;
1503
- color: var(--text-3);
1504
- font-family: var(--font-mono);
1505
- font-size: var(--text-xs);
1506
- cursor: pointer;
1507
- padding: 0;
1508
- letter-spacing: 0.04em;
1509
- }
1510
- .link-button:hover { color: var(--accent); }
1511
-
1512
- .drawer-backdrop {
1513
- position: fixed;
1514
- inset: 0;
1515
- background: rgba(0, 0, 0, 0.55);
1516
- z-index: 199;
1517
- animation: fadeIn 0.15s ease;
1518
- }
1519
-
1520
- @keyframes fadeIn {
1521
- from { opacity: 0; }
1522
- to { opacity: 1; }
1523
- }
1524
-
1525
- .session-drawer {
1526
- position: fixed;
1527
- top: 0;
1528
- right: 0;
1529
- bottom: 0;
1530
- width: min(560px, 100vw);
1531
- background: var(--surface-1);
1532
- border-left: 1px solid var(--border-3);
1533
- box-shadow: -16px 0 40px rgba(0, 0, 0, 0.55);
1534
- z-index: 200;
1535
- display: flex;
1536
- flex-direction: column;
1537
- animation: slideInRight 0.18s ease;
1538
- }
1539
-
1540
- @keyframes slideInRight {
1541
- from { transform: translateX(20px); opacity: 0; }
1542
- to { transform: translateX(0); opacity: 1; }
1543
- }
1544
-
1545
- .drawer-head {
1546
- display: flex;
1547
- align-items: center;
1548
- gap: 10px;
1549
- padding: 14px 18px;
1550
- border-bottom: 1px solid var(--border-1);
1551
- }
1552
-
1553
- .drawer-title {
1554
- flex: 1;
1555
- font-size: var(--text-md);
1556
- font-family: var(--font-mono);
1557
- font-weight: 500;
1558
- color: var(--text-1);
1559
- min-width: 0;
1560
- overflow: hidden;
1561
- text-overflow: ellipsis;
1562
- white-space: nowrap;
1563
- }
1564
-
1565
- .drawer-close {
1566
- background: none;
1567
- border: none;
1568
- color: var(--text-3);
1569
- font-size: 24px;
1570
- line-height: 1;
1571
- cursor: pointer;
1572
- padding: 0 6px;
1573
- }
1574
- .drawer-close:hover { color: var(--text-1); }
1575
-
1576
- .drawer-body {
1577
- overflow-y: auto;
1578
- padding: 16px 18px 80px;
1579
- flex: 1;
1580
- }
1581
-
1582
- .drawer-section {
1583
- font-size: var(--text-xs);
1584
- letter-spacing: 0.06em;
1585
- text-transform: uppercase;
1586
- color: var(--text-3);
1587
- margin: 18px 0 8px;
1588
- font-weight: 500;
1589
- }
1590
-
1591
- .drawer-list {
1592
- list-style: none;
1593
- display: flex;
1594
- flex-direction: column;
1595
- gap: 8px;
1596
- font-size: var(--text-sm);
1597
- color: var(--text-1);
1598
- }
1599
-
1600
- .drawer-list li { display: flex; gap: 8px; align-items: baseline; }
1601
-
1602
- .drawer-paragraph {
1603
- font-size: var(--text-sm);
1604
- color: var(--text-1);
1605
- line-height: var(--lh-loose);
1606
- }
1607
-
1608
- .drawer-body-text {
1609
- background: var(--surface-0);
1610
- border: 1px solid var(--border-1);
1611
- border-radius: var(--r-sm);
1612
- padding: 10px 12px;
1613
- font-size: var(--text-xs);
1614
- color: var(--text-2);
1615
- white-space: pre-wrap;
1616
- word-break: break-word;
1617
- max-height: 360px;
1618
- overflow-y: auto;
1619
- line-height: var(--lh-base);
1620
- }
1621
-
1622
- .entity-chips {
1623
- display: flex;
1624
- flex-wrap: wrap;
1625
- gap: 6px;
1626
- }
1627
-
1628
- /* ── Supersedence banners (SessionDrawer) ───────────────────────────────── */
1629
- .supersedence-banner {
1630
- display: flex;
1631
- align-items: baseline;
1632
- flex-wrap: wrap;
1633
- gap: 6px;
1634
- padding: 8px 12px;
1635
- border-radius: var(--r-sm);
1636
- margin-bottom: 10px;
1637
- font-size: var(--text-sm);
1638
- }
1639
- .supersedence-banner--superseded {
1640
- background: rgba(255, 107, 53, 0.08);
1641
- border: 1px solid rgba(255, 107, 53, 0.25);
1642
- color: var(--danger);
1643
- }
1644
- .supersedence-banner--supersedes {
1645
- background: rgba(168, 168, 168, 0.06);
1646
- border: 1px solid var(--border-2);
1647
- color: var(--text-2);
1648
- }
1649
- .supersedence-label {
1650
- font-weight: 500;
1651
- white-space: nowrap;
1652
- }
1653
- .supersedence-ids {
1654
- display: flex;
1655
- flex-wrap: wrap;
1656
- gap: 4px;
1657
- }
1658
- .supersedence-id {
1659
- color: inherit;
1660
- opacity: 0.8;
1661
- }
1662
- .supersedence-link {
1663
- background: none;
1664
- border: none;
1665
- padding: 0;
1666
- cursor: pointer;
1667
- font-family: var(--font-mono);
1668
- font-size: var(--text-xs);
1669
- color: inherit;
1670
- text-decoration: underline;
1671
- text-underline-offset: 2px;
1672
- }
1673
- .supersedence-link:hover {
1674
- opacity: 0.75;
1675
- }
1676
-
1677
- /* ── Card head with stacked filters ──────────────────────────────────── */
1678
- .card-head.card-head-stack {
1679
- flex-direction: column;
1680
- align-items: stretch;
1681
- gap: 8px;
1682
- padding: 10px 14px 12px;
1683
- }
1684
-
1685
- .card-head-row {
1686
- display: flex;
1687
- align-items: baseline;
1688
- justify-content: space-between;
1689
- }
1690
-
1691
- .card-filters {
1692
- display: flex;
1693
- gap: 12px;
1694
- flex-wrap: wrap;
1695
- }
1696
-
1697
- .filter-group {
1698
- display: flex;
1699
- gap: 4px;
1700
- }
1701
-
1702
- .filter-group .chip {
1703
- font-size: var(--text-xs);
1704
- padding: 2px 8px;
1705
- }
1706
-
1707
- /* ── Thread sessions: search + filters + pagination ──────────────────── */
1708
- .thread-sessions-head {
1709
- display: flex;
1710
- align-items: center;
1711
- gap: 12px;
1712
- margin: 24px 0 8px;
1713
- }
1714
-
1715
- .thread-sessions-title { margin: 0; flex-shrink: 0; }
1716
-
1717
- .thread-sessions-head .search-input { flex: 1; }
1718
-
1719
- .thread-filters {
1720
- display: flex;
1721
- align-items: center;
1722
- gap: 12px;
1723
- flex-wrap: wrap;
1724
- margin-bottom: 8px;
1725
- }
1726
-
1727
- .thread-filters .filter-group { flex-wrap: wrap; }
1728
-
1729
- .pagination {
1730
- display: flex;
1731
- align-items: center;
1732
- gap: 16px;
1733
- flex-wrap: wrap;
1734
- padding: 14px 0 4px;
1735
- border-top: 1px solid var(--border-1);
1736
- margin-top: 4px;
1737
- }
1738
-
1739
- .page-size {
1740
- display: flex;
1741
- align-items: center;
1742
- gap: 8px;
1743
- }
1744
-
1745
- .page-nav {
1746
- display: flex;
1747
- align-items: center;
1748
- gap: 4px;
1749
- }
1750
-
1751
- .page-nav .chip:disabled {
1752
- opacity: 0.4;
1753
- cursor: not-allowed;
1754
- }
1755
-
1756
- .page-indicator {
1757
- font-size: var(--text-sm);
1758
- color: var(--text-2);
1759
- padding: 0 8px;
1760
- min-width: 60px;
1761
- text-align: center;
1762
- }
1763
-
1764
- /* ── Promote-open inline control ───────────────────────────────────────── */
1765
- .marker-row-promotable {
1766
- display: grid;
1767
- grid-template-columns: auto 1fr auto auto;
1768
- gap: 10px;
1769
- align-items: baseline;
1770
- }
1771
-
1772
- .marker-row-promotable .marker-actions {
1773
- display: flex;
1774
- gap: 6px;
1775
- align-items: baseline;
1776
- }
1777
-
1778
- .promote-chip {
1779
- font-size: var(--text-xs);
1780
- padding: 2px 8px;
1781
- color: var(--accent);
1782
- border-color: rgba(232,255,110,0.3);
1783
- background: var(--accent-glow);
1784
- }
1785
- .promote-chip:hover {
1786
- border-color: rgba(232,255,110,0.55);
1787
- color: var(--accent);
1788
- background: var(--accent-dim);
1789
- }
1790
-
1791
- .promote-editor {
1792
- display: flex;
1793
- gap: 6px;
1794
- align-items: center;
1795
- min-width: 280px;
1796
- }
1797
-
1798
- .promote-input {
1799
- flex: 1;
1800
- min-width: 200px;
1801
- }
1802
-
1803
- /* Compact pagination — used inside drawers / narrow panels */
1804
- .pagination.pagination-compact {
1805
- gap: 10px;
1806
- padding: 10px 0 4px;
1807
- font-size: var(--text-xs);
1808
- flex-wrap: wrap;
1809
- }
1810
- .pagination.pagination-compact .page-indicator { min-width: 40px; padding: 0 4px; font-size: var(--text-xs); }
1811
- .pagination.pagination-compact .chip { padding: 1px 6px; font-size: var(--text-xs); }
1812
- .pagination.pagination-compact .form-label { font-size: 9px; }
1813
-
1814
- /* ── River date label month boundary ───────────────────────────────────── */
1815
- .river-date-cell--month-start {
1816
- border-left: 1px solid var(--border-2);
1817
- padding-left: 3px;
1818
- }
1819
-
1820
- /* ── River legend ────────────────────────────────────────────────────────── */
1821
- .river-legend { display: flex; align-items: center; gap: 3px; }
1822
- .river-legend-cell { width: 12px; height: 12px; border-radius: 2px; background: var(--surface-2); }
1823
- .river-legend-cell.tier-1 { background: rgba(232,255,110,0.20); }
1824
- .river-legend-cell.tier-2 { background: rgba(232,255,110,0.40); }
1825
- .river-legend-cell.tier-3 { background: rgba(232,255,110,0.65); }
1826
- .river-legend-cell.tier-4 { background: var(--accent); }
1827
-
1828
- /* ── Empty row ───────────────────────────────────────────────────────────── */
1829
- .empty-row { color: var(--text-2); padding: 16px 0; font-size: var(--text-sm); }
1830
-
1831
- /* ── Session meta 2-line wrap ───────────────────────────────────────────── */
1832
- .session-meta {
1833
- display: -webkit-box;
1834
- -webkit-line-clamp: 2;
1835
- line-clamp: 2;
1836
- -webkit-box-orient: vertical;
1837
- overflow: hidden;
1838
- white-space: normal;
1839
- }
1840
-
1841
- /* ── Search clear button ─────────────────────────────────────────────────── */
1842
- .search-wrap { position: relative; display: flex; align-items: center; }
1843
- .search-wrap .search-input { padding-right: 28px; width: 100%; }
1844
- .search-clear { position: absolute; right: 6px; background: none; border: none; color: var(--text-3); cursor: pointer; display: flex; align-items: center; padding: 0; }
1845
- .search-clear:hover { color: var(--text-1); }
1846
-
1847
- /* ── Drawer nav buttons ──────────────────────────────────────────────────── */
1848
- .drawer-nav {
1849
- display: flex;
1850
- gap: 4px;
1851
- align-items: center;
1852
- flex-shrink: 0;
1853
- }
1854
- .drawer-nav-btn {
1855
- background: none;
1856
- border: 1px solid var(--border-2);
1857
- color: var(--text-3);
1858
- cursor: pointer;
1859
- display: flex;
1860
- align-items: center;
1861
- justify-content: center;
1862
- padding: 3px;
1863
- border-radius: var(--r-sm);
1864
- transition: color var(--ease), border-color var(--ease), background var(--ease);
1865
- }
1866
- .drawer-nav-btn:hover:not(:disabled) { color: var(--text-1); border-color: var(--border-3); background: var(--surface-2); }
1867
- .drawer-nav-btn:disabled { opacity: 0.35; cursor: not-allowed; }
1868
-
1869
- /* ── Dot pulse animation ─────────────────────────────────────────────────── */
1870
- .dot-pulse {
1871
- animation: dot-pulse 2s ease-in-out infinite;
1872
- }
1873
- @keyframes dot-pulse {
1874
- 0%, 100% { opacity: 1; transform: scale(1); }
1875
- 50% { opacity: 0.6; transform: scale(1.35); }
1876
- }
1877
-
1878
- /* ── Search page additions ───────────────────────────────────────────────── */
1879
- .search-hint { margin: 8px 0 12px; }
1880
-
1881
- .search-header { position: sticky; top: 0; z-index: 10; background: var(--surface-0); padding-bottom: 12px; border-bottom: 1px solid var(--border-1); margin-bottom: 16px; }
1882
-
1883
- .session-row.is-active { background: var(--surface-2); border-left: 2px solid var(--accent); padding-left: 12px; }
1884
-
1885
- .live-tag[data-kind="summary"] { background: var(--surface-2); color: var(--text-2); }
1886
- .live-tag[data-kind="label"] { background: var(--surface-2); color: var(--text-1); }
1887
- .live-tag[data-kind="entity"] { background: var(--accent-glow); border-color: rgba(232,255,110,0.25); color: var(--accent); }
1888
-
1889
- .match-snippet { color: var(--text-2); font-size: var(--text-xs); line-height: var(--lh-base); display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; margin-top: 4px; }
1890
- .match-snippet mark { background: rgba(232,255,110,0.15); color: var(--accent); padding: 0 2px; border-radius: 2px; }