@micha.bigler/ui-core-micha 3.13.1 → 3.14.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +35 -0
- package/WORK_ORDERS.md +6 -1
- package/dist/chat/ChatComposer.js +23 -0
- package/dist/chat/ChatList.js +30 -0
- package/dist/chat/ChatThread.js +69 -0
- package/dist/chat/ChatWorkspace.js +218 -0
- package/dist/chat/MarkdownReply.js +21 -0
- package/dist/chat/ModelPicker.js +38 -0
- package/dist/chat/api.js +17 -0
- package/dist/chat/useChatSocket.js +68 -0
- package/dist/chat/wire.js +7 -0
- package/dist/components/ProfileComponent.js +45 -10
- package/dist/i18n/chatTranslations.js +55 -0
- package/dist/i18n/uiCoreTranslations.js +2 -1
- package/dist/index.js +10 -0
- package/dist/theme/kitSxRegistry.js +10 -0
- package/package.json +4 -2
- package/src/chat/ChatComposer.jsx +36 -0
- package/src/chat/ChatList.jsx +87 -0
- package/src/chat/ChatThread.jsx +128 -0
- package/src/chat/ChatWorkspace.jsx +244 -0
- package/src/chat/MarkdownReply.jsx +22 -0
- package/src/chat/ModelPicker.jsx +85 -0
- package/src/chat/api.js +18 -0
- package/src/chat/useChatSocket.js +32 -0
- package/src/chat/wire.js +7 -0
- package/src/components/ProfileComponent.jsx +44 -10
- package/src/i18n/chatTranslations.ts +55 -0
- package/src/i18n/uiCoreTranslations.js +2 -0
- package/src/index.js +11 -0
- package/src/theme/kitSxRegistry.js +10 -0
- package/tests/ProfileComponent.refresh.test.jsx +194 -0
- package/tests/chatApi.test.js +48 -0
- package/tests/chatDriverNames.test.jsx +71 -0
- package/tests/chatExports.test.js +3 -0
- package/tests/chatList.test.jsx +84 -0
- package/tests/chatPicker.test.jsx +82 -0
- package/tests/chatSocket.test.jsx +26 -0
- package/tests/chatThread.test.jsx +116 -0
- package/tests/chatTranslations.test.js +47 -0
- package/tests/chatWorkspace.test.jsx +234 -0
- package/tests/i18nAggregate.test.js +2 -0
- package/work-orders/UCM-AUTH-13.md +47 -0
- package/work-orders/UCM-CHAT-1.md +190 -0
- package/work-orders/UCM-CHAT-2.md +75 -0
- package/work-orders/UCM-DEP-1.md +63 -0
- package/work-orders/UCM-SHELL-8.md +12 -0
- package/work-orders/assets/UCM-CHAT-1-ai-chat.html +447 -0
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# UCM-CHAT-2 — Readable driver names in the chat model picker
|
|
2
|
+
|
|
3
|
+
Prepared: 2026-10-15. Target repository: `ui-core-micha` (`main`). Correction to `UCM-CHAT-1`, found at acceptance.
|
|
4
|
+
|
|
5
|
+
# A. Envelope — addressed to everyone
|
|
6
|
+
|
|
7
|
+
## Goal and expected outcome
|
|
8
|
+
|
|
9
|
+
The model picker of the shared chat surface groups its entries by driver. In the UCM-CHAT-1 implementation, each group heading shows the raw driver id the catalogue returns (`claude_cli`, `anthropic_api`, `openai_api`). The prototype `work-orders/assets/UCM-CHAT-1-ai-chat.html` shows readable names instead.
|
|
10
|
+
|
|
11
|
+
Expected outcome: the three drivers that `django-core-micha/DCM-CHAT-1` ships appear under readable, translated names, both in the picker and wherever else ui-core-micha shows a driver. An unknown driver id still appears as its raw id, so a driver added later (`django-core-micha/DCM-CHAT-2`) stays usable before it gets a name.
|
|
12
|
+
|
|
13
|
+
## Scope
|
|
14
|
+
|
|
15
|
+
- A mapping from the three driver ids to translated names, registered in ui-core-micha's chat translations:
|
|
16
|
+
|
|
17
|
+
| Driver id | en | de | fr | sw |
|
|
18
|
+
|---|---|---|---|---|
|
|
19
|
+
| `claude_cli` | Claude Code subscription | Claude Code (Abo) | Claude Code (abonnement) | Claude Code (usajili) |
|
|
20
|
+
| `anthropic_api` | Anthropic API | Anthropic API | API Anthropic | API ya Anthropic |
|
|
21
|
+
| `openai_api` | OpenAI API | OpenAI API | API OpenAI | API ya OpenAI |
|
|
22
|
+
|
|
23
|
+
- The picker's group heading and the group's accessible name use the translated name.
|
|
24
|
+
- Any other place in the chat surface that shows a driver uses the same name. One example is the model-change divider in the thread.
|
|
25
|
+
- Unknown driver ids fall back to the raw id.
|
|
26
|
+
|
|
27
|
+
## Copy list (released with this Envelope)
|
|
28
|
+
|
|
29
|
+
The twelve names in the table above, verbatim. No other new text.
|
|
30
|
+
|
|
31
|
+
## Non-goals
|
|
32
|
+
|
|
33
|
+
- Any change to the catalogue contract or to django-core-micha. The names live in ui-core-micha.
|
|
34
|
+
- Other picker behaviour, layout or styling.
|
|
35
|
+
- The post-landing re-review of UCM-CHAT-1's last fix batch. That is UCM-CHAT-1's own follow-up.
|
|
36
|
+
|
|
37
|
+
## Tier
|
|
38
|
+
|
|
39
|
+
Tier 3: a change inside shared-core. Small and copy-only in effect.
|
|
40
|
+
|
|
41
|
+
## Risks
|
|
42
|
+
|
|
43
|
+
- **Id mismatch:** the ids must match exactly what DCM-CHAT-1 returns (`django_core_micha/assistant/catalogue.py`, `DRIVERS`). A mismatch silently falls back to raw ids. The existing picker test fixture uses `openai`, which is not a real driver id.
|
|
44
|
+
|
|
45
|
+
## Required tests to write
|
|
46
|
+
|
|
47
|
+
- Picker: groups for `claude_cli`, `anthropic_api` and `openai_api` show their translated names as heading and accessible name. Fixtures use the real driver ids.
|
|
48
|
+
- Unknown driver: an entry with an unknown driver id is grouped under its raw id.
|
|
49
|
+
- Translations: the three new keys exist in all four languages.
|
|
50
|
+
|
|
51
|
+
# B. Implementation map — addressed to the implementer
|
|
52
|
+
|
|
53
|
+
## Context package
|
|
54
|
+
|
|
55
|
+
Tier 3 · tests: picker + translations (see Part A). Work from this package; do not explore broadly. Target working directory: `C:/Users/Micha Bigler/Documents/webapps/ui-core-micha` (never the workspace root).
|
|
56
|
+
|
|
57
|
+
- `src/chat/ModelPicker.jsx` — `groupByDriver` groups `entries` by `entry.driver`; the group is rendered at about line 38 as `<Box key={driver} role="group" aria-label={driver}>` with `<Typography variant="overline">{driver}</Typography>`. Both the accessible name and the heading must show the translated name. `t` comes from `useTranslation()` already in the file.
|
|
58
|
+
- `src/i18n/chatTranslations.ts` — one `chatTranslations` const, entries `'Chat.xxx': { de, en, fr, sw }`. Add exactly three keys, flat like the existing `Chat.effort.low`: `Chat.driver.claude_cli`, `Chat.driver.anthropic_api`, `Chat.driver.openai_api`, with the Envelope's twelve names verbatim (en/de/fr/sw columns). No other new text.
|
|
59
|
+
- A small helper keeps the lookup in one place: export `driverName(t, id)` from `src/chat/ModelPicker.jsx` (or a new `src/chat/driverName.js` if cleaner) returning `t(`Chat.driver.${id}`, { defaultValue: id })`, so an unknown id falls back to the raw id with real i18next. Use it in the picker. The thread's model-change divider (`src/chat/ChatThread.jsx`, `selectionLine`) shows only model and effort, no driver; leave it unchanged. No other place in `src/chat/**` renders a driver id (verify with a search for `driver`).
|
|
60
|
+
- Tests: `tests/chatPicker.test.jsx` mocks `react-i18next` with `t: (key) => key`; make the mock return `values.defaultValue` when the key starts with `Chat.driver.` and a `defaultValue` is given and the id is not one of the three known ids, and the key otherwise, so every other assertion keeps expecting keys. Update the fixture entries to the real ids `claude_cli`, `anthropic_api` (replace the fake `openai`), keep one extra fixture with an unknown id (for example `mystery_driver`). Assert: group role name and heading text for each known driver equal the translation KEY `Chat.driver.<id>` (the mocked t returns keys); the unknown id group is named by the raw id. Also assert with the REAL `chatTranslations` that the three keys exist with the Envelope's exact English names, and that each key is non-empty in de/en/fr/sw (add to `tests/chatTranslations.test.js`). `tests/chatWorkspace.test.jsx` uses `openai`/`claude_cli` ids in its catalogue fixture and finds the group by name `openai`: update that lookup to the new key-based name.
|
|
61
|
+
- Do not edit: `package.json`, lockfile, CHANGELOG, README, `WORK_ORDERS.md`, anything outside `src/chat/**`, `src/i18n/chatTranslations.ts`, `tests/chat*.test.*`. No catalogue contract change.
|
|
62
|
+
- Pitfall: the existing aggregate test `tests/i18nAggregate.test.js` iterates all bundle keys; every value needs all four locales as non-empty strings.
|
|
63
|
+
|
|
64
|
+
## Preamble
|
|
65
|
+
|
|
66
|
+
> The text above is the COMPLETE spec — the committed WO file's content, not a plan to refine; there is no separate plan file. Read the nearest `AGENTS.md`, the relevant `.codex/skills/<role>/SKILL.md`, and the app `MEMORY.md` ONLY for conventions. Stay in scope; do not touch auth/permissions/deps/schema/CI unless the spec says so; do not update `MEMORY.md`. **Do NOT edit `WORK_ORDERS.md` — the register row and the review verdicts are the orchestrator's alone.** **Your tools are for editing source and test files and for running the tests you wrote — nothing else.** Do NOT install dependencies, touch a lockfile, run a package manager, or tidy up stray files; if something in the repo state blocks you, stop and report it as `RESULT: BLOCKED <reason>` instead of fixing it. Do NOT `git add`/`commit`/`push` — leave every change uncommitted in the working tree for the orchestrator's independent review. WRITE the tests the `Required tests` section calls for AND **RUN the tests you just wrote** to confirm they execute and pass — that is the ONLY test run you do (NOT the app's affected/full suite, NOT any review). The orchestrator re-runs the authoritative set + does the independent review after you finish — those are the gate; your own run does not count as the gate.
|
|
67
|
+
>
|
|
68
|
+
> Narrate continuously: a `PLAN: <step1> | <step2> | …` line up front, then a single-line `PROGRESS: [<n>/<total>] <present-tense action>` before every relevant action (and `… done` on completion), spaced so no gap exceeds ~2 min, stdout unbuffered, plus exactly one final `RESULT: DONE|BLOCKED <reason>`.
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
# C. Orchestrator only — not addressed to the implementer
|
|
72
|
+
|
|
73
|
+
> **If this WO was dispatched to you as an implementer: STOP here.**
|
|
74
|
+
|
|
75
|
+
Gate #1 open until recorded in the register row. Publish as a patch release; cockpit/CP-CHAT-4 pins the release that contains it.
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# UCM-DEP-1 — All open Renovate updates in one change on main, one CI run
|
|
2
|
+
|
|
3
|
+
Prepared: 2026-10-15. Target repository: `ui-core-micha` (`main`).
|
|
4
|
+
|
|
5
|
+
# A. Envelope — addressed to everyone
|
|
6
|
+
|
|
7
|
+
## Goal and expected outcome
|
|
8
|
+
|
|
9
|
+
ui-core-micha's eight open Renovate PRs land as one change on `main`, verified by one CI run. A release follows only if a runtime dependency changed; tooling-only updates need none.
|
|
10
|
+
|
|
11
|
+
## Tier
|
|
12
|
+
|
|
13
|
+
Tier 3: dependency changes, majors included.
|
|
14
|
+
|
|
15
|
+
## Operator decisions this Envelope records (2026-10-15)
|
|
16
|
+
|
|
17
|
+
1. The bundle contains these open Renovate PRs' updates, in one change on `main`:
|
|
18
|
+
|
|
19
|
+
| PR | Update |
|
|
20
|
+
|---|---|
|
|
21
|
+
| #17 | npm non-major |
|
|
22
|
+
| #18 | github-actions |
|
|
23
|
+
| #19 | actions/checkout v7 |
|
|
24
|
+
| #20 | actions/setup-node v7 |
|
|
25
|
+
| #21 | jsdom v30 (test) |
|
|
26
|
+
| #22 | pnpm v12 |
|
|
27
|
+
| #23 | typescript v7 |
|
|
28
|
+
| #24 | vitest v5 (test) |
|
|
29
|
+
|
|
30
|
+
2. A major that needs more than small adaptations (configuration, a renamed import, a test helper) is taken out of the bundle, left as its PR, and reported with the reason. The bundle does not grow into a migration.
|
|
31
|
+
3. Verification is one CI run of the repository's own CI on the candidate (for an app: a `ci-test/<ID>` ref with the full job set). A red job is fixed within decision 2 and the run repeated; not more than that.
|
|
32
|
+
4. After the push Renovate closes the PRs whose update landed; a PR it rebases instead is an update that did not land and is reported.
|
|
33
|
+
|
|
34
|
+
## Scope
|
|
35
|
+
|
|
36
|
+
1. Dependency manifests and lockfiles, workflow `uses:` pins, image pins the updates touch.
|
|
37
|
+
2. The small adaptations decision 2 allows, with tests where behaviour is touched.
|
|
38
|
+
3. Each update's changelog read for breaking changes before it goes in; a breaking change the code meets is adapted (decision 2) or the update is taken out.
|
|
39
|
+
4. A release per the repository's own publish procedure only when the published package's runtime dependencies changed.
|
|
40
|
+
|
|
41
|
+
## Non-goals
|
|
42
|
+
|
|
43
|
+
- No new features, no refactoring beyond decision 2.
|
|
44
|
+
- No change to the Renovate configuration.
|
|
45
|
+
- No pin bump in any consuming app.
|
|
46
|
+
|
|
47
|
+
## Risks
|
|
48
|
+
|
|
49
|
+
- pnpm 12 and TypeScript 7 change the build toolchain; the published bundle must stay byte-compatible in its exports. The CI's build and the kit's own tests are the check.
|
|
50
|
+
|
|
51
|
+
## Required tests to write
|
|
52
|
+
|
|
53
|
+
None beyond the adaptations of decision 2. The evidence is the CI run of decision 3.
|
|
54
|
+
|
|
55
|
+
# B. Implementation map — addressed to the implementer
|
|
56
|
+
|
|
57
|
+
*To be filled by the Orchestrator.*
|
|
58
|
+
|
|
59
|
+
# C. Orchestrator only — not addressed to the implementer
|
|
60
|
+
|
|
61
|
+
> **If this WO was dispatched to you as an implementer: STOP here.**
|
|
62
|
+
|
|
63
|
+
Gate #1 open until recorded in the register row. Part of the PR close-out round of 2026-10-15; stagger the CI run with the other bundles of that round (one heavy run at a time on the shared runner). On 2026-10-15 the working tree carried another session's uncommitted changes to `package.json` and `pnpm-lock.yaml` (likely the dcm/ucm chat migration): the same files this bundle changes. Sequence with that session before starting; never fold its changes into this commit.
|
|
@@ -111,3 +111,15 @@ Parent gate: 21 tests in SectionNav.test.jsx, AccountPage.test.jsx and
|
|
|
111
111
|
AccountPage.profileStatements.test.jsx passed with maxWorkers=2; TypeScript build exit 0.
|
|
112
112
|
Publish workflow's full suite is justified by shared-core consumer ripple. App pin and fresh
|
|
113
113
|
consumer capture remain pending after the reviewed core source/release lands.
|
|
114
|
+
|
|
115
|
+
Closing consumer proof: published3.13.1 verified by workflow38435441867,
|
|
116
|
+
744tests89files plus build and npm Trusted Publishing successful. Innoservice
|
|
117
|
+
exact pin3.13.1 is in sourcec527918, CI38444366349. Both source-matching account
|
|
118
|
+
captures375/1280 have no axe failures, no console/network failures, and all11
|
|
119
|
+
rubric items yes (22answers). Parent inspected both actual account images: same
|
|
120
|
+
profile/security/admin/help navigation and consent controls, readable at both
|
|
121
|
+
widths. Three previous kit list violations are gone. This completes the scoped
|
|
122
|
+
consumer gate; unrelated Organisation-policy axe failures in that app candidate
|
|
123
|
+
remain owned by INNO-FIX-11 and do not reopen the kit list correction.
|
|
124
|
+
Review remains the named five independent readonly Luna source passes above,
|
|
125
|
+
1deduplicated raised0accepted,worst accepted none; no source changes afterward.
|
|
@@ -0,0 +1,447 @@
|
|
|
1
|
+
<title>AI Chat Surface</title>
|
|
2
|
+
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=DM+Sans:opsz,wght@9..40,400;9..40,500;9..40,600;9..40,700&display=swap">
|
|
3
|
+
<style>
|
|
4
|
+
/* Layout: chat list column + thread column at 1280; list and model picker become sheets at 375.
|
|
5
|
+
Tokens: cockpit theme (primary #3D5A99) over the ui-core-micha light baseline, identical to
|
|
6
|
+
cockpit/work-orders/assets/CKP-REM-4-prs.html. Cockpit is light-only, so this spec is too. */
|
|
7
|
+
:root {
|
|
8
|
+
color-scheme: light;
|
|
9
|
+
--page: #FAFAFA;
|
|
10
|
+
--paper: #FFFFFF;
|
|
11
|
+
--subtle: #F4F5F6;
|
|
12
|
+
--divider: rgba(33,37,41,.10);
|
|
13
|
+
--ink: #212529;
|
|
14
|
+
--ink-2: #5B6670;
|
|
15
|
+
--ink-3: #6A7178;
|
|
16
|
+
--primary: #3D5A99;
|
|
17
|
+
--primary-dark: #324a7d;
|
|
18
|
+
--accent-tint: #eff2f7;
|
|
19
|
+
--ok-text: #35794A; --ok-bg: #E5F4E9;
|
|
20
|
+
--warn-text: #976100; --warn-bg: #FBF0DC;
|
|
21
|
+
--err-text: #BF3227; --err-bg: #FBEAE8;
|
|
22
|
+
--stale-text: #5B6B7D; --stale-bg: #EAEDF1;
|
|
23
|
+
--scrim: rgba(33,37,41,.32);
|
|
24
|
+
--font: 'DM Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
|
|
25
|
+
--mono: ui-monospace, 'SFMono-Regular', Consolas, monospace;
|
|
26
|
+
}
|
|
27
|
+
* { box-sizing: border-box; }
|
|
28
|
+
body { background: var(--page); color: var(--ink); font-family: var(--font); font-size: 13px; margin: 0; padding: 24px 16px 40px; }
|
|
29
|
+
.frames { display: flex; gap: 32px; align-items: flex-start; overflow-x: auto; padding-bottom: 8px; }
|
|
30
|
+
.frame { flex: 0 0 auto; display: grid; gap: 8px; align-content: start; }
|
|
31
|
+
.frame-label { font-size: 12px; color: var(--ink-3); font-variant-numeric: tabular-nums; }
|
|
32
|
+
.vp { background: var(--page); border: 1px solid var(--divider); border-radius: 6px; position: relative; overflow: hidden; }
|
|
33
|
+
.vp-375 { width: 375px; height: 740px; }
|
|
34
|
+
.vp-1280 { width: 1280px; height: 760px; }
|
|
35
|
+
.coverage { max-width: 1280px; margin: 0 0 20px; color: var(--ink-2); font-size: 12.5px; line-height: 1.5; display: grid; gap: 4px; }
|
|
36
|
+
.coverage b { color: var(--ink); font-weight: 600; }
|
|
37
|
+
|
|
38
|
+
/* Workspace */
|
|
39
|
+
.ws { display: grid; grid-template-columns: 272px minmax(0, 1fr); height: 100%; }
|
|
40
|
+
.vp-375 .ws { grid-template-columns: minmax(0, 1fr); }
|
|
41
|
+
|
|
42
|
+
/* Chat list */
|
|
43
|
+
.list { background: var(--subtle); border-right: 1px solid var(--divider); display: flex; flex-direction: column; min-height: 0; }
|
|
44
|
+
.list-head { display: flex; align-items: center; justify-content: space-between; padding: 14px 12px 10px 16px; }
|
|
45
|
+
.list-title { font-size: 14px; font-weight: 600; }
|
|
46
|
+
.items { display: grid; gap: 2px; padding: 0 8px; overflow: hidden; }
|
|
47
|
+
.item { display: grid; grid-template-columns: minmax(0, 1fr) 28px; align-items: center; gap: 4px; padding: 8px 4px 8px 10px; border-radius: 6px; color: var(--ink); }
|
|
48
|
+
.item.active { background: var(--accent-tint); }
|
|
49
|
+
.item.active .item-title { color: var(--primary-dark); font-weight: 600; }
|
|
50
|
+
.item-title { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
|
51
|
+
.item-meta { font-size: 11.5px; color: var(--ink-3); font-variant-numeric: tabular-nums; }
|
|
52
|
+
.item .icon-btn { opacity: .0; }
|
|
53
|
+
.item.active .icon-btn, .item.hover .icon-btn { opacity: 1; }
|
|
54
|
+
.list-foot { margin-top: auto; border-top: 1px solid var(--divider); padding: 8px; }
|
|
55
|
+
.archived-toggle { display: flex; align-items: center; justify-content: space-between; width: 100%; padding: 8px 10px; border-radius: 6px; color: var(--ink-2); font-weight: 500; }
|
|
56
|
+
.count { color: var(--ink-3); font-variant-numeric: tabular-nums; font-weight: 500; }
|
|
57
|
+
|
|
58
|
+
/* Menu (row overflow) */
|
|
59
|
+
.menu { position: absolute; background: var(--paper); border: 1px solid var(--divider); border-radius: 6px; box-shadow: 0 6px 20px rgba(33,37,41,.14); padding: 4px 0; min-width: 168px; z-index: 3; }
|
|
60
|
+
.menu-item { display: flex; align-items: center; gap: 10px; padding: 7px 14px; }
|
|
61
|
+
.menu-item.danger { color: var(--err-text); }
|
|
62
|
+
.menu-sep { height: 1px; background: var(--divider); margin: 4px 0; }
|
|
63
|
+
|
|
64
|
+
/* Thread */
|
|
65
|
+
.main { display: flex; flex-direction: column; min-width: 0; min-height: 0; background: var(--paper); }
|
|
66
|
+
.bar { display: flex; align-items: center; gap: 8px; padding: 10px 16px; border-bottom: 1px solid var(--divider); min-height: 52px; }
|
|
67
|
+
.vp-375 .bar { padding: 8px 8px 8px 4px; }
|
|
68
|
+
.bar-title { font-size: 15px; font-weight: 600; min-width: 0; flex: 1 1 auto; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
|
69
|
+
.picker-btn { display: inline-flex; align-items: center; gap: 6px; height: 32px; padding: 0 10px; border: 1px solid var(--divider); border-radius: 6px; background: var(--paper); color: var(--ink); font-weight: 500; white-space: nowrap; }
|
|
70
|
+
.picker-btn .sep { color: var(--ink-3); }
|
|
71
|
+
.picker-btn .effort { color: var(--ink-2); }
|
|
72
|
+
.vp-375 .picker-btn { padding: 0 8px; }
|
|
73
|
+
.icon-btn { width: 32px; height: 32px; display: inline-grid; place-items: center; border-radius: 6px; color: var(--ink-2); flex: 0 0 32px; }
|
|
74
|
+
.icon-btn svg, .menu-item svg, .archived-toggle svg, .picker-btn svg, .send svg, .opt svg { width: 18px; height: 18px; fill: currentColor; }
|
|
75
|
+
|
|
76
|
+
.thread { flex: 1 1 auto; overflow: hidden; padding: 20px 24px 8px; display: grid; gap: 18px; align-content: start; }
|
|
77
|
+
.vp-375 .thread { padding: 14px 12px 8px; gap: 14px; }
|
|
78
|
+
.col { width: 100%; max-width: 760px; margin: 0 auto; display: grid; gap: 18px; }
|
|
79
|
+
.vp-375 .col { gap: 14px; }
|
|
80
|
+
.msg-user { justify-self: end; max-width: 78%; background: var(--accent-tint); border-radius: 10px 10px 2px 10px; padding: 10px 14px; line-height: 1.5; }
|
|
81
|
+
.vp-375 .msg-user { max-width: 88%; }
|
|
82
|
+
.msg-ai { display: grid; gap: 8px; line-height: 1.55; min-width: 0; }
|
|
83
|
+
.md p { margin: 0; }
|
|
84
|
+
.md ul { margin: 0; padding-left: 20px; display: grid; gap: 3px; }
|
|
85
|
+
.md code { font-family: var(--mono); font-size: 12px; background: var(--subtle); padding: 1px 4px; border-radius: 3px; }
|
|
86
|
+
.md table { border-collapse: collapse; font-size: 12.5px; font-variant-numeric: tabular-nums; }
|
|
87
|
+
.md th, .md td { text-align: left; padding: 5px 12px 5px 0; border-bottom: 1px solid var(--divider); }
|
|
88
|
+
.md th { font-weight: 600; color: var(--ink-2); }
|
|
89
|
+
.md .table-wrap { overflow-x: auto; }
|
|
90
|
+
.md { display: grid; gap: 8px; }
|
|
91
|
+
|
|
92
|
+
.sources { display: flex; gap: 6px; flex-wrap: wrap; align-items: center; }
|
|
93
|
+
.src { display: inline-flex; align-items: center; gap: 5px; height: 24px; max-width: 260px; padding: 0 8px; border: 1px solid var(--divider); border-radius: 4px; font-size: 12px; color: var(--ink-2); background: var(--paper); }
|
|
94
|
+
.src svg { width: 13px; height: 13px; fill: var(--ink-3); flex: 0 0 13px; }
|
|
95
|
+
.src span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
96
|
+
.turn-meta { font-size: 11.5px; color: var(--ink-3); font-variant-numeric: tabular-nums; }
|
|
97
|
+
.switch-mark { display: flex; align-items: center; gap: 10px; color: var(--ink-3); font-size: 11.5px; }
|
|
98
|
+
.switch-mark::before, .switch-mark::after { content: ""; height: 1px; background: var(--divider); flex: 1 1 auto; }
|
|
99
|
+
|
|
100
|
+
.typing { display: inline-flex; gap: 4px; align-items: center; height: 18px; }
|
|
101
|
+
.typing i { width: 6px; height: 6px; border-radius: 50%; background: var(--ink-3); opacity: .55; }
|
|
102
|
+
.caret { display: inline-block; width: 7px; height: 14px; background: var(--ink-2); vertical-align: -2px; margin-left: 1px; }
|
|
103
|
+
.searching { display: inline-flex; align-items: center; gap: 6px; height: 24px; padding: 0 8px; border-radius: 4px; background: var(--subtle); color: var(--ink-2); font-size: 12px; }
|
|
104
|
+
|
|
105
|
+
/* Composer */
|
|
106
|
+
.composer { border-top: 1px solid var(--divider); padding: 12px 24px 14px; }
|
|
107
|
+
.vp-375 .composer { padding: 10px 12px 12px; }
|
|
108
|
+
.composer .col { gap: 8px; }
|
|
109
|
+
.input { border: 1px solid rgba(33,37,41,.23); border-radius: 8px; min-height: 64px; padding: 10px 12px; color: var(--ink-3); line-height: 1.5; background: var(--paper); }
|
|
110
|
+
.input.filled { color: var(--ink); }
|
|
111
|
+
.input.focus { border: 2px solid var(--primary); padding: 9px 11px; }
|
|
112
|
+
.actions { display: flex; justify-content: flex-end; gap: 8px; align-items: center; }
|
|
113
|
+
.btn { display: inline-flex; align-items: center; gap: 6px; height: 34px; padding: 0 14px; border-radius: 6px; font-weight: 600; font-size: 13px; letter-spacing: .02em; }
|
|
114
|
+
.btn.contained { background: var(--primary); color: #FFFFFF; }
|
|
115
|
+
.btn.contained.disabled { background: rgba(33,37,41,.12); color: rgba(33,37,41,.38); }
|
|
116
|
+
.btn.outlined { border: 1px solid rgba(61,90,153,.5); color: var(--primary); }
|
|
117
|
+
.btn.text { color: var(--primary); padding: 0 8px; }
|
|
118
|
+
.send svg { fill: currentColor; }
|
|
119
|
+
|
|
120
|
+
/* Notices */
|
|
121
|
+
.notice { display: flex; align-items: flex-start; gap: 10px; padding: 10px 12px; border-radius: 6px; line-height: 1.45; }
|
|
122
|
+
.notice.err { background: var(--err-bg); color: var(--err-text); }
|
|
123
|
+
.notice.warn { background: var(--warn-bg); color: var(--warn-text); }
|
|
124
|
+
.notice .grow { flex: 1 1 auto; min-width: 0; }
|
|
125
|
+
.notice .btn { height: 28px; padding: 0 8px; color: inherit; }
|
|
126
|
+
.chip { display: inline-flex; align-items: center; gap: 6px; height: 22px; padding: 0 8px; border-radius: 4px; font-size: 11.5px; font-weight: 500; white-space: nowrap; }
|
|
127
|
+
.chip.stale { background: var(--stale-bg); color: var(--stale-text); }
|
|
128
|
+
.chip.warn { background: var(--warn-bg); color: var(--warn-text); }
|
|
129
|
+
.chip .dot { width: 7px; height: 7px; border-radius: 50%; background: currentColor; }
|
|
130
|
+
|
|
131
|
+
/* Sheets / popover */
|
|
132
|
+
.scrim { position: absolute; inset: 0; background: var(--scrim); z-index: 2; }
|
|
133
|
+
.drawer { position: absolute; top: 0; bottom: 0; left: 0; width: 300px; background: var(--paper); z-index: 3; display: flex; flex-direction: column; box-shadow: 4px 0 24px rgba(33,37,41,.18); }
|
|
134
|
+
.drawer .list { background: var(--paper); border-right: 0; height: 100%; }
|
|
135
|
+
.sheet { position: absolute; left: 0; right: 0; bottom: 0; background: var(--paper); z-index: 3; border-radius: 12px 12px 0 0; box-shadow: 0 -6px 24px rgba(33,37,41,.18); padding: 8px 0 12px; }
|
|
136
|
+
.grabber { width: 36px; height: 4px; border-radius: 2px; background: var(--divider); margin: 0 auto 8px; }
|
|
137
|
+
.popover { position: absolute; top: 50px; right: 56px; width: 340px; background: var(--paper); border: 1px solid var(--divider); border-radius: 8px; box-shadow: 0 8px 28px rgba(33,37,41,.16); z-index: 3; padding: 6px 0 12px; }
|
|
138
|
+
.grp { font-size: 11.5px; font-weight: 600; color: var(--ink-3); padding: 10px 16px 4px; }
|
|
139
|
+
.opt { display: grid; grid-template-columns: 20px minmax(0, 1fr) auto; gap: 10px; align-items: center; padding: 7px 16px; }
|
|
140
|
+
.opt.sel { background: var(--accent-tint); }
|
|
141
|
+
.opt .check { color: var(--primary); }
|
|
142
|
+
.opt .name { font-weight: 500; }
|
|
143
|
+
.opt .cost { font-size: 11.5px; color: var(--ink-3); }
|
|
144
|
+
.effort-row { border-top: 1px solid var(--divider); margin-top: 6px; padding: 12px 16px 0; display: grid; gap: 8px; }
|
|
145
|
+
.effort-label { font-size: 11.5px; font-weight: 600; color: var(--ink-3); }
|
|
146
|
+
.seg { display: grid; grid-template-columns: repeat(4, 1fr); border: 1px solid rgba(61,90,153,.5); border-radius: 6px; overflow: hidden; }
|
|
147
|
+
.seg span { text-align: center; padding: 6px 0; font-weight: 500; color: var(--primary); border-left: 1px solid rgba(61,90,153,.5); }
|
|
148
|
+
.seg span:first-child { border-left: 0; }
|
|
149
|
+
.seg span.on { background: var(--primary); color: #FFFFFF; }
|
|
150
|
+
.seg span.off { color: rgba(33,37,41,.38); background: var(--subtle); }
|
|
151
|
+
|
|
152
|
+
/* Edge-state gallery */
|
|
153
|
+
.states { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 16px; padding: 20px; height: 100%; align-content: start; background: var(--page); }
|
|
154
|
+
.state { background: var(--paper); border: 1px solid var(--divider); border-radius: 6px; display: flex; flex-direction: column; min-height: 220px; overflow: hidden; }
|
|
155
|
+
.state-label { font-size: 12px; color: var(--ink-3); padding: 8px 12px; border-bottom: 1px solid var(--divider); background: var(--subtle); }
|
|
156
|
+
.state-body { padding: 16px; display: grid; gap: 12px; align-content: start; flex: 1 1 auto; }
|
|
157
|
+
.empty { display: grid; gap: 6px; justify-items: center; text-align: center; padding: 28px 8px; color: var(--ink-2); }
|
|
158
|
+
.empty h3 { margin: 0; font-size: 15px; color: var(--ink); font-weight: 600; }
|
|
159
|
+
</style>
|
|
160
|
+
|
|
161
|
+
<div class="coverage">
|
|
162
|
+
<div><b>Coverage:</b> the shared ui-core-micha chat surface (chat list with archive, thread with Markdown replies and source chips, composer with stop, per-chat model and effort picker, edge states), shown in cockpit's theme as the first consumer. Everything app-specific around it (cockpit navigation, the existing Open WebUI chat page) is outside this prototype and stays untouched.</div>
|
|
163
|
+
<div><b>Example content:</b> chat titles, questions, answers and source paths are illustrative, not real knowledge-base data.</div>
|
|
164
|
+
</div>
|
|
165
|
+
|
|
166
|
+
<svg width="0" height="0" style="position:absolute" aria-hidden="true">
|
|
167
|
+
<symbol id="i-more" viewBox="0 0 24 24"><path d="M12 8a2 2 0 1 0 0-4 2 2 0 0 0 0 4zm0 2a2 2 0 1 0 0 4 2 2 0 0 0 0-4zm0 6a2 2 0 1 0 0 4 2 2 0 0 0 0-4z"/></symbol>
|
|
168
|
+
<symbol id="i-new" viewBox="0 0 24 24"><path d="M20 2H4a2 2 0 0 0-2 2v18l4-4h14a2 2 0 0 0 2-2V4a2 2 0 0 0-2-2zm0 14H5.17L4 17.17V4h16v12zM11 5h2v3h3v2h-3v3h-2v-3H8V8h3z"/></symbol>
|
|
169
|
+
<symbol id="i-menu" viewBox="0 0 24 24"><path d="M3 18h18v-2H3v2zm0-5h18v-2H3v2zm0-7v2h18V6H3z"/></symbol>
|
|
170
|
+
<symbol id="i-down" viewBox="0 0 24 24"><path d="M7 10l5 5 5-5z"/></symbol>
|
|
171
|
+
<symbol id="i-right" viewBox="0 0 24 24"><path d="M10 6 8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z"/></symbol>
|
|
172
|
+
<symbol id="i-send" viewBox="0 0 24 24"><path d="M2.01 21 23 12 2.01 3 2 10l15 2-15 2z"/></symbol>
|
|
173
|
+
<symbol id="i-stop" viewBox="0 0 24 24"><path d="M6 6h12v12H6z"/></symbol>
|
|
174
|
+
<symbol id="i-doc" viewBox="0 0 24 24"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8l-6-6zM6 20V4h7v5h5v11H6z"/></symbol>
|
|
175
|
+
<symbol id="i-edit" viewBox="0 0 24 24"><path d="M3 17.25V21h3.75L17.81 9.94l-3.75-3.75L3 17.25zM20.71 7.04a1 1 0 0 0 0-1.41l-2.34-2.34a1 1 0 0 0-1.41 0l-1.83 1.83 3.75 3.75 1.83-1.83z"/></symbol>
|
|
176
|
+
<symbol id="i-archive" viewBox="0 0 24 24"><path d="M20.54 5.23 19.15 3.55A1.45 1.45 0 0 0 18 3H6c-.47 0-.88.21-1.16.55L3.46 5.23A1.97 1.97 0 0 0 3 6.5V19a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V6.5c0-.48-.17-.93-.46-1.27zM12 17.5 6.5 12H10v-2h4v2h3.5L12 17.5zM5.12 5l.81-1h12l.94 1H5.12z"/></symbol>
|
|
177
|
+
<symbol id="i-delete" viewBox="0 0 24 24"><path d="M6 19a2 2 0 0 0 2 2h8a2 2 0 0 0 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z"/></symbol>
|
|
178
|
+
<symbol id="i-check" viewBox="0 0 24 24"><path d="M9 16.17 4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z"/></symbol>
|
|
179
|
+
<symbol id="i-search" viewBox="0 0 24 24"><path d="M15.5 14h-.79l-.28-.27A6.47 6.47 0 0 0 16 9.5 6.5 6.5 0 1 0 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z"/></symbol>
|
|
180
|
+
</svg>
|
|
181
|
+
|
|
182
|
+
<div class="frames">
|
|
183
|
+
|
|
184
|
+
<!-- ===================== 1280 · main working state ===================== -->
|
|
185
|
+
<div class="frame">
|
|
186
|
+
<div class="frame-label">1280 px · chat with a completed answer, a streaming answer and the model picker open</div>
|
|
187
|
+
<div class="vp vp-1280">
|
|
188
|
+
<div class="ws">
|
|
189
|
+
<aside class="list" aria-label="Chats">
|
|
190
|
+
<div class="list-head">
|
|
191
|
+
<span class="list-title">Chats</span>
|
|
192
|
+
<span class="icon-btn" role="button" aria-label="New chat" title="New chat"><svg><use href="#i-new"/></svg></span>
|
|
193
|
+
</div>
|
|
194
|
+
<div class="items">
|
|
195
|
+
<div class="item active"><div><div class="item-title">Steering meeting follow-ups</div><div class="item-meta">Today 09:42</div></div><span class="icon-btn" aria-label="Chat actions" title="Chat actions"><svg><use href="#i-more"/></svg></span></div>
|
|
196
|
+
<div class="item hover"><div><div class="item-title">Funding call deadlines Q1 2027</div><div class="item-meta">Yesterday</div></div><span class="icon-btn" aria-label="Chat actions" title="Chat actions"><svg><use href="#i-more"/></svg></span></div>
|
|
197
|
+
<div class="item"><div><div class="item-title">Calibration targets for the Kigoma run</div><div class="item-meta">13 Oct</div></div><span class="icon-btn" aria-label="Chat actions"><svg><use href="#i-more"/></svg></span></div>
|
|
198
|
+
<div class="item"><div><div class="item-title">What the backup runbook says about restic</div><div class="item-meta">9 Oct</div></div><span class="icon-btn" aria-label="Chat actions"><svg><use href="#i-more"/></svg></span></div>
|
|
199
|
+
<div class="item"><div><div class="item-title">Ethics amendment wording</div><div class="item-meta">2 Oct</div></div><span class="icon-btn" aria-label="Chat actions"><svg><use href="#i-more"/></svg></span></div>
|
|
200
|
+
</div>
|
|
201
|
+
<div class="list-foot">
|
|
202
|
+
<div class="archived-toggle" role="button"><span>Archived</span><span class="count">7 <svg style="vertical-align:-4px"><use href="#i-right"/></svg></span></div>
|
|
203
|
+
</div>
|
|
204
|
+
<!-- row overflow menu, opened on the hovered row -->
|
|
205
|
+
<div class="menu" style="top: 118px; left: 214px;">
|
|
206
|
+
<div class="menu-item"><svg><use href="#i-edit"/></svg>Rename</div>
|
|
207
|
+
<div class="menu-item"><svg><use href="#i-archive"/></svg>Archive</div>
|
|
208
|
+
<div class="menu-sep"></div>
|
|
209
|
+
<div class="menu-item danger"><svg><use href="#i-delete"/></svg>Delete</div>
|
|
210
|
+
</div>
|
|
211
|
+
</aside>
|
|
212
|
+
|
|
213
|
+
<section class="main" aria-label="Chat">
|
|
214
|
+
<div class="bar">
|
|
215
|
+
<span class="bar-title">Steering meeting follow-ups</span>
|
|
216
|
+
<span class="picker-btn" role="button" aria-haspopup="listbox">Opus 5.5 <span class="sep">·</span> <span class="effort">High</span><svg><use href="#i-down"/></svg></span>
|
|
217
|
+
</div>
|
|
218
|
+
|
|
219
|
+
<div class="thread">
|
|
220
|
+
<div class="col">
|
|
221
|
+
<div class="msg-user">Which open points from the October steering meeting are still without an owner?</div>
|
|
222
|
+
<div class="msg-ai">
|
|
223
|
+
<div class="md">
|
|
224
|
+
<p>Three of the eight action items in the minutes have no owner assigned:</p>
|
|
225
|
+
<ul>
|
|
226
|
+
<li><b>Data-sharing agreement</b> with the regional health office, due before the field phase.</li>
|
|
227
|
+
<li><b>Re-run of the calibration</b> with the corrected referral distances (<code>v3.1</code> inputs).</li>
|
|
228
|
+
<li><b>Budget reallocation</b> of the travel line to transcription.</li>
|
|
229
|
+
</ul>
|
|
230
|
+
<div class="table-wrap"><table>
|
|
231
|
+
<thead><tr><th>Item</th><th>Due</th><th>Raised by</th></tr></thead>
|
|
232
|
+
<tbody>
|
|
233
|
+
<tr><td>Data-sharing agreement</td><td>30 Nov</td><td>Supervisor</td></tr>
|
|
234
|
+
<tr><td>Calibration re-run</td><td>15 Nov</td><td>Modelling team</td></tr>
|
|
235
|
+
<tr><td>Budget reallocation</td><td>31 Dec</td><td>Finance</td></tr>
|
|
236
|
+
</tbody>
|
|
237
|
+
</table></div>
|
|
238
|
+
</div>
|
|
239
|
+
<div class="sources" aria-label="Sources">
|
|
240
|
+
<span class="src" title="PhD/hram/meetings/2026-10-07 steering minutes.docx"><svg><use href="#i-doc"/></svg><span>2026-10-07 steering minutes.docx</span></span>
|
|
241
|
+
<span class="src" title="PhD/hram/planning/field phase plan.xlsx"><svg><use href="#i-doc"/></svg><span>field phase plan.xlsx</span></span>
|
|
242
|
+
</div>
|
|
243
|
+
<div class="turn-meta">Opus 5.5 · High</div>
|
|
244
|
+
</div>
|
|
245
|
+
|
|
246
|
+
<div class="msg-user">Draft a short email to the supervisor proposing owners for the first two.</div>
|
|
247
|
+
<div class="msg-ai">
|
|
248
|
+
<span class="searching"><svg style="width:13px;height:13px;fill:currentColor"><use href="#i-search"/></svg>Searching the knowledge base</span>
|
|
249
|
+
<div class="md">
|
|
250
|
+
<p>Here is a draft you can adapt:</p>
|
|
251
|
+
<p>Dear Grace, following up on the steering meeting of 7 October, I would suggest that I take the calibration re-run, since the corrected referral distances are already in the v3.1 inputs, and that<span class="caret"></span></p>
|
|
252
|
+
</div>
|
|
253
|
+
</div>
|
|
254
|
+
</div>
|
|
255
|
+
</div>
|
|
256
|
+
|
|
257
|
+
<div class="composer">
|
|
258
|
+
<div class="col">
|
|
259
|
+
<div class="input">Message</div>
|
|
260
|
+
<div class="actions">
|
|
261
|
+
<span class="btn outlined"><svg style="width:16px;height:16px;fill:currentColor"><use href="#i-stop"/></svg>Stop</span>
|
|
262
|
+
<span class="btn contained disabled send">Send<svg style="width:16px;height:16px"><use href="#i-send"/></svg></span>
|
|
263
|
+
</div>
|
|
264
|
+
</div>
|
|
265
|
+
</div>
|
|
266
|
+
</section>
|
|
267
|
+
</div>
|
|
268
|
+
|
|
269
|
+
<!-- model picker, opened from the bar -->
|
|
270
|
+
<div class="popover" role="listbox" aria-label="Model" style="right: 16px;">
|
|
271
|
+
<div class="grp">Claude Code subscription</div>
|
|
272
|
+
<div class="opt sel"><span class="check"><svg><use href="#i-check"/></svg></span><span class="name">Opus 5.5</span><span></span></div>
|
|
273
|
+
<div class="opt"><span></span><span class="name">Sonnet 5.5</span><span></span></div>
|
|
274
|
+
<div class="grp">Anthropic API</div>
|
|
275
|
+
<div class="opt"><span></span><span class="name">Sonnet 5.5</span><span class="cost">pay per use</span></div>
|
|
276
|
+
<div class="opt"><span></span><span class="name">Haiku 5.5</span><span class="cost">pay per use</span></div>
|
|
277
|
+
<div class="grp">OpenAI API</div>
|
|
278
|
+
<div class="opt"><span></span><span class="name">GPT-6 Luna</span><span class="cost">pay per use</span></div>
|
|
279
|
+
<div class="effort-row">
|
|
280
|
+
<span class="effort-label">Effort</span>
|
|
281
|
+
<div class="seg" role="radiogroup" aria-label="Effort"><span>Low</span><span>Medium</span><span class="on">High</span><span>Max</span></div>
|
|
282
|
+
</div>
|
|
283
|
+
</div>
|
|
284
|
+
</div>
|
|
285
|
+
</div>
|
|
286
|
+
|
|
287
|
+
<!-- ===================== 375 · thread ===================== -->
|
|
288
|
+
<div class="frame">
|
|
289
|
+
<div class="frame-label">375 px · thread (list and picker collapse into the bar)</div>
|
|
290
|
+
<div class="vp vp-375">
|
|
291
|
+
<div class="ws">
|
|
292
|
+
<section class="main" aria-label="Chat">
|
|
293
|
+
<div class="bar">
|
|
294
|
+
<span class="icon-btn" role="button" aria-label="Chats" title="Chats"><svg><use href="#i-menu"/></svg></span>
|
|
295
|
+
<span class="bar-title">Steering meeting follow-ups</span>
|
|
296
|
+
<span class="picker-btn" role="button">Opus 5.5 <span class="sep">·</span> <span class="effort">High</span></span>
|
|
297
|
+
<span class="icon-btn" role="button" aria-label="New chat" title="New chat"><svg><use href="#i-new"/></svg></span>
|
|
298
|
+
</div>
|
|
299
|
+
<div class="thread">
|
|
300
|
+
<div class="col">
|
|
301
|
+
<div class="msg-user">Which open points from the October steering meeting are still without an owner?</div>
|
|
302
|
+
<div class="msg-ai">
|
|
303
|
+
<div class="md">
|
|
304
|
+
<p>Three of the eight action items in the minutes have no owner assigned:</p>
|
|
305
|
+
<ul>
|
|
306
|
+
<li><b>Data-sharing agreement</b> with the regional health office, due before the field phase.</li>
|
|
307
|
+
<li><b>Re-run of the calibration</b> with the corrected referral distances (<code>v3.1</code> inputs).</li>
|
|
308
|
+
<li><b>Budget reallocation</b> of the travel line to transcription.</li>
|
|
309
|
+
</ul>
|
|
310
|
+
</div>
|
|
311
|
+
<div class="sources" aria-label="Sources">
|
|
312
|
+
<span class="src" title="PhD/hram/meetings/2026-10-07 steering minutes.docx"><svg><use href="#i-doc"/></svg><span>2026-10-07 steering minutes.docx</span></span>
|
|
313
|
+
<span class="src" title="PhD/hram/planning/field phase plan.xlsx"><svg><use href="#i-doc"/></svg><span>field phase plan.xlsx</span></span>
|
|
314
|
+
</div>
|
|
315
|
+
<div class="turn-meta">Opus 5.5 · High</div>
|
|
316
|
+
</div>
|
|
317
|
+
<div class="switch-mark">Sonnet 5.5 · Anthropic API · Medium</div>
|
|
318
|
+
<div class="msg-user">Shorter please, three bullets.</div>
|
|
319
|
+
<div class="msg-ai">
|
|
320
|
+
<div class="typing" aria-label="Answer is being written"><i></i><i></i><i></i></div>
|
|
321
|
+
</div>
|
|
322
|
+
</div>
|
|
323
|
+
</div>
|
|
324
|
+
<div class="composer">
|
|
325
|
+
<div class="col">
|
|
326
|
+
<div class="input">Message</div>
|
|
327
|
+
<div class="actions">
|
|
328
|
+
<span class="btn outlined"><svg style="width:16px;height:16px;fill:currentColor"><use href="#i-stop"/></svg>Stop</span>
|
|
329
|
+
<span class="btn contained disabled send">Send<svg style="width:16px;height:16px"><use href="#i-send"/></svg></span>
|
|
330
|
+
</div>
|
|
331
|
+
</div>
|
|
332
|
+
</div>
|
|
333
|
+
</section>
|
|
334
|
+
</div>
|
|
335
|
+
</div>
|
|
336
|
+
</div>
|
|
337
|
+
|
|
338
|
+
<!-- ===================== 375 · chat list drawer ===================== -->
|
|
339
|
+
<div class="frame">
|
|
340
|
+
<div class="frame-label">375 px · chat list as drawer</div>
|
|
341
|
+
<div class="vp vp-375">
|
|
342
|
+
<div class="ws">
|
|
343
|
+
<section class="main"><div class="bar"><span class="icon-btn"><svg><use href="#i-menu"/></svg></span><span class="bar-title">Steering meeting follow-ups</span></div><div class="thread"></div></section>
|
|
344
|
+
</div>
|
|
345
|
+
<div class="scrim"></div>
|
|
346
|
+
<div class="drawer">
|
|
347
|
+
<aside class="list" aria-label="Chats">
|
|
348
|
+
<div class="list-head">
|
|
349
|
+
<span class="list-title">Chats</span>
|
|
350
|
+
<span class="icon-btn" role="button" aria-label="New chat" title="New chat"><svg><use href="#i-new"/></svg></span>
|
|
351
|
+
</div>
|
|
352
|
+
<div class="items">
|
|
353
|
+
<div class="item active"><div><div class="item-title">Steering meeting follow-ups</div><div class="item-meta">Today 09:42</div></div><span class="icon-btn" aria-label="Chat actions"><svg><use href="#i-more"/></svg></span></div>
|
|
354
|
+
<div class="item"><div><div class="item-title">Funding call deadlines Q1 2027</div><div class="item-meta">Yesterday</div></div><span class="icon-btn" aria-label="Chat actions" style="opacity:1"><svg><use href="#i-more"/></svg></span></div>
|
|
355
|
+
<div class="item"><div><div class="item-title">Calibration targets for the Kigoma run</div><div class="item-meta">13 Oct</div></div><span class="icon-btn" aria-label="Chat actions" style="opacity:1"><svg><use href="#i-more"/></svg></span></div>
|
|
356
|
+
<div class="item"><div><div class="item-title">What the backup runbook says about restic</div><div class="item-meta">9 Oct</div></div><span class="icon-btn" aria-label="Chat actions" style="opacity:1"><svg><use href="#i-more"/></svg></span></div>
|
|
357
|
+
<div class="item"><div><div class="item-title">Ethics amendment wording</div><div class="item-meta">2 Oct</div></div><span class="icon-btn" aria-label="Chat actions" style="opacity:1"><svg><use href="#i-more"/></svg></span></div>
|
|
358
|
+
</div>
|
|
359
|
+
<div class="list-foot">
|
|
360
|
+
<div class="archived-toggle" role="button"><span>Archived</span><span class="count">7 <svg style="vertical-align:-4px"><use href="#i-right"/></svg></span></div>
|
|
361
|
+
</div>
|
|
362
|
+
</aside>
|
|
363
|
+
</div>
|
|
364
|
+
</div>
|
|
365
|
+
</div>
|
|
366
|
+
|
|
367
|
+
<!-- ===================== 375 · model picker sheet ===================== -->
|
|
368
|
+
<div class="frame">
|
|
369
|
+
<div class="frame-label">375 px · model and effort picker as bottom sheet</div>
|
|
370
|
+
<div class="vp vp-375">
|
|
371
|
+
<div class="ws">
|
|
372
|
+
<section class="main"><div class="bar"><span class="icon-btn"><svg><use href="#i-menu"/></svg></span><span class="bar-title">Steering meeting follow-ups</span><span class="picker-btn">Opus 5.5 <span class="sep">·</span> <span class="effort">High</span></span></div><div class="thread"></div></section>
|
|
373
|
+
</div>
|
|
374
|
+
<div class="scrim"></div>
|
|
375
|
+
<div class="sheet" role="listbox" aria-label="Model">
|
|
376
|
+
<div class="grabber"></div>
|
|
377
|
+
<div class="grp">Claude Code subscription</div>
|
|
378
|
+
<div class="opt sel"><span class="check"><svg><use href="#i-check"/></svg></span><span class="name">Opus 5.5</span><span></span></div>
|
|
379
|
+
<div class="opt"><span></span><span class="name">Sonnet 5.5</span><span></span></div>
|
|
380
|
+
<div class="grp">Anthropic API</div>
|
|
381
|
+
<div class="opt"><span></span><span class="name">Sonnet 5.5</span><span class="cost">pay per use</span></div>
|
|
382
|
+
<div class="opt"><span></span><span class="name">Haiku 5.5</span><span class="cost">pay per use</span></div>
|
|
383
|
+
<div class="grp">OpenAI API</div>
|
|
384
|
+
<div class="opt"><span></span><span class="name">GPT-6 Luna</span><span class="cost">pay per use</span></div>
|
|
385
|
+
<div class="effort-row">
|
|
386
|
+
<span class="effort-label">Effort</span>
|
|
387
|
+
<div class="seg" role="radiogroup" aria-label="Effort"><span>Low</span><span>Medium</span><span class="on">High</span><span class="off" aria-disabled="true">Max</span></div>
|
|
388
|
+
</div>
|
|
389
|
+
</div>
|
|
390
|
+
</div>
|
|
391
|
+
</div>
|
|
392
|
+
|
|
393
|
+
<!-- ===================== 1280 · edge states ===================== -->
|
|
394
|
+
<div class="frame">
|
|
395
|
+
<div class="frame-label">1280 px · edge states (each shown inside the thread column)</div>
|
|
396
|
+
<div class="vp vp-1280">
|
|
397
|
+
<div class="states">
|
|
398
|
+
<div class="state">
|
|
399
|
+
<div class="state-label">New chat, no messages yet</div>
|
|
400
|
+
<div class="state-body">
|
|
401
|
+
<div class="empty"><h3>New chat</h3><span>Opus 5.5 · High</span></div>
|
|
402
|
+
<div class="input focus">Message</div>
|
|
403
|
+
<div class="actions"><span class="btn contained disabled send">Send<svg style="width:16px;height:16px"><use href="#i-send"/></svg></span></div>
|
|
404
|
+
</div>
|
|
405
|
+
</div>
|
|
406
|
+
<div class="state">
|
|
407
|
+
<div class="state-label">Usage limit of the selected model reached</div>
|
|
408
|
+
<div class="state-body">
|
|
409
|
+
<div class="msg-user" style="max-width:90%">Summarise the restic section.</div>
|
|
410
|
+
<div class="notice warn"><span class="grow">Usage limit reached for Opus 5.5. Choose another model or try again later.</span><span class="btn text">Change model</span></div>
|
|
411
|
+
</div>
|
|
412
|
+
</div>
|
|
413
|
+
<div class="state">
|
|
414
|
+
<div class="state-label">Answer interrupted (provider error, timeout or stop)</div>
|
|
415
|
+
<div class="state-body">
|
|
416
|
+
<div class="msg-user" style="max-width:90%">List the deadlines in November.</div>
|
|
417
|
+
<div class="msg-ai"><div class="md"><p>There are two deadlines in November: the data-sharing agreement</p></div><span class="chip stale"><span class="dot"></span>Interrupted</span></div>
|
|
418
|
+
<div class="notice err"><span class="grow">The answer could not be completed.</span><span class="btn text">Retry</span></div>
|
|
419
|
+
</div>
|
|
420
|
+
</div>
|
|
421
|
+
<div class="state">
|
|
422
|
+
<div class="state-label">Connection lost</div>
|
|
423
|
+
<div class="state-body">
|
|
424
|
+
<span class="chip warn"><span class="dot"></span>Reconnecting</span>
|
|
425
|
+
<div class="input filled">Which items are due before the field phase?</div>
|
|
426
|
+
<div class="actions"><span class="btn contained disabled send">Send<svg style="width:16px;height:16px"><use href="#i-send"/></svg></span></div>
|
|
427
|
+
</div>
|
|
428
|
+
</div>
|
|
429
|
+
<div class="state">
|
|
430
|
+
<div class="state-label">No model configured on this server</div>
|
|
431
|
+
<div class="state-body">
|
|
432
|
+
<div class="empty"><h3>Chat is not available</h3><span>No language model is configured on this server.</span></div>
|
|
433
|
+
</div>
|
|
434
|
+
</div>
|
|
435
|
+
<div class="state">
|
|
436
|
+
<div class="state-label">Archived chat opened</div>
|
|
437
|
+
<div class="state-body">
|
|
438
|
+
<span class="chip stale">Archived</span>
|
|
439
|
+
<div class="msg-user" style="max-width:90%">What the backup runbook says about restic</div>
|
|
440
|
+
<div class="actions"><span class="btn outlined">Restore</span></div>
|
|
441
|
+
</div>
|
|
442
|
+
</div>
|
|
443
|
+
</div>
|
|
444
|
+
</div>
|
|
445
|
+
</div>
|
|
446
|
+
|
|
447
|
+
</div>
|