Skip to content

Merge sandbox into main for CodeAI launch - #178

Merged
libredee merged 184 commits into
mainfrom
sandbox
Aug 3, 2026
Merged

Merge sandbox into main for CodeAI launch#178
libredee merged 184 commits into
mainfrom
sandbox

Conversation

@libredee

Copy link
Copy Markdown
Contributor

Merges the CodeAI rebrand into main ahead of next week's launch so the new code can be validated on the test domains now, with the corporate production deploy held by its environment reviewer gate until launch day.

  • Full rebrand: design tokens, component updates, header/footer/section/typography work, aiday site type
  • LEGACY-ENV-COMPAT layer so the same code renders the legacy production Contentful environment until the content switch (grep LEGACY-ENV-COMPAT to remove later)
  • Conflict-free merge; the only changes main brings in against sandbox are the 5 new locales in locale.ts and the footer Store link removal
  • csforall and aiday production auto-deploy after test; corporate production waits on the environment approval
  • Verified locally on the merged tree: marketing build (lint + types), 1165 jest tests, prettier all green

stephenliang and others added 30 commits March 5, 2026 09:34
Adds codeai-logo-inverse.svg as a separate asset and switches the
marketing header and Storybook story to import it. Resizes the logo's
figure container to 1.375rem height with auto width to fit the new
logo's aspect ratio. Leaves cdo-logo-inverse.svg untouched so any
external references to the original URL still resolve.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Renames Code.org to CodeAI, replaces "Hour of Code" with "Hour of AI",
and adds a note that Code.org is a former trademark of CodeAI.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The component-library Header story is bundled by design-system-storybook,
whose @public alias resolves to its own public/ directory. Without a
local copy of the asset the Webpack5 build fails with
SB_BUILDER-WEBPACK5_0002 (module not found).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Sandbox update: header and footer modifications
The SVG's FLIP animated left/top/width/height (main-thread paint) while
the wrapper FLIPped via transform (GPU compositor); Chrome let the two
drift by a frame or two mid-trip, leaving a visible double-image trail.
Switch the SVG to a composited transform so both layers ride the same
pipeline.
Replace the Barlow Semi Condensed dependency with @fontsource/space-grotesk
(weights 500 + 700) and rename the SCSS vars and theme constant
accordingly. Bump h1 to 5rem / h2 to 4rem with 0.95 line-height and drop
the Noto Sans heading fallback, leaving sans-serif as the lone fallback.
Swap the bundled animation to a 1080x313 animated WebP (vs the 834x313
AVIF). Update aspect ratio, duration (8830ms from per-frame delay sum),
and the final-frame logo rect -- WebP logo is centered at (135, 86)
sized 811x141, so the SVG handoff now uses x=0.125 / y=0.275 rather
than the AVIF-era x=y=0.
New optional fields on the Contentful Heading component let editors switch
a single heading to a Space Grotesk style without changing the global
Barlow default. Adds useAltFont (boolean), fontSize (rem), lineHeight
(unitless), fontWeight (500/700), and colorOverride (hex). With useAltFont
on, defaults apply per heading level — fluid clamp() sizes, lineHeight 1.0,
weight 700, color #1F1976 — and each is individually overridable.

Also adds @fontsource/space-grotesk and the brand SCSS face declarations
alongside the existing Barlow setup; the global heading font on main is
unchanged.
New optional fontKerning Contentful field (auto/normal/none) on the
Heading component. Applies only when useAltFont is on; defaults to 'auto'
in that branch. Headings without the alt font are unchanged.
Swap the bundled animated WebP for an inline CSS-animated SVG of the CODE + Ai mark, shipped as a cached CSS Module (extracted to a content-hashed stylesheet) instead of a raster asset.

Make LogoTransitionOverlay generic: it takes the animation via a children slot and drops the image decode-gate. End-of-playback is event-driven off the Web Animations API (getAnimations().finished), with animationDurationMs as a fallback; the SVG plays only its leading motion fraction and freezes, so the sequence settles in ~3.6s instead of running a 9s tail.

Remove the now-unused animated WebP and AVIF assets.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
feat(logo-transition): replace WebP animation with CSS-animated SVG
- Add -webkit-backdrop-filter (value + transition + fade-out) so the grey
  wash blurs on Safari <=17 / iOS 16; the tsup build doesn't autoprefix
  the component-library CSS Modules, so the unprefixed property was dropped.
- Scale the stage to min(1053px, 70vw) instead of full-bleed 100vw, with a
  left gutter of 3% of that footprint, so the flush-left logo stays centred
  at every viewport and no longer clips on small screens (e.g. 1024x768).
- Pre-scale the wrapper's logo offset in the FLIP so the animation tracks
  the destination SVG into the header instead of drifting mid-slide; covered
  by a new test.
- Drop the unused ai-radiate colour-sweep scaffolding (--ai-* properties,
  blurred inner shapes); the mark renders solid black.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
fix(logo-transition): Safari backdrop, responsive sizing, and hand-off alignment
Reverts b5d2594 to bring back the animated-WebP-driven overlay and drops the
CSS-animated SVG stage. Replaces the WebP with the new asset (~9.11s, same
1080x313 canvas, logo still centered on final frame) and bumps
ANIMATION_DURATION_MS to 9112.
Bumps contentful 11.7→11.12.4, experiences-sdk-react 3.6→3.8.8, and rich-text
renderers 17.1→17.2. contentful 11.12.4 requires axios ^1.15.0, so axios is
also bumped and deduped to 1.17.0.

The new SDK declares ExperienceFields as a type alias rather than an interface,
so the existing module augmentation no-ops. Replaced with a local intersection
cast at the selector boundary.
Drop the seoMetadata reference and pageHeading. Add metaTitle, metaDesc,
opengraphImage, and noIndex directly on Experience. noIndex (default false)
mirrors both robots.index and robots.follow and gates the sitemap.

Swap the default OG image to codeai_default_opengraph.png.
libredee added 22 commits July 28, 2026 14:31
Renders a GoFundMe/Classy checkout form from ids bound from a GoFundMe
Form entry; no free-form embed field. Runtime regex guards back up the
entry-only Studio binding. SDK script is injected into head once per
page and kept on unmount. Editor mode shows a static preview.
The SDK replaces the target div with its own markup and only scans once
at init, which broke hydration when the div was server-rendered. Load
the script in the head on all Code.org pages (the donation reminder
follows visitors between pages), create the target div imperatively in
a React-owned host, and reinit via window.eg so late-mounted forms are
picked up.
…ion-component

GoFundMe Donation component + site-wide checkout SDK

eyes diffs - failures existed prior to this PR and will be reconfigured post-launch
Walk back site-wide loading: the SDK (and its donation reminder) now
loads only on pages using the component. Keeps the imperative target
div and the destroy/init re-scan for soft navigation; adds on-demand
script injection aware of the SDK lifecycle (loaded, loading, absent).
Swap the arrow-right defaults on Content Card and Unit Card (covers Card
Carousel, Unit Carousel, Course Catalog) to angle-right, and default the
icon on Studio-placed Text Links and Buttons (code.org only) to
angle-right. Explicitly set or cleared icons in content are unaffected.
… gray-1

The root's md radius left the summary (radius 0) and details opaque
backgrounds painting square corners over the rounded border, and MUI's
built-in first/last-of-type rules kept the outer corners at 4px. Round
the children, out-specify the MUI rules, and drop MUI's between-item
::before divider, which is stray on separated rounded cards. Details
panel moves from the old secondary gray to codeai-gray-1.
Scope the promo link's hover underline to a label span (PrimaryLink
pattern) so the icon stays clean, and swap the promo and boxed primary
link icons from arrow-right to angle-right. Dropdown item titles move to
Geist while the primary link and column headings stay Space Grotesk.
Featured card titles drop the bold CAPS treatment and match the other
items.
Web style updates: angle-right icons, accordion radius, header dropdown
…mission

- tagline: body default (body2) bolded, was Space Grotesk display
- mission: one step down to body3 (text-sm)
- column headings: overline role settings (Geist semibold text-xs uppercase)
- logo 173px -> 200px
- social icons move from the bottom bar to below the mission, purple-dark
- brand block 360px -> 320px, main column gap spacing(6) -> spacing(12)
- tagline weight 700 -> 500
- drop the visible language label; accessible name moves to aria-label
- AWS logo 140px -> 130px, placed left of the language select
…tweaks

- column headings: text-sm 600 uppercase (Custom Text overline preset)
  in purple dark, replacing the old Overline component role settings
- bottom actions gap -> spacing(4)
- social icons -> 1.65rem
- caption uses the brand-black contrast switch (white on dark sections)
  instead of a hardcoded true black; color owned by the component now
- remove the 1px wrapper border
…nch transition

Sandbox code merges to main before the Contentful production environment
switches, so the new code must serve the current production site from the
old environment for a window. All compat paths detect content shape (not
env name) and are tagged LEGACY-ENV-COMPAT for post-launch removal.

- SEO: resolveSeoFields normalizes legacy pageHeading + seoMetadata entry
  and new flat metaTitle/metaDesc/opengraphImage/noIndex; restores keywords
  and independent noindex/nofollow on the old shape
- sitemap.xml: probe-and-fallback query (noIndex vs seoMetadata link),
  503 no-store instead of a crash on fetch failure
- header/footer: unknownContentType from the CDA renders the legacy
  corporateSite chrome; transient errors keep the new-design defaults
- restore pre-rebrand DSCO header teal and 960px MuiFooter grid (both only
  render as the legacy fallback chrome)
- colors: legacy 'primary' maps to var(--text-neutral-primary) so
  data-theme=Dark sections keep white text on unrebuilt pages
- workflows: retarget deploy/CI to main, deploy corporate+csforall+aiday
The rebranded component-library button styles are unscoped and leak into
the legacy fallback header. legacyHeaderButtons.scss (scoped under the
data-legacy-chrome wrapper) pins the buttons to values measured on
code.org production: transparent sign-in with white border and teal
hover, white/teal create account, transparent round icon buttons, and
the drawer's purple/gray pair. The drawer sign-in lost its color class
entirely when ButtonColor dropped 'gray', so it is matched via the
drawer container. LEGACY-ENV-COMPAT; delete with the legacy chrome.
…pages

The rebrand widened the content container from 960px to 1280px and moved
2rem gutters onto it, which distorts pages authored against the old width.
page.tsx stamps data-legacy-experience on <main> when the experience has
the legacy shape (shared isLegacyShapeExperience helper), and
legacyExperienceLayout.scss pins the pre-rebrand geometry: 960px container
with no side padding, 1.5rem Section gutters, 60rem hero/skinny banner
caps, and testimonial padding. New-environment pages are untouched.
LEGACY-ENV-COMPAT; remove with the rest of the compat layer.
Contentful environment compatibility for the launch transition
- column headings to the Custom Text overline preset (text-sm 600
  uppercase gray6), replacing Space Grotesk md medium
- image column weight 1.6 -> 1.4
- list images at 16/9 cover fill; vertical-list thumbnails 140px wide
  with text middle-aligned against them
- promo banner: text weight 600, icon 1.5rem
CSforAll's theme never adopted the rebrand widths, so the 960px pin
shrank its pages below their native 1200px container.

Fixes: 8219ae8 ("fix(layout): restore production content widths on legacy-environment pages")
next build's lint step fails on import-x/order; never caught because
direct sandbox pushes skip CI.

Fixes: 70dcd1c ("fix(header): pin legacy header buttons to the production styles")
comment-empty-line-before rejects back-to-back comment blocks; only the
dryrun-release CI job runs stylelint, so sandbox pushes never caught it.

Fixes: 70dcd1c ("fix(header): pin legacy header buttons to the production styles")
@libredee
libredee requested a review from stephenliang July 31, 2026 21:38
Per review on #178: undo the sandbox-era workflow edits — eyes job
removal, CONTENTFUL_ENV_ID=sandbox in CI, and the aiday deploy matrix
entries.
@github-actions

github-actions Bot commented Jul 31, 2026

Copy link
Copy Markdown

🖼️ Storybook Visual Comparison Report

✅ No Storybook eyes differences detected!

libredee added 3 commits July 31, 2026 22:30
1hQeP2bdFuIFm5kuYeefew's snapshot file was deleted in 5fba3c6 but the
ID stayed listed, so publish-snapshot crashes before reaching the root
entry; 5CznPyR4ZsbIkhpwSaUxoe was listed twice.
waitBeforeCapture lets the video poster swap and web fonts settle before
the DOM snapshot; ignoreDisplacements drops the sub-pixel font-shift
false positives; the facade poster loads eagerly (it's the facade's
primary visual and an LCP candidate anyway).
Overline/RichText: Applitools render nodes rasterize the Geist variable
font's interpolated weights slightly differently per run; Layout match
tolerates the wobble. GoFundMe LiveMarkup: the real SDK renders the live
checkout with server-varied suggested amounts, so no stable baseline
exists; play() assertions still cover the markup.

@stephenliang stephenliang left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Approved for all infrastructure and core platform related changes. I didn't look at the components or styles, I defer judgement on those to the marketing team.

@libredee
libredee merged commit 89f7be8 into main Aug 3, 2026
15 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.

2 participants