v3.36.0: a deliberate "insert the next card" cue for batch runs
The waiting phase is the only moment the operator must act, so it now: - shows a card-into-reader SVG animation in the status modal (inline SVG, CSS keyframes in src/style.css; reduced-motion users get the static card-above-the-slot picture); - plays a short Web Audio chime once per card, edge-triggered in the 2 s poll so it never repeats (the AudioContext is unlocked by the Start click); - sets the tab title to "Insert next card" while the window is hidden; - offers a speaker toggle next to the status (persisted as simple_ram_batch_sound, on by default). The prebuilt style.css was rebuilt: it had gone stale and lacked utilities the UI already used (bg-blue-50 on the batch notice, inline-flex, mx-2, max-h-48, w-44, min-w-24). 1022 Python + 1062 frontend green; simple-v470.
This commit is contained in:
+96
-10
@@ -616,6 +616,10 @@ video {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.\!visible {
|
||||
visibility: visible !important;
|
||||
}
|
||||
|
||||
.visible {
|
||||
visibility: visible;
|
||||
}
|
||||
@@ -684,6 +688,11 @@ video {
|
||||
grid-column: span 4 / span 4;
|
||||
}
|
||||
|
||||
.mx-2 {
|
||||
margin-left: 0.5rem;
|
||||
margin-right: 0.5rem;
|
||||
}
|
||||
|
||||
.mx-3 {
|
||||
margin-left: 0.75rem;
|
||||
margin-right: 0.75rem;
|
||||
@@ -807,6 +816,10 @@ video {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.inline-flex {
|
||||
display: inline-flex;
|
||||
}
|
||||
|
||||
.table {
|
||||
display: table;
|
||||
}
|
||||
@@ -843,6 +856,10 @@ video {
|
||||
max-height: 8rem;
|
||||
}
|
||||
|
||||
.max-h-48 {
|
||||
max-height: 12rem;
|
||||
}
|
||||
|
||||
.max-h-56 {
|
||||
max-height: 14rem;
|
||||
}
|
||||
@@ -935,6 +952,10 @@ video {
|
||||
width: 10rem;
|
||||
}
|
||||
|
||||
.w-44 {
|
||||
width: 11rem;
|
||||
}
|
||||
|
||||
.w-48 {
|
||||
width: 12rem;
|
||||
}
|
||||
@@ -980,6 +1001,10 @@ video {
|
||||
min-width: 0px;
|
||||
}
|
||||
|
||||
.min-w-24 {
|
||||
min-width: 6rem;
|
||||
}
|
||||
|
||||
.min-w-\[12rem\] {
|
||||
min-width: 12rem;
|
||||
}
|
||||
@@ -1395,6 +1420,11 @@ video {
|
||||
background-color: rgb(219 234 254 / var(--tw-bg-opacity, 1));
|
||||
}
|
||||
|
||||
.bg-blue-50 {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(239 246 255 / var(--tw-bg-opacity, 1));
|
||||
}
|
||||
|
||||
.bg-blue-50\/50 {
|
||||
background-color: rgb(239 246 255 / 0.5);
|
||||
}
|
||||
@@ -1796,6 +1826,11 @@ video {
|
||||
color: rgb(31 41 55 / var(--tw-text-opacity, 1));
|
||||
}
|
||||
|
||||
.text-gray-900 {
|
||||
--tw-text-opacity: 1;
|
||||
color: rgb(17 24 39 / var(--tw-text-opacity, 1));
|
||||
}
|
||||
|
||||
.text-green-600 {
|
||||
--tw-text-opacity: 1;
|
||||
color: rgb(22 163 74 / var(--tw-text-opacity, 1));
|
||||
@@ -1893,10 +1928,60 @@ video {
|
||||
filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow);
|
||||
}
|
||||
|
||||
.transition {
|
||||
transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter;
|
||||
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
|
||||
transition-duration: 150ms;
|
||||
}
|
||||
|
||||
.dark .text-heading {
|
||||
color: #f1f5f9;
|
||||
}
|
||||
|
||||
/* RAM batch: the "insert the next card" cue (v3.36.0).
|
||||
The card slides into the reader slot and back; the slot glows while the
|
||||
run waits. The static transform is the reduced-motion fallback: the card
|
||||
rests above the slot. */
|
||||
|
||||
.ram-insert-card {
|
||||
transform: translateY(-14px);
|
||||
animation: ram-insert 2.8s ease-in-out infinite;
|
||||
}
|
||||
|
||||
@keyframes ram-insert {
|
||||
0%, 12% {
|
||||
transform: translateY(-14px);
|
||||
}
|
||||
|
||||
45%, 55% {
|
||||
transform: translateY(10px);
|
||||
}
|
||||
|
||||
88%, 100% {
|
||||
transform: translateY(-14px);
|
||||
}
|
||||
}
|
||||
|
||||
.ram-insert-glow {
|
||||
animation: ram-insert-glow 1.4s ease-in-out infinite;
|
||||
}
|
||||
|
||||
@keyframes ram-insert-glow {
|
||||
0%, 100% {
|
||||
opacity: 0.35;
|
||||
}
|
||||
|
||||
50% {
|
||||
opacity: 0.95;
|
||||
}
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.ram-insert-card, .ram-insert-glow {
|
||||
animation: none;
|
||||
}
|
||||
}
|
||||
|
||||
.hover\:bg-amber-100:hover {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(254 243 199 / var(--tw-bg-opacity, 1));
|
||||
@@ -1956,11 +2041,6 @@ video {
|
||||
background-color: rgb(55 65 81 / var(--tw-bg-opacity, 1));
|
||||
}
|
||||
|
||||
.hover\:bg-red-100:hover {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(254 226 226 / var(--tw-bg-opacity, 1));
|
||||
}
|
||||
|
||||
.hover\:bg-red-200:hover {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(254 202 202 / var(--tw-bg-opacity, 1));
|
||||
@@ -2093,6 +2173,10 @@ video {
|
||||
background-color: rgb(30 58 138 / 0.1);
|
||||
}
|
||||
|
||||
.dark\:bg-blue-900\/20:is(.dark *) {
|
||||
background-color: rgb(30 58 138 / 0.2);
|
||||
}
|
||||
|
||||
.dark\:bg-blue-900\/40:is(.dark *) {
|
||||
background-color: rgb(30 58 138 / 0.4);
|
||||
}
|
||||
@@ -2258,10 +2342,6 @@ video {
|
||||
background-color: rgb(6 78 59 / 0.4);
|
||||
}
|
||||
|
||||
.dark\:hover\:bg-red-900\/40:hover:is(.dark *) {
|
||||
background-color: rgb(127 29 29 / 0.4);
|
||||
}
|
||||
|
||||
.dark\:hover\:bg-red-900\/50:hover:is(.dark *) {
|
||||
background-color: rgb(127 29 29 / 0.5);
|
||||
}
|
||||
@@ -2289,6 +2369,11 @@ video {
|
||||
color: rgb(209 213 219 / var(--tw-text-opacity, 1));
|
||||
}
|
||||
|
||||
.dark\:hover\:text-slate-200:hover:is(.dark *) {
|
||||
--tw-text-opacity: 1;
|
||||
color: rgb(226 232 240 / var(--tw-text-opacity, 1));
|
||||
}
|
||||
|
||||
.dark\:hover\:text-slate-300:hover:is(.dark *) {
|
||||
--tw-text-opacity: 1;
|
||||
color: rgb(203 213 225 / var(--tw-text-opacity, 1));
|
||||
@@ -2328,7 +2413,8 @@ video {
|
||||
.lg\:flex-row {
|
||||
flex-direction: row;
|
||||
}
|
||||
}/* ===== Theme contrast adjustments ===== */
|
||||
}
|
||||
/* ===== Theme contrast adjustments ===== */
|
||||
|
||||
/* Light theme: darken softer (muted) text one step for higher contrast */
|
||||
.text-gray-400 {
|
||||
|
||||
Reference in New Issue
Block a user