Skip to content

Migrate onto the Moderne design system and rework the header - #538

Draft
zieka wants to merge 2 commits into
masterfrom
refactor/migrate-moderne-design
Draft

Migrate onto the Moderne design system and rework the header#538
zieka wants to merge 2 commits into
masterfrom
refactor/migrate-moderne-design

Conversation

@zieka

@zieka zieka commented Aug 28, 2026

Copy link
Copy Markdown
Member

Problem

  • docs.openrewrite.org shares a Docusaurus ancestor with docs.moderne.io but never moved onto the design system, so the two sites have drifted apart visually while still carrying each other's leftovers (this repo's custom.css and moderne-docs' both still declare the same Beausite @font-face and mint #85FE99).
  • 48 colour literals, two hand-written font stacks and a hand-rolled type scale meant every value was a guess. Nothing failed loudly when one drifted.
  • 5 more colours were baked inside data-URI SVGs, where a CSS variable cannot reach them, forcing duplicate light/dark copies of the same glyph.
  • The single 116px navbar had no section navigation, so all 9 doc sections competed in one 370px sidebar with no top-level axis.

Objectives

  1. Resolve every colour, type and dimension value from @moderneinc/design-system-tokens instead of literals.
  2. Make themeable icons themeable, removing the duplicate dark-mode artwork.
  3. Rework the header into the two-row layout docs.moderne.io uses, with the sidebar scoped to the selected section.
  4. Keep the header's reserved height correct at every viewport.
  5. Preserve OpenRewrite's identity where the system has no equivalent.
Assumptions
  • @moderneinc/design-system-tokens@7.3.0 is public on npm and installs without auth, so this repo's public CI can build it. Pinned exact; the installed moderne.css is byte-identical to the published latest.
  • moderne.css is imported whole rather than per-module. Importing only the four files currently used is ~33% smaller, but a token added later would resolve to nothing with no error — worth 7KB gzip to avoid.
  • Mint #85FE99 has no semantic token. It exists in the palette only as a raw entry, and consuming raw palette entries is the misuse the system warns about, so it stays a brand literal — as docs.moderne.io also keeps it.
  • The active-section colour is blue in light and mint in dark. Mint measures 1.11:1 on the light ground and 14.54:1 on the dark one; docs.moderne.io splits it the same way.
  • --ifm-navbar-height is 56px, not the 37px upstream uses: this site's logo is 33px and its search field 38px, against a smaller lockup there.
  • useWindowSize() is the supported way to tell the desktop and mobile sidebars apart — both render through DocSidebarItems at level 1.
  • navSections.ts hrefs must match generated-index slugs in sidebars.ts. Nothing checks this at build time; a mismatch falls back to the full sidebar rather than failing.
Changes
  • (1) package.json, docusaurus.config.ts — add the tokens dependency; customCss loads moderne.css then custom.css; swap the Inter webfont for Geist + Geist Mono.
  • (1) src/css/custom.css — Infima bridge mapping --ifm-* onto --mod-*. 48 colour literals become 5.
  • (1) src/components/button.module.css, src/theme/DocCard/styles.module.css — onto --mod-button-primary-* and text/border/shadow tokens.
  • (1) src/css/custom.css — admonitions take the mode-aware --mod-color-feedback-* tints and the reference's rounded hairline treatment, replacing Infima's coloured left stripe.
  • (2) src/css/custom.css — sidebar carets, breadcrumb separator, pagination arrows and the footer mark redrawn as mask-image; the SVG supplies the shape, a token the colour. Deletes 3 dark-mode overrides and one duplicated 1.4KB path.
  • (3) src/theme/Navbar/Layout/* — fixed wrapper holding announcement bar, navbar and section nav as one block.
  • (3) src/theme/Navbar/Content/* — three zones: logo left, search and colour-mode toggle centred, external links right.
  • (3) src/components/SecondaryNav/*, src/config/navSections.ts — the section bar; six sections left, three behind a More dropdown mirroring upstream's right-aligned Releases.
  • (3) src/theme/DocSidebarItems/* — scopes the sidebar to the active section, headed by its name. Desktop only.
  • (4) src/theme/Navbar/Layout/index.tsx — a ResizeObserver publishes the header's measured height as --docs-header-height; the CSS value is a first-paint default only.
  • (5) src/css/custom.css — mint kept as --ifm-color-mint for the announcement bar, card hover and dark-mode active section.

No tests: this repo has no test framework or test files, and this PR adds no testable logic. tsc and the production build are the available checks.

Notes
  • Announcement-bar text is deliberately not mode-aware. The mint ground never inverts, so a mode-aware token would put near-white on green at 1.11:1. Pinned to --mod-ink-800 (defined only in the package's :root, never its dark block) it is 11.96:1.
  • The header is measured, not declared. A hardcoded reserve was wrong on mobile — the bar's height is auto there and its copy wraps to ~3 lines against a 30px reserve, hiding content under the fixed header. Measuring is correct at any width and makes a third row a zero-CSS change.
  • Sidebar scoping is desktop-only. The section bar is hidden below 997px, so scoping there would strand a reader in one section with no way out.
  • Beausite is gone. Nothing referenced it after the type swap, so the @font-face went too. The doc h1 is 36px Geist, matching docs.moderne.io.
  • Left alone deliberately: the colourblind-accessible amber code-highlight colours (--mod-color-text-warning is a different colour with a different meaning), and gap: 15px in button.module.css (14 and 16 bracket it on the scale). A near-miss substituted silently is worse than a literal left in place.
  • No token equivalent — worth raising upstream: mint has no semantic tier; semanticTypography tops out at 28px so there is no display size for a docs h1; package shadows have no dark variant, though --mod-color-surface-shadow-neutral supplies the mode-aware colour.
  • Review found three defects, all fixed: two announcement bars rendered (the default slot plus the wrapper), leaving a dead 40px band; two SearchBar instances mounted below 997px, so Cmd+K fired twice; and the header reserve above. Also reused @theme/Icon/ExternalLink and @theme/Navbar/MobileSidebar/Toggle rather than the reimplementations first written, restoring the translated "(opens in new tab)" label and the touchstart/focusin dismissal the theme's dropdown uses.
  • Verified: yarn typecheck clean; production build succeeds; all 43 --mod-*/--docs-* references resolve in the built CSS with none dangling; light and dark checked in-browser; 23 contrast pairings pass AA for normal text in both themes, worst 5.39.
  • Pre-existing, not from this PR: the build's <p> minifier warnings come from <ReactPlayer> inline in markdown (no .md file is touched here). Separately, yarn typecheck OOMs locally if you build first — tsconfig.json sets allowJs: true with no exclude, so tsc walks 1.3GB of build/. CI is unaffected (typecheck runs before build); a one-line exclude would fix it.

https://claude.ai/code/session_019z4aUYg8gVhnMY8vStEdia

…eader

Depend on @moderneinc/design-system-tokens@7.3.0 and bridge Infima's --ifm-*
variables onto its --mod-* tokens, replacing 48 colour literals. Rework the
header into the two-row layout docs.moderne.io uses — navbar above a section
nav — and scope the sidebar to the selected section.

Colours baked inside data-URI SVGs cannot take a CSS variable, so the carets,
breadcrumb separator, pagination arrows and footer mark are redrawn as
mask-image, which let three hand-written dark-mode overrides be deleted.

The header's height is measured rather than declared: the announcement bar
wraps on mobile, so any constant is wrong there.

Claude-Session: https://claude.ai/code/session_019z4aUYg8gVhnMY8vStEdia
Raise the navbar to 72px so the logo clears the announcement bar by 20px
rather than 12px.

Pin card-hover text to --mod-ink-800. The mint hover ground is identical in
both themes, so text following the colour mode went near-white on green in
dark mode — 1.11:1, unreadable. Pinned it is 11.96:1, matching how the
announcement bar already handles the same ground.

Claude-Session: https://claude.ai/code/session_019z4aUYg8gVhnMY8vStEdia
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: In Progress

Development

Successfully merging this pull request may close these issues.

1 participant