Skip to content

v3.11.25 — Hallmark Pre-Beta Design Remediation

A read-only design audit against the objectuve-hallmark skill flagged eight P0 defects and a backlog of token-discipline and accessibility gaps across three apps; this sweep fixed every one of them before the beta.

Summary

Ahead of the beta, a read-only design audit (.planning/audits/hallmark-pre-beta-2026-06-07.md) was run against the objectuve-hallmark design skill across the three user-facing surfaces — the Ionic consumer app, the admin dashboard, and the static marketing site. It surfaced a tier of beta-blocking P0 defects (a silently-broken Coach gradient, an invisible error message, missing keyboard focus rings, reduced-motion gaps, an undersized tap target, a contact form with no error/success state) plus a longer tail of token-discipline drift and polish items.

The remediation shipped as three independent PRs — one per app, each deploying on its own cadence — rather than a single cross-app change. PR #1101 covered ionic_frontend (60 files), #1102 covered admin_dashboard (20 files), and #1103 covered marketing_landing (7 files). A fourth micro-PR (#1108) landed a one-line skill-rule doc edit (gate-7 spacing scale), and a fifth (#1109) recorded the user-facing changes in the CHANGELOG.

The work was deliberately structural, not cosmetic-by-feel: every fix conforms to an existing design token, WCAG success criterion, or anti-social-app principle that the codebase already documented but had drifted from. The ionic and admin fixes reached users in v3.11.23; the marketing-site fixes reached users in v3.11.25.

Goal

Address every P0 defect and the agreed token-discipline / accessibility backlog from the hallmark pre-beta audit across ionic_frontend, admin_dashboard, and marketing_landing — each item either fixed in its PR or explicitly deferred with a comment, none left silently unresolved — so the three surfaces are beta-ready and on-brand.

Scope — What Shipped

ionic_frontend (PR #1101 — a9700147b)

  • Coach dock gradient fixed — the --coach-light CSS token was undefined, so the gradient's second stop silently fell back to transparent. Token now resolves to hsl(271 91% 80%); both stops render.
  • AllyLookup error message made visible — the not-found error used an invented text-coral-600 class and rendered colorless; switched to the text-destructive token.
  • Coach sheet close targetCoachSuggestSheet close button promoted to h-11 w-11 (44×44 px), meeting WCAG 2.5.5.
  • Communities LIVE indicator — changed from an infinite animate-pulse loop to a static treatment, consistent with the anti-social-app philosophy.
  • Focus rings — added to CriticalPathTile, StreakMetaphorSelector, and SideMenu rows, satisfying WCAG 2.4.7.
  • Reduced motionstreakAnimations.ts injects a prefers-reduced-motion: reduce query scoped to [data-streak-anim]; the three streak celebrations and FlameIcon carry the marker and suppress animation when the OS setting is on.
  • Token discipline — arbitrary text-[Npx] sizing in GoalEventForm.vue replaced with scale steps; confetti palettes centralized in src/helpers/brandConfetti.ts (no inline hex arrays remain); slideUp keyframe corrected to 400ms across four views.

admin_dashboard (PR #1102 — 5123dc344)

  • Focus-visible ring recipe — a global :focus-visible recipe added to src/style.css (absent on master), covering shared button, nav, and row classes via the --ring token.
  • OBJ-827 token migration completed — eight remaining views (EmployeeDetail, RunDetail, ContentReports, AuditLog, BadgeStats, Plans, Unauthorized, SignIn) migrated from raw Tailwind palette classes to semantic tokens; post-migration grep returns zero raw palette classes across all eight.
  • Chart.js reads CSS varsEmployeeDetailView chart colors now read --primary / --destructive / --warning from getComputedStyle; no hex literals remain.
  • SignIn CTA on brandbg-blue-600bg-primary.
  • Fake red-dot removed — the always-on notification-bell dot in AdminLayout removed; it returns only when a real unread count is wired.

marketing_landing (PR #1103 — 16fc6149e)

  • Contact form error/success/recovery statescontact.html submits via async Formspree instead of a bare mailto: redirect; a role="status" aria-live="polite" region announces both error and success; the submit button enters .btn:disabled during submission; the error path exposes a direct support@objectuve.com fallback.
  • Reduced motionabout.html GSAP logo timeline and logo-evolution/index.html autoplay both short-circuit to the final frame under prefers-reduced-motion: reduce.
  • Clerk waitlist fallback — the index.html waitlist widget reveals a .waitlist-fallback email-us CTA if Clerk fails to load within the polling timeout; the container is never left as an empty div.
  • Emoji → inline SVG icons — five icons in contact.html and one in 404.html replaced with well-formed 24×24 inline SVGs (stroke-width="2", round caps, aria-hidden).

Skill rule + changelog

  • Gate-7 spacing scale (PR #1108 — c9ca0aa55) — 1.5 added to the allowed-spacing list in .claude/skills/objectuve-hallmark/references/slop-tests.md, aligning the gate with DESIGN.md §SPACING and the ESLint-rule removal landed in #1101.
  • CHANGELOG entries (PR #1109 — d7732d756) — root engineering log + ionic_frontend/CHANGELOG.md user-facing notes for all three app PRs.

Phases

This was an informal remediation sweep coordinated through OBJ-934 — five tasks (T1–T5), not GSD phases. T2/T3/T4 were verify-and-surgical-fix passes on PRs that were already authored.

#TaskPRStatusHighlights
T1slop-tests gate-7 spacing-1.5 edit#1108ShippedOne-line skill-rule doc edit; 1.5 added to allowed spacing scale
T2Verify + surgical-fix ionic_frontend#1101Shipped6 P0 fixes + token discipline; vue-tsc/eslint clean
T3Verify + surgical-fix admin_dashboard#1102ShippedFocus-ring recipe + 8-view OBJ-827 token migration
T4Verify + surgical-fix marketing_landing#1103ShippedContact-form states + reduced-motion + Clerk fallback
T5CHANGELOG + release notes#1109ShippedRoot + ionic_frontend changelog entries

Key Decisions

  • Three separate PRs, not one — each app deploys independently and has different reviewers; collapsing into one PR would only create review friction. The three PRs stayed separate end-to-end.
  • Skill-rule edit landed as its own micro-PR — the gate-7 slop-tests.md change was kept out of the ionic PR. Skill self-modification is auto-blocked for the authoring agent, and a separate change-author signals provenance; it also keeps the skill-rule scope cleanly out of ionic_frontend.
  • Verify-with-fix-authority, not separate QA — verification (T2–T4) was done by the same agent that could land a surgical fix on the existing branch, rather than splitting "find" and "fix" across a round-trip. Remediation deltas were small enough that this was the cheaper path.
  • Reduced-motion coverage scoped honestly — streak SVG glass overlays were intentionally left out of the reduced-motion pass; the CHANGELOG says coverage there is partial, not complete, rather than overstating it.
  • Manual verification was the test strategy — these are visual / accessibility / motion fixes; the acceptance criteria were the binary keyboard, reduced-motion, and grep checks in the task package, backed by the existing vue-tsc + vite build + Vitest/Playwright gates. No new automated specs were added for this one-shot sweep.

Requirements Coverage

No formal REQUIREMENTS.md governs this sweep. The unit of coverage was the audit's defect tiers — eight P0 items plus the agreed token-discipline / polish backlog.

CategoryCountStatus
P0 — ionic_frontend6All resolved (#1101)
P0 — admin_dashboard1Resolved (#1102)
P0 — marketing_landing1Resolved (#1103)
P1/P2 token & polishAddressed or explicitly deferred per PR

Full rationale: .planning/audits/hallmark-pre-beta-2026-06-07.md.

Outcomes

  • The Coach dock renders its intended gradient; the AllyLookup error is legible; the Coach sheet close button is reachable on touch.
  • Keyboard users get a visible focus ring on the consumer app's critical-path tile, streak-metaphor selector, and side menu, and across every shared button/nav/row class in the admin dashboard.
  • Users with "Reduce Motion" on no longer get streak-celebration or marketing-logo animation.
  • The marketing contact form tells you when a send succeeds or fails and always offers a direct email; the waitlist always has a way in even if Clerk fails to load.
  • The admin dashboard's eight last-unmigrated views now use semantic design tokens, completing the OBJ-827 migration.

Tech Debt

  • (ionic) Streak SVG glass overlays were intentionally left out of the reduced-motion pass — coverage there is partial. No ticket yet.
  • (admin) The notification-bell red-dot was removed rather than wired to a real unread count; it returns only when that state exists.
  • (tokens) success-interactive / gold-interactive / muted-interactive tokens carry forward from the v2.6 hallmark milestone with no ticket.
  • (process) No axe-core / Lighthouse CI step exists to catch the missing-focus-ring class of regression; worth a follow-up issue, out of scope here.
  • a9700147b — fix(hallmark): pre-beta design remediation — ionic_frontend (#1101)
  • 5123dc344 — fix(hallmark): pre-beta design remediation — admin_dashboard (#1102)
  • 16fc6149e — fix(hallmark): pre-beta design remediation — marketing_landing (#1103)
  • c9ca0aa55 — docs: add 1.5 to gate-7 allowed-spacing list in slop-tests.md (#1108)
  • d7732d756 — docs(changelog): add hallmark pre-beta remediation entries (#1109)
  • f00e9fb9a — chore(release): update CHANGELOG for v3.11.25

Last updated: 2026-06-08

Loading…