@zq-silk/yui 2.15.0 → 2.17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (104) hide show
  1. package/dist/cli/commandCatalog.js +17 -11
  2. package/dist/cli/interactionCandidates.js +20 -5
  3. package/dist/cli/interactionPolicy.js +5 -4
  4. package/dist/cli/roleWizard.js +7 -0
  5. package/dist/commands/globalRoleCommands.js +13 -2
  6. package/dist/commands/operatorCommands.js +2 -0
  7. package/dist/commands/profileCommands.js +19 -2
  8. package/dist/commands/roleConfiguration.js +3 -0
  9. package/dist/commands/taskCommands.js +16 -0
  10. package/dist/commands/taskRoleRuntimeStatus.js +3 -0
  11. package/dist/controller/agentJobControl.js +9 -1
  12. package/dist/controller/fileSchedulerStoreAdapter.js +35 -4
  13. package/dist/controller/globalInputDelivery.js +14 -8
  14. package/dist/controller/providerRetryAdmission.js +9 -0
  15. package/dist/controller/providerRetryDelivery.js +16 -0
  16. package/dist/controller/runtime.js +14 -0
  17. package/dist/controller/runtimeLaunchCoordinator.js +3 -1
  18. package/dist/executor/fileRoleLaunchPlanner.js +3 -0
  19. package/dist/message/messageContinuation.js +4 -0
  20. package/dist/output/rolePresentation.js +3 -0
  21. package/dist/profile/agentProfile.js +8 -0
  22. package/dist/profile/agentProfileRuntime.js +16 -1
  23. package/dist/review/reviewDecision.js +6 -0
  24. package/dist/role/availability.js +28 -0
  25. package/dist/role/role.js +6 -0
  26. package/dist/runtime/codexNativeAccess.js +21 -4
  27. package/dist/runtime/tmuxAdapters.js +5 -0
  28. package/dist/scheduler/activeRoleRunDelivery.js +9 -0
  29. package/dist/scheduler/leaderWakeupProcessor.js +8 -1
  30. package/dist/scheduler/roleRunLiveness.js +3 -0
  31. package/dist/storage/sqliteSchema.js +10 -0
  32. package/dist/storage/storageVersions.js +1 -1
  33. package/dist/web/assets/client/app/catalog.js +40 -14
  34. package/dist/web/assets/client/app/main.js +43 -26
  35. package/dist/web/assets/client/app/manage.js +18 -0
  36. package/dist/web/assets/client/app/selection.js +4 -1
  37. package/dist/web/assets/client/app/taskView.js +29 -16
  38. package/dist/web/assets/client/i18n/en.js +72 -21
  39. package/dist/web/assets/client/i18n/zh-CN.js +72 -21
  40. package/dist/web/assets/client/index.js +6 -0
  41. package/dist/web/assets/client/layout/manageShell.js +30 -8
  42. package/dist/web/assets/client/layout/shortcuts.js +9 -5
  43. package/dist/web/assets/client/layout/sidebarNav.js +147 -0
  44. package/dist/web/assets/client/layout/sizing.js +5 -2
  45. package/dist/web/assets/client/layout/workspace.js +193 -107
  46. package/dist/web/assets/client/lib/motion.js +59 -0
  47. package/dist/web/assets/client/lib/prefs.js +29 -2
  48. package/dist/web/assets/client/lib/theme.js +11 -4
  49. package/dist/web/assets/client/ui/primitives.js +40 -0
  50. package/dist/web/assets/client/views/dock/conversation.js +421 -123
  51. package/dist/web/assets/client/views/dock/session.js +229 -0
  52. package/dist/web/assets/client/views/dock/terminal.js +48 -39
  53. package/dist/web/assets/client/views/overview.js +8 -5
  54. package/dist/web/assets/client/views/task/page.js +7 -17
  55. package/dist/web/assets/shared/brand.js +22 -0
  56. package/dist/web/assets/shared/geometry.js +7 -1
  57. package/dist/web/assets/shared/icons.js +4 -0
  58. package/dist/web/assets/shared/motion.js +74 -0
  59. package/dist/web/assets/shell/appRail.js +14 -0
  60. package/dist/web/assets/shell/dialogs.js +1 -0
  61. package/dist/web/assets/shell/dock.js +19 -24
  62. package/dist/web/assets/shell/index.js +6 -2
  63. package/dist/web/assets/shell/login.js +9 -8
  64. package/dist/web/assets/shell/manage.js +32 -20
  65. package/dist/web/assets/shell/settingsContent.js +1 -1
  66. package/dist/web/assets/shell/sidebar.js +16 -23
  67. package/dist/web/assets/styles/base.js +1 -1
  68. package/dist/web/assets/styles/index.js +2 -0
  69. package/dist/web/assets/styles/layout/responsive.js +63 -19
  70. package/dist/web/assets/styles/layout/workspace.js +53 -16
  71. package/dist/web/assets/styles/motion.js +51 -0
  72. package/dist/web/assets/styles/tokens.js +5 -3
  73. package/dist/web/assets/styles/ui/controls.js +1 -1
  74. package/dist/web/assets/styles/ui/forms.js +1 -1
  75. package/dist/web/assets/styles/ui/surfaces.js +1 -2
  76. package/dist/web/assets/styles/views/conversation.js +97 -18
  77. package/dist/web/assets/styles/views/dock.js +34 -2
  78. package/dist/web/assets/styles/views/login.js +16 -13
  79. package/dist/web/assets/styles/views/manage.js +25 -42
  80. package/dist/web/assets/styles/views/page.js +2 -3
  81. package/dist/web/assets/styles/views/records.js +1 -1
  82. package/dist/web/assets/styles/views/settings.js +1 -1
  83. package/dist/web/assets/styles/views/sidebar.js +25 -20
  84. package/dist/web/assets/styles/views/task.js +8 -15
  85. package/dist/web/assets/styles/views/terminal.js +13 -9
  86. package/dist/web/webConversation.js +1 -0
  87. package/dist/web/webSettings.js +10 -2
  88. package/docs/managed-turn-and-session-runtime.md +10 -0
  89. package/docs/managed-turn-and-session-runtime.zh-CN.md +6 -0
  90. package/docs/release-workflow.md +46 -0
  91. package/docs/release-workflow.zh-CN.md +34 -0
  92. package/docs/roles-and-configuration.md +45 -1
  93. package/docs/roles-and-configuration.zh-CN.md +35 -0
  94. package/docs/storage-baseline.md +6 -1
  95. package/docs/storage-baseline.zh-CN.md +5 -1
  96. package/docs/testing/review-evaluation.md +35 -1
  97. package/docs/testing/review-evaluation.zh-CN.md +25 -1
  98. package/docs/testing/verification-levels.md +2 -2
  99. package/docs/testing/verification-levels.zh-CN.md +2 -2
  100. package/package.json +1 -1
  101. package/skills/yui-leader/VERSION +1 -1
  102. package/skills/yui-leader/references/execution.md +19 -8
  103. package/skills/yui-reviewer/SKILL.md +13 -2
  104. package/skills/yui-reviewer/VERSION +1 -1
@@ -1,4 +1,5 @@
1
1
  import { DIVIDER_WIDTH, DOCK } from "../shared/geometry.js";
2
+ import { motionTokenStyles } from "../shared/motion.js";
2
3
  import { themeTokenStyles } from "../shared/themes.js";
3
4
  /*
4
5
  * DESIGN TOKENS
@@ -6,8 +7,9 @@ import { themeTokenStyles } from "../shared/themes.js";
6
7
  * Geometry, type, radii, motion and the focus ring are theme-independent and
7
8
  * live once on :root. Colour and effect tokens come from the theme registry
8
9
  * (shared/themes.ts), one block per theme, so switching a theme can never move
9
- * or resize anything. Layout widths come from shared/geometry.ts, the same
10
- * source the client layout controller clamps against.
10
+ * or resize anything. Layout widths come from shared/geometry.ts and motion
11
+ * (durations, easings, stacking layers) from shared/motion.ts, the same
12
+ * sources the client scripts read.
11
13
  */
12
14
  export const TOKEN_STYLES = `
13
15
  :root{
@@ -17,7 +19,7 @@ export const TOKEN_STYLES = `
17
19
  --r-xs:5px;--r-sm:7px;--r-md:10px;--r-lg:14px;--r-pill:999px;
18
20
  --sidebar-w:clamp(260px,21vw,312px);--dock-w:${DOCK.initial}px;--divider-w:${DIVIDER_WIDTH}px;
19
21
  --center-max:880px;--header-h:56px;--gutter:clamp(16px,3vw,40px);
20
- --t-fast:120ms;--t-med:220ms;--ease:cubic-bezier(.2,.8,.2,1);
22
+ ${motionTokenStyles()}
21
23
  --focus:0 0 0 2px var(--canvas),0 0 0 4px var(--accent-line);
22
24
  }
23
25
  ${themeTokenStyles()}
@@ -27,7 +27,7 @@ export const CONTROL_STYLES = `
27
27
  .btn-link:hover:not(:disabled){background:transparent;text-decoration:underline;text-underline-offset:3px}
28
28
  .link-btn{justify-self:start;padding:0;border:0;background:none;color:var(--accent);font-size:var(--fs-xs);font-weight:500}
29
29
  .link-btn:hover{text-decoration:underline;text-underline-offset:3px}
30
- .icon-btn{display:inline-grid;place-items:center;width:32px;height:32px;flex:none;padding:0;border:0;border-radius:var(--r-sm);background:transparent;color:var(--ink-3);transition:background var(--t-fast),color var(--t-fast)}
30
+ .icon-btn{display:inline-grid;place-items:center;width:32px;height:32px;flex:none;padding:0;border:0;border-radius:var(--r-sm);background:transparent;color:var(--ink-3);transition:background var(--t-fast),color var(--t-fast),transform var(--t-fast) var(--ease)}
31
31
  .icon-btn:hover:not(:disabled){background:var(--surface-3);color:var(--ink)}
32
32
  .icon-btn[aria-pressed="true"]{background:var(--accent-soft);color:var(--accent)}
33
33
  .icon-btn:disabled{opacity:.4}
@@ -41,6 +41,6 @@ export const FORM_STYLES = `
41
41
  .shortcut-list dd{margin:0}
42
42
 
43
43
  /* Toast */
44
- .toast{position:fixed;left:50%;bottom:24px;z-index:90;max-width:min(520px,calc(100vw - 32px));padding:10px 16px;border:1px solid var(--line-2);border-radius:var(--r-md);background:var(--surface-2);color:var(--ink);box-shadow:var(--shadow-2);font-size:var(--fs-sm);opacity:0;transform:translate(-50%,8px);pointer-events:none;transition:opacity var(--t-med),transform var(--t-med) var(--ease)}
44
+ .toast{position:fixed;left:50%;bottom:24px;z-index:var(--z-toast);max-width:min(520px,calc(100vw - 32px));padding:10px 16px;border:1px solid var(--line-2);border-radius:var(--r-md);background:var(--surface-2);color:var(--ink);box-shadow:var(--shadow-2);font-size:var(--fs-sm);opacity:0;transform:translate(-50%,8px);pointer-events:none;transition:opacity var(--t-base) var(--ease),transform var(--t-base) var(--ease)}
45
45
  .toast.show{opacity:1;transform:translate(-50%,0)}
46
46
  `;
@@ -108,8 +108,7 @@ details[open]>summary .disclosure-chevron{transform:rotate(90deg)}
108
108
  .show-more:hover,.pager-clear:hover{color:var(--accent);border-color:var(--accent-line)}
109
109
  .show-more{justify-self:start;display:inline-flex;align-items:center;height:30px;padding:0 12px;font-weight:500}
110
110
  .loading-block{display:flex;align-items:center;gap:10px;padding:32px 8px;color:var(--ink-3)}
111
- .spinner{width:14px;height:14px;border-radius:50%;border:2px solid var(--line-3);border-top-color:var(--accent);animation:spin .8s linear infinite}
112
- @keyframes spin{to{transform:rotate(360deg)}}
111
+ .spinner{width:14px;height:14px;border-radius:50%;border:2px solid var(--line-3);border-top-color:var(--accent);animation:m-spin .8s linear infinite}
113
112
 
114
113
  /* Metrics */
115
114
  .metric{display:grid;gap:4px;align-content:start;min-width:0;padding:12px 14px;border:1px solid var(--line);border-radius:var(--r-md);background:var(--surface)}
@@ -6,21 +6,55 @@
6
6
  */
7
7
  export const CONVERSATION_STYLES = `
8
8
  #dock-conversation{min-width:0}
9
+ /* Session page: one view at a time (chat or terminal), rebuilt on a mode switch */
10
+ .session-view{flex:1;min-height:0;min-width:0;display:flex;flex-direction:column}
11
+ .sp-modes{flex:none}
12
+ .sp-modes .seg-btn{gap:5px}
13
+ .sp-modes .seg-btn .icon{width:14px;height:14px;flex:none}
14
+ .sp-modes .seg-btn[aria-disabled="true"]{opacity:.45}
15
+ @container dock (max-width:440px){.sp-modes .seg-btn>span{display:none}.sp-modes .seg-btn{padding:0 7px}}
9
16
  .cv-head{flex:none;display:flex;align-items:center;gap:6px;padding:8px 10px 4px 8px}
10
- .cv-picker{flex:1;min-width:0;display:flex;align-items:center;gap:6px}
11
- /* background-color only: the shorthand would drop the global select arrow */
12
- .cv-session{flex:1;min-width:0;max-width:100%;height:30px;padding:0 28px 0 8px;border:0;background-color:transparent;color:var(--ink);font-weight:600;font-size:var(--fs-md);text-overflow:ellipsis;cursor:pointer;border-radius:var(--r-sm)}
13
- .cv-session:hover,.cv-session:focus{background-color:var(--surface-3);border:0;box-shadow:none}
14
- /* The global select:focus rule resets the whole background, so the arrow is restated for every state */
15
- .cv-session,.cv-session:hover,.cv-session:focus{background-image:linear-gradient(45deg,transparent 50%,var(--ink-3) 50%),linear-gradient(135deg,var(--ink-3) 50%,transparent 50%);background-position:calc(100% - 15px) 50%,calc(100% - 11px) 50%;background-size:4px 4px;background-repeat:no-repeat}
16
- .cv-status{flex:none;display:flex;align-items:center;gap:6px;margin:0;padding:0 16px 6px;color:var(--ink-3);font-size:var(--fs-xs)}
17
+ .cv-head .spacer{flex:1 1 0;min-width:0}
18
+ /* Session picker: one readable name; current and previous Sessions on demand */
19
+ .cv-pop.cv-picker{flex:0 1 auto;min-width:0;max-width:100%}
20
+ .cv-picker-btn{display:flex;align-items:center;gap:4px;min-width:0;height:30px;padding:0 6px 0 8px;border-radius:var(--r-sm);color:var(--ink);font-weight:600;font-size:var(--fs-md);cursor:pointer}
21
+ .cv-picker-btn:hover,.cv-picker[open]>.cv-picker-btn{background:var(--surface-3)}
22
+ .cv-picker-name{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
23
+ .cv-picker-chevron{width:13px;height:13px;flex:none;color:var(--ink-3)}
24
+ .cv-picker>.cv-popbody{left:0;top:calc(100% + 6px);width:min(320px,calc(100vw - 32px))}
25
+ .cv-session-list{display:grid;gap:1px}
26
+ .cv-session-opt{display:flex;align-items:center;gap:8px;width:100%;min-width:0;padding:6px 8px;border:0;border-radius:var(--r-sm);background:transparent;color:var(--ink);text-align:left;cursor:pointer}
27
+ .cv-session-opt:hover,.cv-session-opt[aria-selected=true]{background:var(--surface-3)}
28
+ .cv-so-dot{width:7px;height:7px;border-radius:50%;flex:none;background:var(--idle)}
29
+ .cv-so-dot.is-active{background:var(--ok)}
30
+ .cv-so-dot.is-failed{background:var(--bad)}
31
+ .cv-so-text{flex:1;min-width:0;display:grid}
32
+ .cv-so-main,.cv-so-meta{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
33
+ .cv-so-main{font-size:var(--fs-sm)}
34
+ .cv-so-meta{color:var(--ink-3);font-size:var(--fs-2xs)}
35
+ .cv-so-check{width:14px;height:14px;flex:none}
36
+ .cv-more-sessions{justify-self:start}
37
+ .cv-back{display:inline-flex;align-items:center;gap:3px;flex:none;white-space:nowrap}
38
+ .cv-back .icon{width:13px;height:13px}
39
+ .cv-back[hidden]{display:none}
40
+ /* Status: a dot plus one word; the reason and observation time live in the tooltip */
41
+ .cv-status{flex:0 1 auto;min-width:0;max-width:40%;display:inline-flex;align-items:center;gap:6px;color:var(--ink-3);font-size:var(--fs-xs);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
17
42
  .cv-status::before{content:"";width:7px;height:7px;border-radius:50%;background:var(--idle);flex:none}
18
43
  .cv-status.is-active::before{background:var(--ok)}
19
44
  .cv-status.is-waiting::before{background:var(--warn)}
20
45
  .cv-status.is-failed::before,.cv-status.is-unknown::before{background:var(--bad)}
21
46
  .cv-status:empty{display:none}
22
- .cv-older{flex:none;display:flex;justify-content:center}
23
- .cv-older:empty{display:none}
47
+ /* Details menu: labelled facts, then the exact identity for copying */
48
+ .cv-facts{display:grid;grid-template-columns:auto minmax(0,1fr);gap:4px 10px;margin:0;padding:0 4px;font-size:var(--fs-xs)}
49
+ .cv-facts dt{color:var(--ink-3)}
50
+ .cv-facts dd{margin:0;min-width:0;display:grid;color:var(--ink);overflow-wrap:anywhere}
51
+ .cv-facts small{color:var(--ink-4);font-size:var(--fs-2xs)}
52
+ .cv-identity-row{display:flex;align-items:flex-start;gap:6px;padding:0 4px;min-width:0}
53
+ .cv-identity-row .cv-identity{flex:1;min-width:0;font-family:var(--font-mono)}
54
+ .cv-identity-row .cv-link{display:inline-flex;align-items:center;gap:3px;flex:none}
55
+ .cv-identity-row .icon{width:12px;height:12px}
56
+ .cv-older{position:absolute;z-index:1;top:6px;left:50%;transform:translateX(-50%);padding:3px 10px;border:1px solid var(--line-2);border-radius:var(--r-pill);background:var(--surface-2);box-shadow:var(--shadow-1)}
57
+ .cv-older[hidden]{display:none}
24
58
  .cv-stage{position:relative;flex:1;min-height:0;display:flex;flex-direction:column}
25
59
  .cv-stage .feed{gap:18px;padding:12px 16px 20px}
26
60
  .cv-jump{position:absolute;left:50%;bottom:10px;transform:translateX(-50%);width:32px;height:32px;display:grid;place-items:center;padding:0;border:1px solid var(--line-2);border-radius:50%;background:var(--surface-2);color:var(--ink);box-shadow:var(--shadow-1);cursor:pointer}
@@ -29,14 +63,16 @@ export const CONVERSATION_STYLES = `
29
63
  .cv-note{margin:0;color:var(--ink-3);font-size:var(--fs-xs);overflow-wrap:anywhere}
30
64
  .cv-link{padding:2px 4px;border:0;background:none;color:var(--ink-3);font-size:var(--fs-xs);cursor:pointer;border-radius:var(--r-xs)}
31
65
  .cv-link:hover{color:var(--ink);background:var(--surface-3)}
32
- .cv-link[hidden],.cv-stop[hidden],.cv-chip[hidden]{display:none}
66
+ .cv-link[hidden],.cv-stop[hidden],.cv-sub[hidden],.cv-pop[hidden]{display:none}
33
67
  .cv-code{margin:6px 0 0;padding:8px 10px;max-height:200px;overflow:auto;white-space:pre-wrap;overflow-wrap:anywhere;border-radius:var(--r-sm);background:var(--sunken);font:var(--fs-xs)/1.5 var(--font-mono)}
68
+ .cv-note:empty{display:none}
34
69
  .cv-identity{margin:0;color:var(--ink-4);font-size:var(--fs-2xs);overflow-wrap:anywhere}
35
70
  /* Messages */
36
71
  .cv-msg{min-width:0;overflow-wrap:anywhere}
37
72
  .cv-user{align-self:flex-end;max-width:88%;display:flex;flex-direction:column;align-items:flex-end;gap:4px}
38
73
  .cv-bubble{padding:9px 14px;border-radius:18px;background:var(--info-soft);color:var(--ink);font-size:var(--fs-md);line-height:1.5}
39
74
  .cv-tag{color:var(--ink-4);font-size:var(--fs-2xs)}
75
+ /* A leading tagged context block folds to one line; the raw text stays one click away */
40
76
  .cv-assistant{position:relative;font-size:var(--fs-md);line-height:1.6}
41
77
  /* Copy: always visible under the newest message, a hover badge on older ones */
42
78
  .cv-actions{display:flex;gap:2px;position:absolute;top:-6px;right:0;opacity:0;transition:opacity var(--t-fast)}
@@ -75,14 +111,27 @@ export const CONVERSATION_STYLES = `
75
111
  /* An empty draft reads as inactive, like the reference composers */
76
112
  .cv-box:has(.cv-input:placeholder-shown) .cv-send{background:var(--surface-3);color:var(--ink-4)}
77
113
  .cv-send:disabled{background:var(--surface-3);color:var(--ink-4);cursor:default;opacity:1}
78
- .cv-chip{display:inline-flex;align-items:center;gap:5px;min-width:0;padding:3px 8px;border-radius:var(--r-pill);background:var(--tone-soft,var(--warn-soft));color:var(--tone,var(--warn));font-size:var(--fs-xs)}
79
- .cv-chip .icon{width:13px;height:13px;flex:none}
80
- .cv-chip span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
81
- .cv-pill{display:inline-flex;align-items:center;gap:4px;max-width:180px;height:28px;padding:0 8px;border-radius:var(--r-pill);color:var(--ink-3);font-size:var(--fs-sm);list-style:none;cursor:pointer}
114
+ .cv-notice{display:flex;align-items:center;gap:6px;min-width:0;margin:0;padding:0 6px;color:var(--ink-3);font-size:var(--fs-xs)}
115
+ .cv-notice.is-warn{color:var(--warn)}
116
+ .cv-notice[hidden]{display:none}
117
+ .cv-notice .icon{width:13px;height:13px;flex:none}
118
+ .cv-notice>span{min-width:0;overflow-wrap:anywhere}
119
+ .cv-notice .cv-link{flex:none;margin-left:auto}
120
+ .cv-pill{display:inline-flex;align-items:center;gap:4px;max-width:220px;height:28px;padding:0 8px;border-radius:var(--r-pill);color:var(--ink-3);font-size:var(--fs-sm);list-style:none;cursor:pointer}
82
121
  .cv-pill::-webkit-details-marker{display:none}
83
122
  .cv-pill:hover,.cv-pop[open]>.cv-pill{background:var(--surface-3);color:var(--ink)}
84
123
  .cv-pill .icon{width:13px;height:13px;flex:none}
124
+ .cv-model-state{flex:none;font-size:var(--fs-xs);font-weight:600;color:var(--ink-2)}
125
+ .cv-model-state[hidden]{display:none}
126
+ .cv-model[data-state=pending] .cv-model-state{color:var(--accent,var(--info))}
127
+ /* The model menu shrinks before the send button is pushed out; the state word stays whole and the model name ellipsizes */
128
+ .cv-pop.cv-model{flex:0 1 auto;min-width:0}
129
+ .cv-model>.cv-pill{max-width:min(220px,100%);box-sizing:border-box}
85
130
  .cv-model-label{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
131
+ .cv-model-dot{width:6px;height:6px;border-radius:50%;flex:none;background:var(--ok)}
132
+ .cv-model[data-state=unknown] .cv-model-dot{background:var(--warn)}
133
+ .cv-model[data-state=pending] .cv-model-dot{background:var(--accent,var(--info))}
134
+ .cv-model[data-state=unknown] .cv-model-label{font-style:italic}
86
135
  .cv-hint{display:flex;flex-wrap:wrap;align-items:center;gap:2px 8px;padding:0 6px;min-width:0}
87
136
  .cv-hint:empty{display:none}
88
137
  .cv-hint .cv-note:empty{display:none}
@@ -98,9 +147,39 @@ export const CONVERSATION_STYLES = `
98
147
  .cv-pop{position:relative;flex:none}
99
148
  .cv-pop>summary{list-style:none}
100
149
  .cv-pop>summary::-webkit-details-marker{display:none}
101
- .cv-popbody{position:absolute;z-index:20;display:grid;gap:8px;width:min(300px,calc(100vw - 32px));max-height:min(420px,60vh);overflow:auto;padding:10px;border:1px solid var(--line-2);border-radius:var(--r-lg);background:var(--surface-2);box-shadow:var(--shadow-2);box-sizing:border-box}
150
+ .cv-popbody{position:absolute;z-index:var(--z-popover);display:grid;gap:8px;width:min(300px,calc(100vw - 32px));max-height:min(420px,60vh);overflow:auto;padding:10px;border:1px solid var(--line-2);border-radius:var(--r-lg);background:var(--surface-2);box-shadow:var(--shadow-2);box-sizing:border-box}
102
151
  .cv-attach>.cv-popbody{left:0;bottom:calc(100% + 8px)}
103
- .cv-model>.cv-popbody{right:0;bottom:calc(100% + 8px)}
152
+ .cv-model>.cv-popbody{right:0;bottom:calc(100% + 8px);width:min(300px,calc(100vw - 24px));gap:0;padding:6px}
153
+ /* Model picker: two quiet facts, a short list, one action row. Background
154
+ polls update text in place and never toggle these controls. */
155
+ .cv-model .cv-model-facts{grid-template-columns:auto minmax(0,1fr);gap:5px 14px;align-items:baseline;margin:0;padding:8px 10px 10px;font-size:var(--fs-xs)}
156
+ .cv-model .cv-model-facts dt{color:var(--ink-3);white-space:nowrap}
157
+ .cv-model .cv-model-facts dd{display:flex;align-items:baseline;gap:8px;min-width:0}
158
+ .cv-mf-value{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--ink);font-size:var(--fs-sm);font-weight:600}
159
+ .cv-mf-value.is-empty{color:var(--ink-3);font-weight:400}
160
+ .cv-model .cv-model-facts .cv-mf-note{flex:none;margin-left:auto;color:var(--ink-4);font-size:var(--fs-2xs);white-space:nowrap}
161
+ .cv-mf-note[hidden]{display:none}
162
+ .cv-model[data-state=pending] .cv-mf-note{color:var(--accent)}
163
+ .cv-model .cv-options{gap:2px;max-height:216px;overflow:auto;min-height:0;padding:6px 0;border-top:1px solid var(--line);border-bottom:1px solid var(--line)}
164
+ .cv-model .cv-options:empty{display:none}
165
+ .cv-model .cv-option{gap:10px;min-height:36px;padding:6px 10px;font-size:var(--fs-sm);transition:background var(--t-fast),color var(--t-fast)}
166
+ .cv-model .cv-option:hover:not(:disabled){background:var(--surface-3)}
167
+ .cv-model .cv-option.is-selected{background:var(--accent-soft)}
168
+ .cv-model .cv-option.is-selected .cv-option-name{font-weight:600}
169
+ .cv-model .cv-option.is-selected .icon{color:var(--accent)}
170
+ .cv-model .cv-option:disabled{cursor:default;color:var(--ink-3)}
171
+ .cv-model .cv-option.is-selected:hover:not(:disabled){background:var(--accent-soft)}
172
+ .cv-model .cv-option:disabled:not(.is-selected){background:transparent}
173
+ .cv-option-mark{width:6px;height:6px;flex:none;border-radius:50%;background:transparent}
174
+ .cv-option.is-current .cv-option-mark{background:var(--ok)}
175
+ .cv-model .cv-option-id{display:block;flex:0 1 auto;min-width:0;max-width:45%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--ink-4);font:var(--fs-2xs)/1.4 var(--font-mono)}
176
+ .cv-model .cv-pop-actions{flex-wrap:wrap;justify-content:flex-end;gap:6px 8px;padding:8px 4px 2px 10px}
177
+ .cv-model-notes{flex:1 1 140px;min-width:0;display:grid;gap:2px}
178
+ .cv-model-notes:not(:has(.cv-note:not(:empty))){display:none}
179
+ .cv-model .cv-pop-actions .cv-link{flex:none}
180
+ .cv-model .cv-note:empty{display:none}
181
+ .cv-apply{height:28px;padding:0 12px;flex:none}
182
+ .cv-apply:disabled{background:var(--surface-3);color:var(--ink-4);opacity:1}
104
183
  .cv-menu>.cv-popbody{right:0;top:calc(100% + 6px)}
105
184
  .cv-pop-title{margin:0;padding:0 4px;color:var(--ink-3);font-size:var(--fs-xs)}
106
185
  .cv-pop-actions{display:flex;align-items:center;justify-content:space-between;gap:8px}
@@ -123,11 +202,11 @@ export const CONVERSATION_STYLES = `
123
202
  .cv-card label{display:grid;gap:4px}
124
203
  .cv-card input,.cv-card select,.cv-card textarea{min-width:0;max-width:100%;box-sizing:border-box}
125
204
  /* Keyboard focus */
126
- .cv-iconbtn:focus-visible,.cv-send:focus-visible,.cv-stop:focus-visible,.cv-jump:focus-visible,.cv-pill:focus-visible,.cv-option:focus-visible,.cv-link:focus-visible,.cv-cmd:focus-visible,.cv-x:focus-visible,.cv-activity>summary:focus-visible,.cv-sub>summary:focus-visible{outline:none;box-shadow:var(--focus)}
127
- .cv-session:focus-visible{box-shadow:var(--focus)}
205
+ .cv-iconbtn:focus-visible,.cv-send:focus-visible,.cv-stop:focus-visible,.cv-jump:focus-visible,.cv-pill:focus-visible,.cv-option:focus-visible,.cv-link:focus-visible,.cv-cmd:focus-visible,.cv-x:focus-visible,.cv-activity>summary:focus-visible,.cv-sub>summary:focus-visible,.cv-picker-btn:focus-visible,.cv-session-opt:focus-visible{outline:none;box-shadow:var(--focus)}
128
206
  .cv-input:focus-visible{outline:none;box-shadow:none}
129
207
  @media(max-width:760px){
130
208
  .cv-user{max-width:94%}
209
+ .cv-status{max-width:30%}
131
210
  .cv-composer{padding-bottom:max(12px,env(safe-area-inset-bottom,0px))}
132
211
  }
133
212
  `;
@@ -1,12 +1,44 @@
1
1
  /*
2
2
  * DOCK VIEW — the Discussion pane: its sub-header, the message feed with day
3
3
  * separators and bubbles, the composer, submission facets and next steps.
4
- * The Live session pane is views/terminal; the dock frame is layout/workspace.
4
+ * The session page is views/conversation and views/terminal; the dock frame is layout/workspace.
5
5
  */
6
6
  export const DOCK_STYLES = `
7
7
  .dock-head{height:auto;min-height:var(--header-h);padding-top:6px;padding-bottom:6px}
8
- .dock-head .seg{min-width:0;flex-wrap:wrap}
9
8
  .dock-actions{flex-shrink:0}
9
+ /* Who the panel talks to: a title-like menu button with its target list */
10
+ .dock-target{position:relative;min-width:0}
11
+ .dock-target-btn{display:flex;align-items:center;gap:8px;min-width:0;height:34px;padding:0 10px 0 6px;border-radius:var(--r-md);color:var(--ink);font-size:var(--fs-md);font-weight:600;cursor:pointer;list-style:none;transition:background var(--t-fast)}
12
+ .dock-target-btn::-webkit-details-marker{display:none}
13
+ .dock-target-btn:hover,.dock-target[open] .dock-target-btn{background:var(--surface-3)}
14
+ .dock-target-btn>.icon{width:14px;height:14px;flex:none;color:var(--ink-4)}
15
+ .dock-target-icon{display:inline-grid;place-items:center;width:24px;height:24px;flex:none;border-radius:var(--r-sm);background:var(--accent-soft);color:var(--accent)}
16
+ .dock-target-icon .icon{width:14px;height:14px}
17
+ .dock-target-label{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
18
+ .dock-target-menu{position:absolute;left:0;top:calc(100% + 4px);z-index:var(--z-popover);display:grid;gap:2px;min-width:220px;max-width:min(320px,80vw);padding:6px;border:1px solid var(--line-2);border-radius:var(--r-md);background:var(--surface-2);box-shadow:var(--shadow-2)}
19
+ .dock-target-menu hr{margin:4px 2px;border:0;border-top:1px solid var(--line)}
20
+ .dock-target-options{display:grid;gap:2px}
21
+ .dock-target-item{display:flex;align-items:center;gap:8px;width:100%;min-width:0;height:32px;padding:0 8px;border:0;border-radius:var(--r-sm);background:transparent;color:var(--ink-2);font-size:var(--fs-sm);text-align:left}
22
+ .dock-target-item span{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
23
+ .dock-target-item .icon{width:15px;height:15px;flex:none;color:var(--ink-4)}
24
+ .dock-target-item:hover{background:var(--surface-3);color:var(--ink)}
25
+ .dock-target-item[aria-pressed="true"]{color:var(--ink);font-weight:550}
26
+ .dock-target-item .dock-target-check{color:var(--accent)}
27
+ .dock-target-dot{width:7px;height:7px;margin:0 4px;flex:none;border-radius:50%;background:var(--idle)}
28
+ .dock-target-dot.is-live{background:var(--ok)}
29
+ /* One header row: target, view tabs, actions. The target's name wins space
30
+ first: icon-only tabs up to 480px, the selected label up to 560px, then
31
+ every label. Tabs keep aria-label and title at every width. */
32
+ .dock{container-type:inline-size;container-name:dock}
33
+ .dock-target{flex:0 1 auto}
34
+ .dock-tabs{flex:0 0 auto;display:flex;min-width:0;margin-left:auto}
35
+ .dock-tabs .seg-btn{justify-content:center;gap:5px;min-width:0}
36
+ .dock-tabs .seg-btn .icon{width:14px;height:14px;flex:none}
37
+ .dock-tabs .seg-btn[aria-selected="false"]>span{display:none}
38
+ .dock-tabs .seg-btn>span{white-space:nowrap}
39
+ @container dock (min-width:560px){.dock-tabs .seg-btn[aria-selected="false"]>span{display:inline}}
40
+ @container dock (max-width:480px){.dock-tabs .seg-btn>span{display:none}}
41
+ @container dock (max-width:340px){.dock-target-icon{display:none}}
10
42
  .dock-preview{display:flex;flex-direction:column;min-height:0;overflow:auto}
11
43
  .dock-preview>.feed-note{text-align:left;padding:0 12px;color:var(--ink-3)}
12
44
  .preview-services{flex:none;max-height:40%;overflow:auto}
@@ -1,17 +1,21 @@
1
1
  /*
2
- * LOGIN VIEW — the standalone sign-in document: one centred card on the
3
- * canvas with the workbench brand, a password field (with reveal toggle),
4
- * inline error/notice states and the plain-HTTP reminder. Colour comes only
5
- * from theme tokens; the card collapses to the full width on narrow screens.
2
+ * LOGIN VIEW — the standalone sign-in document: one card centred on the
3
+ * canvas at every size, headed by the brand and the language control, with a
4
+ * password field (with reveal toggle), inline error/notice states and the
5
+ * plain-HTTP reminder. Colour comes only from theme tokens; on phones the
6
+ * card drops its frame and uses the full width.
6
7
  */
7
8
  export const LOGIN_STYLES = `
8
9
  .login-body{height:auto;min-height:100vh;min-height:100dvh;overflow:auto}
9
- .login-shell{position:relative;display:grid;place-items:center;min-height:100vh;min-height:100dvh;padding:72px 16px 48px;background:radial-gradient(120% 70% at 50% -10%,var(--accent-soft),transparent 60%),var(--canvas)}
10
- .login-top{position:absolute;top:16px;right:16px}
11
- .login-locale select{height:30px;width:auto;max-width:132px;padding:0 26px 0 9px;line-height:28px;font-size:var(--fs-xs);background-color:var(--surface)}
12
- .login-card{display:grid;gap:20px;width:min(400px,100%);padding:32px 28px 28px;border:1px solid var(--line-2);border-radius:var(--r-lg);background:var(--surface);box-shadow:var(--shadow-2)}
10
+ .login-shell{display:grid;place-items:center;min-height:100vh;min-height:100dvh;padding:max(24px,env(safe-area-inset-top,0px)) 16px max(24px,env(safe-area-inset-bottom,0px));background:radial-gradient(120% 70% at 50% -10%,var(--accent-soft),transparent 60%),var(--canvas)}
11
+ .login-top{display:flex;align-items:center;justify-content:space-between;gap:12px;min-width:0}
12
+ .login-locale{flex:none}
13
+ .login-locale select{height:30px;width:auto;max-width:132px;padding:0 26px 0 9px;line-height:28px;font-size:var(--fs-xs)}
14
+ .login-card{display:grid;gap:20px;width:min(400px,100%);margin-bottom:6vh;padding:28px;border:1px solid var(--line-2);border-radius:var(--r-lg);background:var(--surface);box-shadow:var(--shadow-2)}
13
15
  .login-brand{display:flex;align-items:center;gap:10px}
14
- .login-brand .brand-mark{display:grid;place-items:center;width:32px;height:32px;flex:none;border-radius:9px;background:var(--accent);color:var(--accent-ink);font-size:17px;font-weight:700;line-height:1}
16
+ .login-brand .brand-mark{display:block;width:32px;height:32px;flex:none;border-radius:8px;background:var(--ink);color:var(--canvas);overflow:hidden}
17
+ .brand-glyph{display:block;width:100%;height:100%}
18
+ .brand-dot{fill:var(--accent)}
15
19
  .login-brand .brand-name{font-size:var(--fs-lg);font-weight:650;letter-spacing:-.02em}
16
20
  .login-heading{display:grid;gap:6px}
17
21
  .login-heading h1{font-size:var(--fs-2xl)}
@@ -29,14 +33,13 @@ export const LOGIN_STYLES = `
29
33
  .login-reveal[aria-pressed="true"] .icon-hide{display:block}
30
34
  .login-error{margin:0;color:var(--bad);font-size:var(--fs-sm);overflow-wrap:anywhere}
31
35
  .login-submit{width:100%;height:40px;font-size:var(--fs-md)}
32
- .login-spinner{display:none;width:14px;height:14px;flex:none;border:2px solid currentColor;border-right-color:transparent;border-radius:50%;animation:login-spin .8s linear infinite}
36
+ .login-spinner{display:none;width:14px;height:14px;flex:none;border:2px solid currentColor;border-right-color:transparent;border-radius:50%;animation:m-spin .8s linear infinite}
33
37
  .login-form[aria-busy="true"] .login-spinner{display:inline-block}
34
- @keyframes login-spin{to{transform:rotate(360deg)}}
35
38
  .login-transport{display:flex;align-items:flex-start;gap:8px;margin:0;padding-top:16px;border-top:1px solid var(--line);color:var(--ink-3);font-size:var(--fs-xs)}
36
39
  .login-transport .icon{width:14px;height:14px;margin-top:2px;color:var(--warn)}
37
40
  @media(max-width:480px){
38
- .login-shell{place-items:start center;padding:64px 12px 32px}
39
- .login-card{padding:24px 20px;border-radius:var(--r-md)}
41
+ .login-shell{padding-left:0;padding-right:0;background:var(--surface)}
42
+ .login-card{width:100%;margin-bottom:0;padding:24px 20px;border:0;border-radius:0;box-shadow:none}
40
43
  .login-heading h1{font-size:var(--fs-xl)}
41
44
  }
42
45
  `;
@@ -1,40 +1,33 @@
1
1
  import { BREAKPOINTS } from "../../shared/geometry.js";
2
2
  /*
3
- * MANAGE VIEW — the frame shared by the management pages (/models and
4
- * /settings): a rail in the dashboard sidebar's language (brand, the fixed
5
- * Workbench / Models / Settings navigation with every section listed under
6
- * its area, the language control) beside one reading column whose sections
7
- * share a heading (area kicker, title, explanation). Page sheets add only
8
- * their own content. Below the narrow breakpoint the rail becomes a top bar:
9
- * brand and language, the three main destinations, then the current area's
10
- * sections, wrapping so every entry stays visible.
3
+ * MANAGE VIEW — what the management pages (/models and /settings) add to the
4
+ * workbench frame (layout/workspace): the section list in the sidebar slot,
5
+ * the language control in the top bar, and one reading column whose sections
6
+ * share a heading (title, explanation). The rail, the collapsible list, the
7
+ * top bar and the narrow-screen drawer are the workbench's own. Page sheets
8
+ * add only their own content.
11
9
  */
12
10
  export const MANAGE_STYLES = `
13
- .manage-body{display:block;height:auto;min-height:100vh;min-height:100dvh;overflow:auto}
14
- .manage-app{display:grid;grid-template-columns:240px minmax(0,1fr);min-height:100vh;min-height:100dvh}
15
11
  .manage-app[hidden],#models-root[hidden],#settings-root[hidden]{display:none}
12
+ .manage-body{--sidebar-w:240px}
13
+ body.manage-body.sidebar-collapsed{--sidebar-w:0px}
16
14
 
17
- /* Rail */
18
- .manage-rail{position:sticky;top:0;display:flex;flex-direction:column;height:100vh;height:100dvh;min-width:0;overflow-y:auto;background:var(--surface);border-right:1px solid var(--line)}
19
- .manage-rail-head{flex:none;display:flex;align-items:center;gap:10px;height:var(--header-h);padding:0 12px 0 16px;border-bottom:1px solid var(--line)}
20
- .manage-rail-head .brand{flex:1;color:var(--ink);text-decoration:none}
21
- .manage-locale{flex:none;min-width:0}
22
- .manage-locale select{height:30px;width:auto;max-width:124px;padding:0 26px 0 9px;line-height:28px;font-size:var(--fs-xs)}
23
- .manage-nav{display:flex;flex-direction:column;gap:6px;padding:12px 8px 20px;min-width:0}
24
- .manage-area{display:grid;gap:2px;min-width:0}
25
- .manage-primary,.manage-link{position:relative;display:flex;align-items:center;min-width:0;border-radius:var(--r-md);text-decoration:none;white-space:nowrap;transition:background var(--t-fast),color var(--t-fast)}
26
- .manage-primary span,.manage-link span{overflow:hidden;text-overflow:ellipsis}
27
- .manage-primary{gap:9px;height:34px;padding:0 10px;color:var(--ink-2);font-size:var(--fs-md);font-weight:550}
28
- .manage-primary .icon{width:16px;height:16px;flex:none;color:var(--ink-4)}
29
- .manage-primary:hover,.manage-link:hover{background:var(--surface-3);color:var(--ink)}
30
- .manage-primary[aria-current]{color:var(--ink)}
31
- .manage-primary[aria-current] .icon{color:var(--accent)}
32
- .manage-sections{display:grid;gap:1px;margin:0 0 4px 18px;padding-left:8px;border-left:1px solid var(--line);min-width:0}
33
- .manage-link{gap:8px;height:30px;padding:0 10px;color:var(--ink-3);font-size:var(--fs-sm);font-weight:500}
15
+ /* Section list: only the current area's sections (the rail switches areas). */
16
+ .manage-nav{flex:1;min-height:0;overflow-y:auto;padding:10px 8px 20px}
17
+ .manage-area:not([data-active="true"]){display:none}
18
+ .manage-sections{display:grid;gap:2px;min-width:0}
19
+ .manage-link{position:relative;display:flex;align-items:center;gap:8px;min-width:0;height:34px;padding:0 10px;border-radius:var(--r-md);color:var(--ink-3);font-size:var(--fs-sm);font-weight:500;text-decoration:none;white-space:nowrap;transition:background var(--t-fast),color var(--t-fast)}
20
+ .manage-link span{overflow:hidden;text-overflow:ellipsis}
21
+ .manage-link:hover{background:var(--surface-3);color:var(--ink)}
34
22
  .manage-link[aria-current="page"]{background:var(--surface-3);color:var(--ink);box-shadow:inset 0 0 0 1px var(--line-2)}
35
- .manage-link[aria-current="page"]::before{content:"";position:absolute;left:-9px;top:6px;bottom:6px;width:2px;border-radius:2px;background:var(--accent)}
23
+ .manage-link[aria-current="page"]::before{content:"";position:absolute;left:0;top:9px;bottom:9px;width:3px;border-radius:0 3px 3px 0;background:var(--accent)}
36
24
  .manage-dirty{display:none;width:7px;height:7px;margin-left:auto;flex:none;border-radius:50%;background:var(--warn);box-shadow:0 0 0 3px var(--warn-soft)}
37
25
  .manage-link[data-dirty="true"] .manage-dirty{display:inline-block}
26
+ @media(pointer:coarse){.manage-link{height:42px}}
27
+
28
+ /* Language control at the end of the top bar */
29
+ .top-locale{flex:none;min-width:0}
30
+ .top-locale select{height:30px;width:auto;max-width:124px;padding:0 26px 0 9px;line-height:28px;font-size:var(--fs-xs)}
38
31
 
39
32
  /* Reading column and the shared section heading */
40
33
  .manage-main{min-width:0;padding:28px var(--gutter) 72px}
@@ -50,20 +43,10 @@ export const MANAGE_STYLES = `
50
43
  .manage-body input[type=checkbox]{width:16px;height:16px;padding:0;accent-color:var(--accent)}
51
44
 
52
45
  @media(max-width:${BREAKPOINTS.narrow}px){
53
- .manage-app{grid-template-columns:minmax(0,1fr)}
54
- .manage-rail{position:static;height:auto;overflow:visible;border-right:0;border-bottom:1px solid var(--line)}
55
- .manage-rail-head{height:52px}
56
- .manage-nav{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:4px;padding:8px 10px}
57
- .manage-area{display:contents}
58
- .manage-primary{justify-content:center;gap:7px;height:36px;padding:0 6px;font-size:var(--fs-sm);background:var(--surface-2);box-shadow:inset 0 0 0 1px var(--line)}
59
- .manage-primary[aria-current]{background:var(--surface-3);box-shadow:inset 0 0 0 1px var(--line-2),inset 0 -2px 0 var(--accent)}
60
- /* Only the current area's sections, as a wrapping strip under the tabs. */
61
- .manage-sections{display:none;grid-column:1/-1;grid-row:2;margin:4px 0 0;padding:0;border:0}
62
- .manage-area[data-active="true"] .manage-sections{display:flex;flex-wrap:wrap;gap:4px}
63
- .manage-link{flex:0 1 auto;max-width:100%;height:32px;padding:0 10px;border:1px solid var(--line)}
64
- .manage-link[aria-current="page"]{border-color:var(--line-2)}
65
- .manage-link[aria-current="page"]::before{left:10px;right:10px;top:auto;bottom:2px;width:auto;height:2px}
66
- .manage-main{padding:18px 14px 56px}
46
+ .manage-main{padding:20px 14px 56px}
47
+ .manage-body .top-locale{display:none}
48
+ /* The top bar already names the section; the page keeps only its explanation. */
49
+ .manage-heading h1{display:none}
67
50
  }
68
51
  @media(max-width:${BREAKPOINTS.small}px){
69
52
  .manage-heading h1{font-size:var(--fs-xl)}
@@ -8,9 +8,8 @@ export const PAGE_STYLES = `
8
8
  .page{max-width:var(--center-max);margin:0 auto;padding:0 var(--gutter) 64px}
9
9
 
10
10
  /* Page scaffolding */
11
- .page-head{display:flex;align-items:flex-end;justify-content:space-between;gap:16px;padding:36px 0 24px}
12
- .kicker{color:var(--accent);font-size:var(--fs-2xs);font-weight:600;text-transform:uppercase;letter-spacing:.1em}
13
- .page-title{margin-top:6px;font-size:var(--fs-2xl);font-weight:650;letter-spacing:-.025em}
11
+ .page-head{display:flex;align-items:flex-end;justify-content:space-between;gap:16px;padding:28px 0 20px}
12
+ .page-title{font-size:var(--fs-2xl);font-weight:650;letter-spacing:-.025em}
14
13
  .page-sub{margin-top:4px;color:var(--ink-3)}
15
14
  .page-foot{margin-top:20px;color:var(--ink-4);font-size:var(--fs-xs);text-align:center}
16
15
  .sub-head{display:flex;align-items:center;gap:8px;margin-top:6px;font-size:var(--fs-sm);font-weight:600}
@@ -50,7 +50,7 @@ summary.work-head:focus-visible{box-shadow:inset 0 0 0 2px var(--accent-line)}
50
50
  .timeline{list-style:none;margin:0;padding:0;position:relative;display:grid;gap:0}
51
51
  .timeline::before{content:"";position:absolute;left:13px;top:6px;bottom:6px;width:1px;background:var(--line-2)}
52
52
  .timeline-item{position:relative;display:grid;grid-template-columns:28px minmax(0,1fr);gap:12px;padding:0 0 18px}
53
- .timeline-mark{position:relative;z-index:1;display:grid;place-items:center;width:28px;height:28px;border-radius:50%;background:var(--surface-2);border:1px solid var(--line-2);color:var(--ink-3)}
53
+ .timeline-mark{position:relative;z-index:var(--z-raised);display:grid;place-items:center;width:28px;height:28px;border-radius:50%;background:var(--surface-2);border:1px solid var(--line-2);color:var(--ink-3)}
54
54
  .kind-decision .timeline-mark{color:var(--ok);border-color:var(--ok-soft);background:var(--ok-soft)}
55
55
  .kind-milestone .timeline-mark{color:var(--accent);border-color:var(--accent-soft);background:var(--accent-soft)}
56
56
  .kind-run .timeline-mark{color:var(--info);border-color:var(--info-soft);background:var(--info-soft)}
@@ -29,7 +29,7 @@ export const SETTINGS_STYLES = `
29
29
  .settings-receipt{white-space:pre-wrap;overflow-wrap:anywhere}
30
30
  .settings-error{color:var(--bad)!important}
31
31
  .settings-observation{max-height:260px;overflow:auto;white-space:pre-wrap;overflow-wrap:anywhere;font-size:var(--fs-xs)}
32
- .settings-search{position:sticky;top:0;z-index:1;padding:10px 0;background:var(--canvas)}
32
+ .settings-search{position:sticky;top:var(--header-h);z-index:var(--z-raised);padding:10px 0;background:var(--canvas)}
33
33
  .settings-search input{width:100%;max-width:520px}
34
34
  #settings-status:empty,#browser-receipt:empty{display:none}
35
35
  .mono-line{overflow-wrap:anywhere}
@@ -1,26 +1,38 @@
1
1
  /*
2
- * SIDEBAR VIEW — the task index: brand and sync state, search, attention
3
- * pills, status filter tabs, grouped task rows, the catalog pager and the
4
- * footer buttons. Region sizing lives in layout/workspace.
2
+ * SIDEBAR VIEW — the task index: title and sync state, search, attention
3
+ * pills, status filter tabs, grouped task rows and the catalog pager. The
4
+ * brand mark is shared with the global rail. Region sizing lives in
5
+ * layout/workspace.
5
6
  */
6
7
  export const SIDEBAR_STYLES = `
7
- /* Brand and sync state */
8
- .brand-mark{width:28px;height:28px;border-radius:8px;background:var(--accent);color:var(--accent-ink);font-size:15px;font-weight:700;line-height:1}
8
+ /* Brand mark (global rail, management top bar) and sync state */
9
+ .brand-mark{width:28px;height:28px;border-radius:7px;background:var(--ink);color:var(--canvas);overflow:hidden}
10
+ .brand-glyph{display:block;width:100%;height:100%}
11
+ .brand-dot{fill:var(--accent)}
9
12
  .brand-name{font-size:var(--fs-lg);font-weight:650;letter-spacing:-.02em}
10
13
  .sync{display:inline-flex;align-items:center;gap:6px;height:24px;padding:0 8px;border-radius:var(--r-pill);background:var(--surface-3);color:var(--ink-3);font-size:var(--fs-2xs);font-variant-numeric:tabular-nums}
11
14
  .sync i{width:6px;height:6px;border-radius:50%;background:var(--ink-4)}
12
15
  .sync[data-state="ok"] i{background:var(--ok);box-shadow:0 0 0 3px var(--ok-soft)}
13
- .sync[data-state="syncing"] i{background:var(--info);animation:blink 1s ease-in-out infinite}
16
+ .sync[data-state="syncing"] i{background:var(--info);animation:m-blink 1s ease-in-out infinite}
14
17
  .sync[data-state="error"] i{background:var(--bad);box-shadow:0 0 0 3px var(--bad-soft)}
15
18
  .sync[data-state="error"]{color:var(--bad)}
16
- @keyframes blink{50%{opacity:.35}}
17
19
 
18
- /* Search and attention filters */
19
- .search-field{position:relative;display:flex;align-items:center;flex:none;margin:12px 12px 0}
20
- .search-field>.icon{position:absolute;left:10px;color:var(--ink-4);pointer-events:none}
21
- .search-field input{height:34px;padding:0 34px 0 32px;border-radius:var(--r-md);background:var(--surface-2)}
20
+ /* Tools block: create, search, category and attention, on one 8px rhythm */
21
+ .side-tools{flex:none;display:grid;gap:8px;padding:12px 12px 4px}
22
+ .side-create{width:100%;height:34px;border-radius:var(--r-md);box-shadow:var(--shadow-1)}
23
+ .side-create .icon{width:16px;height:16px;stroke-width:2.2}
24
+ .side-search{display:flex;align-items:center;gap:6px;min-width:0}
25
+ .search-field{position:relative;display:flex;align-items:center;flex:1;min-width:0}
26
+ .search-field>.icon{position:absolute;left:10px;width:15px;height:15px;color:var(--ink-4);pointer-events:none}
27
+ .search-field input{height:34px;padding:0 32px 0 32px;border-radius:var(--r-md);background:var(--surface-2)}
22
28
  .search-field input::-webkit-search-cancel-button{display:none}
23
- .search-field kbd{position:absolute;right:8px}
29
+ .search-field kbd{position:absolute;right:8px;pointer-events:none}
30
+ .search-field:focus-within kbd{opacity:0}
31
+ .side-search-body{width:34px;height:34px;border:1px solid var(--line-2);border-radius:var(--r-md);background:var(--surface-2)}
32
+ .side-search-body:hover:not(:disabled){border-color:var(--line-3)}
33
+ .source-seg{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));width:100%}
34
+ .source-seg .seg-btn{justify-content:center;min-width:0;overflow:hidden;text-overflow:ellipsis}
35
+ .attention-bar:empty{display:none}
24
36
  .attention-list{display:flex;flex-wrap:wrap;gap:6px}
25
37
  .attention-pill{display:inline-flex;align-items:center;gap:6px;height:26px;padding:0 9px;border:1px solid transparent;border-radius:var(--r-pill);background:var(--tone-soft);color:var(--tone);font-size:var(--fs-xs);font-weight:500}
26
38
  .attention-pill b{font-weight:700;font-variant-numeric:tabular-nums}
@@ -59,17 +71,10 @@ export const SIDEBAR_STYLES = `
59
71
  .list-empty{display:grid;justify-items:center;gap:8px;padding:36px 16px;color:var(--ink-4);font-size:var(--fs-sm);text-align:center}
60
72
  .list-empty.is-error{color:var(--bad)}
61
73
 
62
- /* Catalog pager and footer */
74
+ /* Catalog pager */
63
75
  .pager-btn{height:28px;padding:0 10px;border:1px solid var(--line-2);border-radius:var(--r-sm);background:transparent;color:var(--ink-2);font-size:var(--fs-xs)}
64
76
  .pager-btn:hover:not(:disabled){border-color:var(--line-3);color:var(--ink)}
65
77
  .pager-btn:disabled{opacity:.4}
66
78
  .pager-count{grid-column:2;text-align:center;color:var(--ink-4);font-size:var(--fs-2xs);font-variant-numeric:tabular-nums}
67
79
  .pager-clear{height:28px}
68
- .foot-btn{display:inline-flex;align-items:center;gap:6px;height:32px;padding:0 8px;border:1px solid var(--line-2);border-radius:var(--r-sm);background:transparent;color:var(--ink-2);font-size:var(--fs-xs);font-weight:500;min-width:0}
69
- .foot-btn span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
70
- .foot-btn:hover{color:var(--ink);border-color:var(--line-3);background:var(--surface-3)}
71
- .foot-btn[aria-pressed="true"]{color:var(--accent);border-color:var(--accent-line);background:var(--accent-soft)}
72
- .foot-btn kbd{margin-left:2px}
73
- .side-foot .icon-btn{margin-left:auto}
74
- .side-foot .icon-btn+.icon-btn{margin-left:0}
75
80
  `;
@@ -1,29 +1,22 @@
1
1
  /*
2
- * TASK VIEW — the task page frame and its Overview tab: the sticky header and
3
- * section tabs, the hero, the "now" banner, input requests that need the
2
+ * TASK VIEW — the task page frame and its Overview tab: the sticky section
3
+ * tabs, the hero, the "now" banner, input requests that need the
4
4
  * user, decisions and planning. Rows inside the other tabs live in
5
5
  * views/records and views/delivery.
6
6
  */
7
7
  export const TASK_STYLES = `
8
- /* Sticky header and tab strip: both bleed through the page gutter and frost
9
- the content scrolling beneath them. */
10
- .task-header,.tabs-wrap{position:sticky;margin:0 calc(-1 * var(--gutter));padding:0 var(--gutter);background:color-mix(in srgb,var(--canvas) 88%,transparent);backdrop-filter:saturate(1.4) blur(10px);-webkit-backdrop-filter:saturate(1.4) blur(10px)}
11
- .task-header{top:0;z-index:10}
12
- .task-bar{display:flex;align-items:center;gap:6px;height:var(--header-h)}
13
- .back-btn{display:none}
14
- .crumbs{display:flex;align-items:center;gap:6px;min-width:0;font-size:var(--fs-sm)}
15
- .crumb{padding:3px 6px;border:0;border-radius:var(--r-xs);background:transparent;color:var(--ink-3)}
16
- .crumb:hover{color:var(--ink);background:var(--surface-3)}
17
- .crumb-sep{color:var(--ink-4)}
18
- .crumb-current{color:var(--ink-2);font-size:var(--fs-xs)}
8
+ /* Section tabs: sticky under the top bar, bleeding through the page gutter
9
+ and frosting the content scrolling beneath them. */
10
+ .tabs-wrap{position:sticky;margin:0 calc(-1 * var(--gutter));padding:0 var(--gutter);background:var(--canvas)}
19
11
  .dock-toggle{height:30px}
20
- .task-hero{padding:14px 0 18px}
12
+ .operator-toggle[aria-pressed="true"],.panel-toggle[aria-expanded="true"]{background:var(--accent-soft);color:var(--accent)}
13
+ .task-hero{padding:28px 0 18px}
21
14
  .task-title{font-size:var(--fs-2xl);font-weight:650;letter-spacing:-.025em;line-height:1.25;overflow-wrap:anywhere}
22
15
  .task-meta{display:flex;flex-wrap:wrap;align-items:center;gap:8px;margin-top:12px;color:var(--ink-3);font-size:var(--fs-xs)}
23
16
  .task-meta:empty{display:none}
24
17
  .meta-item{display:inline-flex;align-items:center;gap:5px}
25
18
  .meta-item .when{font-size:inherit}
26
- .tabs-wrap{top:var(--header-h);z-index:9;border-bottom:1px solid var(--line)}
19
+ .tabs-wrap{top:var(--header-h);z-index:calc(var(--z-sticky) - 1);border-bottom:1px solid var(--line)}
27
20
  .tabs{gap:4px}
28
21
  .tab{position:relative;display:inline-flex;align-items:center;gap:7px;flex:none;height:42px;padding:0 10px;border:0;background:transparent;color:var(--ink-3);font-size:var(--fs-sm);font-weight:500}
29
22
  .tab:hover{color:var(--ink)}