diff --git a/docs/superpowers/plans/2026-03-18-report-command.md b/docs/superpowers/plans/2026-03-18-report-command.md
index cb7f712..145461f 100644
--- a/docs/superpowers/plans/2026-03-18-report-command.md
+++ b/docs/superpowers/plans/2026-03-18-report-command.md
@@ -1642,14 +1642,15 @@ Create `ui/src/routes/report/+page.svelte`:
color: var(--fg);
font-size: 0.875rem;
font-family: var(--font-mono);
- outline: none;
- transition: all 0.2s ease;
+ transition: background-color 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease, color 0.2s ease;
box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.2);
}
- .field input:focus,
- .field select:focus,
- .field textarea:focus {
+ .field input:focus-visible,
+ .field select:focus-visible,
+ .field textarea:focus-visible {
+ outline: 2px solid var(--accent);
+ outline-offset: 2px;
border-color: var(--accent);
box-shadow: 0 0 8px var(--border-glow);
}
@@ -1726,7 +1727,7 @@ Create `ui/src/routes/report/+page.svelte`:
text-transform: uppercase;
letter-spacing: 2px;
cursor: pointer;
- transition: all 0.2s ease;
+ transition: background-color 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease, color 0.2s ease, text-shadow 0.2s ease;
text-shadow: var(--text-glow);
box-shadow: inset 0 0 10px color-mix(in srgb, var(--accent) 30%, transparent);
}
@@ -1753,7 +1754,7 @@ Create `ui/src/routes/report/+page.svelte`:
text-transform: uppercase;
letter-spacing: 1px;
cursor: pointer;
- transition: all 0.2s ease;
+ transition: background-color 0.2s ease, border-color 0.2s ease, color 0.2s ease;
}
.btn:hover {
diff --git a/ui/src/app.css b/ui/src/app.css
index 230fae2..09a8ead 100644
--- a/ui/src/app.css
+++ b/ui/src/app.css
@@ -259,6 +259,7 @@ body.theme-8bit-lobster-light:not(.effects-disabled)::after {
/* Base Inputs */
input,
button,
+select,
textarea {
font-family: inherit;
font-size: 0.95em;
@@ -267,14 +268,18 @@ textarea {
border: 1px solid var(--border);
border-radius: var(--radius);
padding: 8px 12px;
- outline: none;
- transition: all 0.2s ease;
+ transition: border-color 0.2s ease, box-shadow 0.2s ease, background-color 0.2s ease, color 0.2s ease;
backdrop-filter: blur(4px);
text-shadow: var(--text-glow);
}
-input:focus,
-textarea:focus {
+input:focus-visible,
+select:focus-visible,
+textarea:focus-visible,
+button:focus-visible,
+a:focus-visible {
+ outline: 2px solid var(--accent);
+ outline-offset: 2px;
border-color: var(--accent);
box-shadow: 0 0 8px var(--border-glow);
}
@@ -349,7 +354,7 @@ button:disabled {
a {
color: var(--accent);
text-decoration: none;
- transition: all 0.2s ease;
+ transition: color 0.2s ease, text-shadow 0.2s ease;
text-shadow: 0 0 2px color-mix(in srgb, var(--accent) 50%, transparent);
}
@@ -364,6 +369,7 @@ body.effects-disabled * {
}
body.effects-disabled input:focus,
+body.effects-disabled select:focus,
body.effects-disabled textarea:focus,
body.effects-disabled button:hover:not(:disabled) {
box-shadow: none !important;
@@ -444,3 +450,19 @@ body.effects-disabled button:hover:not(:disabled) {
transform: translate(0)
}
}
+
+@media (prefers-reduced-motion: reduce) {
+ *,
+ *::before,
+ *::after {
+ animation-duration: 0.01ms !important;
+ animation-iteration-count: 1 !important;
+ transition-duration: 0.01ms !important;
+ scroll-behavior: auto !important;
+ }
+
+ body:not(.effects-disabled)::before,
+ body:not(.effects-disabled)::after {
+ animation: none !important;
+ }
+}
diff --git a/ui/src/lib/components/ChannelList.svelte b/ui/src/lib/components/ChannelList.svelte
index 342d350..1d35410 100644
--- a/ui/src/lib/components/ChannelList.svelte
+++ b/ui/src/lib/components/ChannelList.svelte
@@ -228,7 +228,7 @@
{#if schema?.hasAccounts && isNamedAccount(entry.account)}
{entry.account}
{/if}
-
+
@@ -355,7 +355,7 @@
padding: 1rem;
margin-bottom: 0.75rem;
box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.2);
- transition: all 0.2s ease;
+ transition: background-color 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease, color 0.2s ease, transform 0.2s ease, text-shadow 0.2s ease;
}
.channel-row:hover {
@@ -448,8 +448,7 @@
color: var(--fg);
font-size: 0.875rem;
font-family: var(--font-mono);
- outline: none;
- transition: all 0.2s ease;
+ transition: background-color 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease, color 0.2s ease, transform 0.2s ease, text-shadow 0.2s ease;
box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.2);
}
@@ -486,7 +485,7 @@
color: var(--fg-dim);
font-size: 1rem;
cursor: pointer;
- transition: all 0.2s ease;
+ transition: background-color 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease, color 0.2s ease, transform 0.2s ease, text-shadow 0.2s ease;
}
.remove-btn:hover {
background: color-mix(in srgb, var(--error, #e55) 15%, transparent);
@@ -514,7 +513,7 @@
font-size: 0.8rem;
font-family: var(--font-mono);
cursor: pointer;
- transition: all 0.2s ease;
+ transition: background-color 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease, color 0.2s ease, transform 0.2s ease, text-shadow 0.2s ease;
text-transform: uppercase;
letter-spacing: 1px;
}
@@ -552,7 +551,7 @@
text-transform: uppercase;
letter-spacing: 1px;
cursor: pointer;
- transition: all 0.2s ease;
+ transition: background-color 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease, color 0.2s ease, transform 0.2s ease, text-shadow 0.2s ease;
}
.add-btn:hover {
border-color: var(--accent);
@@ -591,7 +590,7 @@
background: var(--bg-surface);
border: 1px solid var(--border);
border-radius: 2px;
- transition: all 0.2s ease;
+ transition: background-color 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease, color 0.2s ease, transform 0.2s ease, text-shadow 0.2s ease;
box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.5);
}
.toggle-slider::before {
@@ -603,7 +602,7 @@
top: 3px;
background: var(--fg-dim);
border-radius: 2px;
- transition: all 0.2s ease;
+ transition: background-color 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease, color 0.2s ease, transform 0.2s ease, text-shadow 0.2s ease;
}
.toggle input:checked + .toggle-slider {
background: color-mix(in srgb, var(--accent) 20%, transparent);
@@ -654,7 +653,7 @@
border-bottom: 1px solid var(--border);
color: var(--fg);
cursor: pointer;
- transition: all 0.15s ease;
+ transition: background-color 0.15s ease, border-color 0.15s ease, box-shadow 0.15s ease, color 0.15s ease, transform 0.15s ease, text-shadow 0.15s ease;
text-align: left;
font-family: var(--font-mono);
}
diff --git a/ui/src/lib/components/ComponentCard.svelte b/ui/src/lib/components/ComponentCard.svelte
index 34a5d83..d8f54f1 100644
--- a/ui/src/lib/components/ComponentCard.svelte
+++ b/ui/src/lib/components/ComponentCard.svelte
@@ -77,7 +77,7 @@
border-radius: 4px;
padding: 1.5rem;
color: var(--fg);
- transition: all 0.2s ease;
+ transition: background-color 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease, color 0.2s ease, transform 0.2s ease, text-shadow 0.2s ease;
backdrop-filter: blur(4px);
}
@@ -165,7 +165,7 @@
padding: 0.375rem 0.75rem;
border-radius: 2px;
cursor: pointer;
- transition: all 0.2s ease;
+ transition: background-color 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease, color 0.2s ease, transform 0.2s ease, text-shadow 0.2s ease;
text-transform: uppercase;
letter-spacing: 1px;
font-weight: bold;
diff --git a/ui/src/lib/components/ConfigEditor.svelte b/ui/src/lib/components/ConfigEditor.svelte
index 03e8c55..278f853 100644
--- a/ui/src/lib/components/ConfigEditor.svelte
+++ b/ui/src/lib/components/ConfigEditor.svelte
@@ -185,7 +185,7 @@
text-transform: uppercase;
letter-spacing: 1px;
cursor: pointer;
- transition: all 0.2s ease;
+ transition: background-color 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease, color 0.2s ease, text-shadow 0.2s ease;
}
.mode-btn:first-child {
border-radius: 2px 0 0 2px;
@@ -218,7 +218,7 @@
font-weight: 700;
text-transform: uppercase;
letter-spacing: 1px;
- transition: all 0.2s ease;
+ transition: background-color 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease, color 0.2s ease, text-shadow 0.2s ease;
box-shadow: inset 0 0 8px color-mix(in srgb, var(--accent) 30%, transparent);
}
.save-btn:hover:not(:disabled) {
@@ -275,11 +275,12 @@
font-size: 0.875rem;
resize: none;
line-height: 1.6;
- outline: none;
- transition: all 0.2s ease;
+ transition: background-color 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease, color 0.2s ease, text-shadow 0.2s ease;
box-shadow: inset 0 2px 8px rgba(0, 0, 0, 0.5);
}
- .raw-editor:focus {
+ .raw-editor:focus-visible {
+ outline: 2px solid var(--accent);
+ outline-offset: 2px;
border-color: var(--accent);
box-shadow: inset 0 2px 8px rgba(0, 0, 0, 0.5), 0 0 8px var(--border-glow);
}
diff --git a/ui/src/lib/components/ConfigEditorUI.svelte b/ui/src/lib/components/ConfigEditorUI.svelte
index 44be914..4c2bd76 100644
--- a/ui/src/lib/components/ConfigEditorUI.svelte
+++ b/ui/src/lib/components/ConfigEditorUI.svelte
@@ -216,15 +216,23 @@
{@const schema = channelSchemas[channelType]}
{#if schema}
-
@@ -553,7 +556,7 @@
padding: 1rem;
margin-bottom: 0.75rem;
box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.2);
- transition: all 0.2s ease;
+ transition: background-color 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease, color 0.2s ease, transform 0.2s ease, text-shadow 0.2s ease;
}
.provider-row:hover {
@@ -587,8 +590,7 @@
color: var(--fg);
font-size: 0.875rem;
font-family: var(--font-mono);
- outline: none;
- transition: all 0.2s ease;
+ transition: background-color 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease, color 0.2s ease, transform 0.2s ease, text-shadow 0.2s ease;
}
.provider-row-header select:focus {
@@ -614,7 +616,7 @@
color: var(--fg-dim);
font-size: 1rem;
cursor: pointer;
- transition: all 0.2s ease;
+ transition: background-color 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease, color 0.2s ease, transform 0.2s ease, text-shadow 0.2s ease;
}
.icon-btn:hover:not(:disabled) {
@@ -661,8 +663,7 @@
color: var(--fg);
font-size: 0.875rem;
font-family: var(--font-mono);
- outline: none;
- transition: all 0.2s ease;
+ transition: background-color 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease, color 0.2s ease, transform 0.2s ease, text-shadow 0.2s ease;
box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.2);
}
@@ -749,7 +750,7 @@
text-transform: uppercase;
letter-spacing: 1px;
cursor: pointer;
- transition: all 0.2s ease;
+ transition: background-color 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease, color 0.2s ease, transform 0.2s ease, text-shadow 0.2s ease;
}
.status-dot {
@@ -825,7 +826,7 @@
cursor: pointer;
text-align: left;
font-family: var(--font-mono);
- transition: all 0.15s ease;
+ transition: background-color 0.15s ease, border-color 0.15s ease, box-shadow 0.15s ease, color 0.15s ease, transform 0.15s ease, text-shadow 0.15s ease;
}
.saved-item:last-child {
diff --git a/ui/src/lib/components/Sidebar.svelte b/ui/src/lib/components/Sidebar.svelte
index bbfeb3b..584e038 100644
--- a/ui/src/lib/components/Sidebar.svelte
+++ b/ui/src/lib/components/Sidebar.svelte
@@ -203,7 +203,7 @@
font-size: 0.875rem;
text-transform: uppercase;
letter-spacing: 1px;
- transition: all 0.2s ease;
+ transition: background-color 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease, color 0.2s ease, transform 0.2s ease, text-shadow 0.2s ease;
border-left: 3px solid transparent;
}
@@ -271,7 +271,7 @@
font-size: 0.875rem;
text-transform: uppercase;
letter-spacing: 1px;
- transition: all 0.2s ease;
+ transition: background-color 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease, color 0.2s ease, transform 0.2s ease, text-shadow 0.2s ease;
border-left: 3px solid transparent;
}
diff --git a/ui/src/lib/components/StructuredConfigEditor.svelte b/ui/src/lib/components/StructuredConfigEditor.svelte
index f1fdad1..986fd06 100644
--- a/ui/src/lib/components/StructuredConfigEditor.svelte
+++ b/ui/src/lib/components/StructuredConfigEditor.svelte
@@ -291,8 +291,7 @@
color: var(--fg);
font-size: 0.875rem;
font-family: var(--font-mono);
- outline: none;
- transition: all 0.2s ease;
+ transition: background-color 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease, color 0.2s ease, transform 0.2s ease, text-shadow 0.2s ease;
}
.field input:focus,
diff --git a/ui/src/lib/components/TopBar.svelte b/ui/src/lib/components/TopBar.svelte
index 36c0315..b8c373c 100644
--- a/ui/src/lib/components/TopBar.svelte
+++ b/ui/src/lib/components/TopBar.svelte
@@ -169,13 +169,14 @@
font-family: var(--font-mono);
font-size: 0.75rem;
text-transform: uppercase;
- outline: none;
cursor: pointer;
- transition: all 0.2s ease;
+ transition: background-color 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease, color 0.2s ease;
}
- .theme-select:focus,
+ .theme-select:focus-visible,
.theme-select:hover {
+ outline: 2px solid var(--accent);
+ outline-offset: 2px;
border-color: var(--accent);
box-shadow: 0 0 8px var(--border-glow);
}
diff --git a/ui/src/lib/components/WizardRenderer.svelte b/ui/src/lib/components/WizardRenderer.svelte
index 2aa04fe..4162a09 100644
--- a/ui/src/lib/components/WizardRenderer.svelte
+++ b/ui/src/lib/components/WizardRenderer.svelte
@@ -580,7 +580,7 @@
color: var(--fg-dim);
cursor: pointer;
padding: 0.25rem 0;
- transition: all 0.2s ease;
+ transition: background-color 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease, color 0.2s ease, transform 0.2s ease, text-shadow 0.2s ease;
}
.step-dot:disabled { cursor: default; }
@@ -608,7 +608,7 @@
font-size: 0.75rem;
font-weight: 700;
font-family: var(--font-mono);
- transition: all 0.2s ease;
+ transition: background-color 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease, color 0.2s ease, transform 0.2s ease, text-shadow 0.2s ease;
}
.step-label {
@@ -616,7 +616,7 @@
font-weight: 700;
text-transform: uppercase;
letter-spacing: 1px;
- transition: all 0.2s ease;
+ transition: background-color 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease, color 0.2s ease, transform 0.2s ease, text-shadow 0.2s ease;
}
.step-line {
@@ -624,7 +624,7 @@
height: 1px;
background: var(--border);
margin: 0 0.75rem;
- transition: all 0.2s ease;
+ transition: background-color 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease, color 0.2s ease, transform 0.2s ease, text-shadow 0.2s ease;
}
.step-line.completed { background: var(--accent); box-shadow: 0 0 4px var(--border-glow); }
@@ -658,8 +658,7 @@
color: var(--fg);
font-size: 0.875rem;
font-family: var(--font-mono);
- outline: none;
- transition: all 0.2s ease;
+ transition: background-color 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease, color 0.2s ease, transform 0.2s ease, text-shadow 0.2s ease;
box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.2);
}
@@ -689,8 +688,7 @@
color: var(--fg);
font-size: 0.875rem;
font-family: var(--font-mono);
- outline: none;
- transition: all 0.2s ease;
+ transition: background-color 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease, color 0.2s ease, transform 0.2s ease, text-shadow 0.2s ease;
box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.2);
cursor: pointer;
}
@@ -721,7 +719,7 @@
letter-spacing: 1px;
cursor: pointer;
width: 100%;
- transition: all 0.2s ease;
+ transition: background-color 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease, color 0.2s ease, transform 0.2s ease, text-shadow 0.2s ease;
margin-top: 1rem;
}
.advanced-toggle:hover {
@@ -792,7 +790,7 @@
font-size: 0.875rem;
font-weight: 700;
cursor: pointer;
- transition: all 0.2s ease;
+ transition: background-color 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease, color 0.2s ease, transform 0.2s ease, text-shadow 0.2s ease;
text-transform: uppercase;
letter-spacing: 2px;
text-shadow: var(--text-glow);
@@ -824,7 +822,7 @@
font-size: 0.875rem;
font-weight: 700;
cursor: pointer;
- transition: all 0.2s ease;
+ transition: background-color 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease, color 0.2s ease, transform 0.2s ease, text-shadow 0.2s ease;
text-transform: uppercase;
letter-spacing: 2px;
}
diff --git a/ui/src/lib/components/WizardStep.svelte b/ui/src/lib/components/WizardStep.svelte
index 509213d..3e5f451 100644
--- a/ui/src/lib/components/WizardStep.svelte
+++ b/ui/src/lib/components/WizardStep.svelte
@@ -236,7 +236,7 @@
padding: 0.75rem 1rem;
color: var(--fg);
cursor: pointer;
- transition: all 0.2s ease;
+ transition: background-color 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease, color 0.2s ease, transform 0.2s ease, text-shadow 0.2s ease;
}
.option-btn:hover {
@@ -313,8 +313,7 @@
color: var(--fg);
font-size: 0.875rem;
font-family: var(--font-mono);
- outline: none;
- transition: all 0.2s ease;
+ transition: background-color 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease, color 0.2s ease, transform 0.2s ease, text-shadow 0.2s ease;
box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.2);
}
@@ -351,7 +350,7 @@
padding: 0.6rem 0.75rem;
color: var(--fg);
cursor: pointer;
- transition: all 0.1s ease;
+ transition: background-color 0.1s ease, border-color 0.1s ease, box-shadow 0.1s ease, color 0.1s ease, transform 0.1s ease, text-shadow 0.1s ease;
}
.dropdown-item:last-child {
@@ -409,8 +408,7 @@
color: var(--fg);
font-size: 0.875rem;
font-family: var(--font-mono);
- outline: none;
- transition: all 0.2s ease;
+ transition: background-color 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease, color 0.2s ease, transform 0.2s ease, text-shadow 0.2s ease;
box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.2);
}
@@ -446,7 +444,7 @@
background: var(--bg-surface);
border: 1px solid var(--border);
border-radius: 2px;
- transition: all 0.2s ease;
+ transition: background-color 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease, color 0.2s ease, transform 0.2s ease, text-shadow 0.2s ease;
box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.5);
}
@@ -459,7 +457,7 @@
top: 3px;
background: var(--fg-dim);
border-radius: 2px;
- transition: all 0.2s ease;
+ transition: background-color 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease, color 0.2s ease, transform 0.2s ease, text-shadow 0.2s ease;
}
.toggle input:checked + .toggle-slider {
diff --git a/ui/src/lib/components/nullboiler/CheckpointTimeline.svelte b/ui/src/lib/components/nullboiler/CheckpointTimeline.svelte
index 9b50f33..99b8065 100644
--- a/ui/src/lib/components/nullboiler/CheckpointTimeline.svelte
+++ b/ui/src/lib/components/nullboiler/CheckpointTimeline.svelte
@@ -80,7 +80,7 @@
background: var(--border);
border: 2px solid var(--fg-dim);
flex-shrink: 0;
- transition: all 0.2s ease;
+ transition: background-color 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease, color 0.2s ease, transform 0.2s ease, text-shadow 0.2s ease;
}
.dot.selected {
background: var(--accent);
diff --git a/ui/src/lib/components/nullboiler/InterruptPanel.svelte b/ui/src/lib/components/nullboiler/InterruptPanel.svelte
index 136bcd5..5730d4a 100644
--- a/ui/src/lib/components/nullboiler/InterruptPanel.svelte
+++ b/ui/src/lib/components/nullboiler/InterruptPanel.svelte
@@ -30,9 +30,9 @@
}
-
-
-
e.stopPropagation()} onkeydown={(e) => { if (e.key === 'Escape') reject(); }}>
+
+
+
{ if (e.key === 'Escape') reject(); }}>
@@ -70,20 +70,34 @@
.overlay {
position: fixed;
inset: 0;
- background: rgba(0, 0, 0, 0.6);
display: flex;
align-items: center;
justify-content: center;
z-index: 100;
+ }
+ .backdrop {
+ position: absolute;
+ inset: 0;
+ background: rgba(0, 0, 0, 0.6);
backdrop-filter: blur(2px);
+ border: none;
+ padding: 0;
+ margin: 0;
+ cursor: pointer;
+ }
+ .backdrop:focus-visible {
+ outline: 2px solid var(--accent);
+ outline-offset: -4px;
}
.panel {
+ position: relative;
background: var(--bg-surface);
border: 1px solid var(--warning);
border-radius: 4px;
width: 90%;
max-width: 520px;
box-shadow: 0 0 30px color-mix(in srgb, var(--warning) 20%, transparent);
+ overscroll-behavior: contain;
}
.panel-header {
padding: 1rem 1.25rem;
@@ -145,9 +159,10 @@
font-size: 0.8125rem;
line-height: 1.5;
resize: vertical;
- outline: none;
}
- .state-editor:focus {
+ .state-editor:focus-visible {
+ outline: 2px solid var(--accent);
+ outline-offset: 2px;
border-color: var(--accent-dim);
box-shadow: 0 0 6px var(--border-glow);
}
@@ -175,7 +190,7 @@
text-transform: uppercase;
letter-spacing: 1px;
cursor: pointer;
- transition: all 0.2s ease;
+ transition: background-color 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease, text-shadow 0.2s ease;
}
.btn-reject {
background: color-mix(in srgb, var(--error) 10%, transparent);
diff --git a/ui/src/lib/components/nullboiler/StateInspector.svelte b/ui/src/lib/components/nullboiler/StateInspector.svelte
index e2c4a44..1240784 100644
--- a/ui/src/lib/components/nullboiler/StateInspector.svelte
+++ b/ui/src/lib/components/nullboiler/StateInspector.svelte
@@ -130,7 +130,7 @@
text-transform: uppercase;
letter-spacing: 0.5px;
cursor: pointer;
- transition: all 0.15s ease;
+ transition: background-color 0.15s ease, border-color 0.15s ease, box-shadow 0.15s ease, color 0.15s ease, transform 0.15s ease, text-shadow 0.15s ease;
}
.diff-toggle:hover {
background: var(--bg-hover);
diff --git a/ui/src/lib/components/nullboiler/WorkflowJsonEditor.svelte b/ui/src/lib/components/nullboiler/WorkflowJsonEditor.svelte
index be3f86a..14366c3 100644
--- a/ui/src/lib/components/nullboiler/WorkflowJsonEditor.svelte
+++ b/ui/src/lib/components/nullboiler/WorkflowJsonEditor.svelte
@@ -51,7 +51,6 @@
font-size: 0.8125rem;
line-height: 1.6;
resize: vertical;
- outline: none;
transition: border-color 0.2s ease;
tab-size: 2;
}
diff --git a/ui/src/routes/+page.svelte b/ui/src/routes/+page.svelte
index 19688db..9429707 100644
--- a/ui/src/routes/+page.svelte
+++ b/ui/src/routes/+page.svelte
@@ -91,7 +91,7 @@
font-weight: bold;
text-transform: uppercase;
letter-spacing: 1px;
- transition: all 0.2s ease;
+ transition: background-color 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease, color 0.2s ease, transform 0.2s ease, text-shadow 0.2s ease;
text-shadow: var(--text-glow);
}
.install-btn:hover {
@@ -148,7 +148,7 @@
font-weight: bold;
text-transform: uppercase;
letter-spacing: 1px;
- transition: all 0.2s ease;
+ transition: background-color 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease, color 0.2s ease, transform 0.2s ease, text-shadow 0.2s ease;
text-shadow: var(--text-glow);
}
diff --git a/ui/src/routes/channels/+page.svelte b/ui/src/routes/channels/+page.svelte
index 69ed0d2..7040796 100644
--- a/ui/src/routes/channels/+page.svelte
+++ b/ui/src/routes/channels/+page.svelte
@@ -528,8 +528,7 @@
color: var(--fg);
font-size: 0.875rem;
font-family: var(--font-mono);
- outline: none;
- transition: all 0.2s ease;
+ transition: background-color 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease, color 0.2s ease, transform 0.2s ease, text-shadow 0.2s ease;
box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.2);
}
@@ -669,7 +668,7 @@
text-transform: uppercase;
letter-spacing: 1px;
cursor: pointer;
- transition: all 0.2s ease;
+ transition: background-color 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease, color 0.2s ease, transform 0.2s ease, text-shadow 0.2s ease;
text-shadow: var(--text-glow);
}
@@ -705,7 +704,7 @@
text-transform: uppercase;
letter-spacing: 1px;
cursor: pointer;
- transition: all 0.2s ease;
+ transition: background-color 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease, color 0.2s ease, transform 0.2s ease, text-shadow 0.2s ease;
text-shadow: var(--text-glow);
}
@@ -771,7 +770,7 @@
text-transform: uppercase;
letter-spacing: 1px;
font-size: 0.875rem;
- transition: all 0.2s ease;
+ transition: background-color 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease, color 0.2s ease, transform 0.2s ease, text-shadow 0.2s ease;
}
.link-btn:hover {
@@ -811,7 +810,7 @@
background: var(--bg-surface);
border: 1px solid var(--border);
border-radius: 2px;
- transition: all 0.2s ease;
+ transition: background-color 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease, color 0.2s ease, transform 0.2s ease, text-shadow 0.2s ease;
box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.5);
}
.toggle-slider::before {
@@ -823,7 +822,7 @@
top: 3px;
background: var(--fg-dim);
border-radius: 2px;
- transition: all 0.2s ease;
+ transition: background-color 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease, color 0.2s ease, transform 0.2s ease, text-shadow 0.2s ease;
}
.toggle input:checked + .toggle-slider {
background: color-mix(in srgb, var(--accent) 20%, transparent);
diff --git a/ui/src/routes/dashboard/+page.svelte b/ui/src/routes/dashboard/+page.svelte
index 6361c1e..d25fc25 100644
--- a/ui/src/routes/dashboard/+page.svelte
+++ b/ui/src/routes/dashboard/+page.svelte
@@ -415,7 +415,7 @@
text-transform: uppercase;
letter-spacing: 1px;
cursor: pointer;
- transition: all 0.2s ease;
+ transition: background-color 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease, color 0.2s ease, transform 0.2s ease, text-shadow 0.2s ease;
}
.window-selector button:hover {
color: var(--fg);
diff --git a/ui/src/routes/instances/[component]/[name]/+page.svelte b/ui/src/routes/instances/[component]/[name]/+page.svelte
index cbc9a77..7f9b2f3 100644
--- a/ui/src/routes/instances/[component]/[name]/+page.svelte
+++ b/ui/src/routes/instances/[component]/[name]/+page.svelte
@@ -1951,7 +1951,7 @@
text-transform: uppercase;
letter-spacing: 1px;
cursor: pointer;
- transition: all 0.2s ease;
+ transition: background-color 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease, color 0.2s ease, transform 0.2s ease, text-shadow 0.2s ease;
text-shadow: var(--text-glow);
text-decoration: none;
}
@@ -1994,7 +1994,7 @@
text-transform: uppercase;
letter-spacing: 1px;
cursor: pointer;
- transition: all 0.2s ease;
+ transition: background-color 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease, color 0.2s ease, transform 0.2s ease, text-shadow 0.2s ease;
}
.tabs button:hover {
color: var(--accent);
@@ -2023,7 +2023,7 @@
border: 1px solid var(--border);
border-radius: 4px;
backdrop-filter: blur(4px);
- transition: all 0.2s ease;
+ transition: background-color 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease, color 0.2s ease, transform 0.2s ease, text-shadow 0.2s ease;
}
.info-card:hover {
border-color: color-mix(in srgb, var(--accent) 50%, transparent);
@@ -2137,7 +2137,6 @@
.integration-field select:focus,
.integration-field input:focus,
.integration-field textarea:focus {
- outline: none;
border-color: var(--accent);
}
.integration-field textarea {
@@ -2179,7 +2178,6 @@
font-size: 0.75rem;
}
.usage-window:focus {
- outline: none;
border-color: var(--accent);
}
.usage-table-wrap {
@@ -2261,7 +2259,7 @@
background: var(--bg-surface);
border: none;
border-radius: 2px;
- transition: all 0.2s ease;
+ transition: background-color 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease, color 0.2s ease, transform 0.2s ease, text-shadow 0.2s ease;
box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.5);
}
.toggle-thumb {
@@ -2272,7 +2270,7 @@
height: 14px;
background: var(--fg-dim);
border-radius: 2px;
- transition: all 0.2s ease;
+ transition: background-color 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease, color 0.2s ease, transform 0.2s ease, text-shadow 0.2s ease;
}
.toggle-btn.on .toggle-track {
background: color-mix(in srgb, var(--accent) 20%, transparent);
diff --git a/ui/src/routes/nullboiler/+page.svelte b/ui/src/routes/nullboiler/+page.svelte
index 0d84ce2..3cd338a 100644
--- a/ui/src/routes/nullboiler/+page.svelte
+++ b/ui/src/routes/nullboiler/+page.svelte
@@ -61,6 +61,17 @@
function runHref(id: string): string {
return nullboilerUiRoutes.run(id);
}
+
+ function openRun(id: string) {
+ void goto(runHref(id));
+ }
+
+ function handleRunRowKeydown(e: KeyboardEvent, id: string) {
+ if (e.key === 'Enter' || e.key === ' ') {
+ e.preventDefault();
+ openRun(id);
+ }
+ }
@@ -118,7 +129,13 @@
{#each runs.slice(0, 20) as run}
- goto(runHref(run.id))} class="clickable">
+
openRun(run.id)}
+ onkeydown={(e) => handleRunRowKeydown(e, run.id)}
+ class="clickable"
+ role="link"
+ tabindex="0"
+ >
| {(run.id || '').slice(0, 8)} |
{run.workflow_name || run.workflow_id || '-'} |
@@ -187,7 +204,7 @@
font-weight: bold;
text-transform: uppercase;
letter-spacing: 1px;
- transition: all 0.2s ease;
+ transition: background-color 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease, color 0.2s ease, transform 0.2s ease, text-shadow 0.2s ease;
text-shadow: var(--text-glow);
}
.action-btn:hover {
@@ -261,6 +278,13 @@
tr.clickable:hover td {
background: var(--bg-hover);
}
+ tr.clickable:focus-visible {
+ outline: 2px solid var(--accent);
+ outline-offset: -2px;
+ }
+ tr.clickable:focus-visible td {
+ background: var(--bg-hover);
+ }
.status-badge {
display: inline-flex;
align-items: center;
@@ -326,7 +350,7 @@
font-weight: bold;
text-transform: uppercase;
letter-spacing: 1px;
- transition: all 0.2s ease;
+ transition: background-color 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease, color 0.2s ease, transform 0.2s ease, text-shadow 0.2s ease;
text-shadow: var(--text-glow);
}
.empty-state .btn:hover {
diff --git a/ui/src/routes/nullboiler/runs/+page.svelte b/ui/src/routes/nullboiler/runs/+page.svelte
index fd940b5..a4093e8 100644
--- a/ui/src/routes/nullboiler/runs/+page.svelte
+++ b/ui/src/routes/nullboiler/runs/+page.svelte
@@ -103,6 +103,17 @@
function runHref(id: string): string {
return nullboilerUiRoutes.run(id);
}
+
+ function openRun(id: string) {
+ void goto(runHref(id));
+ }
+
+ function handleRunRowKeydown(e: KeyboardEvent, id: string) {
+ if (e.key === 'Enter' || e.key === ' ') {
+ e.preventDefault();
+ openRun(id);
+ }
+ }
@@ -160,7 +171,13 @@
{#each runs as run}
- goto(runHref(run.id))} class="clickable">
+ openRun(run.id)}
+ onkeydown={(e) => handleRunRowKeydown(e, run.id)}
+ class="clickable"
+ role="link"
+ tabindex="0"
+ >
| {(run.id || '').slice(0, 8)} |
{run.workflow_name || run.workflow_id || '-'} |
@@ -237,7 +254,6 @@
border-radius: 2px;
font-size: 0.8125rem;
font-family: var(--font-mono);
- outline: none;
cursor: pointer;
}
.filter-select:focus {
@@ -253,7 +269,6 @@
border-radius: 2px;
font-size: 0.8125rem;
font-family: var(--font-mono);
- outline: none;
}
.filter-input:focus {
border-color: var(--accent-dim);
@@ -320,6 +335,13 @@
tr.clickable:hover td {
background: var(--bg-hover);
}
+ tr.clickable:focus-visible {
+ outline: 2px solid var(--accent);
+ outline-offset: -2px;
+ }
+ tr.clickable:focus-visible td {
+ background: var(--bg-hover);
+ }
.status-badge {
display: inline-flex;
align-items: center;
diff --git a/ui/src/routes/nullboiler/runs/[id]/+page.svelte b/ui/src/routes/nullboiler/runs/[id]/+page.svelte
index d0044ac..41d954b 100644
--- a/ui/src/routes/nullboiler/runs/[id]/+page.svelte
+++ b/ui/src/routes/nullboiler/runs/[id]/+page.svelte
@@ -235,7 +235,7 @@
text-transform: uppercase;
letter-spacing: 1px;
cursor: pointer;
- transition: all 0.2s ease;
+ transition: background-color 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease, color 0.2s ease, transform 0.2s ease, text-shadow 0.2s ease;
text-shadow: var(--text-glow);
text-decoration: none;
}
diff --git a/ui/src/routes/nullboiler/runs/[id]/fork/+page.svelte b/ui/src/routes/nullboiler/runs/[id]/fork/+page.svelte
index 3c07bbb..4bc6735 100644
--- a/ui/src/routes/nullboiler/runs/[id]/fork/+page.svelte
+++ b/ui/src/routes/nullboiler/runs/[id]/fork/+page.svelte
@@ -202,7 +202,7 @@
text-transform: uppercase;
letter-spacing: 1px;
cursor: pointer;
- transition: all 0.2s ease;
+ transition: background-color 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease, color 0.2s ease, transform 0.2s ease, text-shadow 0.2s ease;
text-shadow: var(--text-glow);
}
.fork-btn:hover:not(:disabled) {
@@ -273,7 +273,6 @@
font-size: 0.8125rem;
line-height: 1.5;
resize: vertical;
- outline: none;
}
.override-editor:focus {
border-color: var(--accent-dim);
diff --git a/ui/src/routes/nullboiler/workflows/+page.svelte b/ui/src/routes/nullboiler/workflows/+page.svelte
index 07e3dc9..3eb97ee 100644
--- a/ui/src/routes/nullboiler/workflows/+page.svelte
+++ b/ui/src/routes/nullboiler/workflows/+page.svelte
@@ -126,7 +126,7 @@
font-weight: bold;
text-transform: uppercase;
letter-spacing: 1px;
- transition: all 0.2s ease;
+ transition: background-color 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease, color 0.2s ease, transform 0.2s ease, text-shadow 0.2s ease;
text-shadow: var(--text-glow);
}
.action-btn:hover {
@@ -149,7 +149,7 @@
background: var(--bg-surface);
border: 1px solid var(--border);
border-radius: 4px;
- transition: all 0.2s ease;
+ transition: background-color 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease, color 0.2s ease, transform 0.2s ease, text-shadow 0.2s ease;
}
.wf-card:hover {
border-color: var(--accent-dim);
@@ -202,7 +202,7 @@
text-transform: uppercase;
letter-spacing: 1px;
cursor: pointer;
- transition: all 0.2s ease;
+ transition: background-color 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease, color 0.2s ease, transform 0.2s ease, text-shadow 0.2s ease;
}
.btn-edit {
background: var(--bg-surface);
@@ -290,7 +290,7 @@
font-weight: bold;
text-transform: uppercase;
letter-spacing: 1px;
- transition: all 0.2s ease;
+ transition: background-color 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease, color 0.2s ease, transform 0.2s ease, text-shadow 0.2s ease;
text-shadow: var(--text-glow);
}
.empty-state .btn:hover {
diff --git a/ui/src/routes/nullboiler/workflows/[id]/+page.svelte b/ui/src/routes/nullboiler/workflows/[id]/+page.svelte
index 66ec935..7553518 100644
--- a/ui/src/routes/nullboiler/workflows/[id]/+page.svelte
+++ b/ui/src/routes/nullboiler/workflows/[id]/+page.svelte
@@ -235,7 +235,7 @@
text-transform: uppercase;
letter-spacing: 1px;
cursor: pointer;
- transition: all 0.2s ease;
+ transition: background-color 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease, color 0.2s ease, transform 0.2s ease, text-shadow 0.2s ease;
text-shadow: var(--text-glow);
}
.tool-btn:hover:not(:disabled) {
diff --git a/ui/src/routes/nulltickets/store/+page.svelte b/ui/src/routes/nulltickets/store/+page.svelte
index 5ed7c69..15c20ab 100644
--- a/ui/src/routes/nulltickets/store/+page.svelte
+++ b/ui/src/routes/nulltickets/store/+page.svelte
@@ -116,6 +116,13 @@
if (e.key === 'Enter' && !e.shiftKey) browse();
}
+ function handleEntryRowKeydown(e: KeyboardEvent, entry: any) {
+ if (e.key === 'Enter' || e.key === ' ') {
+ e.preventDefault();
+ void viewEntry(entry);
+ }
+ }
+
function closeModal() {
selectedEntry = null;
}
@@ -233,7 +240,13 @@
|
{#each entries as entry}
- viewEntry(entry)}>
+ viewEntry(entry)}
+ onkeydown={(e) => handleEntryRowKeydown(e, entry)}
+ >
| {entryKey(entry)} |
{#if entry.value !== undefined}
@@ -244,10 +257,10 @@
-
{/if}
|
- e.stopPropagation()}>
+ |
|
@@ -263,9 +276,9 @@
{#if selectedEntry}
-
-
- e.stopPropagation()} onkeydown={(e) => { if (e.key === 'Escape') closeModal(); }}>
+
+
+ { if (e.key === 'Escape') closeModal(); }}>
|