Skip to content

Design audit 1/4: foundations (tokens, motion system, touch, reduced motion) - #124

Merged
Programcode merged 7 commits into
mainfrom
design-audit/fixes
Oct 11, 2026
Merged

Programcode merged 7 commits into
mainfrom
design-audit/fixes

Conversation

@Programcode

@Programcode Programcode commented Oct 9, 2026 •

Copy link
Copy Markdown
Owner

First of four stacked PRs for the 2026-10-09 design audit: Foundations, then Shell, AI tools, Landing. This one targets main; each later PR targets the one before it.

What changed

  • Toasts work again. The global [data-sonner-toast] keyframe (both !important) held Sonner's transform, so toasts could not stack, expand, swipe or leave. It is deleted.
  • Colour tokens. --muted-foreground was identical to --foreground in both themes. Now light is 215 16% 40% (5.55:1 on the page) and dark is 215 20% 70% (8.14:1). Light --primary is 33% lightness (button label 5.10:1), the popover is white, the ghost-hover --accent is visible, --destructive labels pass, --input borders reach 3.2:1 / 3.8:1, and dark shadows are strong enough to see. There is a new --success token, which PR2 uses.
  • Global CSS layer deleted. Gone: the tooltip in/out keyframes (they leaked ease-in into every close), menu-item-in, the second tab underline, the Lucide icon hijacks, the .border-dashed:hover marching ants, the .tabular-nums transition, the progressbar width transition, switch-bounce, check-draw, the slider pulse, input:focus !important, the dialog keyframe, card-hover-glow and hover-icon-spin. The nav pill, stagger, message-enter, streaming and landing classes stay until the PR that removes their last use.
  • One curve per primitive. New Tailwind tokens: ease-out-strong cubic-bezier(0.23,1,0.32,1), ease-drawer and duration-120. Dialog, AlertDialog, Popover, Select and Tooltip enter in 200ms and exit in 120ms as a fade in place. Popover, Select and Tooltip scale from --radix-*-content-transform-origin with transition-none, so the origin itself doesn't animate. Sheet runs 300ms open and 200ms close on the drawer curve. Tabs fade in 150ms with no slide. Switch, Progress (transform), accordion and options-panel chevrons all run 150–200ms on the same curve.
  • Press and hover. .motion-press scales to 0.97 in 100ms and releases in 160ms. The hover lift is now opt-in (.motion-lift on solid and outline buttons only), and every CSS hover sits behind (hover: hover) and (pointer: fine), with hoverOnlyWhenSupported on. will-change is gone, and so are the button-icon scale, the Badge hover:scale-105 and the hover lift on list rows.
  • Touch. A pointer-coarse: variant gives Button, Select triggers, Checkbox and the dialog and sheet close buttons a 44px hit area on touch. Also: -webkit-tap-highlight-color: transparent; --native-safe-* now read env(safe-area-inset-*); and the Toaster, OfflineIndicator and bottom Sheet clear the home indicator.
  • Accessibility.
    • Reduced motion keeps opacity and colour transitions, turns overlays into plain fades and turns spinners and carets into a 1.2s opacity pulse. It used to remove everything.
    • prefers-reduced-transparency and prefers-contrast: more turn blurred surfaces solid. More contrast also darkens muted text and borders, and forced-colors keeps an edge.
    • Focus is one system: a 2px --ring outline on :focus-visible. Primitives that draw focus-visible:ring-* turn the outline off, so no element gets two rings. Dialog and Sheet close buttons, SelectTrigger and Badge moved from focus: to focus-visible:.
  • Theme. Changing the theme now crossfades the page once (View Transitions, 200ms) instead of easing at three different speeds. There are light and dark theme-color metas, and ThemeProvider keeps them in sync.
  • Docs. The plan's status is In progress and the PR1 rows are ticked. verify-debatelab/SKILL.md gets a gotcha: a running stack doesn't reload tailwind.config.ts, so you need down && up.

A change from the audit's literal After

  • Focus: the audit asked for one outline system. Button, Tabs, Switch, Checkbox, Slider and Input already draw a full-alpha Tailwind ring, so the global outline is the default and those primitives turn it off. That keeps a single indicator per element.

Before and after, measured in the same running app

The audit's Playwright probes (toast.mjs, probe.mjs) ran against the verify stack on 2fca7bc (before) and on this branch (after).

  • Toasts, two open: before, both sat at the same spot with an identity transform. After, the back toast sits at y −14 with scale 0.95.
  • Toasts, hover: before, nothing expanded. After, the back toast moves −67.5px and both are readable.
  • Toasts, 150ms after dismiss(): before, both were marked removed but still fully opaque and unmoved. After, they are at opacity 0.50 and 0.13 and moving.
  • Select close: 150ms ease-in → 120ms cubic-bezier(0.23,1,0.32,1).
  • Transform origin: Select was 94.5px 37px and the debate popover 176px 151px (box centres). Both are now 0px 0px, the corner that meets the trigger.
  • Dialog: enter 150ms and exit 150ms ease → enter 200ms and exit 120ms on out-strong.
  • Press: scale 0.985 over 160ms → 0.97 over 100ms.
  • Reduced motion, dialog and Select: no animation at all → motion-fade-in 200ms.
  • prefers-contrast: more, landing nav: rgba(241,245,249,.9) with blur(24px) → solid rgb(248,250,252) with no blur and a visible border.
  • Touch targets at 375px: the only controls under 44px left on Settings and Generate are the header brand link, the header "Start debate" control and the footer text links. All three belong to the shell, which is PR2.

Not in this PR: the mobile menu (420ms, PR2), the nav pill (PR2), the Generate shimmer, message-enter and the Timer ring (PR3), and the landing loops (PR4).

Verification

All of these ran locally on this head (21dc4c6):

  • npm run lint, npm run typecheck, npm test (28 files, 273 tests), npm run build and npm run docs:check: all pass.
  • verify.sh drive all: desktop-chromium 30 passed and 2 skipped; mobile-chromium 30 passed and 2 skipped. The skips are the workspace-autosave recipes, which need up --collab.
  • verify.sh e2e run: 16 files and 180 tests pass on desktop and mobile, including the English, Spanish and Hungarian page sweep.
  • Screenshots in light and dark at 1440px and 375px, plus Hungarian at 375px, for /app, debate, generate, ask, library, history, settings and timer. Horizontal overflow is zero everywhere. In Hungarian, two labels clip inside their controls ("Vitaeset Generálása" and the timer display label). That is a copy fix for PR4's sentence-case pass.

Not verified: real touch hardware, WebKit and Safari (backdrop-filter, View Transitions fallback), staging and production.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • User Experience
    • Light and dark themes use distinct browser interface colors and updated contrast colors, with smoother theme switching.
    • Dialogs and controls use shorter, more consistent animations, with fewer decorative hover and motion effects.
    • Save and external-link actions remain partially visible until hover or keyboard focus.
  • Accessibility
    • Touch controls have larger hit areas, and hover effects are limited to devices that support them.
    • Reduced-motion, increased-contrast, and forced-color preferences receive updated styling.
    • Keyboard focus indicators are clearer.
  • Mobile
    • Offline notices and notifications account for device safe areas.

Programcode and others added 2 commits October 9, 2026 05:41
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Fixes the Foundations rows of the 2026-10-09 design audit.

- Delete the global toast keyframe that froze Sonner, so toasts stack,
  expand and leave again.
- Rewire the colour tokens: muted text is a real lower tier, the ghost
  hover, popover, primary, destructive and input colours meet contrast,
  and dark shadows show.
- Delete the global micro-interaction layer (tooltip, menu items, tab
  underline, icon hijacks, marching ants, switch bounce, progress width,
  .tabular-nums, input focus glow). Each overlay primitive now has one
  curve, exits faster than it enters, and scales from its trigger.
- Gate hover on devices that hover, make press feedback 0.97 over 100ms,
  and give buttons, Select triggers, checkboxes and close buttons 44px hit
  areas on touch.
- Reduced motion fades instead of freezing; reduced transparency and more
  contrast turn blurred surfaces solid; safe-area insets and the tap
  highlight are handled.
- One focus outline, a single theme crossfade, and light and dark
  theme-color metas.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Copilot AI balanced review requested due to automatic review settings October 9, 2026 06:57
@vercel

vercel Bot commented Oct 9, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
debate-navigator Ready Ready Preview Oct 11, 2026 12:17pm UTC
debatelab-staging Ready Ready Preview Oct 11, 2026 12:17pm UTC

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@Programcode

Copy link
Copy Markdown
Owner Author

Evidence from the audit probes, same running app. Before (2fca7bc): toasts pinned on top of each other. After (this head): stacked, then expanded on hover. Plus Settings in light, Generate at 375px dark, and Home in Hungarian at 375px.

Before: toasts on hover

After: toasts stacked

After: toasts expanded

Before: Select open

After: Select open

Settings, light

Settings, dark

Generate 375px dark

Hungarian 375px

@coderabbitai

coderabbitai Bot commented Oct 9, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Repository YAML (base), Organization UI (inherited)
  • Review profile: CHILL
  • Plan: Free
  • Run ID: 670157d4-ed77-4598-af32-9e4fc3009650

📥 Commits

Reviewing files that changed from the base of the PR and between 33b14e4 and 41e7384.


📒 Files selected for processing (1)
  • e2e/animation-polish.spec.ts

Included review availability: This review used your included allowance. Your plan provides up to 1 included review per hour; 0 remain after this review.



📝 Walkthrough

Walkthrough

The changes update theme handling, motion and hover behavior, touch targets, safe-area positioning, and accessibility styles. They also add a design audit and a Tailwind verification note.

Changes

Design System Updates

Layer / File(s) Summary
Theme colors and switching
src/index.css, src/components/ThemeProvider.tsx, index.html
Theme tokens and browser theme colors change. ThemeProvider resolves and applies themes, synchronizes theme-color meta elements, and animates theme changes after initial mount.
Motion styles and component transitions
tailwind.config.ts, src/index.css, src/components/features/*, src/components/ui/*
Shared motion rules and component transitions change. Several hover effects, glows, lifts, and entrance animations are removed or restricted.
Touch targets and safe-area positioning
tailwind.config.ts, src/index.css, src/components/OfflineIndicator.tsx, src/components/ui/*, src/components/features/debate/DebateContextControl.tsx
Coarse-pointer targets and safe-area positioning are added or updated for controls, indicators, toasts, and sheets.
Accessibility rules and design audit
src/index.css, src/components/ui/badge.tsx, e2e/animation-polish.spec.ts, plans/2026-10-09-design-audit.md, plans/README.md, .claude/skills/verify-debatelab/SKILL.md
Reduced-motion, transparency, contrast, and forced-colors styles change. The audit records findings, verification limits, and a proposed work order. The end-to-end assertion checks that reduced-motion transitions exclude movement properties. The verification note describes when Tailwind changes require restarting the stack.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant SystemPreference as prefers-color-scheme
  participant ThemeProvider
  participant RootElement as document.documentElement
  participant ThemeColorMeta as theme-color meta elements
  participant ViewTransitions as View Transitions API
  SystemPreference->>ThemeProvider: report preferred theme
  ThemeProvider->>RootElement: apply resolved theme classes
  ThemeProvider->>ThemeColorMeta: synchronize theme colors
  opt View Transitions API is available
    ThemeProvider->>ViewTransitions: apply animated theme change
  end
Loading

  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Note

🎁 Summarized by CodeRabbit Free

Your organization is on the Free plan. CodeRabbit will generate a high-level summary and a walkthrough for each pull request. For a comprehensive line-by-line review, please upgrade your subscription to CodeRabbit Essentials by visiting https://app.coderabbit.ai/settings/billing.


Comment @coderabbitai help to get the list of available commands.

Programcode and others added 2 commits October 9, 2026 07:47
…overlapping

Codex review r1 on #124:
- Ask's Save and the Factoids link icon were opacity-0 until hover, which
  hoverOnlyWhenSupported made permanent on touch. They now rest at 60%
  and go full on hover or focus, as the audit's accessibility row asks.
- The 44px checkbox hit area overlapped the next row in the debate context
  list. It is 36px, and those rows are at least 44px on touch, so each
  label stays the larger target.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@Programcode

Copy link
Copy Markdown
Owner Author

Codex review round 1 (head 21dc4c6) found two issues. Both were real, and both are fixed in 073e566:

  • Ask's Save button was invisible on touch. It used opacity-0 group-hover:opacity-100, and with hoverOnlyWhenSupported on, touch devices never reach the hover state. Ask's Save and the Factoids external-link icon now rest at 60% opacity and go to full on hover or keyboard focus. That is the audit's After for the hover-only icons row.
  • Checkbox hit areas overlapped the next row in the debate context list. The hit area is now 36px, and those rows are at least 44px on touch, so each row's label is the larger target and a tap can't toggle the wrong source.

Checked locally on 073e566: tsc and eslint pass. I'll rerun the full gates and the recipes once the next review round finishes.

…other

Codex review r2 on #124: switching theme twice before the first transition
was ready left its ready promise rejected and unhandled (AbortError:
Transition was skipped). The final theme was already correct.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@Programcode

Copy link
Copy Markdown
Owner Author

Codex review round 2 (head 9bccae8) confirmed both round-1 fixes and raised one new low-severity finding, which is fixed in 33b14e4:

  • Two quick theme switches threw an uncaught error. If a second switch landed before the first view transition was ready, ready rejected with AbortError: Transition was skipped and nothing handled it. The final theme was already correct. ThemeProvider now handles both ready and finished. This also matters for the agentic suite, which fails on any uncaught page error.

Round 3 is reviewing 33b14e4.

@Programcode

Copy link
Copy Markdown
Owner Author

Codex review round 3 at 33b14e4: no findings. It confirmed all three earlier fixes.

Local results on 33b14e4 (GitHub Actions is out of minutes; every job fails in about 2s with "recent account payments have failed"):

  • npm run lint, typecheck, npm test (274), build, docs:check: all pass.
  • npm run verify: 333 Deno tests and 30 Playwright smoke tests pass.
  • Recipes on both viewports and the full agentic suite (180/180) ran at 21dc4c6. The fixes since then only touch Ask's Save opacity, the checkbox hit area and ThemeProvider. All three are also covered by the PR2 stack runs, which include them.

Ready to merge from my side. Holding without merging, as asked.

The audit replaced the blanket reduced-motion kill with one that keeps
opacity and colour transitions. The spec asserted a 0s transition on the
options panel; it now asserts the panel transitions nothing that moves
(no transform, height, grid rows or 'all').

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@Programcode
Programcode merged commit bba0666 into main Oct 11, 2026
8 of 15 checks passed
@Programcode
Programcode deleted the design-audit/fixes branch October 11, 2026 13:12

This branch was successfully deployed

2 active deployments
Preview – debate-navigator — 80f94902 Deployed Oct 11, 2026 by vercel[bot]
Preview – debatelab-staging — 80f94902 Deployed Oct 11, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants