diff --git a/src/pages/mystery.astro b/src/pages/mystery.astro new file mode 100644 index 0000000..3af1f10 --- /dev/null +++ b/src/pages/mystery.astro @@ -0,0 +1,48 @@ +--- +import '../mystery/ui/crt.css' +--- + + + + + + Halfstreet — Ethan J Lewis + + + + +
+
+
+ + +
+
+
+
+ +
+
+
+ + + + diff --git a/src/ui/crt.css b/src/ui/crt.css new file mode 100644 index 0000000..d6c5159 --- /dev/null +++ b/src/ui/crt.css @@ -0,0 +1,171 @@ +:root[data-mystery-theme='amber'] { + --m-bg: #1a0d00; + --m-fg: #ffb000; + --m-accent-1: #ffb000; + --m-accent-2: #ffb000; + --m-dim: rgba(255, 176, 0, 0.55); + --m-bezel: #0a0500; + --m-divider-style: dashed; +} + +:root[data-mystery-theme='ansi'] { + --m-bg: #000080; + --m-fg: #ffffff; + --m-accent-1: #ffff55; + --m-accent-2: #55ffff; + --m-dim: #aaaaaa; + --m-bezel: #000040; + --m-divider-style: double; +} + +.mystery-root { + position: fixed; + inset: 0; + background: var(--m-bezel); + color: var(--m-fg); + font-family: 'Courier New', 'Cascadia Mono', 'Consolas', monospace; + font-size: 14px; + line-height: 1.45; + letter-spacing: 0.02em; + display: flex; + flex-direction: column; + padding: 16px; + box-sizing: border-box; + text-shadow: 0 0 1.5px currentColor; +} + +.mystery-bezel { + flex: 1; + background: var(--m-bg); + border-radius: 6px; + padding: 22px 26px 14px; + position: relative; + overflow: hidden; + display: flex; + flex-direction: column; + box-shadow: inset 0 0 60px rgba(0, 0, 0, 0.55); +} + +.mystery-bezel::before { + /* scanlines overlay */ + content: ''; + position: absolute; + inset: 0; + pointer-events: none; + background: repeating-linear-gradient( + to bottom, + transparent 0, + transparent 2px, + rgba(0, 0, 0, 0.18) 2px, + rgba(0, 0, 0, 0.18) 3px + ); + opacity: 0.6; + z-index: 1; +} + +.mystery-theme-toggle { + position: absolute; + top: 8px; + right: 12px; + z-index: 3; + display: flex; + gap: 6px; + font-size: 11px; +} + +.mystery-theme-toggle button { + background: transparent; + color: var(--m-dim); + border: 1px solid var(--m-dim); + border-radius: 2px; + padding: 2px 6px; + font: inherit; + cursor: pointer; +} + +.mystery-theme-toggle button[aria-pressed='true'] { + color: var(--m-fg); + border-color: var(--m-fg); +} + +.mystery-transcript { + flex: 1; + overflow-y: auto; + white-space: pre-wrap; + word-break: break-word; + position: relative; + z-index: 2; + padding-right: 6px; +} + +.mystery-transcript .system { + color: var(--m-accent-1); + font-weight: bold; + margin-top: 0.6em; +} + +.mystery-transcript .player { + color: var(--m-accent-2); +} + +.mystery-transcript .player::before { content: '> '; } + +.mystery-transcript .narration { + margin: 0.25em 0; +} + +.mystery-input-row { + display: flex; + align-items: center; + gap: 6px; + margin-top: 10px; + position: relative; + z-index: 2; +} + +.mystery-input-row::before { + content: '>'; + color: var(--m-accent-2); +} + +.mystery-input { + flex: 1; + background: transparent; + color: var(--m-fg); + border: none; + outline: none; + font: inherit; + text-shadow: inherit; + caret-color: var(--m-fg); +} + +.mystery-chips { + display: none; + flex-wrap: wrap; + gap: 4px; + padding: 6px 0 4px; + position: relative; + z-index: 2; + border-top: 1px var(--m-divider-style) var(--m-dim); + margin-top: 8px; +} + +.mystery-chip { + background: transparent; + color: var(--m-fg); + border: 1px solid var(--m-fg); + border-radius: 2px; + padding: 3px 7px; + font: inherit; + cursor: pointer; + font-size: 11px; +} + +.mystery-chip[disabled] { + opacity: 0.35; + cursor: not-allowed; +} + +@media (pointer: coarse) { + .mystery-chips { display: flex; } +} diff --git a/src/ui/terminal.ts b/src/ui/terminal.ts new file mode 100644 index 0000000..2cc0209 --- /dev/null +++ b/src/ui/terminal.ts @@ -0,0 +1,10 @@ +// Stub. Replaced in Task 10 with the full terminal implementation. +console.info('[halfstreet] terminal placeholder loaded') + +const transcript = document.querySelector('[data-mystery-transcript]') +if (transcript) { + const line = document.createElement('div') + line.className = 'narration' + line.textContent = 'Terminal scaffold loaded. Type wiring lands in the next task.' + transcript.appendChild(line) +}