fix(ui): align message motion and composer button radius with DESIGN.md; tolerate unreadable staging revision state
Independent Staging Quality Gate / validate (push) Successful in 13m6s
Independent Staging Quality Gate / publish (push) Successful in 8m3s

- Message entry: 300/420ms power3.out -> Standard 180ms cubic-bezier(.22,1,.36,1) (DESIGN.md section 6); update the layout contract test to the shipped values.
- Composer icon button: full radius instead of 8px (DESIGN.md section 5 Button).
- Staging deploy workflow: fall back to container SHA discovery when .state/deployed-revision exists but is unreadable by the deploy user (Gitea pipeline writes it as root).
This commit is contained in:
Jesse_Chen
2026-08-14 09:13:57 +08:00
parent b4031eff8c
commit 0fd111d16b
4 changed files with 6 additions and 5 deletions
+1 -1
View File
@@ -315,7 +315,7 @@ jobs:
ssh "${ssh_options[@]}" "$remote" "install -d -m 700 '$incoming/.docker'" ssh "${ssh_options[@]}" "$remote" "install -d -m 700 '$incoming/.docker'"
scp -i "$key_path" -P "$DEPLOY_PORT" -o BatchMode=yes -o IdentitiesOnly=yes -o StrictHostKeyChecking=yes -o "UserKnownHostsFile=$known_hosts_path" artifacts/staging-image/controller.tar "$remote:$incoming/controller.tar" scp -i "$key_path" -P "$DEPLOY_PORT" -o BatchMode=yes -o IdentitiesOnly=yes -o StrictHostKeyChecking=yes -o "UserKnownHostsFile=$known_hosts_path" artifacts/staging-image/controller.tar "$remote:$incoming/controller.tar"
ssh "${ssh_options[@]}" "$remote" "tar -xf '$incoming/controller.tar' -C '$incoming' && rm -f -- '$incoming/controller.tar'" ssh "${ssh_options[@]}" "$remote" "tar -xf '$incoming/controller.tar' -C '$incoming' && rm -f -- '$incoming/controller.tar'"
previous_sha="$(ssh "${ssh_options[@]}" "$remote" "state='$DEPLOY_PATH/.state/deployed-revision'; if [ -f \"\$state\" ]; then cat \"\$state\"; else id=\$(sudo -n docker ps -aq --filter 'label=com.docker.compose.project=jyotisha-staging' --filter 'label=com.docker.compose.service=web' | head -n 1); if [ -n \"\$id\" ]; then sudo -n docker inspect --format '{{range .Config.Env}}{{println .}}{{end}}' \"\$id\" | sed -n 's/^GITHUB_SHA=//p' | head -n 1; else printf not-deployed; fi; fi")" previous_sha="$(ssh "${ssh_options[@]}" "$remote" "state='$DEPLOY_PATH/.state/deployed-revision'; if [ -r \"\$state\" ]; then cat \"\$state\"; else id=\$(sudo -n docker ps -aq --filter 'label=com.docker.compose.project=jyotisha-staging' --filter 'label=com.docker.compose.service=web' | head -n 1); if [ -n \"\$id\" ]; then sudo -n docker inspect --format '{{range .Config.Env}}{{println .}}{{end}}' \"\$id\" | sed -n 's/^GITHUB_SHA=//p' | head -n 1; else printf not-deployed; fi; fi")"
[[ "$previous_sha" == not-deployed || "$previous_sha" =~ ^[0-9a-f]{40}$ ]] || exit 1 [[ "$previous_sha" == not-deployed || "$previous_sha" =~ ^[0-9a-f]{40}$ ]] || exit 1
forward_verified=false forward_verified=false
if [[ "$previous_sha" != not-deployed && "$previous_sha" != "$DEPLOY_SHA" && "$ALLOW_ROLLBACK" != true ]]; then if [[ "$previous_sha" != not-deployed && "$previous_sha" != "$DEPLOY_SHA" && "$ALLOW_ROLLBACK" != true ]]; then
+1 -1
View File
@@ -708,7 +708,7 @@ button:disabled { cursor: default; opacity: .45; }
.composer { width: min(760px, 100%); display: flex; align-items: flex-end; gap: 10px; margin: 0 auto; border: 1px solid var(--color-border); transition: border-color 140ms ease-out; min-height: 60px; padding: var(--space-2) var(--space-2) var(--space-2) var(--space-4); border-color: var(--color-border-strong); border-radius: var(--radius-lg); background: var(--color-canvas); box-shadow: 0 0 0 1px color-mix(in srgb, var(--color-border) 42%, transparent); } .composer { width: min(760px, 100%); display: flex; align-items: flex-end; gap: 10px; margin: 0 auto; border: 1px solid var(--color-border); transition: border-color 140ms ease-out; min-height: 60px; padding: var(--space-2) var(--space-2) var(--space-2) var(--space-4); border-color: var(--color-border-strong); border-radius: var(--radius-lg); background: var(--color-canvas); box-shadow: 0 0 0 1px color-mix(in srgb, var(--color-border) 42%, transparent); }
.composer:focus-within { border-color: var(--color-action); box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-action) 15%, transparent); } .composer:focus-within { border-color: var(--color-action); box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-action) 15%, transparent); }
.composer textarea { min-width: 0; min-height: 44px; max-height: 128px; flex: 1; resize: none; padding: 11px 0 8px; border: 0; outline: 0; background: transparent; color: var(--color-ink); line-height: 1.5; font-size: 16px; } .composer textarea { min-width: 0; min-height: 44px; max-height: 128px; flex: 1; resize: none; padding: 11px 0 8px; border: 0; outline: 0; background: transparent; color: var(--color-ink); line-height: 1.5; font-size: 16px; }
.composer button { width: 44px; height: 44px; display: grid; flex: 0 0 auto; place-items: center; border: 0; color: var(--color-on-dark); cursor: pointer; transition: background-color 120ms ease-out, transform 120ms ease-out; border-radius: var(--radius-md); background: var(--color-action); } .composer button { width: 44px; height: 44px; display: grid; flex: 0 0 auto; place-items: center; border: 0; color: var(--color-on-dark); cursor: pointer; transition: background-color 120ms ease-out, transform 120ms ease-out; border-radius: 999px; background: var(--color-action); }
.composer .composer-stop { background: var(--color-action); } .composer .composer-stop { background: var(--color-action); }
.composer .composer-stop:not(:disabled):hover { background: var(--color-action-hover); } .composer .composer-stop:not(:disabled):hover { background: var(--color-action-hover); }
.composer-footer { width: min(760px, 100%); min-height: 44px; display: flex; align-items: center; margin: var(--space-1) auto 0; } .composer-footer { width: min(760px, 100%); min-height: 44px; display: flex; align-items: center; margin: var(--space-1) auto 0; }
+2 -2
View File
@@ -50,8 +50,8 @@ export function ChatMessageRow({
}, { }, {
autoAlpha: 1, autoAlpha: 1,
clearProps: "opacity,transform,visibility", clearProps: "opacity,transform,visibility",
duration: message.role === "user" ? 0.3 : 0.42, duration: 0.18,
ease: "power3.out", ease: "cubic-bezier(.22, 1, .36, 1)",
y: 0, y: 0,
}); });
}); });
@@ -16,7 +16,8 @@ test("aligns the session transcript and composer to one readable column", () =>
test("keeps message motion restrained and honors reduced-motion preferences", () => { test("keeps message motion restrained and honors reduced-motion preferences", () => {
assert.match(messageRowSource, /gsap\.matchMedia\(\)/); assert.match(messageRowSource, /gsap\.matchMedia\(\)/);
assert.match(messageRowSource, /prefers-reduced-motion:\s*no-preference/); assert.match(messageRowSource, /prefers-reduced-motion:\s*no-preference/);
assert.match(messageRowSource, /duration:\s*message\.role === "user" \? 0\.3 : 0\.42/); assert.match(messageRowSource, /duration:\s*0\.18/);
assert.match(messageRowSource, /ease:\s*"cubic-bezier\(\.22,\s*1,\s*\.36,\s*1\)"/);
assert.match(messageRowSource, /clearProps:\s*"opacity,transform,visibility"/); assert.match(messageRowSource, /clearProps:\s*"opacity,transform,visibility"/);
}); });