Two follow-ups on the light-mode acid work: 1) Every hardcoded #d6ff3d and rgba(214,255,61,X) in the browser chrome and every addon panel now goes through var(--acid), so the light-mode BCH-teal (#0AC18E) takes effect everywhere — not just where var(--acid) was already used. Hex-with-alpha (#d6ff3d55 etc.) converts to color-mix(); rgba() converts to rgb(from var(--acid)…) for the same alpha with the current --acid hue. Chromium 128+ supports both. Files touched: chrome / settings / error / home / approval / bchwallet / siawallet / screenshot (html + css). Screenshot editor.js's #d6ff3d stays — that's the drawing colour swatch, not UI chrome. 2) The Theseus button (.logo) and update chip (.upchip) become dark BCH-navy chips (#253A49 background, #F8FDFF text) in light mode. Previously the .logo hardcoded #d6ff3d text on a bright-acid tint — invisible on a light toolbar. The dark chip stands out and gives the light theme a distinct accent using the BCH secondary from whybitcoincash.com's palette.
96 lines
6.5 KiB
HTML
96 lines
6.5 KiB
HTML
<!doctype html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<title>Approval</title>
|
|
<style>
|
|
:root { color-scheme: light dark;
|
|
--surface:#1c222c; --surface2:#0f1621; --line:rgba(255,255,255,.12);
|
|
--ink:#e7eaf1; --mut:#8b98a9; --dim:#5e6678; --acid:#d6ff3d; --danger:#f6768a; }
|
|
@media (prefers-color-scheme: light) {
|
|
:root { --surface:#ffffff; --surface2:#f1f4fa; --line:rgba(0,0,0,.12);
|
|
--ink:#1a1f2b; --mut:#5c6577; --dim:#8a93a5;
|
|
/* Darker acid for light backgrounds — ~5.5:1 on white. */
|
|
--acid: #0AC18E; }
|
|
}
|
|
* { box-sizing: border-box; }
|
|
html, body { margin: 0; height: 100%; background: transparent; }
|
|
body { font: 13px/1.5 system-ui, -apple-system, Segoe UI, Roboto, sans-serif; color: var(--ink); }
|
|
.promptmask { position: fixed; inset: 0; background: rgba(0,0,0,.45);
|
|
display: grid; place-items: start center; padding-top: 48px; }
|
|
.promptbox { background: var(--surface); border: 1px solid var(--line); border-radius: 12px;
|
|
padding: 16px 18px 14px; width: min(460px, calc(100vw - 32px));
|
|
box-shadow: 0 20px 60px #000d; animation: pop .12s ease-out; }
|
|
@keyframes pop { from { transform: translateY(-6px); opacity: 0; } to { transform: none; opacity: 1; } }
|
|
.who { display: flex; align-items: center; gap: 8px; color: var(--dim); font-size: 11.5px; margin-bottom: 8px; }
|
|
.who .addon { color: var(--mut); }
|
|
.title { font-size: 15px; font-weight: 650; letter-spacing: .1px; margin: 0 0 10px; }
|
|
.origin { display: inline-flex; align-items: center; gap: 8px; max-width: 100%;
|
|
background: var(--surface2); border: 1px solid rgb(from var(--acid) r g b / .35); color: var(--acid);
|
|
border-radius: 8px; padding: 6px 10px; margin-bottom: 12px;
|
|
font: 13px/1.3 ui-monospace, "Cascadia Code", Consolas, monospace; word-break: break-all; }
|
|
.origin .lbl { color: var(--dim); font: 11px system-ui, sans-serif; white-space: nowrap; }
|
|
.body { white-space: pre-wrap; color: var(--ink); margin-bottom: 12px; }
|
|
.rows { display: grid; grid-template-columns: max-content 1fr; gap: 6px 14px; margin-bottom: 12px;
|
|
background: var(--surface2); border: 1px solid var(--line); border-radius: 8px; padding: 10px 12px; }
|
|
.rows .k { color: var(--dim); font-size: 12px; white-space: nowrap; }
|
|
.rows .v { word-break: break-all; }
|
|
.rows .v.mono { font: 12.5px/1.4 ui-monospace, "Cascadia Code", Consolas, monospace; }
|
|
.rows .v.strong { font-weight: 650; font-size: 14px; }
|
|
label.chk { display: flex; align-items: center; gap: 8px; color: var(--mut); font-size: 12.5px; margin-bottom: 12px; cursor: pointer; }
|
|
label.chk select { flex: 1; padding: 5px 8px; border-radius: 6px; background: var(--surface2); color: var(--ink);
|
|
border: 1px solid var(--line); font: inherit; font-size: 12.5px; }
|
|
.pact { display: flex; gap: 6px; justify-content: flex-end; }
|
|
.pbtn { padding: 7px 14px; border-radius: 7px; border: 1px solid var(--line); background: var(--surface2);
|
|
color: var(--ink); cursor: pointer; font: inherit; font-size: 12.5px; }
|
|
.pbtn:hover { border-color: rgb(from var(--acid) r g b / .35); }
|
|
.pbtn.primary { background: var(--acid); color: #0b0e14; border-color: transparent; font-weight: 650; }
|
|
.pbtn.danger { background: var(--danger); color: #0b0e14; border-color: transparent; font-weight: 650; }
|
|
.pbtn:focus-visible { outline: 2px solid rgb(from var(--acid) r g b / .6); outline-offset: 1px; }
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<script>
|
|
const esc = (s) => String(s ?? "").replace(/[&<>"']/g, (c) => ({ "&":"&","<":"<",">":">",'"':""","'":"'" })[c]);
|
|
let current = null;
|
|
function finish(action, checked) {
|
|
if (!current) return;
|
|
const { reqId } = current;
|
|
const extra = document.getElementById("sel") ? document.getElementById("sel").value : "";
|
|
current = null;
|
|
document.body.innerHTML = "";
|
|
window.approval.pick(reqId, action, checked, extra);
|
|
}
|
|
window.approval.onShow((req) => {
|
|
current = req;
|
|
const rows = Array.isArray(req.rows) ? req.rows : [];
|
|
const actions = Array.isArray(req.actions) && req.actions.length ? req.actions : [{ id: "ok", label: "OK", primary: true }];
|
|
const hasCancel = actions.some((a) => a.id === "cancel");
|
|
document.body.innerHTML =
|
|
`<div class="promptmask"><div class="promptbox" role="dialog" aria-modal="true">
|
|
<div class="who"><span>🧩</span><span class="addon">${esc(req.addonName || req.addonId)}</span><span>·</span><span>asks for your approval</span></div>
|
|
<h1 class="title">${esc(req.title || "Approve?")}</h1>
|
|
${req.origin ? `<div class="origin"><span class="lbl">from</span><span>${esc(req.origin)}</span></div>` : ""}
|
|
${req.body ? `<div class="body">${esc(req.body)}</div>` : ""}
|
|
${rows.length ? `<div class="rows">${rows.map((r) => `<div class="k">${esc(r.label)}</div><div class="v${r.mono ? " mono" : ""}${r.strong ? " strong" : ""}">${esc(r.value)}</div>`).join("")}</div>` : ""}
|
|
${req.checkbox ? `<label class="chk"><input type="checkbox" id="chk"> ${esc(req.checkbox.label || "Always allow")}</label>` : ""}
|
|
${req.select ? `<label class="chk"><span>${esc(req.select.label)}</span><select id="sel">${req.select.options.map((o) => `<option value="${esc(o.value)}">${esc(o.label)}</option>`).join("")}</select></label>` : ""}
|
|
<div class="pact">
|
|
${hasCancel ? "" : `<button class="pbtn" type="button" data-id="cancel">Cancel</button>`}
|
|
${actions.map((a) => `<button class="pbtn${a.primary ? " primary" : ""}${a.danger ? " danger" : ""}" type="button" data-id="${esc(a.id)}">${esc(a.label || a.id)}</button>`).join("")}
|
|
</div>
|
|
</div></div>`;
|
|
const mask = document.querySelector(".promptmask");
|
|
mask.addEventListener("mousedown", (e) => { if (e.target === mask) finish("cancel", false); });
|
|
document.querySelectorAll("button[data-id]").forEach((b) => {
|
|
b.addEventListener("click", () => finish(b.dataset.id, !!document.getElementById("chk")?.checked));
|
|
});
|
|
// Focus the non-destructive default so Enter never blindly approves a
|
|
// spend; the user has to tab or click onto the primary action.
|
|
const first = document.querySelector('button[data-id="cancel"]') || document.querySelector("button");
|
|
setTimeout(() => first && first.focus(), 0);
|
|
});
|
|
document.addEventListener("keydown", (e) => { if (e.key === "Escape") finish("cancel", false); });
|
|
</script>
|
|
</body>
|
|
</html>
|