feat: differentiated hero + GSAP motion for aigate marketing site - #16
Merged
Conversation
Replace the generic text-left/terminal-right hero with a stacked layout: hero copy on top, then a full-width CSS/SVG sandbox-boundary diagram below, drawn to aigate's actual mechanism -- an AI agent process inside a kernel-enforced perimeter with FILE/EXEC/NETWORK gates. Syscalls (reused from the site's existing demo data: deny_read, deny_exec, allow_net) travel from the process toward a gate; allowed ones pass through to an external host pill, blocked ones bounce back inside the boundary. Motion via GSAP 3.12.5 + ScrollTrigger (CDN): - Hero entrance timeline: kicker -> h1 -> lede -> ctas -> trust line -> diagram, staggered on load. - Boundary "sealing" draw-in (stroke-dashoffset on the rect, measured via getTotalLength) followed by corner brackets, process box, gates, and the destination pill popping in, then a looping pair of syscall dots crossing/bouncing on a timer. - Scroll-triggered fade+rise reveals, staggered per section, once per section (isolation, platforms, commands, usecases, install). Reduced-motion guard: a single top-level `prefers-reduced-motion` check short-circuits the whole script before anything is hidden, so the page renders in its full, final, visible state by default (progressive enhancement) rather than depending on JS to reveal content. Verified with a real prefers-reduced-motion emulation, not just code review. Dropped the old feed-window/terminal-box markup and its now-dead CSS; kept .feed-caption/.pulse-dot/.feed-tone* since the isolation feature cards still use them. No changes to brand tokens, topbar, footer, or SEO head tags.
✅ PR title follows the required formatCurrent title: |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What changed
The five AxeForge marketing sites built this session shared one template: same topbar, same "kicker / h1 / lede / two buttons" hero on the left, same terminal-window demo on the right. This PR gives aigate's site its own hero, grounded in its actual mechanism, while keeping the brand system (tokens, topbar, footer, SEO) untouched.
New hero concept: a sandbox boundary diagram
Replaced the text-left/terminal-right layout with a stacked hero: copy on top, then a full-width CSS/SVG diagram below that draws aigate's kernel-enforced isolation directly instead of describing it in a fake terminal log.
The diagram shows an "AI agent process" box inside a sealed boundary with three gates — FILE, EXEC, NETWORK — matching the product's real
deny_read/deny_exec/allow_netrule types. Small dots represent syscalls leaving the process toward a gate: allowed ones pass through to an external host pill (api.anthropic.com), blocked ones bounce back inside the boundary. The five example events are the same ones the old hero's simulated feed already used (cat ~/.ssh/id_rsa,curl ifconfig.me,connect evil-exfil.com:443,connect api.anthropic.com,kubectl delete pods), just made visible instead of logged as text.GSAP motion (3.12.5 + ScrollTrigger, via CDN)
stroke-dashoffset(length fromgetTotalLength()), then corner brackets, the process box, the three gates, and the destination pill pop in, then a pair of syscall dots start looping across the gates on a timer.isolation,platforms,commands,usecases,install) fades + rises in, staggered across its cards, once per section viaScrollTrigger.Reduced motion: a single
prefers-reduced-motioncheck at the top of the script short-circuits everything before any element is hidden — the page is progressive enhancement (default CSS = fully visible), not "hide then reveal via JS", so a failed CDN load or reduced-motion preference both degrade to the same fully-visible static page. Verified with a real--force-prefers-reduced-motionbrowser emulation, not just by reading the code: screenshot shows the entire hero, diagram, and even the first feature-card section rendered immediately with zero animation.Verification
web/locally, screenshotted at 1440×1600 and 375×1400 (plus taller captures to see the full page) and read every image.document.documentElement.scrollWidthvswindow.innerWidthat both 375px and 1440px — no overflow at either. The diagram itself uses a containedoverflow-x:autowrapper (reusing the same pattern the platforms table already uses) with amin-widthfloor, so it degrades to a scrollable technical diagram on narrow phones instead of forcing page-wide scroll.data-theme="light") renders correctly — every new color in the diagram is token-driven (var(--af-accent),var(--af-text),var(--af-surface), etc.) except the two pre-existing hardcoded warn/info hex values already used elsewhere on this page.impeccable/scripts/detect.mjs --json— same pre-existing advisory-only findings as before my changes (grid-background pattern, single-font, em-dash count), no new findings.Impeccable score: 20/20 (all 5 dimensions held at 4/4, none needed a fix)
role="img"+ a real<title>describing the mechanism; reduced-motion verified via real emulation, not assumption; tone is never color-only (always paired with text in the readout/legend).cx/cy.data-theme="light") mode.detect.mjsshows zero new findings.Test plan
python3 -m http.serverinweb/, screenshot at 1440×1600 and 375×1400detect.mjs --json— no new findings--force-prefers-reduced-motiondata-theme="light"scrollWidthvsinnerWidthat 375px/1440px — no horizontal overflow