Skip to content

Increase dark-mode button contrast#8494

Open
aurorascharff wants to merge 1 commit into
reactjs:mainfrom
aurorascharff:button-contrast-dark-mode
Open

Increase dark-mode button contrast#8494
aurorascharff wants to merge 1 commit into
reactjs:mainfrom
aurorascharff:button-contrast-dark-mode

Conversation

@aurorascharff

@aurorascharff aurorascharff commented Jun 23, 2026

Copy link
Copy Markdown
Collaborator

Bumps button contrast to match the treatment on reactnative.dev, in both dark and light mode.

In dark mode the primary button's text (dark:text-secondary, #404756) and the secondary button's border (#404756) were both low-contrast against the teal and dark backgrounds. This raises the primary text to near-black (gray-95, #16181D) and lifts the secondary border to #4E5769, the same value React Native uses (rgb(78, 86, 104)). Primary text contrast goes from about 4.6:1 to about 8.9:1.

In light mode the buttons already nearly matched React Native; the only gap was the secondary border, which was a touch lighter (#D9DBE3) than React Native's (#BCC1CD). This nudges it to #BCC1CD so the two are consistent.

Token changes:

  • ButtonLink.tsx: primary dark:text-secondary to dark:text-gray-95
  • tailwind.config.js: secondary-button-stroke-dark #404756 to #4E5769 (dark), and secondary-button-stroke #D9DBE3 to #BCC1CD (light)

Screenshots

Before After React Native (reference)
CleanShot 2026-06-23 at 13 05 19@2x
image | CleanShot 2026-06-23 at 13 05 47@2x |

React Native reference: https://reactnative.dev/

Notes

  • Affects both dark and light mode (verified both).
  • These are shared tokens, so every primary/secondary button is affected — flagging for design sign-off.

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.

Pull request overview

This PR adjusts dark-mode button styling for improved contrast, but it also includes a broad Next.js/React/TypeScript + routing migration (Pages Router → App Router) and related infrastructure updates across the site.

Changes:

  • Increase dark-mode button contrast by updating primary button text color and secondary button stroke token.
  • Migrate major routes and supporting logic from Next.js Pages Router to App Router (new src/app/* pages/routes, new server helpers under src/lib/*, removal of several src/pages/* entrypoints).
  • Update build/tooling configuration (Next/React versions, TS config, Next config, lint scripts, and type declarations).

Reviewed changes

Copilot reviewed 46 out of 54 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
tsconfig.json Updates TS module resolution / JSX mode and includes additional .next type paths.
tailwind.config.js Raises dark-mode secondary button stroke token value.
src/utils/compileMDX.ts Switches MDX component-name enumeration to a server-safe list and bumps disk cache breaker; expands return type.
src/types/jsx-bridge.d.ts Adds global JSX namespace bridge for React 19 type changes.
src/types/css.d.ts Adds module declarations for CSS side-effect imports.
src/pages/errors/index.tsx Removes Pages Router error decoder index entrypoint.
src/pages/errors/[errorCode].tsx Removes Pages Router error decoder page and SSG logic.
src/pages/api/md/[...path].ts Removes Pages Router API endpoint for serving markdown.
src/pages/[[...markdownPath]].js Removes Pages Router catch-all markdown rendering page.
src/pages/_document.tsx Removes custom Pages Router Document in favor of App Router layout/head.
src/pages/_app.tsx Removes Pages Router App wrapper; client effects moved to App Router equivalents.
src/lib/readMarkdownPage.ts Adds server-only helper to read/compile MDX with cache semantics.
src/lib/loadErrorDecoderData.ts Adds server-only error decoder data loader + caching and code listing.
src/lib/collectPaths.ts Adds cached filesystem traversal utilities for static params generation.
src/lib/buildPageMetadata.ts Adds App Router metadata builder replacing old Seo behavior.
src/hooks/usePendingRoute.ts Removes pending-route tracking (no App Router router.events equivalent).
src/components/Seo.tsx Removes old Pages Router <Head>-based SEO component.
src/components/Search.tsx Migrates navigation from next/router to next/navigation and removes per-component <Head> preconnect.
src/components/PageHeading.tsx Switches from useRouter().asPath to usePathname() for markdown-copy behavior.
src/components/MDX/MDXComponentsList.ts Adds server-safe constant list of MDX component names.
src/components/MDX/MDXComponents.tsx Marks MDX components module as client and notes sync requirement with the new names list.
src/components/MDX/ExpandableExample.tsx Replaces asPath hash parsing with window.location.hash.
src/components/MDX/Challenges/Challenges.tsx Migrates from next/router to usePathname() and uses window.location.hash for initial selection.
src/components/Layout/useDeserializedMDX.tsx Introduces shared client hook for deserializing MDX JSON to React nodes.
src/components/Layout/TopNav/TopNav.tsx Migrates from next/router to usePathname() for route-change reactions.
src/components/Layout/Sidebar/SidebarRouteTree.tsx Migrates current-slug detection from next/router to usePathname().
src/components/Layout/Page.tsx Converts Page to a client component, adds pathname prop, lazy-loads HomeContent, and removes old SEO/RSS <Head> usage.
src/components/Layout/HomeContent.js Switches to React’s built-in use and removes local polyfill.
src/components/ErrorDecoderContext.tsx Updates comment to reflect App Router usage (context populated by route’s server component).
src/components/ButtonLink.tsx Updates primary button dark-mode text class to dark:text-gray-95.
src/app/warnings/[slug]/page.tsx Adds App Router page for warnings slugs using shared section renderer.
src/app/versions/page.tsx Adds App Router page for /versions using shared section renderer.
src/app/renderSectionPage.tsx Adds shared section page renderer + metadata helper for App Router.
src/app/reference/[[...slug]]/page.tsx Adds App Router reference catch-all page with static params generation.
src/app/page.tsx Adds App Router home page using MDX read + metadata builder.
src/app/not-found.tsx Adds App Router not-found UI using the shared Page component API.
src/app/llms.txt/route.ts Migrates llms.txt generation from SSR to an App Router route handler.
src/app/learn/[[...slug]]/page.tsx Adds App Router learn catch-all page with static params generation.
src/app/layout.tsx Adds App Router root layout including metadata, scripts, preloads, RSS link, and client effects.
src/app/errors/page.tsx Adds App Router errors index page backed by server data loader.
src/app/errors/ErrorDecoderView.tsx Adds client view component to render error decoder content within the shared Page.
src/app/errors/[errorCode]/page.tsx Adds App Router error code page with static params + metadata.
src/app/error.tsx Adds App Router global error boundary UI.
src/app/DocsPage.tsx Adds client wrapper to render MDX content/toc into Page.
src/app/community/[[...slug]]/page.tsx Adds App Router community catch-all page with static params generation.
src/app/clientEffects.tsx Adds App Router client effects for analytics + scroll restoration.
src/app/blog/[[...slug]]/page.tsx Adds App Router blog catch-all page with static params generation.
src/app/api/md/[...path]/route.ts Adds App Router route handler to serve raw markdown with static params prerendering.
package.json Updates scripts, upgrades Next/React/types, removes next-remote-watch, updates engines, and adds resolutions.
next.config.js Enables cache components, adjusts config for Next 16/webpack usage, and lists server external packages.
next-env.d.ts Adds an import of a generated .next routes type file (currently problematic).
CLAUDE.md Updates repo structure docs to include src/app/ and src/lib/, and adds a Next.js agent rules block.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread package.json Outdated
@github-actions

github-actions Bot commented Jun 23, 2026

Copy link
Copy Markdown

Size changes

Details

📦 Next.js Bundle Analysis for react-dev

This analysis was generated by the Next.js Bundle Analysis action. 🤖

⚠️ Global Bundle Size Increased

Page Size (compressed)
global 115.14 KB (🟡 +5 B)
Details

The global bundle is the javascript bundle that loads alongside every page. It is in its own category because its impact is much higher - an increase to its size means that every page on your website loads slower, and a decrease means every page loads faster.

Any third party scripts you have added directly to your app using the <script> tag are not accounted for in this analysis

If you want further insight into what is behind the changes, give @next/bundle-analyzer a try!

Five Pages Changed Size

The following pages changed size from the code in this PR compared to its base branch:

Page Size (compressed) First Load
/404 127.02 KB (🟡 +6 B) 242.16 KB
/500 127.03 KB (🟡 +6 B) 242.17 KB
/[[...markdownPath]] 129.46 KB (🟡 +6 B) 244.61 KB
/errors 127.27 KB (🟡 +6 B) 242.42 KB
/errors/[errorCode] 127.25 KB (🟡 +6 B) 242.39 KB
Details

Only the gzipped size is provided here based on an expert tip.

First Load is the size of the global bundle plus the bundle for the individual page. If a user were to show up to your website and land on a given page, the first load size represents the amount of javascript that user would need to download. If next/link is used, subsequent page loads would only need to download that page's bundle (the number in the "Size" column), since the global bundle has already been downloaded.

Any third party scripts you have added directly to your app using the <script> tag are not accounted for in this analysis

Next to the size is how much the size has increased or decreased compared with the base branch of this PR. If this percentage has increased by 10% or more, there will be a red status indicator applied, indicating that special attention should be given to this.

@rickhanlonii

Copy link
Copy Markdown
Member

Maybe there's a better third option, but the darker text seems worse, like there's too much contrast.

How about 'gray-80': '#343A46'

Screenshot 2026-06-23 at 11 43 25 AM

@rickhanlonii

Copy link
Copy Markdown
Member

gray-90 also seems fine. i think the issue with 95 is that theres no cyan tint to it

Screenshot 2026-06-23 at 11 45 15 AM

Bumps button contrast to match the treatment on reactnative.dev.

Dark mode:
- primary text: dark:text-secondary (#404756) -> dark:text-gray-90 (#23272F)
- secondary border: #404756 -> #4E5769 (matches RN's rgb(78,86,104))

Light mode:
- secondary border: #D9DBE3 -> #BCC1CD (matches RN's rgb(188,193,205))

gray-90 keeps a subtle cyan tint on the teal button, per review feedback
(gray-95 was too flat).
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.

3 participants