Skip to content

feat(theme): unify platform colors, refine badges, and tighten api-status chips#1089

Merged
Huxpro merged 10 commits into
mainfrom
feat/unify-platform-colors
Jun 7, 2026
Merged

feat(theme): unify platform colors, refine badges, and tighten api-status chips#1089
Huxpro merged 10 commits into
mainfrom
feat/unify-platform-colors

Conversation

@Huxpro

@Huxpro Huxpro commented Jun 4, 2026

Copy link
Copy Markdown
Collaborator

Summary

Continuation of the platform-icon unification work (#1082 / #1086). After unifying the SVG glyphs, three different color palettes still lived across PlatformBadge, the homepage feature row, and APIStatus. This PR collapses them, reframes a couple of badge variants, and fixes the long-standing visual quirks that the unification exposed (Android glyph reading smaller than its peers, badge baseline alignment in headings, and the api-status support chips rendering at default --icon-size instead of the compact pill they were meant to be).

1. One palette, one token map

New src/components/platform-navigation/platform-colors.ts is the single source of truth. Homepage icon.tsx now imports PLATFORM_TINT from it (replacing the inline duplicate), and PlatformBadge.css mirrors the same hex values.

Family Hue Was on PlatformBadge
iOS / macOS zinc (Apple silver) blue
Android emerald emerald ✓
Harmony rose (Huawei red) orange
Web / web_lynx orange (Lynx warmth) purple
Windows sky sky ✓
Clay umbrella + all clay_* cyan (one Clay signature) teal + cyan + indigo + sky (4 hues)

All clay_* variants intentionally share one Clay hue rather than borrowing the underlying-platform color — clay_android and android share the Android glyph, so the color has to be the differentiator.

2. Quieter PlatformBadge contrast

Background drops from ~500@10% saturated wash to a tinted 50 / 950. The icon stays in full platform color so the badge is still scannable, with the icon doing the signalling and the bg stopping the shouting.

3. *Only vs No* actually look different now

Before, the CSS overrode info, warning, and danger all to the same platform color, so <IOSOnly> and <NoIOS> looked identical except for the word. Now:

  • default: platform color, subtle bg
  • .platform-badge--only: inset platform-tinted ring (emphasis)
  • .platform-badge--no: drops platform color, mutes to neutral, strikes the label, dims the icon (negation)

4. Bare clay -> "Desktop"

User-facing label only. <ClayOnly>, <NoClay> component exports keep their names so MDX callers don't break (component-name derivation now uses a separate technical-name mapping so the SSG export shape stays stable). APIStatus and compat tables keep clay. Temporary per request until the desktop branding settles.

5. Badge baseline fixed in headings

vertical-align: middle on .rp-badge inside the platform-badge wrapper. Default inline-flex baseline alignment made the chip cling to the bottom of large heading lines (image 3 of the original triage); centering it on the line box makes the same chip sit cleanly next to a code chip in body text, a TOC list item, and a heading without changing its size.

6. Android glyph normalized

Android SVG viewBox cropped from 0 0 21 20 to 1.5 1.5 18 18. The half-dome glyph only filled the lower half of the original viewBox, so at the same --icon-size it rendered visibly smaller than Apple / Harmony / Web (which fill their viewBoxes). The new square crop centers on the glyph centroid and removes the dead margin so Android picks up the same visual weight as its peers.

7. api-status support chips back to compact

APIStatusDashboard.tsx chips were rendering huge on desktop — <Icon className="w-2.5 h-2.5"> was losing to .icon { width: var(--size) } in the cascade, so the icon held at the default 1rem (16px) instead of the intended ~10px. Threaded a style prop through PlatformSvg and the api-status icon factory, set the support-chip icon to { width: 10, height: 10 } inline, switched the status dot from <span> (inline, ignores width/height) to inline-block, and dialed paddings/gap to match the older compact pill (~22x14 footprint).

Test plan

  • Netlify deploy preview
  • Homepage feature-row icons still tinted correctly
  • An API doc page with multiple badge variants — <PlatformBadge>, <AndroidOnly>, <NoAndroid> look distinct
  • APIStatus dashboard — support chips read as compact pills on both mobile and desktop, Android icon matches the visual weight of Apple / Harmony / Web
  • Light + dark mode for all of the above
  • Any page that renders <ClayOnly> displays "Desktop Only"

Copilot AI review requested due to automatic review settings June 4, 2026 18:40
@Huxpro Huxpro requested a review from SoonIter as a code owner June 4, 2026 18:40
@netlify

netlify Bot commented Jun 4, 2026

Copy link
Copy Markdown

Deploy Preview for lynx-doc ready!

Name Link
🔨 Latest commit f7d2f11
🔍 Latest deploy log https://app.netlify.com/projects/lynx-doc/deploys/6a25ba6ea9b3bc0008401bf3
😎 Deploy Preview https://deploy-preview-1089--lynx-doc.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

@coderabbitai

coderabbitai Bot commented Jun 4, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Adds a centralized platform-colors module, refactors PlatformBadge CSS to use semantic platform variables and new variants, updates PlatformBadge to apply type-driven modifier classes and separate display labels, and makes icon wrapper import tints/types from the new module.

Changes

Platform colors centralization and badge styling

Layer / File(s) Summary
Platform colors centralization
src/components/platform-navigation/platform-colors.ts
Adds PlatformKey and PlatformHue, defines brand-family hues, exports PLATFORM_HUES, and derives PLATFORM_TINT for all platform keys.
Platform badge CSS semantic variables
src/components/api-badge/PlatformBadge.css
Platform classes now set --platform-badge-fg/bg/ring (light/dark), a centralized [class*='platform-badge-'] maps those to --rp-container-*, universal layout tweaks added, and .platform-badge--only / .platform-badge--no variants are added.
Badge component modifier classes and labels
src/components/api-badge/PlatformBadge.tsx
Introduce mapPlatformNameToTechnicalName and mapPlatformNameToLabel (renders clay as Desktop), add TYPE_TO_MODIFIER to compute CSS modifier classes, restructure inner markup with platform-badge__label and platform-badge__icon, and change "no" text to No ${Label}; export identifiers remain stable.
Icon wrapper platform-colors integration
src/components/home-comps/features/icon.tsx
PlatformIconWrapper imports PLATFORM_TINT and PlatformKey from platform-colors and narrows the platform prop type to PlatformKey.
APIStatus compact badge sizing
src/components/api-status/APIStatusDashboard.tsx
Reduce multi-platform icon and indicator dot sizes in APIItem for compact badge rendering.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested reviewers

  • SoonIter
  • icecreamx10
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title accurately captures the main objective of the PR: unifying platform colors and refining badges/status chips across multiple components.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/unify-platform-colors

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/components/api-badge/PlatformBadge.tsx (1)

170-178: ⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Preserve stable ClayOnly/NoClay export keys when label text changes to “Desktop”.

Component keys are currently derived from mapPlatformNameToFullName(). After changing clay display text to "Desktop", generation now creates DesktopOnly/NoDesktop, but this file still exports ClayOnly/NoClay. Those exports resolve to undefined at runtime.

Proposed fix
 for (const platform of platformNames) {
-  const name = mapPlatformNameToFullName(platform)
+  const exportStem =
+    platform === 'clay' ? 'Clay' : mapPlatformNameToFullName(platform);
+  const name = exportStem
     .split(' ')
     .map((word) => word.charAt(0).toUpperCase() + word.slice(1))
     .join('');

Also applies to: 195-286

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/api-badge/PlatformBadge.tsx` around lines 170 - 178, The
export keys break because component names are built from
mapPlatformNameToFullName(platform) which reflects display labels (e.g.,
"Desktop") instead of the stable platform identifier (e.g., "clay"), causing
exports like ClayOnly/NoClay to become undefined; change the naming to use the
stable platform identifier (the loop variable platform) when building
componentNameOnly and componentNameNo (capitalize platform to produce
"ClayOnly"/"NoClay") rather than using mapPlatformNameToFullName; keep the
display label from mapPlatformNameToFullName only for UI text, not for export
keys, and update any related code that constructs
componentNameOnly/componentNameNo (and the same pattern in the 195-286 range) to
follow this approach.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/components/api-badge/PlatformBadge.css`:
- Around line 18-23: The CSS rules for .platform-badge-clay_ios and
.platform-badge-clay_macos are incorrectly using the Apple/zinc color (`#52525b`);
update their --platform-badge-fg to use the Clay/cyan hue token consistent with
platform-colors.ts (i.e., switch the color value for the clay_* classes in the
light and dark blocks to the centralized Clay/cyan contract), and repeat the
same change for the other occurrences of those classes in the file (the blocks
around the other mentioned ranges) so clay_ios/clay_macos match the unified Clay
mapping.

---

Outside diff comments:
In `@src/components/api-badge/PlatformBadge.tsx`:
- Around line 170-178: The export keys break because component names are built
from mapPlatformNameToFullName(platform) which reflects display labels (e.g.,
"Desktop") instead of the stable platform identifier (e.g., "clay"), causing
exports like ClayOnly/NoClay to become undefined; change the naming to use the
stable platform identifier (the loop variable platform) when building
componentNameOnly and componentNameNo (capitalize platform to produce
"ClayOnly"/"NoClay") rather than using mapPlatformNameToFullName; keep the
display label from mapPlatformNameToFullName only for UI text, not for export
keys, and update any related code that constructs
componentNameOnly/componentNameNo (and the same pattern in the 195-286 range) to
follow this approach.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 89d5c51e-3af8-4e46-9ee0-f24850266b85

📥 Commits

Reviewing files that changed from the base of the PR and between aba4ad7 and e03a0b8.

📒 Files selected for processing (4)
  • src/components/api-badge/PlatformBadge.css
  • src/components/api-badge/PlatformBadge.tsx
  • src/components/home-comps/features/icon.tsx
  • src/components/platform-navigation/platform-colors.ts

Comment on lines +18 to +23
/* apple family (ios, macos) → zinc */
.platform-badge-ios,
.platform-badge-clay_ios,
.platform-badge-macos,
.platform-badge-clay_macos {
--platform-badge-fg: #52525b; /* zinc-600 */

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Align clay_ios/clay_macos with the centralized Clay hue contract.

platform-colors.ts maps every clay_* key to the Clay/cyan family, but this stylesheet still assigns clay_ios and clay_macos to Apple/zinc in both light and dark rules. That breaks the new unified mapping and makes Clay variants visually inconsistent.

Proposed fix
 /* apple family (ios, macos) → zinc */
 .platform-badge-ios,
-.platform-badge-clay_ios,
 .platform-badge-macos,
-.platform-badge-clay_macos {
+.platform-badge-macos {
   --platform-badge-fg: `#52525b`; /* zinc-600 */
   --platform-badge-bg: `#fafafa`; /* zinc-50 */
   --platform-badge-ring: `#d4d4d8`; /* zinc-300 */
 }

 /* clay umbrella + variants → cyan (Clay/Desktop signature) */
 .platform-badge-clay,
+.platform-badge-clay_ios,
 .platform-badge-clay_android,
+.platform-badge-clay_macos,
 .platform-badge-clay_windows {
   --platform-badge-fg: `#0891b2`;
   --platform-badge-bg: `#ecfeff`;
   --platform-badge-ring: `#a5f3fc`;
 }

 :where(html.rp-dark, html.dark) .platform-badge-ios,
-:where(html.rp-dark, html.dark) .platform-badge-clay_ios,
 :where(html.rp-dark, html.dark) .platform-badge-macos,
-:where(html.rp-dark, html.dark) .platform-badge-clay_macos {
+:where(html.rp-dark, html.dark) .platform-badge-macos {
   --platform-badge-fg: `#d4d4d8`;
   --platform-badge-bg: `#27272a99`;
   --platform-badge-ring: `#52525b`;
 }

 :where(html.rp-dark, html.dark) .platform-badge-clay,
+:where(html.rp-dark, html.dark) .platform-badge-clay_ios,
 :where(html.rp-dark, html.dark) .platform-badge-clay_android,
+:where(html.rp-dark, html.dark) .platform-badge-clay_macos,
 :where(html.rp-dark, html.dark) .platform-badge-clay_windows {
   --platform-badge-fg: `#22d3ee`;
   --platform-badge-bg: `#08344499`;
   --platform-badge-ring: `#155e75`;
 }

Also applies to: 57-60, 67-70, 101-103

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/api-badge/PlatformBadge.css` around lines 18 - 23, The CSS
rules for .platform-badge-clay_ios and .platform-badge-clay_macos are
incorrectly using the Apple/zinc color (`#52525b`); update their
--platform-badge-fg to use the Clay/cyan hue token consistent with
platform-colors.ts (i.e., switch the color value for the clay_* classes in the
light and dark blocks to the centralized Clay/cyan contract), and repeat the
same change for the other occurrences of those classes in the file (the blocks
around the other mentioned ranges) so clay_ios/clay_macos match the unified Clay
mapping.

Copilot stopped reviewing on behalf of Huxpro due to an error June 4, 2026 19:40
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jun 4, 2026

Copy link
Copy Markdown

Deploying lynx-website-next with  Cloudflare Pages  Cloudflare Pages

Latest commit: f7d2f11
Status:⚡️  Build in progress...

View logs

Huxpro added 5 commits June 6, 2026 21:06
Extracts the inline PLATFORM_TINT map from the homepage feature row into
src/components/platform-navigation/platform-colors.ts as the single source
of truth for platform brand color across the site. Covers every platform
key consumed by PlatformBadge — including the clay umbrella + clay_*
variants — and exposes both the Tailwind tint string and the underlying
hex/bg values so the PlatformBadge CSS can stay in lockstep with what
the homepage row uses.

Brand mapping:
  apple family (ios, macos) -> zinc
  android                   -> emerald
  harmony                   -> rose
  web / web_lynx            -> orange
  windows                   -> sky
  clay umbrella + variants  -> cyan

Change-Id: I10af83dc736bf9e057e3b6bd1a6d0c4a0c93d7fe
Three coordinated changes so the API-doc PlatformBadge stops fighting the
rest of the site:

1. Palette unified to the shared platform color tokens. iOS goes from
   saturated blue back to Apple's zinc-silver, Harmony from orange to the
   Huawei rose, web from purple to lynx orange, and the four clay_*
   variants collapse from cyan/indigo/teal/sky into one Clay cyan so
   ClayAndroidOnly stays visually distinct from AndroidOnly even though
   they share the Android glyph.

2. Contrast quieted. Background drops from a saturated ~500@10% wash to a
   tinted 50/950, while the icon stays in full platform color so the badge
   is still scannable at a glance — the icon does the signalling.

3. Visual semantics for *Only / No*. Previously info/warning/danger all
   rendered in the same platform color, so "iOS Only" and "No iOS" looked
   like the same chip with different words. Now:
     default            platform color, subtle bg
     .platform-badge--only  adds an inset platform-tinted ring (emphasis)
     .platform-badge--no    drops platform color, mutes to neutral, strikes
                            the label, dims the icon (negation)

Also relabels bare `clay` as "Desktop" in the user-facing label only — the
component export names (ClayOnly, NoClay), APIStatus colors, and compat
tables keep `clay`. Temporary until the desktop branding settles.

Change-Id: If12a812aab5d351e19c39f01065847954ca24d85
The previous commit changed mapPlatformNameToFullName('clay') to return
'Desktop' so the badge would read "Desktop", but that same function also
drove the dynamic component-name derivation. Result: generatedComponents
held 'DesktopOnly'/'NoDesktop' while the destructured exports still asked
for 'ClayOnly'/'NoClay', so both came back as undefined and every MDX page
that rendered <ClayOnly/> SSG-failed with React #130.

Split the responsibility:
  - mapPlatformNameToTechnicalName -> stable 'Clay'/'Harmony'/... drives
    the generatedComponents keys, so ClayOnly/NoClay stay valid.
  - mapPlatformNameToLabel         -> what the user sees, returns
    'Desktop' for clay.

Also drops em dashes from comments in this PR's new code per repo prose
preferences.

Change-Id: Ib82b76c1511b665405204e76a7475c58dc092dad
Change-Id: I98a04f9a62cc6e860d74719f5e4f1d0f6bb968ea
The Rspress Badge is inline-flex, which baseline-aligns its line box to
the surrounding text baseline. That looks fine next to body text and code
chips, but inside a heading it makes the chip cling to the bottom of the
heading line and read as stranded. Setting vertical-align: middle on the
chip re-centers it on the line box and fixes alignment in body, TOC, and
heading contexts without changing the chip's size.

Also moves the icon size from inline Tailwind utilities into the same
CSS rule (--icon-size: 0.9rem) so future tweaks live in one place.

Change-Id: Ibc9c30567a716e666be65a20e55b9e323d7963d5
@Huxpro Huxpro force-pushed the feat/unify-platform-colors branch from 24ee6ac to 38ab2ec Compare June 7, 2026 04:06
Huxpro added 4 commits June 6, 2026 21:57
Two adjacent fixes for how platform chips read on the api/status page.

1. Android SVG viewBox cropped from `0 0 21 20` to `1.5 1.5 18 18`.
   The half-dome glyph only fills the lower half of the original
   viewBox, so at the same `--icon-size` the rendered Android glyph
   looked visibly smaller than Apple / Harmony / Web (which fill their
   viewBoxes). The new square crop centers on the glyph centroid and
   removes the dead margin so the rendered icon picks up the same
   visual weight as the other platforms.

2. API-status support chips in `APIStatusDashboard.tsx` shrunk to
   match the older compact pill. Icon 10px -> 8px, dot 6px -> 4px,
   padding 4/2px -> 2/1px, gap 2px -> 1px. The chip footprint goes
   from ~26x14 down to ~16x10, restoring the tight pill feel.

Change-Id: I5f45a45f00c314871207eab1ebc98112be3c50af
…ine-block on dot

Tailwind `w-2 h-2` lost to `.icon { width: var(--size) }` in CSS source
order, so the chip icons rendered at 1rem (16px) instead of the intended
8px. Pass `--icon-size: 0.5rem` on the chip wrapper so the .icon rule
picks up the right size, and switch the status dot from `<span>` (inline,
ignores width/height) to an inline-block element so the 4px circle
actually renders.

Change-Id: I50f994b4a40449a20c80cf10f62d3e9c93fad799
Previous shrink went too tight: icon (8px) and dot (4px) sat right next
to each other with 1px gap and 2px padding, so the chip read as a single
cramped square instead of an "icon + status" pill.

Back off slightly to match the reference proportions:
  --icon-size: 0.625rem (10px)
  dot 6px
  gap 4px
  padding 4px / 2px

Chip footprint becomes roughly 22 x 14 — small enough on mobile to fit a
multi-platform row, comfortable enough on desktop that the icon and the
status dot don't read as one blob.

Change-Id: I2303122243c05c347974668186381e84abddf2bb
The previous attempt set --icon-size on the chip wrapper hoping it would
cascade into the .icon child, but .icon's `width: var(--size)` was still
winning at the rendered size (~16px) on desktop, so the chips read as
huge despite the smaller Tailwind paddings. Add a `style` pass-through
on PlatformSvg + the api-status icon factory, and set the chip icon to
{ width: 10, height: 10 } directly. Inline style sits above any cascade
contest so the icon actually renders at 10px now.

Change-Id: I1a2a182b24f183ed3d3e1ce2e981133166f41a5a
@Huxpro Huxpro changed the title feat(theme): unify platform colors across badges, homepage, and APIStatus feat(theme): unify platform colors, refine badges, and tighten api-status chips Jun 7, 2026
@Huxpro Huxpro merged commit 679c646 into main Jun 7, 2026
9 of 13 checks passed
@Huxpro Huxpro deleted the feat/unify-platform-colors branch June 7, 2026 18:40
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