Help via ? key, not per-name button #7
+77
-30
@@ -266,32 +266,33 @@
|
||||
font-size: 0.95rem; line-height: 1;
|
||||
}
|
||||
.play.playing { background: var(--ink); color: var(--paper); }
|
||||
.say-row .card-help { margin-left: auto; }
|
||||
.card-help {
|
||||
position: relative;
|
||||
}
|
||||
.card-help > summary {
|
||||
list-style: none;
|
||||
width: 2rem; height: 2rem;
|
||||
display: inline-grid; place-items: center;
|
||||
border: 1px solid var(--rule);
|
||||
color: var(--muted);
|
||||
cursor: pointer;
|
||||
font-family: "Source Sans 3", sans-serif;
|
||||
font-size: 0.95rem; font-weight: 600;
|
||||
}
|
||||
.card-help > summary::-webkit-details-marker { display: none; }
|
||||
.card-help[open] > summary { color: var(--ink); border-color: var(--ink); }
|
||||
.card-help .help-body {
|
||||
position: absolute; right: 0; top: calc(100% + 0.35rem);
|
||||
z-index: 2; width: min(16rem, 70vw);
|
||||
margin: 0; padding: 0.55rem 0.65rem;
|
||||
background: var(--sheet); color: var(--muted);
|
||||
border: 1px solid var(--rule);
|
||||
font-size: 0.8rem; line-height: 1.35;
|
||||
box-shadow: 0 4px 14px rgba(20, 20, 20, 0.08);
|
||||
}
|
||||
.empty { color: var(--muted); font-size: 0.92rem; padding: 0.35rem 0; }
|
||||
.help-dialog {
|
||||
border: 1px solid var(--rule);
|
||||
background: var(--sheet);
|
||||
color: var(--ink);
|
||||
padding: 0;
|
||||
max-width: min(22rem, calc(100vw - 2rem));
|
||||
box-shadow: 0 10px 36px rgba(20, 20, 20, 0.18);
|
||||
}
|
||||
.help-dialog::backdrop { background: rgba(20, 18, 14, 0.35); }
|
||||
.help-dialog .help-inner { padding: 1rem 1.1rem 1.05rem; }
|
||||
.help-dialog h2 {
|
||||
font-family: "Libre Baskerville", Georgia, serif;
|
||||
font-size: 1.05rem; margin: 0 0 0.55rem;
|
||||
}
|
||||
.help-dialog p { margin: 0 0 0.55rem; color: var(--muted); font-size: 0.9rem; line-height: 1.4; }
|
||||
.help-dialog ul {
|
||||
margin: 0 0 0.85rem; padding-left: 1.1rem;
|
||||
color: var(--muted); font-size: 0.88rem; line-height: 1.45;
|
||||
}
|
||||
.help-dialog kbd {
|
||||
font-family: "Source Sans 3", sans-serif;
|
||||
font-size: 0.85rem; font-weight: 600;
|
||||
border: 1px solid var(--rule); padding: 0.05rem 0.35rem;
|
||||
background: var(--input-bg); color: var(--ink);
|
||||
}
|
||||
.help-dialog .row { margin-top: 0.25rem; }
|
||||
.hidden { display: none !important; }
|
||||
.compose-head {
|
||||
display: flex; justify-content: space-between; gap: 0.75rem;
|
||||
@@ -318,6 +319,12 @@
|
||||
color: var(--muted); font-size: 0.85rem;
|
||||
}
|
||||
.foot a { color: var(--ink); }
|
||||
.foot kbd, .hint kbd {
|
||||
font-family: "Source Sans 3", sans-serif;
|
||||
font-size: 0.8rem; font-weight: 600;
|
||||
border: 1px solid var(--rule); padding: 0.05rem 0.3rem;
|
||||
background: var(--input-bg); color: var(--ink);
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
@@ -423,8 +430,25 @@
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<p class="foot">Paper board · <a href="/v1">classic layout</a> · mark is logo concept 1</p>
|
||||
<p class="foot">Paper board · press <kbd>?</kbd> for help · <a href="/v1">classic layout</a></p>
|
||||
</main>
|
||||
<dialog id="help-dialog" class="help-dialog" aria-labelledby="help-title">
|
||||
<div class="help-inner">
|
||||
<h2 id="help-title">Board tips</h2>
|
||||
<p>Open a name to vote, play pronunciation, and leave notes.</p>
|
||||
<ul>
|
||||
<li><strong>▶</strong> play — AI speech until you record</li>
|
||||
<li><strong>●</strong> record / <strong>■</strong> stop — your clip replaces AI</li>
|
||||
<li><strong>↺</strong> clear recording and use AI again</li>
|
||||
<li><strong>✎</strong> edit spoken form, origin, meaning · <strong>✓</strong> save</li>
|
||||
<li>Swipe columns sideways on phone</li>
|
||||
</ul>
|
||||
<div class="row">
|
||||
<button type="button" id="help-close">Close</button>
|
||||
<span class="hint" style="margin:0">Esc or <kbd>?</kbd> again</span>
|
||||
</div>
|
||||
</div>
|
||||
</dialog>
|
||||
<script>
|
||||
const MAX_COLUMNS = 4;
|
||||
const SPEECH_LANG = { en: "en-US", ru: "ru-RU", he: "he-IL" };
|
||||
@@ -443,6 +467,33 @@
|
||||
let speakingBtn = null;
|
||||
let audioEl = null;
|
||||
|
||||
function isTypingTarget(el) {
|
||||
if (!el || !(el instanceof Element)) return false;
|
||||
const tag = el.tagName;
|
||||
return tag === "INPUT" || tag === "TEXTAREA" || tag === "SELECT" || el.isContentEditable;
|
||||
}
|
||||
|
||||
function toggleHelp() {
|
||||
const dlg = document.getElementById("help-dialog");
|
||||
if (!dlg) return;
|
||||
if (dlg.open) dlg.close();
|
||||
else dlg.showModal();
|
||||
}
|
||||
|
||||
document.getElementById("help-close").addEventListener("click", () => {
|
||||
document.getElementById("help-dialog").close();
|
||||
});
|
||||
document.getElementById("help-dialog").addEventListener("click", (e) => {
|
||||
if (e.target === e.currentTarget) e.currentTarget.close();
|
||||
});
|
||||
document.addEventListener("keydown", (e) => {
|
||||
if (e.key === "?" || (e.key === "/" && e.shiftKey)) {
|
||||
if (isTypingTarget(e.target)) return;
|
||||
e.preventDefault();
|
||||
toggleHelp();
|
||||
}
|
||||
});
|
||||
|
||||
function colLabel(col) {
|
||||
const label = (col && col.label || "").trim();
|
||||
return label || "Untitled";
|
||||
@@ -647,10 +698,6 @@
|
||||
<div class="pills">${pills}</div>
|
||||
<button type="button" class="play" data-play aria-label="Play pronunciation" title="Play">▶</button>
|
||||
<span class="voice-status">${hasRec ? "<strong>Your voice</strong>" : "AI speech"}</span>
|
||||
<details class="card-help">
|
||||
<summary aria-label="How voice and notes work" title="Help">?</summary>
|
||||
<p class="help-body">Play uses AI speech until you record your own. Re-record replaces the clip. The reset icon returns to AI. Pencil edits spoken form, origin, and meaning.</p>
|
||||
</details>
|
||||
</div>
|
||||
${editing || !hasNotes ? notesEdit : notesView}
|
||||
<div class="voice-row">
|
||||
|
||||
Reference in New Issue
Block a user