fix: harden responsive accessibility contracts

This commit is contained in:
NuklearRabbit
2026-07-29 16:22:46 +02:00
parent ae6c41ff90
commit a7ab2d6cc8
4 changed files with 33 additions and 5 deletions
+12 -2
View File
@@ -686,7 +686,7 @@ function renderTitlebar() {
return `<header class="titlebar">
<div class="titlebar-left"><div class="wordmark"><img class="brand-logo" src="./assets/itworx-mark.png" alt="ITWorx.tech"/><span>ForgeFlow</span><small>by ITWorx.tech</small></div><span class="workspace-name">${escapeHtml(title)}</span></div>
<div class="titlebar-right">
<button class="command-trigger" data-action="open-palette">${icon("search")}<span>Commands</span><kbd>Ctrl K</kbd></button>
<button class="command-trigger" data-action="open-palette" aria-label="Open command palette">${icon("search")}<span>Commands</span><kbd>Ctrl K</kbd></button>
<div class="search-wrap">${icon("search")}<input id="global-search" class="global-search" value="${attr(ui.search)}" placeholder="Search repositories…" aria-label="Search repositories" /></div>
<span class="connection-chip" title="${connected ? `Connected as ${attr(user?.login || "user")}` : "Not connected"}"><span class="dot" style="${connected ? "" : "background:var(--danger)"}"></span>${connected ? escapeHtml(user?.login || "Gitea") : "Offline"}</span>
<button class="icon-button" data-action="refresh" title="Refresh repositories">${icon("refresh")}</button>
@@ -1208,7 +1208,7 @@ function renderServerInventory() {
const candidate = linked
? `Linked to ${workload.link?.repositoryFullName || "repository"}`
: topCandidate
? `${topCandidate.repositoryFullName} suggested · ${topCandidate.confidence}`
? `${topCandidate.repositoryFullName} suggested · ${topCandidate.confidence || topCandidate.status || "review required"}`
: "No repository candidate; select one manually";
const canQuickLink = !linked && topCandidate && ["exact", "strong"].includes(topCandidate.confidence) && Boolean(workload.remoteFolderCandidate);
const linkButton = canQuickLink
@@ -1618,6 +1618,16 @@ function enhanceRenderedUi() {
`<section class="section-block"><div class="section-heading"><div><h2>Operational audit log</h2><span class="meta">Append-only release, pull-request and recovery events</span></div><div class="stack horizontal compact"><button class="button" data-action="load-audit-log">Refresh</button><button class="button" data-action="export-audit-json">Export JSON</button><button class="button" data-action="export-audit-csv">Export CSV</button></div></div><div class="panel">${ui.auditEvents.length ? `<table class="data-table"><thead><tr><th>Time</th><th>Event</th><th>Repository</th><th>Result</th></tr></thead><tbody>${ui.auditEvents.map((item) => `<tr><td>${formatDate(item.timestamp)}</td><td>${escapeHtml(item.event)}</td><td>${escapeHtml(item.details?.repository || "—")}</td><td>${escapeHtml(item.details?.result || item.details?.note || "—")}</td></tr>`).join("")}</tbody></table>` : '<div class="empty-state compact"><p>Load the operational audit log.</p></div>'}</div></section>`,
);
}
document.querySelectorAll("button.icon-button:not([aria-label])").forEach((button) => {
const action = String(button.title || button.dataset.action || "Action").replaceAll("-", " ");
button.setAttribute("aria-label", action.charAt(0).toUpperCase() + action.slice(1));
});
document.querySelectorAll(".field > label:not([for])").forEach((label, index) => {
const control = label.parentElement?.querySelector("input, select, textarea");
if (!control) return;
if (!control.id) control.id = `forgeflow-field-${index}`;
label.htmlFor = control.id;
});
}
function render() {
+8
View File
@@ -2818,6 +2818,14 @@ kbd {
color: var(--text-faint);
font-size: 10px;
}
.action-panel-body .panel-callout > h2,
.action-panel-body .panel-callout > p {
display: none;
}
@media (max-height: 760px) {
.palette-backdrop { padding-top: 3vh; }
.palette-list { max-height: calc(100vh - 150px); }
}
.discovery-progress {
min-height: 260px;
display: grid;