diff --git a/.Jules/palette.md b/.Jules/palette.md
index 6e3411a..b0b031e 100644
--- a/.Jules/palette.md
+++ b/.Jules/palette.md
@@ -31,3 +31,6 @@
## 2026-06-09 - Empty State Feedback
**Learning:** When a list or process finishes with zero results, an empty summary container gives no feedback, leaving the user wondering if it actually ran or failed silently.
**Action:** Always provide a helpful empty state message explaining why no results might have occurred, using styles consistent with other hints to offer guidance without showing as an error.
+## 2026-10-26 - Semantic Grouping over ARIA Workarounds
+**Learning:** Prioritizing native semantic HTML (`
` and ``) over generic `` elements with ARIA attributes (`role="radiogroup"`, `aria-labelledby`) for form groups provides more robust accessibility out of the box, reduces markup bloat, and aligns with HTML standards.
+**Action:** Always use `
` to group related form controls (like radio buttons or mode selectors) and `` for their label. If custom styling is needed, reset default browser styles (`border: none`, `margin: 0`, `padding: 0`) rather than resorting to non-semantic wrappers.
diff --git a/biome.json b/biome.json
index 85ee3ce..adb6282 100644
--- a/biome.json
+++ b/biome.json
@@ -1,5 +1,5 @@
{
- "$schema": "https://biomejs.dev/schemas/2.4.16/schema.json",
+ "$schema": "https://biomejs.dev/schemas/2.5.0/schema.json",
"vcs": {
"enabled": true,
"clientKind": "git",
@@ -33,7 +33,7 @@
"linter": {
"enabled": true,
"rules": {
- "recommended": true,
+ "preset": "recommended",
"suspicious": {
"noExplicitAny": "off",
"noImplicitAnyLet": "off"
diff --git a/popup.css b/popup.css
index 85153c2..c32113c 100644
--- a/popup.css
+++ b/popup.css
@@ -85,7 +85,21 @@ input[type="password"]:focus {
margin-bottom: 8px;
}
-.setting-row label {
+fieldset {
+ border: none;
+ margin: 0;
+ padding: 0;
+}
+
+legend {
+ display: block;
+ font-size: 12px;
+ color: #94a3b8;
+ margin-bottom: 6px;
+}
+
+.setting-row label,
+.setting-row legend {
margin-bottom: 4px;
}
diff --git a/popup.html b/popup.html
index e4c322c..6a91a70 100644
--- a/popup.html
+++ b/popup.html
@@ -13,20 +13,20 @@ Jules Task Archiver
Options
-
-
Operation
-
+
+ Operation
+
Archive Tasks
Start Suggestions
-
-
-
Execution Mode
-
+
@@ -34,13 +34,13 @@ Options
Archive every task, ignoring state and matching open Pull Requests
-
-
Scope
-
+
diff --git a/tests/popup.test.js b/tests/popup.test.js
index 3f3db03..6f7d210 100644
--- a/tests/popup.test.js
+++ b/tests/popup.test.js
@@ -435,11 +435,13 @@ describe('popup.html accessibility', () => {
)
})
- it('should use explicit visible labels for radio groups via aria-labelledby', () => {
- assert.ok(popupHtml.includes('id="execModeLabel"'), 'execModeLabel should exist')
- assert.ok(popupHtml.includes('aria-labelledby="execModeLabel"'), 'mode radiogroup should use aria-labelledby')
- assert.ok(popupHtml.includes('id="scopeLabel"'), 'scopeLabel should exist')
- assert.ok(popupHtml.includes('aria-labelledby="scopeLabel"'), 'scope radiogroup should use aria-labelledby')
+ it('should use explicit semantic fieldsets and legends for grouped controls', () => {
+ assert.ok(popupHtml.includes(''), 'should use fieldset for grouped controls')
+ assert.ok(
+ popupHtml.includes('Execution Mode '),
+ 'should use semantic legend for execution mode'
+ )
+ assert.ok(popupHtml.includes('Scope '), 'should use semantic legend for scope')
})
})