diff --git a/configs/bank-landing/goa-amount.js b/configs/bank-landing/goa-amount.js
new file mode 100644
index 0000000..67c3859
--- /dev/null
+++ b/configs/bank-landing/goa-amount.js
@@ -0,0 +1,169 @@
+/* Compact GOA / CUR:amount display using currency alt_unit_names.
+ * Large values → "1.23 Mega-GOA" (title = full GOA:n) so landing tiles fit.
+ */
+(function (global) {
+ "use strict";
+
+ var DEFAULT_ALT = {
+ "24": "Yotta-GOA",
+ "21": "Zetta-GOA",
+ "18": "Exa-GOA",
+ "15": "Peta-GOA",
+ "12": "Tera-GOA",
+ "9": "Giga-GOA",
+ "6": "Mega-GOA",
+ "3": "Kilo-GOA",
+ "0": "GOA",
+ "-1": "Deci-GOA",
+ "-2": "Centi-GOA",
+ "-3": "Milli-GOA",
+ "-6": "Micro-GOA",
+ "-7": "Deci-Micro-GOA",
+ "-8": "Atomic-GOA"
+ };
+
+ var THRESHOLD = 1000;
+
+ function parseAmount(s) {
+ if (s == null || s === "") return { cur: "GOA", val: 0 };
+ if (typeof s === "number") return { cur: "GOA", val: s };
+ var t = String(s).trim();
+ var i = t.indexOf(":");
+ if (i < 0) return { cur: "GOA", val: parseFloat(t) || 0 };
+ return {
+ cur: t.slice(0, i) || "GOA",
+ val: parseFloat(t.slice(i + 1)) || 0
+ };
+ }
+
+ function fmtCoeff(v) {
+ if (!isFinite(v)) return "?";
+ var a = Math.abs(v);
+ if (Math.abs(a - Math.round(a)) < 1e-9) return String(Math.round(v));
+ var s = v.toFixed(4).replace(/\.?0+$/, "");
+ return s;
+ }
+
+ function baseStr(cur, val) {
+ if (!isFinite(val)) return String(cur) + ":?";
+ if (Math.abs(val - Math.round(val)) < 1e-9) return cur + ":" + Math.round(val);
+ return cur + ":" + String(val).replace(/(\.\d*?[1-9])0+$/, "$1").replace(/\.0+$/, "");
+ }
+
+ /**
+ * @param {string|number} amount
+ * @param {object} [altMap]
+ * @returns {{ display: string, title: string, raw: string, usedAlt: boolean }}
+ */
+ function format(amount, altMap) {
+ if (amount == null || amount === "") {
+ return { display: "—", title: "", raw: "", usedAlt: false };
+ }
+ // Prefer server-provided alt if caller passes object {amount, amount_alt}
+ if (typeof amount === "object" && amount) {
+ if (amount.amount_alt) {
+ var rawO = amount.amount || amount.amount_full || String(amount.amount_alt);
+ return {
+ display: String(amount.amount_alt),
+ title: amount.amount_full || rawO,
+ raw: String(rawO),
+ usedAlt: true
+ };
+ }
+ amount = amount.amount || amount.amount_full || "";
+ }
+
+ var alt = altMap || global.__GOA_ALT_UNITS || DEFAULT_ALT;
+ var p = parseAmount(amount);
+ var raw = baseStr(p.cur, p.val);
+ // Foreign currencies must not pick up Kilo-GOA / Mega-GOA labels
+ var baseName = (alt && alt["0"]) || p.cur;
+ var curU = String(p.cur || "").toUpperCase();
+ var baseU = String(baseName || "").toUpperCase();
+ if (curU && curU !== "GOA" && (baseU === "GOA" || baseU.indexOf("GOA") !== -1)) {
+ return { display: raw, title: raw, raw: raw, usedAlt: false };
+ }
+ if (p.val === 0) {
+ return { display: raw, title: raw, raw: raw, usedAlt: false };
+ }
+ if (Math.abs(p.val) < THRESHOLD) {
+ return { display: raw, title: raw, raw: raw, usedAlt: false };
+ }
+
+ var scales = [];
+ Object.keys(alt || {}).forEach(function (k) {
+ var n = parseInt(k, 10);
+ if (!isNaN(n)) scales.push({ sc: n, name: String(alt[k]) });
+ });
+ scales.sort(function (a, b) { return b.sc - a.sc; });
+
+ var abs = Math.abs(p.val);
+ var chosen = null;
+ for (var i = 0; i < scales.length; i++) {
+ var unit = Math.pow(10, scales[i].sc);
+ if (!(unit > 0)) continue;
+ var coeff = abs / unit;
+ if (coeff >= 1) {
+ chosen = {
+ sc: scales[i].sc,
+ name: scales[i].name,
+ coeff: p.val >= 0 ? coeff : -coeff
+ };
+ break;
+ }
+ }
+ if (!chosen || chosen.sc === 0) {
+ return { display: raw, title: raw, raw: raw, usedAlt: false };
+ }
+ var short = fmtCoeff(chosen.coeff) + " " + chosen.name;
+ return {
+ display: short,
+ title: short + " (" + raw + ")",
+ raw: raw,
+ usedAlt: true
+ };
+ }
+
+ function setText(el, amount, altMap) {
+ if (!el) return;
+ var f = format(amount, altMap);
+ el.textContent = f.display;
+ if (f.title && f.title !== f.display) el.setAttribute("title", f.title);
+ else el.removeAttribute("title");
+ }
+
+ function setById(id, amount, altMap) {
+ setText(document.getElementById(id), amount, altMap);
+ }
+
+ /** Prefer amount_alt from stats row, else format amount. */
+ function pick(rowOrAmount, altMap) {
+ if (rowOrAmount && typeof rowOrAmount === "object") {
+ if (rowOrAmount.amount_alt) {
+ return format({
+ amount: rowOrAmount.amount,
+ amount_alt: rowOrAmount.amount_alt,
+ amount_full: rowOrAmount.amount_full
+ }, altMap);
+ }
+ return format(rowOrAmount.amount || rowOrAmount.total_amount, altMap);
+ }
+ return format(rowOrAmount, altMap);
+ }
+
+ function rememberAlt(stats) {
+ if (stats && stats.alt_unit_names && typeof stats.alt_unit_names === "object") {
+ global.__GOA_ALT_UNITS = stats.alt_unit_names;
+ }
+ }
+
+ global.GoaAmount = {
+ format: format,
+ setText: setText,
+ setById: setById,
+ pick: pick,
+ rememberAlt: rememberAlt,
+ DEFAULT_ALT: DEFAULT_ALT,
+ THRESHOLD: THRESHOLD
+ };
+})(typeof window !== "undefined" ? window : globalThis);
diff --git a/configs/bank-landing/index.html b/configs/bank-landing/index.html
index b527ea7..4531fa2 100644
--- a/configs/bank-landing/index.html
+++ b/configs/bank-landing/index.html
@@ -1493,6 +1493,33 @@ tw run-until-done && tw balance
+
+
+