Spaces:
Running
Running
Warm up queue copy: overhug subline + funnier at-capacity modal
Browse files- Add a sentence-case reassurance line under the queued position ("Sorry,
we overhugged! ..."), shown only while waiting in line. New
#circle-subcaption element + style; toggled in setState.
- Rework the at-capacity modal copy to the same tone ("Hugged to the
limit").
- index.html +1 -0
- main.js +11 -0
- style.css +14 -0
- ui/account.js +2 -2
index.html
CHANGED
|
@@ -131,6 +131,7 @@
|
|
| 131 |
</div>
|
| 132 |
|
| 133 |
<p id="circle-caption" class="circle-caption" role="status">Tap to start</p>
|
|
|
|
| 134 |
|
| 135 |
<div id="queue-actions" class="queue-actions" hidden>
|
| 136 |
<button id="join-queue-btn" class="join-queue-btn" type="button" hidden>
|
|
|
|
| 131 |
</div>
|
| 132 |
|
| 133 |
<p id="circle-caption" class="circle-caption" role="status">Tap to start</p>
|
| 134 |
+
<p id="circle-subcaption" class="circle-subcaption" hidden></p>
|
| 135 |
|
| 136 |
<div id="queue-actions" class="queue-actions" hidden>
|
| 137 |
<button id="join-queue-btn" class="join-queue-btn" type="button" hidden>
|
main.js
CHANGED
|
@@ -180,6 +180,8 @@ const LIVE_STATES = new Set(["listening", "user-speaking", "processing", "ai-spe
|
|
| 180 |
const circleBtn = $("#main-circle");
|
| 181 |
/** @type {HTMLParagraphElement} */
|
| 182 |
const circleCaption = $("#circle-caption");
|
|
|
|
|
|
|
| 183 |
/** @type {HTMLElement} */
|
| 184 |
const orbWrap = $(".orb-wrap");
|
| 185 |
/** @type {HTMLButtonElement} */
|
|
@@ -360,6 +362,15 @@ function setState(next) {
|
|
| 360 |
leaveQueueBtn.tabIndex = inLine ? 0 : -1;
|
| 361 |
if (!yourTurn) stopJoinCountdown();
|
| 362 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 363 |
updateRestartAvailability();
|
| 364 |
}
|
| 365 |
|
|
|
|
| 180 |
const circleBtn = $("#main-circle");
|
| 181 |
/** @type {HTMLParagraphElement} */
|
| 182 |
const circleCaption = $("#circle-caption");
|
| 183 |
+
/** @type {HTMLParagraphElement} */
|
| 184 |
+
const circleSubcaption = $("#circle-subcaption");
|
| 185 |
/** @type {HTMLElement} */
|
| 186 |
const orbWrap = $(".orb-wrap");
|
| 187 |
/** @type {HTMLButtonElement} */
|
|
|
|
| 362 |
leaveQueueBtn.tabIndex = inLine ? 0 : -1;
|
| 363 |
if (!yourTurn) stopJoinCountdown();
|
| 364 |
|
| 365 |
+
// Warm reassurance under the terse position, only while waiting in line.
|
| 366 |
+
if (next === "queued") {
|
| 367 |
+
circleSubcaption.textContent =
|
| 368 |
+
"Sorry, we overhugged! 🤗 Every slot is busy, so we saved you a spot. Hang tight, you're moving up.";
|
| 369 |
+
circleSubcaption.hidden = false;
|
| 370 |
+
} else {
|
| 371 |
+
circleSubcaption.hidden = true;
|
| 372 |
+
}
|
| 373 |
+
|
| 374 |
updateRestartAvailability();
|
| 375 |
}
|
| 376 |
|
style.css
CHANGED
|
@@ -847,6 +847,20 @@ a:hover {
|
|
| 847 |
letter-spacing: 0.08em;
|
| 848 |
}
|
| 849 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 850 |
/* Queue actions sit under the caption: "Join now" (primary, only when it's your
|
| 851 |
* turn) stacked above the quiet "Leave queue" escape hatch. */
|
| 852 |
.queue-actions {
|
|
|
|
| 847 |
letter-spacing: 0.08em;
|
| 848 |
}
|
| 849 |
|
| 850 |
+
/* Warm, human line under the mono caption — sentence case, only while queued.
|
| 851 |
+
* The caption keeps the terse position; this reassures. */
|
| 852 |
+
.circle-subcaption {
|
| 853 |
+
margin: 8px 0 0;
|
| 854 |
+
max-width: 32ch;
|
| 855 |
+
font-size: 13.5px;
|
| 856 |
+
line-height: 1.5;
|
| 857 |
+
color: var(--text-dim);
|
| 858 |
+
text-align: center;
|
| 859 |
+
text-wrap: balance;
|
| 860 |
+
transition: opacity 0.25s ease;
|
| 861 |
+
}
|
| 862 |
+
.circle-subcaption[hidden] { display: none; }
|
| 863 |
+
|
| 864 |
/* Queue actions sit under the caption: "Join now" (primary, only when it's your
|
| 865 |
* turn) stacked above the quiet "Leave queue" escape hatch. */
|
| 866 |
.queue-actions {
|
ui/account.js
CHANGED
|
@@ -179,9 +179,9 @@ export class Account {
|
|
| 179 |
/** Show a warm "we're at capacity" message when even the waiting line is full.
|
| 180 |
* Reuses the limit modal shell; no call-to-action, just reassurance. */
|
| 181 |
showBusy() {
|
| 182 |
-
this._modalTitle.textContent = "
|
| 183 |
this._modalMsg.textContent =
|
| 184 |
-
"
|
| 185 |
this._modalNote.textContent = "A spot usually opens up within a few minutes.";
|
| 186 |
this._modalCta.hidden = true;
|
| 187 |
if (!this._modal.open) this._modal.showModal();
|
|
|
|
| 179 |
/** Show a warm "we're at capacity" message when even the waiting line is full.
|
| 180 |
* Reuses the limit modal shell; no call-to-action, just reassurance. */
|
| 181 |
showBusy() {
|
| 182 |
+
this._modalTitle.textContent = "Hugged to the limit 🤗";
|
| 183 |
this._modalMsg.textContent =
|
| 184 |
+
"Every slot and the whole line are full right now. Too much love! Grab a coffee and pop back in a minute.";
|
| 185 |
this._modalNote.textContent = "A spot usually opens up within a few minutes.";
|
| 186 |
this._modalCta.hidden = true;
|
| 187 |
if (!this._modal.open) this._modal.showModal();
|