Foundations & UI
Small Wins Batch
Three independent, low-risk deck-clearing items built under one spec: an app-wide a11y contrast fix, per-message deep links so nudge taps land on the exact Slack/Gmail/Calendar item, and a full doc/estate refresh.
Situation
Three roadmap items were small enough to bundle rather than spec separately: a global focus-ring/muted-text contrast failure flagged during Round A, nudges whose native_url field was populated in schema but never filled in (so taps always fell back to a generic https/chat view instead of the exact item), and estate docs that had drifted since 2026-06-15 while a lot of work shipped underneath them.
Build order is deliberate — a11y first, then deep links, then the doc refresh last, so the refreshed design guide can record the final token values and capture both other items plus everything recently shipped.
Key decisions
Per-theme --focus token
Dark theme uses brand gold (~6:1 on --panel/--bg), light theme uses deep oxblood (~7:1) — no single colour cleared 3:1 on both themes.
Bump --muted on dark
Dark --muted moves from #767b8a (~4.15:1, failing) to #8b909f (≥4.5:1 on both --panel and --bg); light-theme --muted is checked and bumped only if it's also under 4.5:1.
Per-source native_url construction
Slack uses the true slack://channel?...&message=<ts> custom scheme; Gmail uses an https://mail.google.com/mail/u/0/#all/<threadId> link that Android App Links route into the Gmail app; Calendar uses the connector's own htmlLink (simpler than hand-computing a base64 eid, discovered during planning) with an empty-string fallback so a missing id never emits a malformed scheme.
New SLACK_TEAM_ID config key
The workspace's T… team id (not derivable from the mathscircle subdomain or the Slack MCP) is added to config.env; an empty value falls back to the existing https permalink rather than breaking the scheme.
Docs stay self-contained, vault is a snapshot
docs/estate/* remains the single canonical source; the vault copy is re-synced after the PR merges to avoid three-way drift, and a new root AGENTS.md points coding agents (including the Q dev-driver) at it.
Risks & guardrails
Keyboard-only focus ring
The --focus swap stays scoped to :focus-visible, so pointer taps are unaffected — only keyboard navigation shows the ring.
Never a malformed deep-link scheme
Every native_url path (Slack team id, Gmail thread id, Calendar htmlLink) falls back to an empty string / existing https permalink when the source id is missing or odd, verified by offline jq/shell tests.
Deploys held for Alex
The a11y fix is a web deploy, the deep-link work is a Tower pull — both are review-then-deploy, not auto-shipped.
Delivery
Phase 1 — a11y pass
--focus token + --muted bump in web/src/app.css, verified by npm run check plus a recorded contrast computation.
Phase 2 — deep links
Slack/Gmail native_url in mention.jq, calendar-sync wired to pass team + native_url, Calendar native_url via the connector's htmlLink, new SLACK_TEAM_ID config key.
Phase 3 — doc refresh + grounding
Reconcile estate docs + ROADMAP, add design-guide examples + token values, new AGENTS.md, Hermes memory note + vault snapshot (Tower, after the PR merges).
Out of scope
docs/superpowers/specs/2026-06-19-small-wins-batch-design.mdplan ·
docs/superpowers/plans/2026-06-19-small-wins-batch.md