@@ -141,7 +141,7 @@ function CatalogCard({ record, thumbPath, onOpen, onRenamed, onDeleted }) {
type="button"
onClick={startDelete}
aria-label={`Delete ${record.name}`}
- className="p-1.5 rounded bg-port-card/90 border border-port-border text-gray-300 hover:text-port-error hover:border-port-error"
+ className="min-h-[44px] min-w-[44px] inline-flex items-center justify-center p-1.5 rounded bg-port-card/90 border border-port-border text-gray-300 hover:text-port-error hover:border-port-error"
>
diff --git a/client/src/components/sprites/SpriteDetailHeader.jsx b/client/src/components/sprites/SpriteDetailHeader.jsx
index b73eac0439..b9bbcd8ce2 100644
--- a/client/src/components/sprites/SpriteDetailHeader.jsx
+++ b/client/src/components/sprites/SpriteDetailHeader.jsx
@@ -63,7 +63,7 @@ export default function SpriteDetailHeader({ record, onRenamed, onDeleted }) {
type="button"
onClick={startRename}
aria-label={`Rename ${record.name}`}
- className="shrink-0 p-1 rounded text-gray-400 hover:text-white hover:bg-port-border/50"
+ className="min-h-[44px] min-w-[44px] inline-flex items-center justify-center shrink-0 p-1 rounded text-gray-400 hover:text-white hover:bg-port-border/50"
>
@@ -71,7 +71,7 @@ export default function SpriteDetailHeader({ record, onRenamed, onDeleted }) {
type="button"
onClick={startDelete}
aria-label={`Delete ${record.name}`}
- className="shrink-0 p-1 rounded text-gray-400 hover:text-port-error hover:bg-port-border/50"
+ className="min-h-[44px] min-w-[44px] inline-flex items-center justify-center shrink-0 p-1 rounded text-gray-400 hover:text-port-error hover:bg-port-border/50"
>
diff --git a/client/src/components/sync/SyncDetailDrawer.jsx b/client/src/components/sync/SyncDetailDrawer.jsx
index 6d129422ba..f541d92b05 100644
--- a/client/src/components/sync/SyncDetailDrawer.jsx
+++ b/client/src/components/sync/SyncDetailDrawer.jsx
@@ -384,7 +384,7 @@ export default function SyncDetailDrawer({ kind, recordId, onClose }) {
type="button"
onClick={() => { refresh(); loadRecord(); }}
title="Refresh sync status + reload record" aria-label="Refresh sync status + reload record"
- className="p-1 text-gray-500 hover:text-gray-300 rounded"
+ className="min-h-[44px] min-w-[44px] inline-flex items-center justify-center p-1 text-gray-500 hover:text-gray-300 rounded"
>
diff --git a/client/src/components/universe/VisionDescribeModal.jsx b/client/src/components/universe/VisionDescribeModal.jsx
index 07c32345c9..29df0465f0 100644
--- a/client/src/components/universe/VisionDescribeModal.jsx
+++ b/client/src/components/universe/VisionDescribeModal.jsx
@@ -246,7 +246,7 @@ export default function VisionDescribeModal({
onClick={() => removeImage(imageKey(img))}
title="Remove image"
aria-label="Remove image"
- className="absolute -top-1.5 -right-1.5 bg-port-bg border border-port-border rounded-full p-0.5 text-gray-400 hover:text-port-error"
+ className="min-h-[44px] min-w-[44px] inline-flex items-center justify-center absolute -top-1.5 -right-1.5 bg-port-bg border border-port-border rounded-full p-0.5 text-gray-400 hover:text-port-error"
>
diff --git a/client/src/components/universeBuilder/CompositeSheetsEditor.jsx b/client/src/components/universeBuilder/CompositeSheetsEditor.jsx
index 087d172ba7..827ac27958 100644
--- a/client/src/components/universeBuilder/CompositeSheetsEditor.jsx
+++ b/client/src/components/universeBuilder/CompositeSheetsEditor.jsx
@@ -103,7 +103,7 @@ export default function CompositeSheetsEditor({
: 'Lock all composite boards — Expand will preserve them'}
aria-label={allSheetsLocked ? 'Unlock all composite boards' : 'Lock all composite boards'}
aria-pressed={allSheetsLocked}
- className={`p-1 rounded ${
+ className={`min-h-[44px] min-w-[44px] inline-flex items-center justify-center p-1 rounded ${
allSheetsLocked
? 'text-port-accent hover:bg-port-accent/20'
: 'text-gray-500 hover:text-gray-300'
@@ -292,12 +292,12 @@ function SheetRow({
);
const body =
{sheet.prompt}
;
const actions = (
-
+
{onRender && (
@@ -305,7 +305,7 @@ function SheetRow({
)}
@@ -313,14 +313,14 @@ function SheetRow({
diff --git a/client/src/components/universeBuilder/UniverseBibleTab.jsx b/client/src/components/universeBuilder/UniverseBibleTab.jsx
index 851e8716b5..c202662e27 100644
--- a/client/src/components/universeBuilder/UniverseBibleTab.jsx
+++ b/client/src/components/universeBuilder/UniverseBibleTab.jsx
@@ -24,7 +24,7 @@ function LockButton({ field, locked, onToggle, label }) {
onToggle(field)}
- className={`p-1 rounded -mr-1 transition-colors ${
+ className={`min-h-[44px] min-w-[44px] inline-flex items-center justify-center p-1 rounded -mr-1 transition-colors ${
isLocked
? 'bg-port-accent/20 text-port-accent ring-1 ring-port-accent/50 hover:bg-port-accent/30'
: 'text-gray-600 hover:text-gray-300 hover:bg-white/5'
@@ -252,7 +252,7 @@ export default function BibleTab({
onClick={() => setRefineImage(null)}
title="Remove reference image"
aria-label="Remove reference image"
- className="absolute -top-1.5 -right-1.5 bg-port-bg border border-port-border rounded-full p-0.5 text-gray-400 hover:text-port-error"
+ className="min-h-[44px] min-w-[44px] inline-flex items-center justify-center absolute -top-1.5 -right-1.5 bg-port-bg border border-port-border rounded-full p-0.5 text-gray-400 hover:text-port-error"
>
diff --git a/client/src/components/universeBuilder/UniverseCategoryEditor.jsx b/client/src/components/universeBuilder/UniverseCategoryEditor.jsx
index ef0de5e900..99ab577478 100644
--- a/client/src/components/universeBuilder/UniverseCategoryEditor.jsx
+++ b/client/src/components/universeBuilder/UniverseCategoryEditor.jsx
@@ -172,12 +172,12 @@ export function CategoryEditor({
{humanizeCategory(category)}
{variations.length}
-
+
{onRenderCategory && (
@@ -188,7 +188,7 @@ export function CategoryEditor({
setAssignOpen((v) => !v)}
- className="p-1 text-port-accent hover:bg-port-accent/20 rounded"
+ className="min-h-[44px] min-w-[44px] inline-flex items-center justify-center p-1 text-port-accent hover:bg-port-accent/20 rounded"
title="Move this bucket into a canon trunk (variations stay in place)"
aria-label="Assign bucket to a canon trunk"
aria-haspopup="menu"
@@ -226,7 +226,7 @@ export function CategoryEditor({
setGenOpen((v) => !v)}
disabled={generating}
- className="p-1 text-port-accent hover:bg-port-accent/20 disabled:opacity-30 disabled:cursor-not-allowed rounded"
+ className="min-h-[44px] min-w-[44px] inline-flex items-center justify-center p-1 text-port-accent hover:bg-port-accent/20 disabled:opacity-30 disabled:cursor-not-allowed rounded"
title="Ask the LLM for more variations in this category"
aria-label="Generate more variations"
aria-haspopup="menu"
@@ -286,7 +286,7 @@ export function CategoryEditor({
: 'Lock all variations — Expand / Generate will preserve them'}
aria-label={allLocked ? 'Unlock all variations' : 'Lock all variations'}
aria-pressed={allLocked}
- className={`p-1 rounded ${
+ className={`min-h-[44px] min-w-[44px] inline-flex items-center justify-center p-1 rounded ${
allLocked
? 'text-port-accent hover:bg-port-accent/20'
: 'text-gray-500 hover:text-gray-300'
@@ -298,7 +298,7 @@ export function CategoryEditor({
{canRemove && (
@@ -483,7 +483,7 @@ function VariationCard({
const title = {v.label}
;
const body = {v.prompt}
;
const actions = (
-
+
{onPromote && (
onRenderVariation(v)}
disabled={!canRender}
- className="p-1 text-gray-400 hover:text-port-accent disabled:opacity-30 disabled:cursor-not-allowed rounded"
+ className="min-h-[44px] min-w-[44px] inline-flex items-center justify-center p-1 text-gray-400 hover:text-port-accent disabled:opacity-30 disabled:cursor-not-allowed rounded"
title={canRender ? 'Render this variation' : 'Save the world and configure a render backend to enable'} aria-label={canRender ? 'Render this variation' : 'Save the world and configure a render backend to enable'}
>
@@ -538,7 +538,7 @@ function VariationCard({
)}
@@ -546,14 +546,14 @@ function VariationCard({
diff --git a/client/src/components/universeBuilder/UniverseStyleReferences.jsx b/client/src/components/universeBuilder/UniverseStyleReferences.jsx
index 78aa8589d5..aebd14fcb2 100644
--- a/client/src/components/universeBuilder/UniverseStyleReferences.jsx
+++ b/client/src/components/universeBuilder/UniverseStyleReferences.jsx
@@ -123,7 +123,7 @@ export default function UniverseStyleReferences({
onRemove?.(reference.id)}
- className="shrink-0 rounded p-1 text-gray-500 hover:bg-white/5 hover:text-port-error"
+ className="min-h-[44px] min-w-[44px] inline-flex items-center justify-center shrink-0 rounded p-1 text-gray-500 hover:bg-white/5 hover:text-port-error"
aria-label={`Remove ${reference.title}`}
title="Remove art reference"
>
diff --git a/client/src/components/videoGen/IcLoraPanel.jsx b/client/src/components/videoGen/IcLoraPanel.jsx
index cdb1a8b3ba..fc526e4cdb 100644
--- a/client/src/components/videoGen/IcLoraPanel.jsx
+++ b/client/src/components/videoGen/IcLoraPanel.jsx
@@ -106,7 +106,7 @@ export default function IcLoraPanel({
onClick={() => onRemoveReferenceImage(i)}
disabled={referenceImageFiles.length <= minRefs}
aria-label={`Remove reference ${i + 1}`}
- className="mt-1 p-1 text-gray-400 hover:text-port-error disabled:opacity-30 disabled:cursor-not-allowed"
+ className="min-h-[44px] min-w-[44px] inline-flex items-center justify-center mt-1 p-1 text-gray-400 hover:text-port-error disabled:opacity-30 disabled:cursor-not-allowed"
>
diff --git a/client/src/components/videoGen/KeyframePanel.jsx b/client/src/components/videoGen/KeyframePanel.jsx
index 8466051648..906bc21260 100644
--- a/client/src/components/videoGen/KeyframePanel.jsx
+++ b/client/src/components/videoGen/KeyframePanel.jsx
@@ -72,7 +72,7 @@ export default function KeyframePanel({
onClick={() => onRemoveKeyframe(i)}
disabled={keyframes.length <= 2}
aria-label={`Remove keyframe ${i + 1}`}
- className="mt-5 p-1 text-gray-400 hover:text-port-error disabled:opacity-30 disabled:cursor-not-allowed"
+ className="min-h-[44px] min-w-[44px] inline-flex items-center justify-center mt-5 p-1 text-gray-400 hover:text-port-error disabled:opacity-30 disabled:cursor-not-allowed"
>
diff --git a/client/src/components/voice/VoicePicker.jsx b/client/src/components/voice/VoicePicker.jsx
index edf2519e71..d2498ac749 100644
--- a/client/src/components/voice/VoicePicker.jsx
+++ b/client/src/components/voice/VoicePicker.jsx
@@ -183,7 +183,7 @@ export default function VoicePicker({
disabled={!value || previewing || disabled}
title={value ? `Audition ${value}` : 'Pick a voice to audition'}
aria-label={value ? `Audition ${value}` : 'Audition voice'}
- className="shrink-0 p-1 rounded text-gray-400 hover:text-port-accent disabled:opacity-30 disabled:cursor-not-allowed"
+ className="min-h-[44px] min-w-[44px] inline-flex items-center justify-center shrink-0 p-1 rounded text-gray-400 hover:text-port-accent disabled:opacity-30 disabled:cursor-not-allowed"
>
{previewing ? : }
diff --git a/client/src/components/voice/VoiceWidget.jsx b/client/src/components/voice/VoiceWidget.jsx
index 8c4bbb3462..6e64018ecd 100644
--- a/client/src/components/voice/VoiceWidget.jsx
+++ b/client/src/components/voice/VoiceWidget.jsx
@@ -728,7 +728,7 @@ export default function VoiceWidget() {
onClick={handleClear}
title="Clear conversation"
aria-label="Clear conversation"
- className="p-1 rounded text-gray-400 hover:text-port-error hover:bg-port-error/10"
+ className="min-h-[44px] min-w-[44px] inline-flex items-center justify-center p-1 rounded text-gray-400 hover:text-port-error hover:bg-port-error/10"
>
@@ -842,7 +842,7 @@ export default function VoiceWidget() {
onClick={() => setCollapsed((c) => !c)}
title={collapsed ? 'Show conversation' : 'Hide conversation'}
aria-label={collapsed ? 'Show conversation' : 'Hide conversation'}
- className="p-1.5 rounded-full text-gray-400 hover:text-white hover:bg-port-border/70"
+ className="min-h-[44px] min-w-[44px] inline-flex items-center justify-center p-1.5 rounded-full text-gray-400 hover:text-white hover:bg-port-border/70"
>
{collapsed ?
:
}
diff --git a/client/src/components/wiki/tabs/BrowseTab.jsx b/client/src/components/wiki/tabs/BrowseTab.jsx
index 546cccf17c..671a4001c0 100644
--- a/client/src/components/wiki/tabs/BrowseTab.jsx
+++ b/client/src/components/wiki/tabs/BrowseTab.jsx
@@ -148,7 +148,7 @@ export default function BrowseTab({ vaultId, notes, rawNotes, allNotes, onRefres
{ loadTags(); setShowTags(!showTags); }}
- className={`p-1.5 rounded ${showTags ? 'text-port-accent' : 'text-gray-500 hover:text-white'}`}
+ className={`min-h-[44px] min-w-[44px] inline-flex items-center justify-center p-1.5 rounded ${showTags ? 'text-port-accent' : 'text-gray-500 hover:text-white'}`}
title="Tags" aria-label="Tags"
>
@@ -238,7 +238,7 @@ export default function BrowseTab({ vaultId, notes, rawNotes, allNotes, onRefres
{ setSelectedNote(null); updateNoteParam(null, { replace: true }); }}
aria-label="Back to list"
- className="p-1 rounded hover:bg-port-card text-gray-400 hover:text-white md:hidden"
+ className="min-h-[44px] min-w-[44px] inline-flex items-center justify-center p-1 rounded hover:bg-port-card text-gray-400 hover:text-white md:hidden"
>
@@ -269,7 +269,7 @@ export default function BrowseTab({ vaultId, notes, rawNotes, allNotes, onRefres
{ setEditing(false); setNoteContent(selectedNote.content); }}
aria-label="Cancel"
- className="p-1.5 rounded hover:bg-port-card text-gray-400 hover:text-white"
+ className="min-h-[44px] min-w-[44px] inline-flex items-center justify-center p-1.5 rounded hover:bg-port-card text-gray-400 hover:text-white"
>
@@ -285,7 +285,7 @@ export default function BrowseTab({ vaultId, notes, rawNotes, allNotes, onRefres
)}
setConfirmDelete(selectedNote.path)}
- className="p-1.5 rounded hover:bg-port-card text-gray-400 hover:text-port-error"
+ className="min-h-[44px] min-w-[44px] inline-flex items-center justify-center p-1.5 rounded hover:bg-port-card text-gray-400 hover:text-port-error"
title="Delete note" aria-label="Delete note"
>
diff --git a/client/src/components/wiki/tabs/GraphTab.jsx b/client/src/components/wiki/tabs/GraphTab.jsx
index fca4b93f88..5e6d019be2 100644
--- a/client/src/components/wiki/tabs/GraphTab.jsx
+++ b/client/src/components/wiki/tabs/GraphTab.jsx
@@ -210,14 +210,14 @@ export default function GraphTab({ vaultId }) {
setZoom(z => Math.min(z + 0.2, 3))}
aria-label="Zoom in"
- className="p-1.5 rounded bg-port-card border border-port-border text-gray-400 hover:text-white"
+ className="min-h-[44px] min-w-[44px] inline-flex items-center justify-center p-1.5 rounded bg-port-card border border-port-border text-gray-400 hover:text-white"
>
setZoom(z => Math.max(z - 0.2, 0.3))}
aria-label="Zoom out"
- className="p-1.5 rounded bg-port-card border border-port-border text-gray-400 hover:text-white"
+ className="min-h-[44px] min-w-[44px] inline-flex items-center justify-center p-1.5 rounded bg-port-card border border-port-border text-gray-400 hover:text-white"
>
diff --git a/client/src/hooks/useAgentFeedbackToast.jsx b/client/src/hooks/useAgentFeedbackToast.jsx
index b90a89a3ed..01a79702c6 100644
--- a/client/src/hooks/useAgentFeedbackToast.jsx
+++ b/client/src/hooks/useAgentFeedbackToast.jsx
@@ -94,10 +94,10 @@ function AgentFeedbackToast({ t, agentData, onFeedback }) {
{/* Feedback buttons */}
Was this helpful?
-
+
onFeedback(agentId, 'positive', t.id)}
- className="p-1.5 rounded bg-green-500/20 hover:bg-green-500/30 text-green-400 transition-colors"
+ className="min-h-[44px] min-w-[44px] inline-flex items-center justify-center p-1.5 rounded bg-green-500/20 hover:bg-green-500/30 text-green-400 transition-colors"
title="Helpful"
aria-label="Mark as helpful"
>
@@ -105,7 +105,7 @@ function AgentFeedbackToast({ t, agentData, onFeedback }) {
onFeedback(agentId, 'negative', t.id)}
- className="p-1.5 rounded bg-red-500/20 hover:bg-red-500/30 text-red-400 transition-colors"
+ className="min-h-[44px] min-w-[44px] inline-flex items-center justify-center p-1.5 rounded bg-red-500/20 hover:bg-red-500/30 text-red-400 transition-colors"
title="Not helpful"
aria-label="Mark as not helpful"
>
diff --git a/client/src/pages/ApiExplorer.jsx b/client/src/pages/ApiExplorer.jsx
index 6397173091..f159d25859 100644
--- a/client/src/pages/ApiExplorer.jsx
+++ b/client/src/pages/ApiExplorer.jsx
@@ -142,7 +142,7 @@ function CatalogView() {
{operation.summary} · {operation.access}
-
copyToClipboard(`${operation.method} ${operation.path}`, 'Operation copied')} className="p-1.5 text-gray-500 hover:text-white" aria-label={`Copy ${operation.method} ${operation.path}`}>
+ copyToClipboard(`${operation.method} ${operation.path}`, 'Operation copied')} className="min-h-[44px] min-w-[44px] inline-flex items-center justify-center p-1.5 text-gray-500 hover:text-white" aria-label={`Copy ${operation.method} ${operation.path}`}>
@@ -279,7 +279,7 @@ function EventCatalogView() {
)}
-
copyToClipboard(event.event, 'Event copied')} className="p-1.5 text-gray-500 hover:text-white" aria-label={`Copy ${event.event}`}>
+
copyToClipboard(event.event, 'Event copied')} className="min-h-[44px] min-w-[44px] inline-flex items-center justify-center p-1.5 text-gray-500 hover:text-white" aria-label={`Copy ${event.event}`}>
))}
diff --git a/client/src/pages/Browser.jsx b/client/src/pages/Browser.jsx
index 95ac7d95f1..a50a8e23fe 100644
--- a/client/src/pages/Browser.jsx
+++ b/client/src/pages/Browser.jsx
@@ -597,7 +597,7 @@ export default function BrowserPage() {
handleDeleteDownload(file.name)}
- className="p-1.5 rounded-md text-gray-400 hover:text-port-error hover:bg-port-border/50 transition-colors"
+ className="min-h-[44px] min-w-[44px] inline-flex items-center justify-center p-1.5 rounded-md text-gray-400 hover:text-port-error hover:bg-port-border/50 transition-colors"
title="Delete file" aria-label="Delete file"
>
diff --git a/client/src/pages/ChiefOfStaff.jsx b/client/src/pages/ChiefOfStaff.jsx
index 41c2573524..08ef8a6405 100644
--- a/client/src/pages/ChiefOfStaff.jsx
+++ b/client/src/pages/ChiefOfStaff.jsx
@@ -848,7 +848,7 @@ export default function ChiefOfStaff() {
{desktopPanelCollapsed && (
@@ -866,7 +866,7 @@ export default function ChiefOfStaff() {
@@ -947,7 +947,7 @@ export default function ChiefOfStaff() {
{/* Desktop Collapse Button */}
diff --git a/client/src/pages/FableLoom.jsx b/client/src/pages/FableLoom.jsx
index ba9a301555..0e9b274d51 100644
--- a/client/src/pages/FableLoom.jsx
+++ b/client/src/pages/FableLoom.jsx
@@ -304,7 +304,7 @@ export default function FableLoom() {
type="button"
aria-label={`Delete ${loom.name}`}
onClick={() => del.requestDelete(loom.id)}
- className="text-port-text-muted hover:text-port-error p-1"
+ className="min-h-[44px] min-w-[44px] inline-flex items-center justify-center text-port-text-muted hover:text-port-error p-1"
>
diff --git a/client/src/pages/HistoryPage.jsx b/client/src/pages/HistoryPage.jsx
index 5405f823c3..7706cbdb61 100644
--- a/client/src/pages/HistoryPage.jsx
+++ b/client/src/pages/HistoryPage.jsx
@@ -213,7 +213,7 @@ export function HistoryPage() {
{formatTime(entry.timestamp)}
handleDelete(entry.id, e)}
- className="p-1 text-gray-500 hover:text-port-error transition-colors sm:opacity-0 sm:group-hover:opacity-100 focus:opacity-100 focus:outline-hidden focus:ring-2 focus:ring-port-accent rounded"
+ className="min-h-[44px] min-w-[44px] inline-flex items-center justify-center p-1 text-gray-500 hover:text-port-error transition-colors sm:opacity-0 sm:group-hover:opacity-100 focus:opacity-100 focus:outline-hidden focus:ring-2 focus:ring-port-accent rounded"
title="Delete entry"
aria-label={`Delete ${entry.action} entry from ${formatTime(entry.timestamp)}`}
>
diff --git a/client/src/pages/ImageGen.jsx b/client/src/pages/ImageGen.jsx
index cb369c9fd3..9877a200b8 100644
--- a/client/src/pages/ImageGen.jsx
+++ b/client/src/pages/ImageGen.jsx
@@ -1305,7 +1305,7 @@ export default function ImageGen() {
refreshStatus(effectiveMode, modelId)}
disabled={statusLoading}
- className="p-1.5 rounded text-gray-400 hover:text-white hover:bg-port-border/50 disabled:opacity-50"
+ className="min-h-[44px] min-w-[44px] inline-flex items-center justify-center p-1.5 rounded text-gray-400 hover:text-white hover:bg-port-border/50 disabled:opacity-50"
title="Refresh status" aria-label="Refresh status"
>
diff --git a/client/src/pages/Instances.jsx b/client/src/pages/Instances.jsx
index 6799ee5b28..0ba6751a9f 100644
--- a/client/src/pages/Instances.jsx
+++ b/client/src/pages/Instances.jsx
@@ -1149,12 +1149,12 @@ function PeerCard({ peer, onRefresh, syncStatus, tailnetInfo, parityReport }) {
)}
-
+
@@ -1163,7 +1163,7 @@ function PeerCard({ peer, onRefresh, syncStatus, tailnetInfo, parityReport }) {
@@ -1183,7 +1183,7 @@ function PeerCard({ peer, onRefresh, syncStatus, tailnetInfo, parityReport }) {
) : (
setConfirmRemove(true)}
- className="p-1.5 text-gray-600 hover:text-port-error transition-colors"
+ className="min-h-[44px] min-w-[44px] inline-flex items-center justify-center p-1.5 text-gray-600 hover:text-port-error transition-colors"
title="Remove peer" aria-label="Remove peer"
>
diff --git a/client/src/pages/Loops.jsx b/client/src/pages/Loops.jsx
index 8cdfed505b..2e4ebc55b0 100644
--- a/client/src/pages/Loops.jsx
+++ b/client/src/pages/Loops.jsx
@@ -250,22 +250,22 @@ function LoopCard({ loop, onAction, expandedId, onToggle }) {
-
+
{loop.isRunning ? (
<>
-
{ e.stopPropagation(); onAction('trigger', loop.id); }} className="p-1.5 rounded hover:bg-port-border text-gray-400 hover:text-port-accent" title="Run now" aria-label="Run now">
+ { e.stopPropagation(); onAction('trigger', loop.id); }} className="min-h-[44px] min-w-[44px] inline-flex items-center justify-center p-1.5 rounded hover:bg-port-border text-gray-400 hover:text-port-accent" title="Run now" aria-label="Run now">
- { e.stopPropagation(); onAction('stop', loop.id); }} className="p-1.5 rounded hover:bg-port-border text-gray-400 hover:text-port-warning" title="Stop" aria-label="Stop">
+ { e.stopPropagation(); onAction('stop', loop.id); }} className="min-h-[44px] min-w-[44px] inline-flex items-center justify-center p-1.5 rounded hover:bg-port-border text-gray-400 hover:text-port-warning" title="Stop" aria-label="Stop">
>
) : (
- { e.stopPropagation(); onAction('resume', loop.id); }} className="p-1.5 rounded hover:bg-port-border text-gray-400 hover:text-port-success" title="Resume" aria-label="Resume">
+ { e.stopPropagation(); onAction('resume', loop.id); }} className="min-h-[44px] min-w-[44px] inline-flex items-center justify-center p-1.5 rounded hover:bg-port-border text-gray-400 hover:text-port-success" title="Resume" aria-label="Resume">
)}
- { e.stopPropagation(); onAction('delete', loop.id); }} className="p-1.5 rounded hover:bg-port-border text-gray-400 hover:text-port-error" title="Delete" aria-label="Delete">
+ { e.stopPropagation(); onAction('delete', loop.id); }} className="min-h-[44px] min-w-[44px] inline-flex items-center justify-center p-1.5 rounded hover:bg-port-border text-gray-400 hover:text-port-error" title="Delete" aria-label="Delete">
{expanded ? : }
diff --git a/client/src/pages/Loras.jsx b/client/src/pages/Loras.jsx
index 32d802ef2b..3c869d177a 100644
--- a/client/src/pages/Loras.jsx
+++ b/client/src/pages/Loras.jsx
@@ -1357,7 +1357,7 @@ function LoraCard({ lora, onDelete, onMeasured, deleting, deleteConfirm }) {
@@ -1365,7 +1365,7 @@ function LoraCard({ lora, onDelete, onMeasured, deleting, deleteConfirm }) {
deleteConfirm.requestDelete(lora.filename)}
- className="text-port-error hover:text-port-error/80 p-1.5 rounded hover:bg-port-error/10"
+ className="min-h-[44px] min-w-[44px] inline-flex items-center justify-center text-port-error hover:text-port-error/80 p-1.5 rounded hover:bg-port-error/10"
title={`Delete ${displayName}`} aria-label={`Delete ${displayName}`}
>
diff --git a/client/src/pages/MediaCollectionDetail.jsx b/client/src/pages/MediaCollectionDetail.jsx
index b05398e2e8..56e5465265 100644
--- a/client/src/pages/MediaCollectionDetail.jsx
+++ b/client/src/pages/MediaCollectionDetail.jsx
@@ -514,7 +514,7 @@ export default function MediaCollectionDetail() {
type="button"
onClick={exitSelectMode}
disabled={bulkBusy}
- className="p-1 text-gray-400 hover:text-white disabled:opacity-40"
+ className="min-h-[44px] min-w-[44px] inline-flex items-center justify-center p-1 text-gray-400 hover:text-white disabled:opacity-40"
title="Exit select mode"
aria-label="Exit select mode"
>
diff --git a/client/src/pages/MediaHistory.jsx b/client/src/pages/MediaHistory.jsx
index 75a56079e1..18061a9d89 100644
--- a/client/src/pages/MediaHistory.jsx
+++ b/client/src/pages/MediaHistory.jsx
@@ -203,7 +203,7 @@ export default function MediaHistory() {
setQuery('')}
- className="absolute right-1 top-1/2 -translate-y-1/2 p-0.5 text-gray-500 hover:text-white"
+ className="min-h-[44px] min-w-[44px] inline-flex items-center justify-center absolute right-1 top-1/2 -translate-y-1/2 p-0.5 text-gray-500 hover:text-white"
title="Clear search" aria-label="Clear search"
>
diff --git a/client/src/pages/MoodBoardDetail.jsx b/client/src/pages/MoodBoardDetail.jsx
index c4037171a2..7b6f9b76f3 100644
--- a/client/src/pages/MoodBoardDetail.jsx
+++ b/client/src/pages/MoodBoardDetail.jsx
@@ -626,7 +626,7 @@ export default function MoodBoardDetail() {
onClick={() => setAnalyzeItemId(item.id)}
title={item.analysis ? 'View AI analysis' : 'Analyze with AI'}
aria-label={item.analysis ? 'View AI analysis' : 'Analyze with AI'}
- className={`p-1 transition-colors ${item.analysis ? 'text-port-accent hover:text-port-accent/80' : 'text-gray-500 hover:text-white'}`}
+ className={`min-h-[44px] min-w-[44px] inline-flex items-center justify-center p-1 transition-colors ${item.analysis ? 'text-port-accent hover:text-port-accent/80' : 'text-gray-500 hover:text-white'}`}
>
@@ -636,7 +636,7 @@ export default function MoodBoardDetail() {
onClick={() => setConfirmingItemId(item.id)}
title="Remove item"
aria-label="Remove item"
- className="p-1 text-gray-500 hover:text-port-error transition-colors"
+ className="min-h-[44px] min-w-[44px] inline-flex items-center justify-center p-1 text-gray-500 hover:text-port-error transition-colors"
>
@@ -692,7 +692,7 @@ export default function MoodBoardDetail() {
copyToClipboard(analyzeItem.analysis.prompt, 'Analysis prompt copied')}
- className="p-1 rounded text-gray-400 hover:text-white hover:bg-port-border/50"
+ className="min-h-[44px] min-w-[44px] inline-flex items-center justify-center p-1 rounded text-gray-400 hover:text-white hover:bg-port-border/50"
aria-label="Copy saved analysis prompt"
>
diff --git a/client/src/pages/MoodBoards.jsx b/client/src/pages/MoodBoards.jsx
index 9083d911d3..c5ee514c49 100644
--- a/client/src/pages/MoodBoards.jsx
+++ b/client/src/pages/MoodBoards.jsx
@@ -140,7 +140,7 @@ export default function MoodBoards() {
onClick={() => setConfirmingId(board.id)}
title="Delete board"
aria-label={`Delete ${board.name}`}
- className="p-1.5 text-gray-500 hover:text-port-error transition-colors"
+ className="min-h-[44px] min-w-[44px] inline-flex items-center justify-center p-1.5 text-gray-500 hover:text-port-error transition-colors"
>
diff --git a/client/src/pages/PipelineSeries.jsx b/client/src/pages/PipelineSeries.jsx
index 4809dbf284..8228539d7d 100644
--- a/client/src/pages/PipelineSeries.jsx
+++ b/client/src/pages/PipelineSeries.jsx
@@ -204,7 +204,7 @@ export default function PipelineSeries() {
@@ -351,7 +351,7 @@ function BibleSidebar({ series, universes, patchSeries, onSeriesUpdate, onFlushP
diff --git a/client/src/pages/PromptManager.jsx b/client/src/pages/PromptManager.jsx
index a5980af6c5..11b8ffd24c 100644
--- a/client/src/pages/PromptManager.jsx
+++ b/client/src/pages/PromptManager.jsx
@@ -526,7 +526,7 @@ export default function PromptManager() {
Prompt Stages
setCreatingStage(true)}
- className="p-1 text-port-accent hover:text-port-accent/80"
+ className="min-h-[44px] min-w-[44px] inline-flex items-center justify-center p-1 text-port-accent hover:text-port-accent/80"
title="New Stage" aria-label="New Stage"
>
@@ -781,7 +781,7 @@ export default function PromptManager() {
@@ -818,7 +818,7 @@ export default function PromptManager() {
requestVarDelete(key)}
aria-label={`Delete variable ${v.name || key}`}
- className="p-1 text-gray-500 hover:text-port-error"
+ className="min-h-[44px] min-w-[44px] inline-flex items-center justify-center p-1 text-gray-500 hover:text-port-error"
>
diff --git a/client/src/pages/Review.jsx b/client/src/pages/Review.jsx
index 6286526f45..c27cbbc533 100644
--- a/client/src/pages/Review.jsx
+++ b/client/src/pages/Review.jsx
@@ -449,7 +449,7 @@ export default function Review() {
setBriefingFullscreen(prev => !prev)}
- className="p-1 text-gray-500 hover:text-white transition-colors rounded-md hover:bg-white/5"
+ className="min-h-[44px] min-w-[44px] inline-flex items-center justify-center p-1 text-gray-500 hover:text-white transition-colors rounded-md hover:bg-white/5"
title={briefingFullscreen ? 'Exit fullscreen' : 'Fullscreen'} aria-label={briefingFullscreen ? 'Exit fullscreen' : 'Fullscreen'}
>
{briefingFullscreen ? : }
@@ -609,7 +609,7 @@ function QueueRow({ item, onDrill, onDismiss, onResolve, onPromoteAsk, resolving
)}
-
+
{item.action && onResolve && (
onResolve(item)}
@@ -657,14 +657,14 @@ function QueueRow({ item, onDrill, onDismiss, onResolve, onPromoteAsk, resolving
)}
onDrill(item)}
- className="p-1.5 text-gray-500 hover:text-port-accent transition-colors"
+ className="min-h-[44px] min-w-[44px] inline-flex items-center justify-center p-1.5 text-gray-500 hover:text-port-accent transition-colors"
title="Open" aria-label="Open"
>
onDismiss(item.id)}
- className="p-1.5 text-gray-500 hover:text-port-warning transition-colors"
+ className="min-h-[44px] min-w-[44px] inline-flex items-center justify-center p-1.5 text-gray-500 hover:text-port-warning transition-colors"
title="Dismiss from queue (this session)" aria-label="Dismiss from queue (this session)"
>
@@ -811,11 +811,11 @@ function ReviewItem({ item, config, idScope, isEditing, onComplete, onDismiss, o
{isPending && !isEditing && (
-
+
{item.type === 'todo' && (
@@ -823,21 +823,21 @@ function ReviewItem({ item, config, idScope, isEditing, onComplete, onDismiss, o
)}
onComplete(item.id)}
- className="p-1.5 text-gray-500 hover:text-port-success transition-colors"
+ className="min-h-[44px] min-w-[44px] inline-flex items-center justify-center p-1.5 text-gray-500 hover:text-port-success transition-colors"
title={item.type === 'alert' ? 'Accept' : 'Complete'} aria-label={item.type === 'alert' ? 'Accept' : 'Complete'}
>
onDismiss(item.id)}
- className="p-1.5 text-gray-500 hover:text-port-warning transition-colors"
+ className="min-h-[44px] min-w-[44px] inline-flex items-center justify-center p-1.5 text-gray-500 hover:text-port-warning transition-colors"
title={item.type === 'alert' ? 'Reject' : 'Dismiss'} aria-label={item.type === 'alert' ? 'Reject' : 'Dismiss'}
>
onDelete(item.id)}
- className="p-1.5 text-gray-500 hover:text-port-error transition-colors"
+ className="min-h-[44px] min-w-[44px] inline-flex items-center justify-center p-1.5 text-gray-500 hover:text-port-error transition-colors"
title="Delete" aria-label="Delete"
>
diff --git a/client/src/pages/RoundEditor.jsx b/client/src/pages/RoundEditor.jsx
index 4f6655fa3d..1e8bffeb6b 100644
--- a/client/src/pages/RoundEditor.jsx
+++ b/client/src/pages/RoundEditor.jsx
@@ -77,7 +77,7 @@ export default function RoundEditor() {
navigate("/rounds")}
- className="p-1 text-gray-400 hover:text-white transition-colors"
+ className="min-h-[44px] min-w-[44px] inline-flex items-center justify-center p-1 text-gray-400 hover:text-white transition-colors"
title="Back to Rounds"
aria-label="Back to Rounds"
>
diff --git a/client/src/pages/RunnerPage.jsx b/client/src/pages/RunnerPage.jsx
index b91a77ddff..6582c7fff1 100644
--- a/client/src/pages/RunnerPage.jsx
+++ b/client/src/pages/RunnerPage.jsx
@@ -270,7 +270,7 @@ ${prompt.trim()}`;
setContinueContext(null)}
- className="p-1 text-gray-400 hover:text-white"
+ className="min-h-[44px] min-w-[44px] inline-flex items-center justify-center p-1 text-gray-400 hover:text-white"
title="Dismiss context"
aria-label="Dismiss context"
>
diff --git a/client/src/pages/ThreejsModelDetail.jsx b/client/src/pages/ThreejsModelDetail.jsx
index 81fd74447c..c2155133f8 100644
--- a/client/src/pages/ThreejsModelDetail.jsx
+++ b/client/src/pages/ThreejsModelDetail.jsx
@@ -557,7 +557,7 @@ export default function ThreejsModelDetail() {
setConfirmingDelete(true)}
- className="rounded p-1.5 text-gray-500 hover:bg-port-error/10 hover:text-port-error"
+ className="min-h-[44px] min-w-[44px] inline-flex items-center justify-center rounded p-1.5 text-gray-500 hover:bg-port-error/10 hover:text-port-error"
aria-label={`Delete ${record.name}`}
title="Delete model"
>
diff --git a/client/src/pages/Tribe.jsx b/client/src/pages/Tribe.jsx
index 6510ed6b44..23e31a1c55 100644
--- a/client/src/pages/Tribe.jsx
+++ b/client/src/pages/Tribe.jsx
@@ -493,7 +493,7 @@ function MemoryLinksPanel({ personId }) {
onClick={() => unlinkMemory(link.memoryId)}
title="Unlink memory"
aria-label="Unlink memory"
- className="shrink-0 rounded p-1 text-gray-500 hover:text-rose-300"
+ className="min-h-[44px] min-w-[44px] inline-flex items-center justify-center shrink-0 rounded p-1 text-gray-500 hover:text-rose-300"
>
diff --git a/client/src/pages/VideoGen.jsx b/client/src/pages/VideoGen.jsx
index 73fb67267b..df0a216055 100644
--- a/client/src/pages/VideoGen.jsx
+++ b/client/src/pages/VideoGen.jsx
@@ -859,7 +859,7 @@ export default function VideoGen() {
diff --git a/client/src/pages/VideoTimeline.jsx b/client/src/pages/VideoTimeline.jsx
index 396125ff65..6f31a9534e 100644
--- a/client/src/pages/VideoTimeline.jsx
+++ b/client/src/pages/VideoTimeline.jsx
@@ -118,7 +118,7 @@ export default function VideoTimeline() {
handleDelete(project)}
- className="p-1 text-gray-500 hover:text-port-error transition-colors"
+ className="min-h-[44px] min-w-[44px] inline-flex items-center justify-center p-1 text-gray-500 hover:text-port-error transition-colors"
title="Delete project" aria-label="Delete project"
>
diff --git a/client/src/pages/VideoTimelineEditor.jsx b/client/src/pages/VideoTimelineEditor.jsx
index c0dc6b7818..34db529ca9 100644
--- a/client/src/pages/VideoTimelineEditor.jsx
+++ b/client/src/pages/VideoTimelineEditor.jsx
@@ -766,7 +766,7 @@ export default function VideoTimelineEditor() {
navigate('/media/timeline')}
- className="p-1.5 text-gray-400 hover:text-white"
+ className="min-h-[44px] min-w-[44px] inline-flex items-center justify-center p-1.5 text-gray-400 hover:text-white"
title="Back to projects" aria-label="Back to projects"
>
diff --git a/client/src/pages/WritersRoom.jsx b/client/src/pages/WritersRoom.jsx
index 49330db078..ab448b2dce 100644
--- a/client/src/pages/WritersRoom.jsx
+++ b/client/src/pages/WritersRoom.jsx
@@ -134,7 +134,7 @@ export default function WritersRoom() {