2026-05-08 23:39:58 -05:00
|
|
|
---
|
2026-05-09 11:33:06 -05:00
|
|
|
import '../ui/crt.css'
|
2026-05-12 20:52:35 -05:00
|
|
|
|
|
|
|
|
const buildNumber = process.env.CI_PIPELINE_NUMBER ?? 'local'
|
2026-05-08 23:39:58 -05:00
|
|
|
---
|
|
|
|
|
|
|
|
|
|
<html lang="en">
|
|
|
|
|
<head>
|
|
|
|
|
<meta charset="utf-8" />
|
|
|
|
|
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
|
|
|
|
|
<title>Halfstreet — Ethan J Lewis</title>
|
|
|
|
|
<meta name="description" content="A gothic mystery." />
|
|
|
|
|
<meta name="robots" content="noindex" />
|
2026-05-10 07:00:22 -05:00
|
|
|
<link rel="icon" href="/favicon.ico" sizes="any" />
|
|
|
|
|
<link rel="icon" href="/favicon.svg" type="image/svg+xml" />
|
|
|
|
|
<link rel="icon" href="/favicon-96x96.png" type="image/png" sizes="96x96" />
|
|
|
|
|
<link rel="apple-touch-icon" href="/apple-touch-icon.png" />
|
|
|
|
|
<link rel="manifest" href="/site.webmanifest" />
|
|
|
|
|
<meta name="theme-color" content="#1a0d00" />
|
2026-05-08 23:39:58 -05:00
|
|
|
</head>
|
|
|
|
|
<body>
|
|
|
|
|
<div class="mystery-root" data-mystery-root>
|
|
|
|
|
<div class="mystery-bezel">
|
2026-05-10 07:00:22 -05:00
|
|
|
<div class="mystery-options" data-mystery-options>
|
|
|
|
|
<button
|
|
|
|
|
type="button"
|
|
|
|
|
class="mystery-options-toggle"
|
|
|
|
|
data-options-toggle
|
|
|
|
|
aria-label="Options"
|
|
|
|
|
aria-expanded="false"
|
|
|
|
|
>
|
2026-05-10 07:34:51 -05:00
|
|
|
<svg
|
|
|
|
|
class="mystery-options-icon"
|
|
|
|
|
aria-hidden="true"
|
|
|
|
|
viewBox="0 0 1200 1200"
|
|
|
|
|
focusable="false"
|
|
|
|
|
>
|
|
|
|
|
<path d="m541.45 262.22-14.297 48.703c-2.8125 8.8125-9.7031 15.703-18.469 18.609-5.8594 2.1562-12.703 4.6875-20.766 8.1562-8.3906 4.0781-18.234 4.0781-26.625 0l-46.078-25.688c-9.2812-4.9688-20.578-4.3125-29.156 1.7812-25.969 19.266-49.266 41.859-69.281 67.219-6.4219 8.4375-7.125 19.969-1.7812 29.156l25.781 44.156c4.5469 7.875 4.875 17.531 0.84375 25.688-3.6094 7.0781-6.4688 13.781-9.1406 20.531h0.046875c-3.2344 8.4844-10.312 14.953-19.078 17.391l-50.766 13.781c-10.219 2.625-17.906 11.062-19.453 21.516-4.4531 31.406-4.4531 63.328 0 94.781 1.3594 10.641 9.2344 19.266 19.688 21.609l50.297 13.781c8.9062 2.3906 16.125 8.9062 19.406 17.531 2.5312 6.6094 5.3906 13.219 8.7656 20.297 3.8438 7.9219 3.6094 17.25-0.70312 24.938l-25.781 44.625h-0.046875c-5.4375 9.1406-4.6406 20.719 1.9219 29.062 20.062 25.172 43.359 47.625 69.281 66.703 8.5312 6.3281 20.016 6.9844 29.25 1.6875l45.609-24.844c8.3906-4.2656 18.281-4.5 26.859-0.70312 7.0781 3.2344 13.781 5.8594 20.859 8.3906h0.046875c8.6719 2.9062 15.516 9.75 18.375 18.469l14.156 48.703v0.046875c2.5312 10.406 11.297 18.141 21.938 19.406 12.234 1.5 24.516 2.25 36.844 2.2969 12.047-0.28125 24.047-1.2188 36-2.8594 10.594-1.1719 19.406-8.7656 22.078-19.078l14.297-48.938v-0.046875c2.7188-8.6719 9.375-15.516 18-18.469 7.4531-2.625 14.156-5.2969 21-8.3906 8.625-3.9375 18.562-3.7031 27 0.5625l46.078 25.219c9.1406 5.3906 20.625 4.875 29.25-1.3125 26.016-19.266 49.359-41.812 69.516-67.078 6.4688-8.3906 7.1719-19.922 1.7812-29.062l-25.781-45c-4.3125-7.6406-4.5938-16.922-0.75-24.844 3.375-7.2188 6.2344-13.781 8.625-20.156h0.046875c3.2344-8.6719 10.453-15.281 19.406-17.766l50.062-13.688v0.046875c10.406-2.1562 18.375-10.594 19.922-21.141 4.4062-31.547 4.4062-63.516 0-95.062-1.5938-10.453-9.2812-18.984-19.594-21.562l-50.766-13.781 0.046875-0.046875c-8.7656-2.4375-15.891-8.8594-19.078-17.391-2.625-6.7031-5.5312-13.453-9-20.297-3.8906-8.0156-3.6094-17.391 0.70312-25.172l25.781-44.297c5.4375-9.1406 4.6875-20.625-1.7812-29.016-20.016-25.453-43.359-48.047-69.375-67.312-8.4375-6.0469-19.547-6.8438-28.781-2.0625l-45.844 25.078c-8.4844 4.0781-18.375 4.0781-26.906 0-7.9219-3.4688-14.766-6-20.625-8.1562-8.7188-2.8594-15.562-9.6562-18.469-18.375l-14.156-48.609c-2.625-10.359-11.344-18.047-21.984-19.312-12.188-1.4531-24.422-2.3438-36.703-2.625-12 0-24 1.5469-36 3.1406-10.781 1.0312-19.734 8.625-22.547 19.078zm58.547 175.18c65.766 0 125.06 39.609 150.24 100.41 25.172 60.75 11.25 130.69-35.25 177.19s-116.44 60.422-177.19 35.25c-60.797-25.172-100.41-84.469-100.41-150.24 0.09375-89.766 72.844-162.52 162.61-162.61z" />
|
|
|
|
|
</svg>
|
2026-05-10 07:00:22 -05:00
|
|
|
</button>
|
|
|
|
|
<div class="mystery-options-menu" data-options-menu hidden>
|
|
|
|
|
<div class="mystery-options-group" aria-label="Screen">
|
|
|
|
|
<div class="mystery-options-label">Screen</div>
|
|
|
|
|
<button type="button" data-theme-choice="amber" aria-pressed="true">Amber</button>
|
|
|
|
|
<button type="button" data-theme-choice="ansi" aria-pressed="false">ANSI</button>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="mystery-options-group" aria-label="Cursor">
|
|
|
|
|
<div class="mystery-options-label">Cursor</div>
|
|
|
|
|
<button type="button" data-cursor-choice="bar" aria-pressed="true">Bar</button>
|
|
|
|
|
<button type="button" data-cursor-choice="block" aria-pressed="false">Block</button>
|
|
|
|
|
<button type="button" data-cursor-choice="underscore" aria-pressed="false">Underline</button>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="mystery-options-group" aria-label="Game">
|
|
|
|
|
<div class="mystery-options-label">Game</div>
|
2026-05-12 14:48:19 -05:00
|
|
|
<button type="button" data-chips-choice="on" aria-pressed="true">Chips On</button>
|
|
|
|
|
<button type="button" data-chips-choice="off" aria-pressed="false">Chips Off</button>
|
2026-05-10 07:00:22 -05:00
|
|
|
<button type="button" data-restart-choice>Restart</button>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
2026-05-08 23:39:58 -05:00
|
|
|
</div>
|
|
|
|
|
<div class="mystery-transcript" data-mystery-transcript aria-live="polite" aria-atomic="false"></div>
|
2026-05-10 10:17:42 -05:00
|
|
|
<div class="mystery-controls">
|
|
|
|
|
<div class="mystery-chips" data-mystery-chips></div>
|
|
|
|
|
<div class="mystery-light-meter" data-mystery-light-meter aria-hidden="true"></div>
|
|
|
|
|
</div>
|
2026-05-08 23:39:58 -05:00
|
|
|
<div class="mystery-input-row">
|
|
|
|
|
<input
|
|
|
|
|
class="mystery-input"
|
|
|
|
|
data-mystery-input
|
|
|
|
|
type="text"
|
|
|
|
|
autocomplete="off"
|
|
|
|
|
autocorrect="off"
|
|
|
|
|
autocapitalize="none"
|
|
|
|
|
spellcheck="false"
|
|
|
|
|
aria-label="Command input"
|
|
|
|
|
/>
|
2026-05-10 07:00:22 -05:00
|
|
|
<span class="mystery-input-display" data-mystery-input-display aria-hidden="true"></span>
|
2026-05-08 23:39:58 -05:00
|
|
|
</div>
|
|
|
|
|
</div>
|
2026-05-09 21:51:12 -05:00
|
|
|
<footer class="mystery-footer">
|
2026-05-10 07:00:22 -05:00
|
|
|
© 2026 <a href="https://ethanjlewis.com">Ethan J Lewis</a>
|
2026-05-09 21:51:12 -05:00
|
|
|
<span aria-hidden="true">|</span>
|
2026-05-10 07:00:22 -05:00
|
|
|
<a href="https://half.st/ejlewis/halfstreet/src/branch/main/LICENSE">GNU 3.0</a>
|
2026-05-09 21:51:12 -05:00
|
|
|
<span aria-hidden="true">|</span>
|
2026-05-12 20:52:35 -05:00
|
|
|
<span>Build #{buildNumber}</span>
|
|
|
|
|
<span aria-hidden="true">|</span>
|
2026-05-10 07:00:22 -05:00
|
|
|
<a href="https://half.st/ejlewis/halfstreet">Source Code</a>
|
2026-05-09 21:51:12 -05:00
|
|
|
</footer>
|
2026-05-08 23:39:58 -05:00
|
|
|
</div>
|
|
|
|
|
<script>
|
|
|
|
|
// Theme attribute is set on :root before any rendering to avoid a flash
|
|
|
|
|
// of the wrong palette. The full theme toggle wiring lands in Task 11.
|
|
|
|
|
const stored = (() => {
|
|
|
|
|
try { return localStorage.getItem('halfstreet:theme:v1') } catch { return null }
|
|
|
|
|
})()
|
2026-05-10 07:00:22 -05:00
|
|
|
const storedCursor = (() => {
|
|
|
|
|
try { return localStorage.getItem('halfstreet:cursor:v1') } catch { return null }
|
|
|
|
|
})()
|
2026-05-12 14:48:19 -05:00
|
|
|
const storedChips = (() => {
|
|
|
|
|
try { return localStorage.getItem('halfstreet:chips:v1') } catch { return null }
|
|
|
|
|
})()
|
2026-05-08 23:39:58 -05:00
|
|
|
document.documentElement.setAttribute('data-mystery-theme', stored === 'ansi' ? 'ansi' : 'amber')
|
2026-05-10 07:00:22 -05:00
|
|
|
document.documentElement.setAttribute(
|
|
|
|
|
'data-mystery-cursor',
|
|
|
|
|
storedCursor === 'block' || storedCursor === 'underscore' ? storedCursor : 'bar',
|
|
|
|
|
)
|
2026-05-12 14:48:19 -05:00
|
|
|
document.documentElement.setAttribute('data-mystery-chips-state', storedChips === 'off' ? 'off' : 'on')
|
2026-05-08 23:39:58 -05:00
|
|
|
</script>
|
|
|
|
|
<script>
|
2026-05-09 11:33:06 -05:00
|
|
|
import '../ui/terminal.ts'
|
|
|
|
|
import '../ui/theme.ts'
|
2026-05-08 23:39:58 -05:00
|
|
|
</script>
|
|
|
|
|
</body>
|
|
|
|
|
</html>
|