From b2b1b23027fb3485e9815fd894f00f433db7413f Mon Sep 17 00:00:00 2001 From: esengine <359807859@qq.com> Date: Thu, 5 Nov 2026 10:21:36 +0000 Subject: [PATCH] fix(studio): running pulses take the live duration and the streaming caret blinks as the board draws it --- desktop/frontend-next/src/styles/app.css | 10 +++++----- desktop/frontend-next/src/styles/studio.css | 8 ++++---- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/desktop/frontend-next/src/styles/app.css b/desktop/frontend-next/src/styles/app.css index 76dbc708a5..5cb6ee1966 100644 --- a/desktop/frontend-next/src/styles/app.css +++ b/desktop/frontend-next/src/styles/app.css @@ -340,7 +340,7 @@ .mode.danger::before { content: ""; position: absolute; inset: 0; z-index: -1; border-radius: inherit; background: color-mix(in srgb, var(--err) 12%, transparent); - animation: m-pulse 2.6s var(--ease) infinite; + animation: m-pulse var(--t-live) var(--ease) infinite; } .sep { width: 1px; height: 14px; flex: none; margin-inline: -1px; background: var(--border); opacity: .75 } @@ -1021,7 +1021,7 @@ .out .txt code { font: var(--w-reg) var(--fs-ui) var(--mono); color: var(--text) } - .caret { display: inline-block; width: 6px; height: 13px; background: var(--net); vertical-align: -2px; animation: m-pulse 1.1s var(--ease) infinite } + .caret { display: inline-block; width: 6px; height: 13px; background: var(--net); vertical-align: -2px; animation: caret-blink 1s steps(1) infinite } .tk .caret { width: 5px; height: 11px; background: var(--faint); margin-left: 2px } .rgroup { display: flex; flex-direction: column; gap: 4px } .rgroup .hd { font: var(--w-med) var(--fs-micro) var(--mono); letter-spacing: var(--track-cap); color: var(--warn-ink) } @@ -2488,7 +2488,7 @@ .srv-hd { display: flex; align-items: baseline; gap: 9px } .srv .pip { align-self: center } .srv[data-st="ready"] .pip { background: var(--ok) } - .srv[data-st="connecting"] .pip { background: var(--net); animation: m-pulse 1.6s ease-in-out infinite } + .srv[data-st="connecting"] .pip { background: var(--net); animation: m-pulse var(--t-live) ease-in-out infinite } .srv[data-st="failed"] .pip { background: var(--err) } .srv[data-st="pending"] .pip { background: var(--warn-ink) } .srv[data-st="disabled"] .pip { background: var(--ghost) } @@ -2558,7 +2558,7 @@ flex: none; width: 5px; height: 5px; border-radius: 50%; background: var(--ghost); transition: background var(--t-line) var(--ease-out); } - .reload[data-s="run"] .rdot { background: var(--net); animation: m-pulse 1.1s var(--ease) infinite } + .reload[data-s="run"] .rdot { background: var(--net); animation: m-pulse var(--t-live) var(--ease) infinite } .reload[data-s="run"]:disabled { color: var(--text) } .reload[data-s="ok"] { color: var(--ok-ink); border-color: var(--ok) } .reload[data-s="ok"] .rdot { background: var(--ok); animation: m-card var(--t-card) var(--ease-out) } @@ -4116,7 +4116,7 @@ .ptab-host::before { content: "◦"; margin-right: 2px; opacity: .7 } .ptab .pip { flex: none; background: var(--ghost) } - .ptab[data-run="running"] .pip { background: var(--net); animation: m-pulse 1.4s ease-in-out infinite } + .ptab[data-run="running"] .pip { background: var(--net); animation: m-pulse var(--t-live) ease-in-out infinite } @media (prefers-reduced-motion: reduce) { .ptab[data-run="running"] .pip { animation: none } } .ptab[data-run="halt"] .pip { background: var(--accent-ink) } .ptab[data-run="done"] .pip { background: transparent; box-shadow: inset 0 0 0 1.5px var(--ok) } diff --git a/desktop/frontend-next/src/styles/studio.css b/desktop/frontend-next/src/styles/studio.css index bff2aa1a52..1d811e0dfa 100644 --- a/desktop/frontend-next/src/styles/studio.css +++ b/desktop/frontend-next/src/styles/studio.css @@ -1715,7 +1715,7 @@ button, input, textarea { font-size: var(--fs-ui); } .studio-deckchip[aria-expanded="true"] { color: var(--text); background: var(--overlay); border-color: var(--hair); } /* Live is the one thing here worth a moving mark: work is happening that this row is the only sign of. */ -.studio-deckchip[data-live] .studio-icon { color: var(--accent); animation: m-pulse 2.4s ease-in-out infinite; } +.studio-deckchip[data-live] .studio-icon { color: var(--accent); animation: m-pulse var(--t-live) ease-in-out infinite; } @media (prefers-reduced-motion: reduce) { .studio-deck-pop { transition: none } .studio-deckchip[data-live] .studio-icon { animation: none } @@ -2421,7 +2421,7 @@ button, input, textarea { font-size: var(--fs-ui); } .studio-browser-note[data-loading]::before { content: ""; width: 6px; height: 6px; display: inline-block; margin-right: 6px; - border-radius: 50%; background: #7890c7; animation: m-pulse 1.1s ease-in-out infinite; + border-radius: 50%; background: #7890c7; animation: m-pulse var(--t-live) ease-in-out infinite; } /* Product wordmark: the interface face remains neutral; the brand gets its @@ -2641,7 +2641,7 @@ button, input, textarea { font-size: var(--fs-ui); } .studio-runstate .rmark path:nth-child(3) { animation-delay: -1.44s; } .studio-runstate[data-waiting] .rmark path { stroke-dasharray: 100; - animation: m-pulse 1.8s ease-in-out infinite; + animation: m-pulse var(--t-live) ease-in-out infinite; } @keyframes studio-r-run { to { stroke-dashoffset: -100; } } /* At rest the mark is a whole letter, not a segment mid-trace: a shape that @@ -3383,7 +3383,7 @@ button, input, textarea { font-size: var(--fs-ui); } .turntools .studio-refine { order: 1; } .studio-refine[aria-disabled="true"] { cursor: default; } .studio-refine[aria-disabled="true"] > .studio-icon { opacity: .35; } -.studio-refine[aria-busy="true"] > .studio-icon { animation: m-pulse 1s ease-in-out infinite; } +.studio-refine[aria-busy="true"] > .studio-icon { animation: m-pulse var(--t-live) ease-in-out infinite; } .refine-card { display: grid; gap: 8px;