Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,13 @@ updates:
groups:
actions:
patterns: ["*"]

- package-ecosystem: "npm"
cooldown:
default-days: 7
directory: "/scripts/a11y"
schedule:
interval: "weekly"
groups:
a11y:
patterns: ["*"]
28 changes: 27 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,32 @@ jobs:
- name: Build the site
run: ./site/build.sh

# axe-core (WCAG 2.2 A/AA, light and dark) over the website and the web UI
# running against fictional seed data. See scripts/a11y/run.sh.
a11y:
name: Accessibility
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- uses: actions/checkout@v7
with:
persist-credentials: false
fetch-depth: 0 # the versioned docs read every release tag

- uses: actions/setup-go@v7
with:
go-version-file: go.mod

- uses: peaceiris/actions-hugo@2752ce1d29631191ea3f27c23495fa06139a5b78 # v3.2.1
with:
hugo-version: "0.165.0"

- uses: actions/setup-node@v7
with:
node-version: "24"

- run: scripts/a11y/run.sh

# The shared go-ci job covers Linux amd64. Release binaries also ship for
# macOS, Windows and Linux arm64, so run the tests there too (no -race:
# that needs cgo, and the release builds don't use it).
Expand Down Expand Up @@ -134,7 +160,7 @@ jobs:
required-checks-passed:
name: Required checks passed
runs-on: ubuntu-latest
needs: [ci, zizmor, coverage, site, cross-platform, vulncheck]
needs: [ci, zizmor, coverage, site, a11y, cross-platform, vulncheck]
if: always()
steps:
- if: contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled')
Expand Down
1 change: 1 addition & 0 deletions docs/code-patterns.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
- **History startup**: CLI commands use `openHistoryStore`, which opens the schema and runs the versioned, transactional saved-reply migration via `inbox.MigrateNoDataResponses`. Keep new entry points on this helper so upgrades do not require visiting the web UI. The migration is local-only and retryable after a rollback.
- **Pipeline UI**: counts and pending rows share `history.GetActionItems`; use it for Pipeline and Action Needed together. The Pipeline URL carries view, status, response type, search, review, and page filters. Response search filters the active profile in SQLite before pagination, including stored email bodies.
- **Multi-profile scoping**: any new `history.Store` method that reads/writes per-user data should take a `profileID string` first parameter and filter by it (see [multi-profile.md](multi-profile.md)) - the two deliberate exceptions are `ClearBrokerResponses`/`GetAllBrokerResponses`, which operate on the one shared inbox across all profiles.
- **Accessibility**: CI runs axe-core (WCAG 2.2 A/AA, light and dark) over the website and the web UI against fictional seed data: `scripts/a11y/run.sh` runs the same thing locally (needs Go, Hugo, Node and Chrome). Add a new web UI page to the URL list in that script. Rules of thumb it enforces: every `<select>`/icon-only control needs an `aria-label`, links inside body text need an underline, text must hit 4.5:1 in both themes. In the web UI use `--accent` for text and borders and `--accent-solid` for fills behind white text, since the dark theme needs a lighter accent for text than for buttons. Headings step down one level at a time (`h1` then `h2`), never by tag size.

## Known quirks

Expand Down
20 changes: 12 additions & 8 deletions internal/web/static/css/tokens.css
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,20 @@
--bg-elevated: #1a1a1d;
--bg-glass: rgba(19, 19, 21, 0.9);

--accent: #6366f1;
--accent-hover: #818cf8;
--accent: #818cf8;
--accent-hover: #a5b4fc;
--accent-solid: #4f46e5;
--accent-solid-hover: #4338ca;
--accent-muted: rgba(99, 102, 241, 0.12);
--accent-glow: rgba(99, 102, 241, 0.3);

--success: #22c55e;
--warning: #eab308;
--error: #ef4444;
--error: #f87171;

--text-primary: #e4e4e7;
--text-secondary: #a1a1aa;
--text-muted: #6b6b71;
--text-muted: #8b8b93;

--border: #232326;
--border-subtle: #1a1a1d;
Expand All @@ -44,17 +46,19 @@
--bg-glass: rgba(255, 255, 255, 0.9);

--accent: #4f46e5;
--accent-hover: #6366f1;
--accent-hover: #4338ca;
--accent-solid: #4f46e5;
--accent-solid-hover: #4338ca;
--accent-muted: rgba(79, 70, 229, 0.08);
--accent-glow: rgba(79, 70, 229, 0.25);

--success: #16a34a;
--warning: #b45309;
--error: #dc2626;
--warning: #92400e;
--error: #b91c1c;

--text-primary: #18181b;
--text-secondary: #52525b;
--text-muted: #a1a1aa;
--text-muted: #666670;

--border: #e4e4e7;
--border-subtle: #f4f4f5;
Expand Down
5 changes: 2 additions & 3 deletions internal/web/static/css/utilities.css
Original file line number Diff line number Diff line change
Expand Up @@ -901,7 +901,7 @@ img,video {
}

.bg-\[var\(--accent\)\] {
background-color:var(--accent);
background-color:var(--accent-solid);
}

.bg-\[var\(--bg-elevated\)\] {
Expand Down Expand Up @@ -1126,8 +1126,7 @@ img,video {
}

.text-accent {
--tw-text-opacity:1;
color:rgb(99 102 241/var(--tw-text-opacity,1));
color:var(--accent);
}

.text-white {
Expand Down
3 changes: 3 additions & 0 deletions internal/web/templates/brokers.html
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ <h1 class="font-display text-3xl font-bold text-primary">Data Brokers</h1>
<div class="flex flex-wrap items-center gap-3">
<select
name="status"
aria-label="Status"
class="input w-auto min-w-[120px]"
hx-get="/api/brokers"
hx-trigger="change"
Expand All @@ -115,6 +116,7 @@ <h1 class="font-display text-3xl font-bold text-primary">Data Brokers</h1>
</select>
<select
name="category"
aria-label="Category"
class="input w-auto min-w-[140px]"
hx-get="/api/brokers"
hx-trigger="change"
Expand All @@ -128,6 +130,7 @@ <h1 class="font-display text-3xl font-bold text-primary">Data Brokers</h1>
</select>
<select
name="region"
aria-label="Region"
class="input w-auto min-w-[120px]"
hx-get="/api/brokers"
hx-trigger="change"
Expand Down
2 changes: 1 addition & 1 deletion internal/web/templates/history.html
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ <h1 class="font-display text-3xl font-bold text-primary">Request History</h1>
<div class="flex-1 min-w-0">
<div class="flex items-start justify-between gap-4">
<div>
<h3 class="font-medium text-primary">{{.BrokerName}}</h3>
<h2 class="font-medium text-primary">{{.BrokerName}}</h2>
<p class="text-sm text-muted">{{.Email}}</p>
</div>
<div class="text-right flex-shrink-0">
Expand Down
7 changes: 5 additions & 2 deletions internal/web/templates/layout.html
Original file line number Diff line number Diff line change
Expand Up @@ -158,12 +158,12 @@
}

.btn-primary {
background: var(--accent);
background: var(--accent-solid);
color: white;
}

.btn-primary:hover {
background: var(--accent-hover);
background: var(--accent-solid-hover);
}

.btn-secondary {
Expand Down Expand Up @@ -267,6 +267,9 @@
color: var(--error);
}

.light .badge-success { color: #166534; }
.text-muted a { text-decoration: underline; }

.badge-neutral {
background: var(--bg-elevated);
color: var(--text-secondary);
Expand Down
20 changes: 10 additions & 10 deletions internal/web/templates/tasks.html
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ <h1 class="font-display text-3xl font-bold text-primary">Action Needed</h1>
<!-- Details -->
<div class="flex-1 min-w-0">
<div class="flex items-center gap-2">
<h3 class="text-sm font-semibold text-primary">{{.BrokerName}}</h3>
<h2 class="text-sm font-semibold text-primary">{{.BrokerName}}</h2>
<span class="rounded-full chip chip-info">Form</span>
</div>
{{if .EmailSubject}}
Expand Down Expand Up @@ -233,7 +233,7 @@ <h3 class="text-sm font-semibold text-primary">{{.BrokerName}}</h3>
<!-- Task Details -->
<div class="flex-1 min-w-0">
<div class="flex items-center gap-2">
<h3 class="text-sm font-semibold text-primary">{{.BrokerName}}</h3>
<h2 class="text-sm font-semibold text-primary">{{.BrokerName}}</h2>
<span class="rounded-full
{{if eq .TaskType "captcha"}}chip chip-warning
{{else if eq .TaskType "manual_form"}}chip chip-info
Expand Down Expand Up @@ -308,7 +308,7 @@ <h3 class="text-sm font-semibold text-primary">{{.BrokerName}}</h3>
<!-- Details -->
<div class="flex-1 min-w-0">
<div class="flex items-center gap-2">
<h3 class="text-sm font-semibold text-primary">{{.BrokerName}}</h3>
<h2 class="text-sm font-semibold text-primary">{{.BrokerName}}</h2>
<span class="rounded-full chip chip-warning">Needs Review</span>
</div>
<p class="text-xs text-muted mt-1 truncate">{{.EmailSubject}}</p>
Expand Down Expand Up @@ -355,7 +355,7 @@ <h3 class="text-sm font-semibold text-primary">{{.BrokerName}}</h3>
</div>
<div class="flex-1 min-w-0">
<div class="flex items-center gap-2">
<h3 class="text-sm font-semibold text-primary">{{.BrokerName}}</h3>
<h2 class="text-sm font-semibold text-primary">{{.BrokerName}}</h2>
<span class="rounded-full chip chip-success">Completed</span>
</div>
<p class="text-xs text-muted mt-1">Task completed</p>
Expand Down Expand Up @@ -385,7 +385,7 @@ <h3 class="text-sm font-semibold text-primary">{{.BrokerName}}</h3>
</div>
<div class="flex-1 min-w-0">
<div class="flex items-center gap-2">
<h3 class="text-sm font-semibold text-primary">{{.BrokerName}}</h3>
<h2 class="text-sm font-semibold text-primary">{{.BrokerName}}</h2>
<span class="rounded-full chip chip-success">Completed</span>
</div>
<p class="text-xs text-muted mt-1">Form submitted successfully</p>
Expand All @@ -409,7 +409,7 @@ <h3 class="text-sm font-semibold text-primary">{{.BrokerName}}</h3>
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"/>
</svg>
</div>
<h3 class="text-lg font-semibold text-primary mb-2">All caught up!</h3>
<h2 class="text-lg font-semibold text-primary mb-2">All caught up!</h2>
<p class="text-secondary">No pending action items at the moment.</p>
<a href="/pipeline" class="btn btn-secondary mt-4">View Pipeline</a>
</div>
Expand All @@ -419,15 +419,15 @@ <h3 class="text-lg font-semibold text-primary mb-2">All caught up!</h3>

<!-- Instructions Card -->
<div class="card p-6">
<h3 class="font-display text-lg font-semibold text-primary mb-4">How to Complete Tasks</h3>
<h2 class="font-display text-lg font-semibold text-primary mb-4">How to Complete Tasks</h2>
<div class="grid grid-cols-1 md:grid-cols-3 gap-4">
<div class="p-4 rounded-lg" style="background: var(--bg-elevated);">
<div class="w-8 h-8 icon-box icon-box-info mb-3">
<svg class="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"/>
</svg>
</div>
<h4 class="text-sm font-semibold text-primary mb-1">Opt-Out Forms</h4>
<h3 class="text-sm font-semibold text-primary mb-1">Opt-Out Forms</h3>
<p class="text-xs text-secondary">Some brokers require filling out an online form. Click "Open Form", enter your details, and submit.</p>
</div>
<div class="p-4 rounded-lg" style="background: var(--bg-elevated);">
Expand All @@ -436,7 +436,7 @@ <h4 class="text-sm font-semibold text-primary mb-1">Opt-Out Forms</h4>
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m5.618-4.016A11.955 11.955 0 0112 2.944a11.955 11.955 0 01-8.618 3.04A12.02 12.02 0 003 9c0 5.591 3.824 10.29 9 11.622 5.176-1.332 9-6.03 9-11.622 0-1.042-.133-2.052-.382-3.016z"/>
</svg>
</div>
<h4 class="text-sm font-semibold text-primary mb-1">CAPTCHA Forms</h4>
<h3 class="text-sm font-semibold text-primary mb-1">CAPTCHA Forms</h3>
<p class="text-xs text-secondary">Click "Solve CAPTCHA" for a helper page with copy buttons for your info. Complete the CAPTCHA, then paste your details.</p>
</div>
<div class="p-4 rounded-lg" style="background: var(--bg-elevated);">
Expand All @@ -445,7 +445,7 @@ <h4 class="text-sm font-semibold text-primary mb-1">CAPTCHA Forms</h4>
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z"/>
</svg>
</div>
<h4 class="text-sm font-semibold text-primary mb-1">Email Confirmations</h4>
<h3 class="text-sm font-semibold text-primary mb-1">Email Confirmations</h3>
<p class="text-xs text-secondary">Check your email for confirmation links from brokers. Click the link to verify your removal request.</p>
</div>
</div>
Expand Down
1 change: 1 addition & 0 deletions scripts/a11y/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
node_modules/
Loading
Loading