Merge master into feat/offline-state (keep both offline overlay and approvals drawer)

This commit is contained in:
Codeman maintainer
2026-08-09 17:01:34 +02:00
58 changed files with 4768 additions and 138 deletions
+122 -1
View File
@@ -479,7 +479,11 @@ html.mobile-init .file-browser-panel {
.btn-icon-header.btn-lifecycle-log,
.btn-icon-header.btn-away-digest,
.btn-icon-header.btn-session-manager,
.btn-icon-header.btn-file-viewer {
.btn-icon-header.btn-file-viewer,
/* Approvals bell: phones answer from the overview's NEEDS YOU rows instead
(inline approve/deny in mobile-overview.js); the bell would only crowd the
header it was designed to stay out of. */
.btn-icon-header.btn-approvals {
display: none !important;
}
@@ -2503,6 +2507,41 @@ html.mobile-init .file-browser-panel {
background: var(--bg-hover);
}
/* Approvals Inbox answer strip: sits under a NEEDS YOU row (sibling of the
row <button>, see _buildMobileOverviewApprovalStrip). Buttons inherit no
toolbar styling on purpose; they are one-tap dialog answers, not runs. */
.mobile-overview-row-wrap {
width: 100%;
}
.mobile-overview-approval-strip {
display: flex;
flex-wrap: wrap;
gap: 0.4rem;
padding: 0.4rem 0.2rem 0.1rem;
}
.mobile-overview-approval-btn {
border: 1px solid var(--border);
border-radius: 8px;
background: var(--bg-card);
color: var(--text);
font-family: inherit;
font-size: 0.72rem;
padding: 0.35rem 0.6rem;
max-width: 100%;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.mobile-overview-approval-btn.primary {
background: var(--accent);
border-color: var(--accent);
color: white;
}
.mobile-overview-approval-btn.danger {
border-color: var(--error);
color: var(--error);
}
/* Attention states mirror the session tabs exactly: red blink when the agent
asked something (permission / question), yellow blink when it is waiting for
a prompt. Same hues and same cadence as tab-blink-red / tab-blink-yellow in
@@ -2522,6 +2561,51 @@ html.mobile-init .file-browser-panel {
border-color: var(--red);
}
/* Working is not an alert, so it gets a calm green breathing edge rather than a
blink: at a glance the row reads "this one is moving", without competing with
the two states that actually want you. Slower than both of them on purpose. */
.mobile-overview-row--working {
border-color: var(--green);
animation: mobile-overview-breathe-green 2.2s ease-in-out infinite;
}
@keyframes mobile-overview-breathe-green {
0%,
100% {
background: var(--bg-card);
border-color: var(--border);
}
50% {
background: rgba(34, 197, 94, 0.1);
border-color: var(--green);
}
}
/* The pill picks up a three-dot ellipsis that fills in and empties, so the row
still reads as active on a skin where the border tint is subtle. */
.mobile-overview-pill--working::after {
content: '';
display: inline-block;
width: 0.75em;
text-align: left;
animation: mobile-overview-pill-dots 1.5s steps(1, end) infinite;
}
@keyframes mobile-overview-pill-dots {
0% {
content: '';
}
25% {
content: '.';
}
50% {
content: '..';
}
75% {
content: '...';
}
}
@keyframes mobile-overview-blink-red {
0%,
100% {
@@ -2603,6 +2687,25 @@ html.mobile-init .file-browser-panel {
will-change: opacity;
}
/* Ring the pulsing dot with the SAME spinner a tab shows while it loads: same
2px ring, same bright leading edge, same `tab-load-spin` keyframes from
styles.css (reused, not re-declared, so the two can never drift). Green
rather than the tab's blue because here it means "running", not "loading":
the motion is the shared part, the color still belongs to the state. */
.mobile-overview-dot {
position: relative;
}
.mobile-overview-dot--working::after {
content: '';
position: absolute;
inset: -4px;
border: 2px solid rgba(34, 197, 94, 0.25);
border-top-color: var(--green);
border-radius: 50%;
animation: tab-load-spin 0.7s linear infinite;
}
.mobile-overview-dot--idle {
background: var(--green);
}
@@ -2713,6 +2816,24 @@ html.mobile-init .file-browser-panel {
.mobile-overview-dot--working {
animation: none;
}
/* The ring stays as a static full circle: it still marks the row, it just
stops turning. */
.mobile-overview-dot--working::after {
border-color: var(--green);
animation: none;
}
/* Working is only informational, so it drops to a static green edge and a
static ellipsis rather than holding a tint the way the alerts do. */
.mobile-overview-row--working {
animation: none;
}
.mobile-overview-pill--working::after {
content: '...';
animation: none;
}
}
/* Light-skin compatibility for mobile-only chrome. These components predate