Skip to content

Brand alignment: BodyMaps tokens, IBM Plex, identity assets, and a brand guard - #7

Merged
andyy-yang merged 8 commits into
BodyMaps:mainfrom
andyy-yang:bodymaps-styling
Aug 13, 2026
Merged

Brand alignment: BodyMaps tokens, IBM Plex, identity assets, and a brand guard#7
andyy-yang merged 8 commits into
BodyMaps:mainfrom
andyy-yang:bodymaps-styling

Conversation

@andyy-yang

@andyy-yang andyy-yang commented May 20, 2026

Copy link
Copy Markdown
Collaborator

TLDR

Aligns the viewer with the BodyMaps brand in one conflict-free pass: the adopted mark and favicon/OG identity, self-hosted IBM Plex, an ink-primary / orange-accent color system driven by design tokens, a slim site footer routing commercial inquiries to thebodymaps.com, and automated brand enforcement (CI guard + invariant tests). Deliberately scoped so it cannot disturb in-flight work: hot files under active development are untouched (or touched by ≤2 provably disjoint lines) and registered as a deferred migration list.

Major decisions

  1. Same-filename logo swappublic/bodymaps-logo.svg now contains the adopted mark (two ink bars + orange band), so the header, auth dialog, and legal pages rebrand with zero component edits. The previous navy crosshair was never an approved mark. (Rationale: conflict-surface minimization.)
  2. Ink #0F172A is the primary UI color — button fills, active nav, focus borders, toggles. Orange is strictly an accent: links and small orange text (--accent-deep #C2532F) on light, vivid/tint (#E76F51/#F08A6F) on dark. (Source: brand book — "paper-dominant, orange scarce by design".)
  3. Viewer re-accented through the existing --vp-* token seam — one line in index.css flips ~300 var() call sites from blue to the brand accent without editing viewer CSS that teammates are actively changing.
  4. Enforcement is dependency-free — a plain-node guard script, a new workflow file, and a vitest file that rides the existing test step. package.json is untouched, so the queued dependabot PRs are unaffected. The guard bans only patterns this PR fully eradicated; surfaces still carrying pre-brand styling are explicit per-rule allowlist entries (the deferred register), so the guard cannot fail any current in-flight work — verified by simulating it against every open PR's added lines (all green), and the in-flight SharePatientCard branch is pre-registered.
  5. Fonts self-hosted (IBM Plex Sans 400/500/600 + Mono 400/500, latin/latin-ext woff2, 270KB) — removes the Google Fonts runtime dependency. Note: the brand pack's exported webfonts for Sans 500/600 contained the Regular face; genuine Medium/SemiBold subsets were regenerated from the pack's TTFs (weights verified with fontTools). The retired families ("Space Grotesk"/"JetBrains Mono") alias onto Plex via @font-face, so deferred surfaces render deterministically until migrated.

What changed

Area Files Change
Identity assets public/bodymaps-logo.svg, public/favicon*, apple-touch-icon.png, og-image-1200x630.png, public/fonts/* Adopted mark; brand favicon set; OG share image; self-hosted Plex woff2
Head metadata index.html Favicon links, theme-color #0F172A, meta description, OG/Twitter tags, font preloads; Google Fonts links removed
Tokens src/styles/brand.css (new), src/index.css Brand-pack palette verbatim + @font-face; dead --brand/--accent #111111 palette deleted (zero usages, verified); --vp-accent/font/mono re-pointed at brand tokens
Chrome re-theme Header, AuthButton, AuthModal, UpgradeDialog, BatchDetailsModal, Settings.css, LegalPage.css, LandingPage, TeamPage, Homepage/components/*, ComparePage.css, CompareViewerPage.css, ProcessingSummaryBar, ScrollToTopButton JHU Heritage Blue (~70 usages) and stray blue accents replaced with tokens: ink fills, orange accents; Plex font stacks; weights >600 normalized
Site footer components/SiteFooter/ (new); mounted in LandingPage, Homepage, TeamPage, UploadPage Company line + "For commercial use, please visit thebodymaps.com" → /contact/; pinned to page bottom via flex-column page shells
Enforcement scripts/brand-guard.mjs, .github/workflows/brand-guard.yml, src/test/brand.test.ts, BRANDING.md 7 pattern rules + head-metadata invariants with per-rule deferred allowlists; runs on all PRs; invariant tests lock logo/tokens/metadata via the existing blocking vitest step
Cleanup public/ and src/assets/ Removed orphans: old logo PNGs, jhu_logo.jpg, vite/react scaffold SVGs, unused Inter TTFs (all verified unreferenced, including in open PR diffs)

Testing

All checks were run on the exact tree a squash merge produces (this branch's merge-base equals the current main tip, and git merge-tree reports a clean merge):

  • node scripts/brand-guard.mjs: OK (212 files, 7 rules + head metadata)
  • npm run typecheck: clean · npm run test: 197/197 across 23 files (includes the new brand invariant tests) · npm run build: green
  • Conflict safety: git merge-tree --write-tree simulations for every open PR and recently pushed branch, computed against both main and this branch — the set of conflicts caused by this branch is empty in every case. The only files shared with any open PR are UploadPage.tsx (2 added lines: one import, one <SiteFooter />) and UploadPage.css (top-of-file layout lines vs. their end-of-file appends); the merged result for PR Feat/analytics dashboard #137 was reconstructed and contains both sides with zero conflict markers.
  • Guard future-safety: the guard was run against every open PR's added lines and against the simulated merged tree with Feat/analytics dashboard #137 — green everywhere.
  • Browser-verified on the dev server: landing, dataset library, upload, team, terms, sign-in dialog, compare — mark renders unclipped at 38px, fonts serve from /fonts, favicon/OG assets return 200, footer pinned at the page bottom (38px) on all mounted pages.
  • Contrast (computed WCAG 2.1): ink fills with white text ≥14:1; accent-deep links 4.59:1 on white; the legal page uses the darker accent on its off-white ground (plain accent-deep is 4.40:1 there); accent-tint on dark 7.3:1; the footer link is underlined at rest (use-of-color).
  • Verified correct — no change needed: all functional/data colors (segmentation palettes, organ meshes, CT windowing grays, status colors) deliberately untouched; reserved teal #0B4F6C confirmed absent from chrome; deleted assets confirmed referenced nowhere.
  • Lower-severity deferred (each with a reason, tracked in BRANDING.md + the guard allowlists): UploadPage/viewer/segmentation/walkthrough colors & fonts (files under active PRs — migrate when they land); Flask PDF report header (same); og:image left relative until the canonical production origin is set; static.yml Pages deploy publishes the raw source tree (pre-existing issue, unchanged here); neutral-gray sweep; Tailwind @theme mapping; stylelint.

Out of scope

Copy/positioning decisions (hero tagline vs. tab title, team-page attribution, placeholder legal text), decorative polish (gradient orbs, shadows), per-route document titles, a 404 route, README rebrand, and the deploy-config cleanup — all follow-ups so this PR stays a pure, verifiable brand pass.

Note for the team

This adds a new Brand guard CI check. It is advisory (not a required check) and cannot fail any currently open PR — that was explicitly simulated. If it flags a future change, BRANDING.md at the repo root has the tokens to use; please don't extend the allowlists to silence it.

Test plan for reviewers

  • cd PanTS-Demo && npm run typecheck && npm run test && npm run build
  • node scripts/brand-guard.mjs from the repo root
  • npm run dev → check /, /dashboard, /upload, /team, /terms, and the sign-in dialog: adopted mark, ink primary buttons, orange only as accent, footer at the page bottom
  • Browser tab shows the BodyMaps favicon; page source head carries description + OG tags
  • If you own an open PR: confirm this diff's only overlap with it is the 2-line UploadPage.tsx footer mount

Additive-only styling pass that aligns the PanTS-Viewer landing page
with the BodyMaps brand (https://thebodymaps.com) for visitors who
arrive at the viewer from there. Zero changes to any <script> block,
existing CSS class, React component logic, routing, or backend code.

PanTS-Demo/public/home.html
  - <link rel="icon"> -> /logo.png
  - <title> "CT Finder · Search + Viewer (Dark)" -> "PanTS Viewer · BodyMaps"
  - <meta name="description"> added for share / SEO previews
  - --brand token #2a6cff -> #E76F51 (BodyMaps "agreement band" orange).
    Cascades to .btnSearch background and #inferProgressBar fill.
  - --accent token #febb02 -> #E76F51 (unified with brand).
  - ~100 lines of new bm-*-prefixed CSS appended to the existing
    <style> block. Does not override or touch any existing class.
  - Sticky top header with BodyMaps logo + wordmark + a single link
    back to thebodymaps.com.
  - Hero intro section above the existing #inferenceSection panel
    (eyebrow + H1 with one orange-accented word + lead).
  - Footer at the bottom with one attribution line linking to
    thebodymaps.com.

PanTS-Demo/src/index.css
  - Same --brand and --accent swap so the React viewer (reachable
    from home.html via /case/<id>, /session/<id>, /reconstruction/<id>)
    inherits the same orange.

PanTS-Demo/src/components/SnakeGame/SnakeGame.tsx
  - One-line cosmetic change: snake-game apple color
    bg-red-600 border-red-600 -> bg-[#E76F51] border-[#E76F51].
    Snake body color unchanged. The game is a loading-state amusement,
    so this is purely visual.

New assets
  - public/logo.png         BodyMaps mark, transparent, used as favicon.
  - public/logo-light.png   Same mark with white bars + orange band,
                            used in the dark header.

Untouched
  - All <script> blocks in home.html (search / filter / browse /
    upload / viewer JS).
  - All existing CSS classes in home.html (.hero, .searchRail,
    .recBar, .main, .filters, .viewer, .modal, etc.).
  - All React components except the one SnakeGame color line.
  - flask-server/, helpers/, contexts/, types/.
  - package.json (no new dependencies).
@vercel

vercel Bot commented May 20, 2026

Copy link
Copy Markdown

Someone is attempting to deploy a commit to the eireawerawer's projects Team on Vercel.

A member of the Team first needs to authorize it.

Andy Yang added 7 commits August 12, 2026 17:22
# Conflicts:
#	PanTS-Demo/index.html
#	PanTS-Demo/public/home.html
#	PanTS-Demo/src/components/SnakeGame/SnakeGame.tsx
#	PanTS-Demo/src/index.css
- Add src/styles/brand.css: brand-pack color tokens verbatim plus
  @font-face for IBM Plex Sans 400/500/600 and Plex Mono 400/500
  (woff2 in public/fonts) - no more Google Fonts dependency
- Replace public/bodymaps-logo.svg content with the adopted mark
  (same filename, so Header/AuthModal/LegalPage inherit it unchanged)
- Add favicon set, apple-touch-icon, og-image; index.html head gets
  icon links, theme-color, meta description, og/twitter tags
- Re-point the live --vp-* viewer tokens (accent/font/mono) at brand
  tokens; delete the dead palette block (zero var() usages, verified)
- Remove orphaned assets: old logo pngs, jhu_logo.jpg, vite/react
  scaffold svgs, unused Inter TTFs
Replace the JHU Heritage Blue theme (#002D72/#00399a/#68ACE5) and
stray blue accents (#2563eb family) across header, landing, auth,
settings, upload-adjacent chrome, homepage library, compare pages,
team and legal pages. Primary fills, active states, focus borders and
toggles use ink (#0F172A, hover ink-2); orange appears only as accent:
links and small orange text (accent-deep), stat values, decorative
bars, and dark-surface accents (vivid/tint). Fonts switch from Space
Grotesk/JetBrains Mono/Inter literals to the IBM Plex stacks; weights
above 600 normalized to shipped subsets. Hot files under active PRs
(UploadPage, VisualizationPage, annotation/segmentation tools) are
deliberately untouched and tracked as deferred in BRANDING.md.
- scripts/brand-guard.mjs: dependency-free checker banning off-brand
  fonts/colors/marks with an explicit per-rule allowlist of deferred
  files; verifies index.html identity metadata
- .github/workflows/brand-guard.yml: runs the guard on PRs and main
  (advisory until made a required check)
- src/test/brand.test.ts: locks logo, tokens, head metadata and the
  viewer accent seam via the existing blocking vitest step
- BRANDING.md: token roles, typography, logo and naming rules plus
  the deferred-surface register
New SiteFooter component (company line + partnership link, brand
tokens, mono pointer) mounted on the landing page, dataset library,
and team page.
Fixes from a pre-merge safety review of the brand alignment:

- Fonts: the brand pack's IBM Plex Sans 500/600 woff2 exports contained
  the 400 face (identical checksums); regenerated genuine Medium and
  SemiBold subsets from the pack TTFs (weights verified via fontTools).
- Deterministic typography for deferred surfaces: alias @font-face maps
  'Space Grotesk'/'JetBrains Mono' onto the self-hosted Plex faces, so
  viewer chrome no longer depends on which page's CSS loaded first.
- brand-guard.mjs: path handling via fileURLToPath (spaces/Windows),
  friendly error outside a git checkout, rename-tolerant allowlists,
  regex coverage for JSX-escaped font quotes, camelCase fontFamily
  inline styles, and rgb()-form JHU blue; pre-registered the in-flight
  SharePatientCard.tsx so that branch's future PR stays green.
- brand-guard.yml: run on all PRs (matching ci.yml convention), least-
  privilege permissions, concurrency group.
- Contrast: legal-page links use the darker accent on the off-white
  ground (accent-deep is below AA there); footer link underlined at
  rest (use-of-color); progress track recolored from JHU-blue rgba to
  an ink tint.
- Landing page scrolls on short viewports instead of clipping the hero.
- Stale pre-brand comments rewritten (UploadPage.css header, AuthModal,
  AuthButton); BRANDING.md documents guard scope, the paper-2 contrast
  caveat, and the alias shim.
@andyy-yang andyy-yang changed the title Style: BodyMaps brand alignment for home.html landing + viewer accent Brand alignment: BodyMaps tokens, IBM Plex, identity assets, and a brand guard Aug 13, 2026
@andyy-yang
andyy-yang merged commit a84b36f into BodyMaps:main Aug 13, 2026
9 checks passed
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.

1 participant