Skip to content

feat(landing): M2/M5/M6/M7 editorial moments — sage & cream - #721

Merged
njrini99-code merged 14 commits into
batch/baseball-fixesfrom
feat/entry-world-editorial
Jul 2, 2026
Merged

feat(landing): M2/M5/M6/M7 editorial moments — sage & cream#721
njrini99-code merged 14 commits into
batch/baseball-fixesfrom
feat/entry-world-editorial

Conversation

@njrini99-code

Copy link
Copy Markdown
Owner

LAYOUT BRIEF

  • Page's one job: carry the visitor calmly from M1's hero exit through the "what is Helm," "the intelligence is honest," "the player matters too," and "we don't fake it" beats before M8's final ask.
  • Primary action: none of these four sections have a CTA — they build belief so M8's dual CTA converts; M2's serif statement is the read-first anchor.
  • Visual hierarchy: serif Fraunces headline > sage-ink ledger/vignette labels > sage-deep eyebrows > tinted sage-ink body copy > brass hairlines as the quietest structural element.
  • Scan pattern: vertical center-column read for M2/M5/M7 (headline → detail), a 3-up grid scan for M6's vignettes.
  • What got demoted: no cards, no drop shadows, no white rectangles — ledger lines and glass vignettes replace card chrome; kelly green is demoted everywhere except inside M5's literal product-signal replica.

This lane's history (context for reviewers)

This lane was killed twice. On resume: preserved the second builder's uncommitted sage-era work as wip: sage partial work (builder killed mid-build), then audited it against the AMENDED spec line-by-line. That inherited work was already strong — correctly recolored to sage/cream, correct reduced-motion pattern (useReducedMotion + transition={reduced ? {duration:0} : {...}}), correct MaskedReveal/AnimatedNumber usage. This PR's diff is the remaining fix-up on top of that inheritance:

  • M5: the confidence-bar fill animated width (0%82%), which forces layout reflow every frame. Switched to a GPU-safe scaleX transform (transform-origin: left) per the transform/opacity-only motion rule — pixel-identical result, compositor-only cost.
  • M2 / M6 / M7: three spots (M2's ledger detail, M6's three vignette copy lines, M7's body paragraph + stat caption) and one eyebrow (M7's "Built by players") had fallen back to the generic warm-neutral Tailwind scale (text-warm-500/600) instead of the sage-ink tokens the palette table calls out ("sage-ink — dark bands + ALL body/display ink"). M5, built in the same PR, had already established the correct pattern (rgba(var(--fl-sage-ink-rgb), n) for secondary/tinted text, var(--fl-sage-deep) for eyebrows) — recolored the other three moments to match so all four read as one system.

Owned files (per CONTRACTS.md)

  • src/components/marketing/first-light/moments/M2Clarity.tsx
  • src/components/marketing/first-light/moments/M5Intelligence.tsx
  • src/components/marketing/first-light/moments/M6ForThePlayer.tsx
  • src/components/marketing/first-light/moments/M7Honesty.tsx

Design-bar checklist

  • Sage & cream only — zero hardcoded #143527/#16A34A; kelly appears ONLY inside M5's signal-card replica (product content, per amendment)
  • Daylight mood — no dark/moody surfaces; M5's gradient only reaches sage-ink at its far edge, majority of the section (and the signal card itself) sits in the light cream→sage-mist range
  • Fraunces for display, Space Grotesk (font-annual) for UI/numerals — no Inter/system-sans, no italic accent words
  • No cards-on-cream — M2 is explicitly hairline-ruled ledger lines, M6/M5 use fl-glass-2 inset glass, never a stark white rectangle
  • Motion: transform/opacity only (fixed M5's width→scaleX); house easing [0.16,1,0.3,1] throughout; useReducedMotion() + prop-only transition={reduced ? {duration:0}: {...}} on every reveal
  • Reveals are entry-only (whileInView, once: true) — no PinnedScrub/scrub-linking in this lane, sections stay calm per the brief
  • ≤2 fl-glass-* layers per viewport in every section
  • Cross-moment consistency — sage-ink tinted text + sage-deep eyebrows used identically across all four files

Gate results

  • npx tsc --noEmit → 0 errors
  • npx eslint <4 changed files> → 0 errors, 0 warnings (exit 0)

Visual proof frames deferred — this session is browser-free (machine stability); frames will be captured in a later pass.

Fable Integrator and others added 6 commits July 2, 2026 12:27
…ll primitives

Builds the shared First Light landing scaffold (docs/LANDING_ENTRY_WORLD_DESIGN.md)
every downstream lane composes on: palette + 3-grade glass grammar, Lenis
scroll root, scroll-progress/pinned-scrub/masked-reveal primitives, and nine
M1–M9 moment stubs wired into a coherent draft page.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CHFRrZkRsAHWTwvxhySkfe
…ily (Nick 2026-07-02)

Repoints --fl-pine -> #2E3A2C (sage-ink) and --fl-green -> #5C6E58
(sage-deep) so in-flight lane work recolors automatically, and adds
first-class --fl-cream/--fl-cream-high/--fl-sage-mist/--fl-sage/
--fl-sage-deep/--fl-sage-ink tokens (+ rgb twins) per the SAGE & CREAM
amendment in docs/LANDING_ENTRY_WORLD_DESIGN.md. Kelly #16A34A is
demoted to product-only (real screenshots + M5 signal-card replica) —
never on landing/auth chrome. Updates CONTRACTS.md's palette section to
the v2 table, the pine->sage-ink / kelly->sage-deep read-mapping, and
the daylight-mood sentence.

Swept the foundation's shared files (fonts.ts, lib/, scroll/*, index.ts,
page.tsx) for hardcoded #143527/#16A34A: none found, nothing to move.
One hardcoded #143527 remains in moments/M3ProductCinema.tsx (the
landing-cinema lane's owned stub, out of this lane's ownership) —
left in place for that lane to pick up when it replaces the stub.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RVnwXMnsgREVfjpGSAJPvT
Inherited sage-recolored partial work from the second builder (killed
mid-build) already satisfied the amendment's letter and spirit — M2's
ledger, M5's signal-card replica, M6's player vignettes, and M7's
honesty band were all built against the sage/cream tokens with correct
reduced-motion handling. This pass closes the remaining gaps:

- M5's confidence-bar fill animated `width` (layout reflow every frame);
  switched to a GPU-safe `scaleX` transform (transform-origin left) per
  the transform/opacity-only motion rule — visually identical, cheaper.
- M2/M6/M7 fell back to the generic warm-neutral Tailwind scale for
  secondary/body text and one eyebrow, breaking from M5's own precedent
  (rgba(--fl-sage-ink-rgb, n)) in the same PR. Recolored all instances
  to sage-ink tints and sage-deep eyebrows so the four moments read as
  one system.

Visual proof frames deferred — this session is browser-free (machine
stability); frames will be captured in a later pass.
@greptile-apps

greptile-apps Bot commented Jul 2, 2026

Copy link
Copy Markdown

PR title or description contains an excluded keyword.

@coderabbitai

coderabbitai Bot commented Jul 2, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

🗂️ Base branches to auto review (3)
  • main
  • develop
  • release/*

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 408607e9-e1b7-47ce-b962-62b2aef1ef6f

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/entry-world-editorial
  • 🛠️ helm safety pass
  • 🛠️ dashboard ux pass
  • 🛠️ rls test pass

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

@vercel

vercel Bot commented Jul 2, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
helmv3 Ignored Ignored Jul 2, 2026 8:44pm

Request Review

@qodo-code-review

Copy link
Copy Markdown

PR Summary by Qodo

First Light landing scaffold + sage/cream moments with Lenis + motion primitives

✨ Enhancement 📝 Documentation ⚙️ Configuration changes 🕐 40+ Minutes

Grey Divider

AI Description

• Swap landing page composition to First Light M1–M9 sequence under a single Lenis root.
• Introduce shared sage/cream palette + 3-grade glass CSS grammar and supporting utilities.
• Add scroll/motion primitives (PinnedScrub, MaskedReveal, scroll progress) with reduced-motion
 safety.
Diagram

graph TD
  A["src/app/page.tsx (Landing)"] --> B["LenisRoot"] --> C["M1–M9 moments"]
  C --> D["first-light.css (tokens + glass)"]
  C --> E["photoLayerStyle"]
  C --> F["Scroll primitives: PinnedScrub / MaskedReveal"] --> G["useScrollProgress + usePrefersReducedMotion"]
  B --> H{{"Lenis + Framer Motion"}}
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Use framer-motion useScroll/useTransform directly (no custom hook)
  • ➕ Less bespoke code to maintain
  • ➕ Keeps behavior aligned with upstream framer-motion APIs
  • ➖ PR notes a real freeze bug when Motion accelerates scroll timelines across component boundaries
  • ➖ Harder to guarantee consistent behavior under Lenis + render-prop composition (PinnedScrub)
2. Centralize reduced-motion via MotionConfig reducedMotion="user" at the root
  • ➕ Simplifies per-component reduced-motion checks
  • ➕ One consistent policy for whileInView transitions
  • ➖ Can reintroduce hydration mismatches if reduced-motion is resolved synchronously on first client render
  • ➖ Less explicit control over which components structurally branch vs. only tweak transition props
3. CSS ScrollTimeline/ViewTimeline for scrubbed sequences (where supported)
  • ➕ Potentially very performant; browser-native scroll linking
  • ➕ Reduces JS scroll listeners
  • ➖ Cross-browser support gaps and polyfill complexity
  • ➖ Harder to integrate with Lenis and existing MotionValue-based composition

Recommendation: Keep the PR’s approach: a single LenisRoot provider plus custom useScrollProgress and SSR-safe usePrefersReducedMotion. Given the documented Motion v12 accelerated-timeline edge case and the need to pass progress through component boundaries (PinnedScrub render-prop), the hand-rolled progress calculation is a pragmatic reliability tradeoff. Revisit useScroll only after reproducing and validating that the upstream issue is fixed in a future framer-motion upgrade.

Files changed (21) +2242 / -10

Enhancement (10) +1126 / -9
page.tsxCompose landing as First Light M1–M9 under LenisRoot +35/-9

Compose landing as First Light M1–M9 under LenisRoot

• Replaces the legacy landing Hero/Footer/SmoothScroll composition with the First Light moment sequence (M1–M9) wrapped in LenisRoot. Adds direct import of first-light.css and updates the main container to use overflow-x-clip with an inline background token to preserve sticky behavior.

src/app/page.tsx

M1Hero.tsxImplement M1 hero with photo background, nav pill, and reveals +151/-0

Implement M1 hero with photo background, nav pill, and reveals

• Adds the M1 Hero section with graded photo fallback, grain overlay, glass nav pill, and headline/body/CTA reveals. Uses scroll progress to subtly scale the background photo and fade content for a calm exit into the next moments.

src/components/marketing/first-light/moments/M1Hero.tsx

M2Clarity.tsxImplement M2 editorial clarity ledger section with MaskedReveal +105/-0

Implement M2 editorial clarity ledger section with MaskedReveal

• Adds a cream editorial section anchored by a serif MaskedReveal headline and a three-row ledger-style list. Uses framer-motion whileInView transitions with reduced-motion prop-only disabling for the row entrances.

src/components/marketing/first-light/moments/M2Clarity.tsx

M3ProductCinema.tsxImplement M3 pinned scrub product cinema sequence +184/-0

Implement M3 pinned scrub product cinema sequence

• Adds the main scroll set piece using PinnedScrub: a glass desktop frame with three scrubbed placeholder screens and captions, plus a phone frame that arcs in mid-scrub. Uses MotionValues and transforms for scroll-linked motion and relies on PinnedScrub’s reduced-motion fallback behavior.

src/components/marketing/first-light/moments/M3ProductCinema.tsx

M4TwoFields.tsxImplement M4 two-field portal diptych with photo fallbacks +94/-0

Implement M4 two-field portal diptych with photo fallbacks

• Adds a two-up (stacked on mobile) portal section for GolfHelm and BaseballHelm using photoLayerStyle fallbacks and fl-glass-2 cards. Includes hover-based dim/brighten behavior via framer-motion animate for desktop interaction.

src/components/marketing/first-light/moments/M4TwoFields.tsx

M5Intelligence.tsxImplement M5 intelligence signal card with animated number and scaleX fill +161/-0

Implement M5 intelligence signal card with animated number and scaleX fill

• Adds the editorial signal moment: a glass insight card showcasing source/limitation transparency and product-like confidence styling. Uses AnimatedNumber gated by in-view state and animates the confidence bar via scaleX (transform-origin left) with reduced-motion-safe transitions.

src/components/marketing/first-light/moments/M5Intelligence.tsx

M6ForThePlayer.tsxImplement M6 player-focused vignette grid +133/-0

Implement M6 player-focused vignette grid

• Adds a light sage/cream gradient section with three fl-glass-2 vignettes, each including a small UI-like detail (completeness bar, check-in line, readiness dot). Uses entry-only whileInView reveals with reduced-motion transition disabling.

src/components/marketing/first-light/moments/M6ForThePlayer.tsx

M7Honesty.tsxImplement M7 honesty band with in-view triggered stats +87/-0

Implement M7 honesty band with in-view triggered stats

• Adds the honesty section with founder statement copy and two AnimatedNumber stats that only roll once the stats row enters the viewport. Uses useInView to gate the value changes and applies reduced-motion-safe transition configuration for reveal animations.

src/components/marketing/first-light/moments/M7Honesty.tsx

M8FinalCTA.tsxImplement M8 final CTA with mist photo fallback and dual CTAs +62/-0

Implement M8 final CTA with mist photo fallback and dual CTAs

• Adds the final call-to-action moment with a photoLayerStyle background, grain overlay, and a centered serif ask. Renders the two CTAs linking to /golf/demo and /golf/join with entry-only motion.

src/components/marketing/first-light/moments/M8FinalCTA.tsx

M9Footer.tsxImplement M9 footer with real product/account links +114/-0

Implement M9 footer with real product/account links

• Adds a server-rendered footer with links for both sports, both logins/signups, and legal pages. Ensures the landing footer routes resolve and matches the First Light palette styling.

src/components/marketing/first-light/moments/M9Footer.tsx

Documentation (1) +290 / -0
CONTRACTS.mdAdd First Light build contracts and ownership map +290/-0

Add First Light build contracts and ownership map

• Introduces a detailed contract doc defining file ownership, palette/token rules, glass grammar, reduced-motion patterns, scroll primitives usage, and asset contracts. Serves as the integration guide for downstream lanes replacing individual moments.

src/components/marketing/first-light/CONTRACTS.md

Other (10) +826 / -1
next-env.d.tsUpdate Next route types import path for dev builds +1/-1

Update Next route types import path for dev builds

• Switches the generated Next.js routes type reference from ".next/types" to ".next/dev/types". This keeps TypeScript aligned with the current Next build output structure.

next-env.d.ts

first-light.cssAdd sage/cream tokens, glass grades, grain, and shared utilities +222/-0

Add sage/cream tokens, glass grades, grain, and shared utilities

• Defines the First Light palette as CSS custom properties (including legacy alias repoints), plus a 3-grade glass system with grain/edge-light and fallback behavior. Adds shared utilities like brass hairlines and line masks used by MaskedReveal and moments.

src/components/marketing/first-light/first-light.css

fonts.tsAdd dedicated Fraunces font loader for First Light +25/-0

Add dedicated Fraunces font loader for First Light

• Creates a landing-specific next/font Fraunces configuration with multiple weights and no italic style. Exposes the font via a CSS variable and module export for consistent serif usage across moments.

src/components/marketing/first-light/fonts.ts

index.tsAdd First Light barrel exports for shared primitives and moments +43/-0

Add First Light barrel exports for shared primitives and moments

• Introduces an index barrel exporting fonts, scroll primitives, shared helpers, and all M1–M9 moment components and prop types. Establishes stable import/contract points for the landing composition.

src/components/marketing/first-light/index.ts

photoBg.tsAdd photo-over-gradient background helper +37/-0

Add photo-over-gradient background helper

• Adds photoLayerStyle to layer a fallback gradient beneath a photo URL in CSS background-image, preventing broken-image rendering when assets are missing. Used by photo-backed moments (hero, portals, final CTA).

src/components/marketing/first-light/lib/photoBg.ts

LenisRoot.tsxAdd LenisRoot provider with LazyMotion and conditional Lenis enablement +72/-0

Add LenisRoot provider with LazyMotion and conditional Lenis enablement

• Creates the landing root wrapper that mounts the single Lenis instance on capable devices and falls back to native scroll for reduced-motion and coarse pointers. Also provides the LazyMotion domAnimation bundle in strict mode for consistent use of m.* components across moments.

src/components/marketing/first-light/scroll/LenisRoot.tsx

MaskedReveal.tsxAdd reduced-motion-safe line-mask reveal primitive +174/-0

Add reduced-motion-safe line-mask reveal primitive

• Implements a line-by-line serif reveal that works either as an in-view one-shot or scrub-linked via a progress MotionValue. Uses an SSR-safe reduced-motion hook to avoid hydration mismatches when structurally branching between animated and static render paths.

src/components/marketing/first-light/scroll/MaskedReveal.tsx

PinnedScrub.tsxAdd pinned scrub primitive with reduced-motion static fallback +67/-0

Add pinned scrub primitive with reduced-motion static fallback

• Implements a sticky inner viewport within a tall spacer and passes a 0→1 MotionValue to children for transform-only scroll effects. Under prefers-reduced-motion it disables pinning and supplies a static progress=1 MotionValue for a coherent final-frame rendering.

src/components/marketing/first-light/scroll/PinnedScrub.tsx

usePrefersReducedMotion.tsAdd SSR-safe prefers-reduced-motion hook for structural branching +47/-0

Add SSR-safe prefers-reduced-motion hook for structural branching

• Introduces a useSyncExternalStore-based reduced-motion hook that returns a stable server snapshot to prevent hydration mismatch when used to choose different JSX trees. Intended for components like MaskedReveal/PinnedScrub that structurally branch on the flag.

src/components/marketing/first-light/scroll/usePrefersReducedMotion.ts

useScrollProgress.tsAdd custom scroll progress hook compatible with Lenis and component boundaries +138/-0

Add custom scroll progress hook compatible with Lenis and component boundaries

• Implements a hand-rolled scroll progress calculator with configurable offset windows and optional spring smoothing. Avoids a documented framer-motion accelerated timeline edge case that can freeze MotionValue updates when progress is passed across component boundaries.

src/components/marketing/first-light/scroll/useScrollProgress.ts

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 95e5ba94e5

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

const y = useTransform(
progress,
[start, enterEnd, exitStart, end],
['28%', '0%', '0%', '-28%'],

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Keep the final cinema panel centered

When PinnedScrub renders the reduced-motion branch it passes progress = 1, and the opacity mapping keeps the last screen visible at that value. This '-28%' end translation still applies to that visible last screen, so reduced-motion users see the Decision Room panel shifted upward instead of the documented final landed frame; the same off-center state appears at the bottom of the scrub. Special-case the last panel's end transform to stay at 0% or stop keeping it visible while it exits.

Useful? React with 👍 / 👎.

@qodo-code-review

qodo-code-review Bot commented Jul 2, 2026

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (3) 📘 Rule violations (2) 📜 Skill insights (0)

Context used
✅ Compliance rules (platform): 93 rules

Grey Divider


Action required

1. Dev-only routes type import 🐞 Bug ☼ Reliability
Description
next-env.d.ts imports ./.next/dev/types/routes.d.ts, a generated dev artifact that won’t exist
in clean checkouts and may not exist after next build, causing tsc --noEmit (used by `npm run
typecheck`) to fail.
Code

next-env.d.ts[3]

+import "./.next/dev/types/routes.d.ts";
Relevance

⭐⭐⭐ High

Team favors missing-artifact hard failures; accepted similar “missing generated artifact” CI checks
in PR420.

PR-#420

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The codebase runs tsc --noEmit directly, while .next/ is not committed; importing a
.next/dev/... file will fail when that generated file isn’t present (clean CI, fresh clone, or
build outputs that don’t create the dev path).

next-env.d.ts[1-4]
package.json[6-36]
.gitignore[19-22]
tsconfig.json[58-65]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`next-env.d.ts` currently imports a generated file under `./.next/dev/types/`.

Because `.next/` is ignored and not guaranteed to exist (and build output paths differ between dev and build), this import can break `npm run typecheck` in CI/fresh checkouts.

## Issue Context
- The repo’s `typecheck` script is `tsc --noEmit` (no implicit Next build step).
- `.next/` is gitignored, so the imported file is not present reliably.

## Fix Focus Areas
- next-env.d.ts[1-6]
- tsconfig.json[58-65]
- package.json[6-36]
- .gitignore[19-22]

## Suggested fix
- Remove the `import "./.next/dev/types/routes.d.ts";` line from `next-env.d.ts`.
- If typed routes are still desired, include them via `tsconfig.json` patterns that do **not** hard-fail when `.next/` is missing (e.g., include `.next/**/types/**/*.d.ts`), or ensure CI generates `.next` types before `tsc` runs (explicit pre-step).

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. --fl-cream not #FFFEFA 📘 Rule violation ⚙ Maintainability
Description
The new --fl-cream token is defined as #f5f1e6, but the compliance requirement specifies the
designated cream background token must be #FFFEFA. This breaks the single source-of-truth
requirement for the cream background color.
Code

src/components/marketing/first-light/first-light.css[R62-66]

+  /* ── Sage & cream — first-class tokens (2026-07-02 respec) ──────────── */
+  /* Cream field — alias of --fl-ecru, same value, first-class name. */
+  --fl-cream: #f5f1e6;
+  --fl-cream-rgb: 245, 241, 230;
+  /* Cream high — glass highlights, replaces white. */
Relevance

⭐⭐ Medium

No prior enforcement of exact #FFFEFA; closest token/hex feedback in PR304 was undetermined.

PR-#304

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The rule requires the cream background token/variable to be #FFFEFA. The PR defines --fl-cream
as #f5f1e6, which does not match the required cream value.

Rule 1519249: Use the designated cream background color token
src/components/marketing/first-light/first-light.css[62-66]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The cream background token does not match the required value.

## Issue Context
Compliance requires that the designated cream background token/variable be defined once and have the exact value `#FFFEFA`.

## Fix Focus Areas
- src/components/marketing/first-light/first-light.css[62-66]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


3. fl-glass-2 missing required utilities 📘 Rule violation ⚙ Maintainability
Description
New glass-effect elements use the custom fl-glass-2 class without including the required utility
set (bg-white/70, backdrop-blur-xl, border-white/20, rounded-2xl). This violates the
standardized glass-effect class requirement and can lead to inconsistent styling across the
codebase.
Code

src/components/marketing/first-light/moments/M5Intelligence.tsx[R67-74]

+      <m.div
+        ref={cardRef}
+        initial={{ opacity: 0, y: 20 }}
+        whileInView={{ opacity: 1, y: 0 }}
+        viewport={{ once: true, margin: '-15%' }}
+        transition={reduced ? { duration: 0 } : { duration: 0.6, ease: [0.16, 1, 0.3, 1] }}
+        className="fl-glass-2 relative z-10 mx-auto mt-12 max-w-xl overflow-hidden rounded-2xl"
+      >
Relevance

⭐⭐ Medium

No evidence enforcing specific glass utility bundle vs custom class; similar styling-token feedback
undetermined.

PR-#304

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The compliance rule requires the standardized glass-effect utility classes to be present on
glass-effect elements. The added landing components instead use fl-glass-2 and omit the required
utilities in their className.

Rule 1519253: Enforce standardized glass-effect utility classes
src/components/marketing/first-light/moments/M5Intelligence.tsx[67-74]
src/components/marketing/first-light/moments/M4TwoFields.tsx[76-76]
src/components/marketing/first-light/moments/M6ForThePlayer.tsx[64-82]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
Glass-effect elements must include the standardized Tailwind utility set. The new landing components use `fl-glass-2` but do not include the required utilities in their `className`.

## Issue Context
Compliance requires glass-effect elements to include **all** of: `bg-white/70`, `backdrop-blur-xl`, `border-white/20`, `rounded-2xl`.

## Fix Focus Areas
- src/components/marketing/first-light/moments/M5Intelligence.tsx[67-74]
- src/components/marketing/first-light/moments/M4TwoFields.tsx[72-80]
- src/components/marketing/first-light/moments/M6ForThePlayer.tsx[64-82]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

4. Hardcoded retired palette colors 🐞 Bug ⚙ Maintainability
Description
Multiple First Light moments hardcode retired pine/kelly colors (e.g. #143527,
rgba(20,53,39,...), rgba(22,163,74,...)) and use Tailwind primary-* greens on landing CTAs,
bypassing the new --fl-* token contract and reintroducing off-spec greens.
Code

src/components/marketing/first-light/moments/M3ProductCinema.tsx[R34-39]

+const SCREENS: CinemaScreen[] = [
+  {
+    label: 'Command Center',
+    caption: 'Roster, calendar, and tasks — the whole program, one screen.',
+    tint: 'linear-gradient(155deg, #1c4632 0%, #143527 100%)',
+  },
Relevance

⭐⭐⭐ High

Design-system guardrails ban certain greens/hexes; team pushes toward tokens (PR147).

PR-#147

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The contract explicitly bans hardcoding retired pine/kelly and states kelly is product-only, but new
moments include #143527 and raw kelly/primary greens in gradients and hover states.

src/components/marketing/first-light/CONTRACTS.md[121-137]
src/components/marketing/first-light/moments/M3ProductCinema.tsx[34-50]
src/components/marketing/first-light/moments/M1Hero.tsx[29-31]
src/components/marketing/first-light/moments/M1Hero.tsx[71-87]
src/components/marketing/first-light/moments/M4TwoFields.tsx[30-46]
src/components/marketing/first-light/moments/M8FinalCTA.tsx[16-22]
src/components/marketing/first-light/moments/M8FinalCTA.tsx[44-48]
src/components/marketing/first-light/moments/M9Footer.tsx[31-37]
tailwind.config.ts[99-116]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
Several newly-added First Light moments bypass the palette contract by hardcoding old pine/kelly values and/or using Tailwind `primary-*` greens for landing chrome.

This defeats the “repointed aliases + token-only” approach and makes future palette adjustments non-global.

## Issue Context
`CONTRACTS.md` explicitly states:
- kelly (`#16A34A`) is product-only; landing/auth chrome should not use it.
- never hardcode `#143527` / `#16A34A`; always use the token vars.

## Fix Focus Areas
- src/components/marketing/first-light/moments/M3ProductCinema.tsx[34-50]
- src/components/marketing/first-light/moments/M1Hero.tsx[29-31]
- src/components/marketing/first-light/moments/M1Hero.tsx[82-86]
- src/components/marketing/first-light/moments/M4TwoFields.tsx[30-45]
- src/components/marketing/first-light/moments/M8FinalCTA.tsx[20-22]
- src/components/marketing/first-light/moments/M8FinalCTA.tsx[44-48]
- src/components/marketing/first-light/moments/M9Footer.tsx[31-37]

## Suggested fix
- Replace hardcoded pine hex/rgba in gradients with token-based equivalents, e.g. `rgba(var(--fl-sage-ink-rgb), …)` / `var(--fl-sage-ink)` / `var(--fl-sage-mist)` / `var(--fl-cream-high)`.
- Replace `hover:bg-primary-500` on landing CTAs with a First Light token-based hover (e.g. a slightly adjusted `--fl-sage-deep`-based value), so hover states don’t jump back to brand kelly greens.
- Replace footer `rgba(22,163,74,...)` glow with a token (likely `--fl-sage-deep-rgb` or brass) to keep the footer in the sage/cream system.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


5. Duplicate grain overlay mounts 🐞 Bug ➹ Performance
Description
.fl-grain is a fixed full-bleed overlay intended to be mounted once per page, but M8 adds another
instance on top of the ones already mounted in M1 and M3, increasing compositing/paint work
unnecessarily.
Code

src/components/marketing/first-light/moments/M8FinalCTA.tsx[29]

+      <div className="fl-grain" aria-hidden="true" />
Relevance

⭐⭐ Medium

No historical evidence about deduplicating fixed overlays like grain for performance.

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The contract says the fixed .fl-grain overlay should be mounted once; the CSS defines it as fixed
full-bleed, and three different moments currently render it.

src/components/marketing/first-light/CONTRACTS.md[78-80]
src/components/marketing/first-light/first-light.css[83-98]
src/components/marketing/first-light/moments/M1Hero.tsx[46-55]
src/components/marketing/first-light/moments/M3ProductCinema.tsx[52-56]
src/components/marketing/first-light/moments/M8FinalCTA.tsx[24-30]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
Multiple moments render `<div className="fl-grain" />`, but `.fl-grain` is `position: fixed` and the contract says to mount it once per page.

## Issue Context
- `.fl-grain` is a fixed, full-bleed overlay with `mix-blend-mode: overlay`.
- `CONTRACTS.md` calls out “Mount once per page”.

## Fix Focus Areas
- src/components/marketing/first-light/CONTRACTS.md[78-80]
- src/components/marketing/first-light/first-light.css[89-98]
- src/components/marketing/first-light/moments/M1Hero.tsx[48-55]
- src/components/marketing/first-light/moments/M3ProductCinema.tsx[52-56]
- src/components/marketing/first-light/moments/M8FinalCTA.tsx[24-30]
- src/app/page.tsx[57-69]

## Suggested fix
- Render a single `<div className="fl-grain" aria-hidden="true" />` at the landing page root (e.g. in `src/app/page.tsx` inside `LenisRoot` but outside individual moments), and remove per-moment instances in M1/M3/M8.
- Verify z-index layering remains correct after de-duplication.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Qodo Logo

Comment on lines +67 to +74
<m.div
ref={cardRef}
initial={{ opacity: 0, y: 20 }}
whileInView={{ opacity: 1, y: 0 }}
viewport={{ once: true, margin: '-15%' }}
transition={reduced ? { duration: 0 } : { duration: 0.6, ease: [0.16, 1, 0.3, 1] }}
className="fl-glass-2 relative z-10 mx-auto mt-12 max-w-xl overflow-hidden rounded-2xl"
>

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Action required

1. fl-glass-2 missing required utilities 📘 Rule violation ⚙ Maintainability

New glass-effect elements use the custom fl-glass-2 class without including the required utility
set (bg-white/70, backdrop-blur-xl, border-white/20, rounded-2xl). This violates the
standardized glass-effect class requirement and can lead to inconsistent styling across the
codebase.
Agent Prompt
## Issue description
Glass-effect elements must include the standardized Tailwind utility set. The new landing components use `fl-glass-2` but do not include the required utilities in their `className`.

## Issue Context
Compliance requires glass-effect elements to include **all** of: `bg-white/70`, `backdrop-blur-xl`, `border-white/20`, `rounded-2xl`.

## Fix Focus Areas
- src/components/marketing/first-light/moments/M5Intelligence.tsx[67-74]
- src/components/marketing/first-light/moments/M4TwoFields.tsx[72-80]
- src/components/marketing/first-light/moments/M6ForThePlayer.tsx[64-82]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment on lines +62 to +66
/* ── Sage & cream — first-class tokens (2026-07-02 respec) ──────────── */
/* Cream field — alias of --fl-ecru, same value, first-class name. */
--fl-cream: #f5f1e6;
--fl-cream-rgb: 245, 241, 230;
/* Cream high — glass highlights, replaces white. */

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Action required

2. --fl-cream not #fffefa 📘 Rule violation ⚙ Maintainability

The new --fl-cream token is defined as #f5f1e6, but the compliance requirement specifies the
designated cream background token must be #FFFEFA. This breaks the single source-of-truth
requirement for the cream background color.
Agent Prompt
## Issue description
The cream background token does not match the required value.

## Issue Context
Compliance requires that the designated cream background token/variable be defined once and have the exact value `#FFFEFA`.

## Fix Focus Areas
- src/components/marketing/first-light/first-light.css[62-66]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment thread next-env.d.ts
/// <reference types="next" />
/// <reference types="next/image-types/global" />
import "./.next/types/routes.d.ts";
import "./.next/dev/types/routes.d.ts";

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Action required

3. Dev-only routes type import 🐞 Bug ☼ Reliability

next-env.d.ts imports ./.next/dev/types/routes.d.ts, a generated dev artifact that won’t exist
in clean checkouts and may not exist after next build, causing tsc --noEmit (used by `npm run
typecheck`) to fail.
Agent Prompt
## Issue description
`next-env.d.ts` currently imports a generated file under `./.next/dev/types/`.

Because `.next/` is ignored and not guaranteed to exist (and build output paths differ between dev and build), this import can break `npm run typecheck` in CI/fresh checkouts.

## Issue Context
- The repo’s `typecheck` script is `tsc --noEmit` (no implicit Next build step).
- `.next/` is gitignored, so the imported file is not present reliably.

## Fix Focus Areas
- next-env.d.ts[1-6]
- tsconfig.json[58-65]
- package.json[6-36]
- .gitignore[19-22]

## Suggested fix
- Remove the `import "./.next/dev/types/routes.d.ts";` line from `next-env.d.ts`.
- If typed routes are still desired, include them via `tsconfig.json` patterns that do **not** hard-fail when `.next/` is missing (e.g., include `.next/**/types/**/*.d.ts`), or ensure CI generates `.next` types before `tsc` runs (explicit pre-step).

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment on lines +34 to +39
const SCREENS: CinemaScreen[] = [
{
label: 'Command Center',
caption: 'Roster, calendar, and tasks — the whole program, one screen.',
tint: 'linear-gradient(155deg, #1c4632 0%, #143527 100%)',
},

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Remediation recommended

4. Hardcoded retired palette colors 🐞 Bug ⚙ Maintainability

Multiple First Light moments hardcode retired pine/kelly colors (e.g. #143527,
rgba(20,53,39,...), rgba(22,163,74,...)) and use Tailwind primary-* greens on landing CTAs,
bypassing the new --fl-* token contract and reintroducing off-spec greens.
Agent Prompt
## Issue description
Several newly-added First Light moments bypass the palette contract by hardcoding old pine/kelly values and/or using Tailwind `primary-*` greens for landing chrome.

This defeats the “repointed aliases + token-only” approach and makes future palette adjustments non-global.

## Issue Context
`CONTRACTS.md` explicitly states:
- kelly (`#16A34A`) is product-only; landing/auth chrome should not use it.
- never hardcode `#143527` / `#16A34A`; always use the token vars.

## Fix Focus Areas
- src/components/marketing/first-light/moments/M3ProductCinema.tsx[34-50]
- src/components/marketing/first-light/moments/M1Hero.tsx[29-31]
- src/components/marketing/first-light/moments/M1Hero.tsx[82-86]
- src/components/marketing/first-light/moments/M4TwoFields.tsx[30-45]
- src/components/marketing/first-light/moments/M8FinalCTA.tsx[20-22]
- src/components/marketing/first-light/moments/M8FinalCTA.tsx[44-48]
- src/components/marketing/first-light/moments/M9Footer.tsx[31-37]

## Suggested fix
- Replace hardcoded pine hex/rgba in gradients with token-based equivalents, e.g. `rgba(var(--fl-sage-ink-rgb), …)` / `var(--fl-sage-ink)` / `var(--fl-sage-mist)` / `var(--fl-cream-high)`.
- Replace `hover:bg-primary-500` on landing CTAs with a First Light token-based hover (e.g. a slightly adjusted `--fl-sage-deep`-based value), so hover states don’t jump back to brand kelly greens.
- Replace footer `rgba(22,163,74,...)` glow with a token (likely `--fl-sage-deep-rgb` or brass) to keep the footer in the sage/cream system.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

className={cn('relative overflow-hidden px-6 py-28 sm:py-36', className)}
style={photoLayerStyle({ src: '/marketing/first-light/photos/mist.jpg', fallbackGradient: MIST_FALLBACK_GRADIENT })}
>
<div className="fl-grain" aria-hidden="true" />

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Remediation recommended

5. Duplicate grain overlay mounts 🐞 Bug ➹ Performance

.fl-grain is a fixed full-bleed overlay intended to be mounted once per page, but M8 adds another
instance on top of the ones already mounted in M1 and M3, increasing compositing/paint work
unnecessarily.
Agent Prompt
## Issue description
Multiple moments render `<div className="fl-grain" />`, but `.fl-grain` is `position: fixed` and the contract says to mount it once per page.

## Issue Context
- `.fl-grain` is a fixed, full-bleed overlay with `mix-blend-mode: overlay`.
- `CONTRACTS.md` calls out “Mount once per page”.

## Fix Focus Areas
- src/components/marketing/first-light/CONTRACTS.md[78-80]
- src/components/marketing/first-light/first-light.css[89-98]
- src/components/marketing/first-light/moments/M1Hero.tsx[48-55]
- src/components/marketing/first-light/moments/M3ProductCinema.tsx[52-56]
- src/components/marketing/first-light/moments/M8FinalCTA.tsx[24-30]
- src/app/page.tsx[57-69]

## Suggested fix
- Render a single `<div className="fl-grain" aria-hidden="true" />` at the landing page root (e.g. in `src/app/page.tsx` inside `LenisRoot` but outside individual moments), and remove per-moment instances in M1/M3/M8.
- Verify z-index layering remains correct after de-duplication.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Fable Integrator and others added 3 commits July 2, 2026 15:52
Each ledger line's rule had origin-left set but never animated. Now it
draws in via whileInView (scaleX 0 -> 1, once, -15% margin), staggered
per line, instant under reduced motion.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Fz1ajgmqcEp1yPEzjnXgY5
… glow, specular/shadow tokens, lit cards, gradient ring, underline wipe (Amendment 2)
@njrini99-code

Copy link
Copy Markdown
Owner Author

🤖 Mission Control — PR summary

What it changes: Landing editorial moments M2/M5/M6/M7 in the "First Light" sage & cream language (e.g. M2 ledger rules that draw in on scroll). +2,253 / −10 across 25 files — additive presentation, stacked on batch/baseball-fixes.

Risk / areas: Public landing surface only. Scroll/whileInView animations + editorial layout; no data or auth surface.

Reviewers should watch: whileInView once-triggers and margins, reduced-motion fallbacks, and layout stability across the stacked landing sections (no double-band / seam regressions with M3/M4).

⚠️ CI failing — Blocked. Red gates: Unit tests, Business contracts, Supabase lint + RLS, Playwright (chromium), Review Gate all; plus advisory lighthouse-preview. Do not merge until the required gates are green.

Posted automatically by the Helm Mission Control sweep · read-only triage, no changes made.

Fable Integrator and others added 5 commits July 2, 2026 16:16
… lit cards, gradient-ring signal card (Amendment 2)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Fz1ajgmqcEp1yPEzjnXgY5
…ext (Nick)

.fl-card, .fl-light-pool, and .fl-aurora's brightest blob were flat
cream-high fills; demoted to cream (or a cream-high-to-cream top edge on
.fl-card) so nothing larger than the 1px specular lip renders near-white.
…e-art (Amendment 3)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Fz1ajgmqcEp1yPEzjnXgY5
…d glint, brand weave (Amendment 3)

Merges feat/entry-world-foundation (brand/HelmMark+HelmRosette+SportGlyph,
§D2 no-white utilities) and rebuilds M2/M5/M6/M7 per Amendment 3 §A.2/§B.3/
§C.2/§D: M2 breaks into a serif-left/ledger-right editorial split with a
rosette eyebrow; M5 goes off-axis with the signal card right-of-center and
the honesty line as a left margin-note; M6 becomes a 6-col bento with a
dominant readiness tile (div-based sparkline, no chart lib) and per-tile
sport glyphs; M7 goes left-weighted with the founder line + refusals on the
left and a tabular-nums stat ledger on the right, carrying the page's one
animated-gold moment (a single glint sweep on the founder-line brass rule).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Fz1ajgmqcEp1yPEzjnXgY5
@njrini99-code
njrini99-code merged commit bee4966 into batch/baseball-fixes Jul 2, 2026
25 of 30 checks passed
@njrini99-code
njrini99-code deleted the feat/entry-world-editorial branch July 2, 2026 20:53
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