From 5e9b59f957f4e68e22a51574eba81dc77b40ec4d Mon Sep 17 00:00:00 2001 From: Fable Integrator Date: Thu, 9 Jul 2026 23:58:03 -0400 Subject: [PATCH 1/3] Mobile pass M0: perf killers, overflow root-cause, logo fix, accent-card retirement MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Perf (phone-class GPUs): - FairwayTopBar: opaque bg-surface at 0.3s, no remount-per-open; desktop rail gated behind useMediaQuery - Route transitions single-sourced: baseball template.tsx owns the fade, AppShell RouteTransition disabled (mirrors golf) - LazyMotion for real: async domAnimation loader (src/lib/motion/ load-features.ts), ~59 call sites off the synchronous import - React.memo actually effective: shell element props (brand, sidebarFooter, topBarActions/teamSwitcher) memoized in both product shells - use-unread-count realtime subscription per-user filtered - round-review First Load JS split (5.2MB -> dynamic segments) UI: - SectionMasthead overflow root-cause fixed (shrink-0 actions + unconstrained h1) — un-breaks ~65 baseball pages at 390px - Broken signup logo fixed; HelmMark extracted (src/components/brand/), 5 call sites - Accent-stripe cards retired both products -> dateline-rule idiom (28x2px tone rule); Card variant="stat" removed - Bridge sessions table wraps on mobile Gates: tsc 0, eslint 0, unit 455 files / 4616 passed, production build clean. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01J2E46URHkhCnEQSYDtZLJX --- src/app/about/page.tsx | 5 +- src/app/admin/_components/AdminShell.tsx | 67 +++++++------ src/app/admin/_components/SessionsPanel.tsx | 4 +- src/app/admin/_components/TeamHealthTable.tsx | 4 +- src/app/admin/_motion-provider.tsx | 5 +- src/app/admin/activity/ActivityFeed.tsx | 9 +- src/app/admin/baseball/page.tsx | 13 ++- src/app/admin/golf/page.tsx | 10 +- src/app/admin/golf/tracer/page.tsx | 14 ++- src/app/admin/jobs/page.tsx | 10 +- src/app/admin/teams/[id]/RosterTable.tsx | 4 +- src/app/admin/teams/[id]/page.tsx | 19 ++-- src/app/admin/users/[id]/EngagementPanel.tsx | 4 +- .../(dashboard)/BaseballFairwayShell.tsx | 30 +++++- .../(dashboard)/_components/hub-sub-nav.tsx | 5 +- .../dashboard/dev-plan/DevPlanClient.tsx | 3 +- .../(dashboard)/dashboard/template.tsx | 5 +- .../(onboarding)/coach-onboarding/page.tsx | 29 +++--- src/app/baseball/(onboarding)/player/page.tsx | 32 +++---- .../(player-dashboard)/player/template.tsx | 5 +- src/app/baseball/(public)/team/[id]/page.tsx | 10 +- src/app/golf/(auth)/demo/page.tsx | 5 +- src/app/golf/(auth)/forgot-password/page.tsx | 5 +- src/app/golf/(auth)/login/page.tsx | 19 ++-- src/app/golf/(auth)/reset-password/page.tsx | 5 +- src/app/golf/(auth)/signup/page.tsx | 7 +- src/app/golf/(auth)/welcome/page.tsx | 5 +- .../(dashboard)/FairwayDashboardShell.tsx | 49 +++++++--- .../dashboard/rounds/[id]/review/page.tsx | 44 ++++++++- .../continue/[id]/continue-round-client.tsx | 18 +++- .../dashboard/rounds/new/new-round-client.tsx | 18 +++- src/app/golf/(onboarding)/coach/page.tsx | 5 +- src/app/golf/(onboarding)/player/page.tsx | 5 +- src/app/golf/admin/_motion-provider.tsx | 5 +- .../golf/admin/components/AdminStatCard.tsx | 13 +-- .../golf/admin/components/SessionHeatmap.tsx | 7 +- src/app/golf/admin/components/StatCardV2.tsx | 6 -- .../admin/components/TeamUserDirectory.tsx | 2 +- .../tracer/TracerRoundInspector.tsx | 2 +- .../admin/crm/components/CRMDashboard.tsx | 5 +- .../admin/crm/components/CalendarView.tsx | 11 --- .../golf/admin/crm/components/CoachTable.tsx | 4 +- .../admin/crm/components/resend/KPIGrid.tsx | 15 ++- .../components/resend/ResendActivityView.tsx | 4 +- .../join/[code]/golf-join-team-client.tsx | 5 +- src/app/golf/join/page.tsx | 5 +- src/app/products/page.tsx | 5 +- src/components/auth/baseball-auth-shell.tsx | 47 +++++----- src/components/baseball/NotificationBell.tsx | 21 ++++- .../announcements/AnnouncementsCoachView.tsx | 41 ++++---- .../announcements/AnnouncementsPlayerView.tsx | 36 ++++--- .../baseball/announcements/PlayerSelector.tsx | 2 +- .../CoachPlayerDailyContractPanel.tsx | 5 +- .../command-center/DailyBriefPanel.tsx | 5 +- .../baseball/command-center/RiskFeedStrip.tsx | 5 +- .../baseball/daily-contract/DailyContract.tsx | 5 +- .../import-center/ImportWizardClient.tsx | 6 +- .../living-annual/SectionMasthead.tsx | 10 +- .../baseball/passport/PlayerPassportCard.tsx | 5 +- .../baseball/passport/ScoutPacketManager.tsx | 5 +- .../baseball/passport/ScoutPacketView.tsx | 5 +- .../baseball/performance/PlayerLiftToday.tsx | 15 +-- .../performance/lift-canvas/ExerciseBin.tsx | 18 ++-- .../performance/lift-canvas/SessionBlock.tsx | 15 ++- .../player-profile/PlayerInsightsPanel.tsx | 5 +- .../player-profile/PlayerNotesSection.tsx | 5 +- .../player-profile/ProfileTimeline.tsx | 5 +- .../position-planner/PositionPlayerPill.tsx | 6 +- .../PracticeEffectivenessClient.tsx | 5 +- .../practice-player/PlayerPracticeClient.tsx | 5 +- .../settings/PhilosophySettingsClient.tsx | 5 +- .../settings/ProgramSettingsClient.tsx | 7 +- .../settings/SeasonSettingsClient.tsx | 5 +- .../baseball/source-trust/SourceDrawer.tsx | 7 +- .../baseball/staff/StaffSettingsClient.tsx | 5 +- .../baseball/stat-visuals/StatVisualFrame.tsx | 5 +- .../stats-center/StatsCenterClient.tsx | 7 +- src/components/baseball/video/VideoCard.tsx | 7 +- .../baseball/video/VideoLibraryClient.tsx | 11 ++- src/components/brand/HelmMark.tsx | 93 +++++++++++++++++++ src/components/fairway/app-shell/AppShell.tsx | 67 +++++++++---- .../fairway/app-shell/FairwayBottomNav.tsx | 16 +++- .../fairway/app-shell/FairwaySidebar.tsx | 11 ++- .../fairway/app-shell/FairwayTopBar.tsx | 24 +++-- .../messages/MessageConversationRail.tsx | 21 ++--- .../player-game/FairwayMyGameProfile.tsx | 14 ++- .../rounds-new/FairwayRoundSubmitOverlay.tsx | 5 +- .../rounds-new/FairwayRoundSummarySheet.tsx | 5 +- .../golf/calendar/ConflictWarning.tsx | 2 +- src/components/golf/calendar/EventCard.tsx | 10 +- .../golf/calendar/PlayerRSVPCard.tsx | 5 +- .../golf/calendar/PremiumEventBlock.tsx | 13 ++- src/components/golf/calendar/WeekView.tsx | 13 +-- .../coachhelm/insights/DiagnosisPanel.tsx | 8 +- .../coachhelm/insights/DiagnosisSheet.tsx | 25 +++-- .../coachhelm/insights/InsightCallout.tsx | 32 +++++++ .../round-review/RoundIntelligence.tsx | 8 +- .../golf/coachhelm/v3/HoleShotPath/index.tsx | 5 +- .../golf/coachhelm/v3/PuttHeatmap/index.tsx | 5 +- src/components/golf/layout/AnimatedPage.tsx | 5 +- .../golf/rounds/RoundLibraryClient.tsx | 5 +- src/components/landing/Hero.tsx | 5 +- src/components/landing/MobileNav.tsx | 5 +- .../lifting/athletes/AthleteRosterClient.tsx | 2 +- .../lifting/players/PlayerLiftHomeClient.tsx | 11 ++- src/components/ui/card.tsx | 20 +++- src/hooks/use-unread-count.ts | 32 ++++++- src/lib/calendar/event-styles.ts | 26 +++--- src/lib/calendar/premium-utils.ts | 14 +++ src/lib/motion/load-features.ts | 16 ++++ src/lib/types/calendar.ts | 3 +- src/styles/calendar-tokens.css | 2 +- 112 files changed, 938 insertions(+), 487 deletions(-) create mode 100644 src/components/brand/HelmMark.tsx create mode 100644 src/components/golf/coachhelm/insights/InsightCallout.tsx create mode 100644 src/lib/motion/load-features.ts diff --git a/src/app/about/page.tsx b/src/app/about/page.tsx index 73040dfb9..204cc347e 100644 --- a/src/app/about/page.tsx +++ b/src/app/about/page.tsx @@ -2,7 +2,8 @@ import Link from 'next/link'; import Image from 'next/image'; -import { m, LazyMotion, domAnimation, useReducedMotion } from 'framer-motion'; +import { m, LazyMotion, useReducedMotion } from 'framer-motion'; +import { loadFeatures } from '@/lib/motion/load-features'; import { Navigation } from '@/components/landing/Navigation'; import { Footer } from '@/components/landing/Footer'; import { Button } from '@/components/ui/button'; @@ -61,7 +62,7 @@ const staggerContainer = { export default function AboutPage() { const prefersReducedMotion = useReducedMotion(); return ( - +
Skip to main content diff --git a/src/app/admin/_components/AdminShell.tsx b/src/app/admin/_components/AdminShell.tsx index c74c058ac..ae98dd76a 100644 --- a/src/app/admin/_components/AdminShell.tsx +++ b/src/app/admin/_components/AdminShell.tsx @@ -205,43 +205,56 @@ export function AdminShell({ [], ); + // Stable element/object identities (perf packet [shell-render-hygiene]): + // inline literals here are fresh objects every render (e.g. each ⌘K + // open/close), defeating the React.memo on FairwaySidebar/FairwayTopBar. + const brand = useMemo( + () => ( + + + HB + + + Helm Bridge + + + ), + [], + ); + const shellUser = useMemo(() => ({ name: 'Super admin', teamName: email }), [email]); + const topBarActions = useMemo( + () => ( +
+ + prod + + +
+ ), + [router], + ); + return (
- - HB - - - Helm Bridge - - - } - user={{ name: 'Super admin', teamName: email }} + brand={brand} + user={shellUser} pathname={pathname} linkComponent={Link} breadcrumbs={breadcrumbs} onSearchOpen={() => setCommandOpen(true)} searchPlaceholder="Jump to command, incident, user…" - topBarActions={ -
- - prod - - -
- } + topBarActions={topBarActions} > {children}
diff --git a/src/app/admin/_components/SessionsPanel.tsx b/src/app/admin/_components/SessionsPanel.tsx index f8c0ae948..401af4627 100644 --- a/src/app/admin/_components/SessionsPanel.tsx +++ b/src/app/admin/_components/SessionsPanel.tsx @@ -21,8 +21,8 @@ export function SessionsPanel({ sessions }: { sessions: SessionRow[] }) {