diff --git a/docker/lnd-ui/index.html b/docker/lnd-ui/index.html
index bc31a5ae..c5cf8da5 100644
--- a/docker/lnd-ui/index.html
+++ b/docker/lnd-ui/index.html
@@ -196,8 +196,8 @@
not a loading state, and it is the one number that frightens
people. It inherits currentColor, so each tile shimmers in its own
rail colour. */
- .bal-pixels { display: inline-grid; grid-template-columns: repeat(14, 4px); grid-auto-rows: 4px; gap: 1px; vertical-align: 0.15em; }
- .bal-pixels i { width: 4px; height: 4px; border-radius: 0.5px; background: currentColor; opacity: 0.16; animation: bal-pixel-scan 1.4s ease-in-out infinite; }
+ .bal-pixels { display: inline-grid; grid-auto-flow: column; grid-template-rows: repeat(3, 4px); grid-auto-columns: 4px; gap: 1px; vertical-align: 0.1em; }
+ .bal-pixels i { width: 4px; height: 4px; border-radius: 0.5px; background: currentColor; opacity: 0.16; animation: bal-pixel-scan 1.6s ease-in-out infinite; }
@keyframes bal-pixel-scan { 0%, 70%, 100% { opacity: 0.16; } 25% { opacity: 1; } 45% { opacity: 0.42; } }
@media (prefers-reduced-motion: reduce) { .bal-pixels i { animation: none; opacity: 0.35; } }
.bg-green { background: #4ade80; } .bg-yellow { background: #facc15; } .bg-red { background: #f87171; }
@@ -1083,9 +1083,11 @@
// 28 cells = 14 columns x 2 rows, delays staggered so the lit column
// travels across the matrix.
+ // 14 columns x 3 rows, laid out column-first so the three cells of a
+ // column share a delay and the lit column scans across as one line.
const BAL_PIXELS = '' +
- Array.from({ length: 28 }, function (_, i) {
- return '';
+ Array.from({ length: 42 }, function (_, i) {
+ return '';
}).join('') + '';
// Render a balance, or the pixel readout when it is not known yet.
diff --git a/neode-ui/src/components/BalanceAmount.vue b/neode-ui/src/components/BalanceAmount.vue
index ae8bf6c7..caaf3cb2 100644
--- a/neode-ui/src/components/BalanceAmount.vue
+++ b/neode-ui/src/components/BalanceAmount.vue
@@ -34,9 +34,18 @@ const props = withDefaults(
{ suffix: 'sats', label: 'balance' },
)
-// 14 columns × 2 rows. Enough to read as a matrix rather than a spinner, and
-// close to the width of a five-figure sat amount.
-const CELLS = 28
+// 14 columns × 3 rows, laid out column-first so all three cells of a column
+// share a delay and the lit column travels across as a single scan line —
+// that is what makes it read as a readout rather than a progress bar.
+const COLUMNS = 14
+const ROWS = 3
+const CELLS = COLUMNS * ROWS
+const STEP_MS = 55
+
+/** Delay for cell `i` (1-based), constant within a column. */
+function cellDelay(i: number): string {
+ return `${Math.floor((i - 1) / ROWS) * STEP_MS}ms`
+}
/**
* Built as one string rather than interpolated around a ``, so the
@@ -59,7 +68,7 @@ const display = computed(() => {
:aria-label="`Loading ${props.label}`"
:title="`Loading ${props.label}…`"
>
-
+
{{ display }}
@@ -67,12 +76,15 @@ const display = computed(() => {