diff --git a/web/index.html b/web/index.html
index 51aa617..464de71 100644
--- a/web/index.html
+++ b/web/index.html
@@ -81,6 +81,10 @@
.ytRow { display: flex; gap: 10px; padding: 8px; border-radius: 10px; cursor: pointer; align-items: flex-start; white-space: normal; }
.ytRow:hover { background: var(--surface-3); }
+ .ytRow:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; background: var(--surface-3); }
+ .iconBtn:focus-visible, .mdSelect:focus-visible, .searchStage .searchHeader button:focus-visible {
+ outline: 2px solid var(--primary); outline-offset: 2px;
+ }
.ytRow img { width: 120px; aspect-ratio: 16/9; object-fit: cover; border-radius: 8px; background: #000; flex-shrink: 0; }
.ytRow .meta { min-width: 0; }
.ytRow .title { font-size: 13px; line-height: 1.4; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; white-space: normal; }
@@ -286,6 +290,12 @@ document.getElementById('playerWrap').addEventListener('click', () => {
}
});
+document.addEventListener('keydown', (e) => {
+ if (e.key === 'Escape' && document.getElementById('playerWrap').classList.contains('pip')) {
+ exitSearchMode();
+ }
+});
+
document.getElementById('searchCancelBtn').addEventListener('click', exitSearchMode);
function loadVideo(id, opts) {
@@ -312,6 +322,9 @@ function decodeEntities(text) {
function buildYtRow(item) {
const row = document.createElement('div');
row.className = 'ytRow';
+ row.tabIndex = 0;
+ row.setAttribute('role', 'button');
+ row.setAttribute('aria-label', decodeEntities(item.title));
const title = document.createElement('div');
title.className = 'title';
title.textContent = decodeEntities(item.title);
@@ -328,6 +341,12 @@ function buildYtRow(item) {
row.appendChild(img);
row.appendChild(meta);
row.addEventListener('click', () => loadVideo(item.videoId));
+ row.addEventListener('keydown', (e) => {
+ if (e.key === 'Enter' || e.key === ' ') {
+ e.preventDefault();
+ loadVideo(item.videoId);
+ }
+ });
return row;
}
@@ -355,6 +374,7 @@ document.getElementById('loadBtn').addEventListener('click', () => {
document.getElementById('urlInput').addEventListener('keydown', (e) => {
if (e.key === 'Enter') document.getElementById('loadBtn').click();
+ if (e.key === 'Escape') exitSearchMode();
});
const modelSelect = document.getElementById('modelSelect');
@@ -369,6 +389,10 @@ modelSelect.addEventListener('change', () => {
lockIcon.classList.toggle('unlocked', modelSelect.value === 'gemini' && !!unlockCode);
});
+document.getElementById('unlockInput').addEventListener('keydown', (e) => {
+ if (e.key === 'Enter') document.getElementById('unlockBtn').click();
+});
+
document.getElementById('unlockBtn').addEventListener('click', async () => {
const code = document.getElementById('unlockInput').value.trim();
if (!code) return;
@@ -475,9 +499,6 @@ async function sendChatMessage(message, opts) {
finalizeBubble(statusDiv, evt.reply, evt.videos);
chatHistory.push({ role: 'user', text: message });
chatHistory.push({ role: 'model', text: evt.reply });
- if (evt.videos && evt.videos.length) {
- setPip(true);
- }
if (evt.autoPlayVideoId) {
loadVideo(evt.autoPlayVideoId, { notifyAI: false });
}