Polish terminal bar: centered chevron, legend dot, resume divider

- Replace the text triangle with an SVG chevron so it centers with the label
- Make the "your actions (simulated)" legend dot the same yellow as the
  markers on simulated lines
- When live worker output was held back during a visitor's simulated
  cycle, print a divider before flushing it so the jump is explained
This commit is contained in:
Johan Sandoval committed 2026-10-06 15:51:03 +00:00
1 parent 1c531bc2ab
commit c1b107e264
2 files changed
+13 -7

No files matched your search

+5 -4
View File
@@ -19,9 +19,9 @@ body.usmt-term-open { padding-bottom: calc(var(--usmt-term-h, 340px) + 72px); }
background: transparent; border: 1px solid transparent; color: #d1d5db; cursor: pointer; background: transparent; border: 1px solid transparent; color: #d1d5db; cursor: pointer;
font: inherit; font-size: 0.85em; padding: 4px 10px; border-radius: 4px; white-space: nowrap; font: inherit; font-size: 0.85em; padding: 4px 10px; border-radius: 4px; white-space: nowrap;
} }
.usmt-term-toggle { font-weight: 600; color: #fff; } .usmt-term-toggle { font-weight: 600; color: #fff; display: inline-flex; align-items: center; gap: 6px; line-height: 1; }
.usmt-term-toggle:hover, .usmt-term-tab:hover, .usmt-term-btn:hover { background: rgba(255,255,255,0.08); } .usmt-term-toggle:hover, .usmt-term-tab:hover, .usmt-term-btn:hover { background: rgba(255,255,255,0.08); }
.usmt-term-chevron { display: inline-block; font-size: 0.75em; transition: transform 0.2s; } .usmt-term-chevron { width: 11px; height: 11px; flex: 0 0 11px; display: block; transition: transform 0.2s; }
.usmt-term:not(.collapsed) .usmt-term-chevron { transform: rotate(180deg); } .usmt-term:not(.collapsed) .usmt-term-chevron { transform: rotate(180deg); }
.usmt-term-tabs { display: flex; gap: 2px; min-width: 0; } .usmt-term-tabs { display: flex; gap: 2px; min-width: 0; }
.usmt-term-tab { font-family: Consolas, 'Cascadia Mono', 'Courier New', monospace; position: relative; } .usmt-term-tab { font-family: Consolas, 'Cascadia Mono', 'Courier New', monospace; position: relative; }
@@ -35,7 +35,8 @@ body.usmt-term-open { padding-bottom: calc(var(--usmt-term-h, 340px) + 72px); }
} }
.usmt-term-live i { width: 7px; height: 7px; border-radius: 50%; background: #16c60c; animation: usmt-pulse 1.6s infinite; } .usmt-term-live i { width: 7px; height: 7px; border-radius: 50%; background: #16c60c; animation: usmt-pulse 1.6s infinite; }
@keyframes usmt-pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.25; } } @keyframes usmt-pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.25; } }
.usmt-term-legend { font-size: 0.75em; color: #9ca3af; white-space: nowrap; cursor: help; } .usmt-term-legend { display: inline-flex; align-items: center; gap: 6px; font-size: 0.75em; color: #9ca3af; white-space: nowrap; cursor: help; }
.usmt-term-legend-dot { width: 7px; height: 7px; border-radius: 50%; background: #f9f1a5; opacity: 0.8; }
.usmt-term-follow.active { border-color: #4b5563; color: #fff; } .usmt-term-follow.active { border-color: #4b5563; color: #fff; }
.usmt-term-window { height: var(--usmt-term-h); display: flex; flex-direction: column; background: #012456; } .usmt-term-window { height: var(--usmt-term-h); display: flex; flex-direction: column; background: #012456; }
@@ -53,7 +54,7 @@ body.usmt-term-open { padding-bottom: calc(var(--usmt-term-h, 340px) + 72px); }
.usmt-term-body.active { display: block; } .usmt-term-body.active { display: block; }
.usmt-term-line { position: relative; min-height: 1.35em; } .usmt-term-line { position: relative; min-height: 1.35em; }
.usmt-term-line.sim::before { .usmt-term-line.sim::before {
content: '\25CF'; position: absolute; left: -13px; top: 0; font-size: 9px; line-height: 1.8em; color: #f9f1a5; opacity: 0.6; content: ''; position: absolute; left: -12px; top: 0.5em; width: 6px; height: 6px; border-radius: 50%; background: #f9f1a5; opacity: 0.8;
} }
/* PowerShell ConsoleColor -> Windows Terminal "Campbell Powershell" palette */ /* PowerShell ConsoleColor -> Windows Terminal "Campbell Powershell" palette */
+8 -3
View File
@@ -85,11 +85,11 @@
<div class="usmt-term-resize" title="Drag to resize"></div> <div class="usmt-term-resize" title="Drag to resize"></div>
<div class="usmt-term-bar"> <div class="usmt-term-bar">
<button class="usmt-term-toggle" type="button" title="Show / hide terminals"> <button class="usmt-term-toggle" type="button" title="Show / hide terminals">
<span class="usmt-term-chevron">&#9650;</span> Terminals <svg class="usmt-term-chevron" viewBox="0 0 10 10" aria-hidden="true"><path d="M1.5 6.5 5 3l3.5 3.5" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"/></svg><span>Terminals</span>
</button> </button>
<div class="usmt-term-tabs"></div> <div class="usmt-term-tabs"></div>
<span class="usmt-term-live" title="Streaming the real PowerShell console output from the server"><i></i>LIVE</span> <span class="usmt-term-live" title="Streaming the real PowerShell console output from the server"><i></i>LIVE</span>
${this.demo ? '<span class="usmt-term-legend" title="Lines marked with a dot were produced by your own actions. They are simulated in your browser and never reach the real services.">&#9679; your actions (simulated)</span>' : ''} ${this.demo ? '<span class="usmt-term-legend" title="Lines marked with a dot were produced by your own actions. They are simulated in your browser and never reach the real services."><i class="usmt-term-legend-dot"></i>your actions (simulated)</span>' : ''}
<button class="usmt-term-btn usmt-term-follow active" type="button" title="Auto-scroll">Follow</button> <button class="usmt-term-btn usmt-term-follow active" type="button" title="Auto-scroll">Follow</button>
</div> </div>
<div class="usmt-term-window"> <div class="usmt-term-window">
@@ -193,7 +193,12 @@
const st = this.state[id]; const st = this.state[id];
if (!st) return; if (!st) return;
st.hold = on; st.hold = on;
if (!on && st.held.length) { this.render(id, st.held, false); st.held = []; } if (!on && st.held.length) {
// Live output that arrived while a simulated cycle was printing
this.render(id, [{ s: [[`--- live output resumed: ${st.held.length} line(s) from the real worker arrived during your simulated cycle ---`, 'DarkGray']] }], true);
this.render(id, st.held, false);
st.held = [];
}
}, },
async poll(id) { async poll(id) {