bitspire/apps/machine/index.html
Padreug aa22ba1c27 fix(machine): keep the mouse pointer visible on the web demo
index.html's inline <style> hid the cursor on any viewport >= 1024px:

    @media (min-width: 1024px) { html, body { overflow: hidden; cursor: none; } }

which is every desktop browser opening the public demo. Descendants inherit
it, so the pointer vanished everywhere except over buttons — those carry
Tailwind's .cursor-pointer, which overrode the inherited value and made the
bug look stranger than it was.

This is the rule the earlier .kiosk scoping missed: src/style.css got gated,
this one did not, so the two disagreed.

Delete it rather than gate it. src/style.css's `.kiosk, .kiosk *` rule already
covers <html> and every descendant with !important, and main.ts applies that
class unless VITE_DEMO_TAG is set — so real machines are unaffected and cursor
hiding now has exactly one owner, the one that knows whether this is a kiosk.
The block here cannot make that call: it is static HTML, and the page CSP
(script-src 'self') forbids an inline script that could read the env.

overflow: hidden stays as it was — untouched on both.

Verified by building both ways: without the tag the built HTML has no cursor
rule, the JS still adds .kiosk and the CSS still carries the !important
hide; with the tag the .kiosk branch is dead-code-eliminated and no
cursor: none survives anywhere.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013A6683cCHnQxFUosx1krY4
2026-09-22 14:54:57 +02:00

55 lines
2.1 KiB
HTML

<!doctype html>
<html lang="en" class="dark">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/png" href="/logo.png" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no" />
<!--
Content Security Policy:
- script-src 'self': only our own bundled scripts, no inline/eval (XSS protection)
- style-src 'self' 'unsafe-inline': Vue injects styles inline
- connect-src: WebSocket for Nostr relay, HTTPS for Lightning.Pub and exchange rate APIs
- img-src 'self' data: blob:: QR codes use data URIs
- default-src 'self': deny everything not explicitly allowed
- frame-src 'none': no iframes
- object-src 'none': no plugins
-->
<meta
http-equiv="Content-Security-Policy"
content="default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; connect-src 'self' ws: wss: http: https:; img-src 'self' data: blob:; font-src 'self'; frame-src 'none'; object-src 'none'"
/>
<title>bitSpire ATM</title>
<style>
/* Prevent text selection and context menu on kiosk */
* {
user-select: none;
-webkit-user-select: none;
touch-action: manipulation;
-webkit-tap-highlight-color: transparent;
}
html,
body {
margin: 0;
padding: 0;
background: #000;
}
/* Kiosk-only: lock overflow. The cursor is NOT hidden here — that is
src/style.css's `.kiosk` rule, which main.ts applies at runtime unless
VITE_DEMO_TAG is set. This block can't make that distinction (static
HTML, and the CSP forbids an inline script to read the env), so a
`cursor: none` here would also blank the pointer on the public web
demo, where people drive the kiosk with a mouse. One owner for cursor
hiding, and it is the one that knows whether this is a real machine. */
@media (min-width: 1024px) {
html,
body {
overflow: hidden;
}
}
</style>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.ts"></script>
</body>
</html>