feat: updated site redesign changes#4
feat: updated site redesign changes#4opeyemiariyo-netizen wants to merge 1 commit intointent-solutions-io:mainfrom
Conversation
- Astro 5 + React 19 + Tailwind CSS 4 stack - IAM (Intent Agent Models) positioning and messaging - Model-agnostic AI agent framework branding (IAE) - PipelinePilot MVP showcase with 4-agent configuration - Resellers page updated to distribution partner model - Transparent pricing with interactive calculator - Education hub (Learn section) with pricing/security/models pages - HUSTLE survey system (15 sections, 76 questions) - Charcoal slate design system with Framer Motion animations - New components: AnimatedBackground, NeuralNetwork, DataFlow, Testimonials - Redesign variants for A/B testing - Additional public assets (icons, images, video) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
📝 WalkthroughWalkthroughThe pull request migrates the site from Firebase-based backend and layout architecture to Netlify deployment, completely redesigns the site with new component-driven architecture, introduces IAM-focused positioning in documentation, and replaces legacy pages with redesigned templates using a new LayoutRedesign component. Changes
Estimated code review effort🎯 4 (Complex) | ⏱️ ~75 minutes Poem
🚥 Pre-merge checks | ✅ 1 | ❌ 2❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (1 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Tip Try Coding Plans. Let us write the prompt for your AI agent so you can ship faster (with fewer bugs). Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Review Summary by QodoComplete website redesign with modern layout, animations, and A/B testing variants
WalkthroughsDescription• Complete website redesign with modern layout, animations, and glassmorphism design system • Migration of multiple pages (resellers, automation, private-ai, cloud, support) from old Layout to new LayoutRedesign component • New redesign variant pages (private-ai-redesign, resellers-redesign, agents-redesign, automation-redesign, cloud-redesign, index-redesign, about-redesign) for A/B testing • Restructured content with hero sections, wave animations, semantic CSS classes, and CSS variables for consistent styling • New FooterRedesign component with responsive multi-column layout and social media integration • Updated form handling from client-side JavaScript to Netlify Forms with honeypot fields • Added comprehensive inline styling with CSS Grid layouts, responsive breakpoints, and Framer Motion animations • New Astro configuration files for content modules and assets management Diagramflowchart LR
OldLayout["Old Layout Component"]
NewLayoutRedesign["LayoutRedesign Component"]
Pages["Pages: resellers, automation, private-ai, cloud, support"]
DesignVariants["A/B Testing Variants: -redesign pages"]
NewComponents["New Components: FooterRedesign, PageHero, PageCTA"]
Styling["Modern Styling: CSS Variables, Glassmorphism, Animations"]
Forms["Form Updates: Netlify Forms Integration"]
OldLayout -- "migrate to" --> NewLayoutRedesign
NewLayoutRedesign --> Pages
Pages --> DesignVariants
NewLayoutRedesign --> NewComponents
NewComponents --> Styling
Pages --> Forms
File Changes1. astro-site/src/pages/resellers.astro
|
Code Review by Qodo
1. Broken Netlify workflow
|
Summary of ChangesHello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request delivers a comprehensive overhaul of the website, focusing on a refreshed user experience and updated content. The changes aim to better articulate the company's offerings in AI solutions, automation, and cloud services, while leveraging a modern and efficient technology stack for improved performance and maintainability. Highlights
Changelog
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
There was a problem hiding this comment.
Code Review
This pull request introduces a major redesign of the website, migrating from Firebase to Netlify, updating the tech stack to Astro 5 and React 19, and overhauling the site's design, components, and content. The changes are extensive and well-executed. My review focuses on ensuring the new deployment pipeline is correctly configured and that project documentation is consistent with the new setup. I've identified a critical issue in the GitHub Actions workflow that will likely cause deployments to fail, along with some documentation inconsistencies that could cause confusion.
Note: Security Review did not run due to the size of the PR.
| cache: 'npm' | ||
|
|
||
| - name: Install dependencies | ||
| run: npm ci |
There was a problem hiding this comment.
| ### Astro + React Islands Pattern | ||
| - **Astro pages** (`.astro`) handle routing and static content | ||
| - **React components** (`.tsx`) are hydrated client-side for interactivity | ||
| - Layout wrapper: `src/layouts/Layout.astro` provides SEO, fonts, meta tags |
There was a problem hiding this comment.
The documentation mentions src/layouts/Layout.astro as the layout wrapper. However, the redesign introduced src/layouts/LayoutRedesign.astro, which is now used across the site. This should be updated to avoid confusing the AI assistant this file is intended for.
| - Layout wrapper: `src/layouts/Layout.astro` provides SEO, fonts, meta tags | |
| - Layout wrapper: `src/layouts/LayoutRedesign.astro` provides SEO, fonts, meta tags |
| ```bash | ||
| npm run dev | ||
| ``` |
There was a problem hiding this comment.
| - name: Setup Node.js | ||
| uses: actions/setup-node@v4 | ||
| with: | ||
| node-version: '20' | ||
| cache: 'npm' | ||
|
|
||
| - name: Install dependencies | ||
| run: npm ci | ||
|
|
||
| - name: Build site | ||
| run: npm run build | ||
|
|
||
| - name: Deploy to Netlify | ||
| uses: nwtgck/actions-netlify@v3.0 | ||
| with: | ||
| publish-dir: './dist' | ||
| production-deploy: true |
There was a problem hiding this comment.
1. Broken netlify workflow 🐞 Bug ⛯ Reliability
The new Netlify deploy workflow is placed under astro-site/.github/workflows (not repo-root .github/workflows) so it will not be picked up by GitHub Actions, and it also runs npm ci/build from the repo root where there is no package.json. Even if moved, publish-dir is set to ./dist instead of astro-site/dist, so deployment would upload the wrong directory.
Agent Prompt
### Issue description
A Netlify deployment workflow was added under `astro-site/.github/workflows/`, which GitHub Actions won’t execute, and it runs `npm ci`/`npm run build` from the repo root where there is no `package.json`. It also deploys `./dist` instead of `astro-site/dist`.
### Issue Context
The repository’s Astro app lives in the `astro-site/` subdirectory and existing CI/CD already builds from there.
### Fix Focus Areas
- astro-site/.github/workflows/deploy.yml[1-48]
- .github/workflows/firebase-deploy.yml[14-40]
- astro-site/package.json[1-10]
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
| const onSubmit = async (data: ContactForm) => { | ||
| try { | ||
| setSubmitError(null); | ||
|
|
||
| const response = await fetch('/api/contact', { | ||
| const response = await fetch('/', { | ||
| method: 'POST', | ||
| headers: { 'Content-Type': 'application/json' }, | ||
| body: JSON.stringify({ | ||
| name: data.name, | ||
| email: data.email, | ||
| company: data.company || undefined, | ||
| phone: data.phone || undefined, | ||
| interest: data.interest, | ||
| projectType: data.projectType || undefined, | ||
| budget: data.budget || undefined, | ||
| timeline: data.timeline || undefined, | ||
| message: data.message, | ||
| website: data.website || undefined, // Honeypot | ||
| headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, | ||
| body: encodeFormData({ | ||
| 'form-name': 'contact', | ||
| 'bot-field': '', | ||
| ...data, | ||
| }), | ||
| }); | ||
|
|
||
| if (!response.ok) { | ||
| const errorData = await response.json().catch(() => ({})); | ||
| throw new Error(errorData.error || `Form submission failed with status ${response.status}`); | ||
| throw new Error(`Netlify form submission failed with status ${response.status}`); | ||
| } |
There was a problem hiding this comment.
2. Netlify forms break firebase 🐞 Bug ✓ Correctness
Contact and survey submissions have been switched to Netlify Forms, but the repo is still configured and auto-deployed to Firebase Hosting + Functions (with /api/* rewrites). In the current deployment, these forms will not be processed by Netlify and the existing Firebase function contract (/api/contact JSON with required fields like interest) no longer matches the data being sent.
Agent Prompt
### Issue description
Frontend forms were changed to Netlify Forms, but CI/CD + hosting configuration remains Firebase Hosting + Firebase Functions with `/api/*` rewrites and strict backend schemas. This will break contact/survey submissions in the currently deployed environment.
### Issue Context
Firebase Hosting is configured to rewrite `/api/contact` and `/api/survey` to Firebase Functions, and the production GitHub Action deploys both hosting and functions to Firebase.
### Fix Focus Areas
- astro-site/src/components/Contact.tsx[16-67]
- astro-site/src/pages/survey/15.astro[31-46]
- astro-site/firebase.json[14-21]
- astro-site/functions/src/index.ts[22-34]
- .github/workflows/firebase-deploy.yml[42-99]
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
| @@ -0,0 +1 @@ | |||
| /* /index.html 200 | |||
There was a problem hiding this comment.
3. Catch-all netlify rewrite 🐞 Bug ✓ Correctness
The added Netlify redirect rule rewrites every path to /index.html, which will break Astro’s multi-page routing (e.g., /about, /survey/15) if deployed to Netlify and will hide real 404s. This also risks intercepting future non-static endpoints since it matches /*.
Agent Prompt
### Issue description
A Netlify `_redirects` catch-all rewrite (`/* /index.html 200`) will cause every route to serve the homepage on Netlify, breaking Astro’s multi-page routing.
### Issue Context
The site defines many separate pages under `src/pages/` and tests navigate to deep routes.
### Fix Focus Areas
- astro-site/public/_redirects[1-1]
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
There was a problem hiding this comment.
Actionable comments posted: 12
Note
Due to the large number of review comments, Critical, Major severity comments were prioritized as inline comments.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
astro-site/src/pages/learn/security.astro (1)
59-60:⚠️ Potential issue | 🟠 MajorQualification required for compliance and post-quantum claims.
Line 59 presents "Kyber-safe TLS" as a direct feature without specifying whether it's optional, automatic, or configuration-dependent. Lines 119–120 state that "HIPAA, SOC 2, PCI DSS, and FedRAMP High compliance [is] inherited from Google Cloud platform certifications"—this risks implying automatic compliance just by using the platform, when compliance inheritance requires correct implementation and configuration. Lines 283–284 assert "Immutable, tamper-proof logs" as an automatic feature without qualification about prerequisites or scope.
These high-risk compliance and security statements need legal/compliance sign-off to clarify scope, prerequisites, and configuration dependencies. Otherwise they create liability exposure on this public-facing page.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@astro-site/src/pages/learn/security.astro` around lines 59 - 60, Update the copy to avoid definitive security/compliance claims by adding clear qualifiers and requesting sign-off: change the phrases "Kyber-safe TLS", "HIPAA, SOC 2, PCI DSS, and FedRAMP High compliance" and "Immutable, tamper-proof logs" to include scope and prerequisites (e.g., "Kyber-safe TLS (available with additional configuration)", "Compliance depends on correct implementation and independent certification — consult Legal/Compliance", "Immutable, tamper‑proof logs when configured with X and retained under Y policies"), and add a short legal/compliance review note near these lines to require sign-off from the compliance team before publishing; reference the exact text tokens "Kyber-safe TLS", "HIPAA, SOC 2, PCI DSS, and FedRAMP High compliance", and "Immutable, tamper-proof logs" to locate and update the copy.astro-site/src/pages/learn/pricing.astro (1)
43-43:⚠️ Potential issue | 🟡 MinorUse
classinstead ofclassNameon native HTML elements.In
.astrofiles, native HTML must use theclassattribute, notclassName(JSX syntax). These four<strong>tags use JSX syntax, which means the Tailwind classes will not apply and the labels will render unstyled.Suggested fix
- <strong className="text-zinc-300">Deliverables:</strong> Architecture diagram, + <strong class="text-zinc-300">Deliverables:</strong> Architecture diagram, - <strong className="text-zinc-300">Scope-dependent.</strong> Includes deployment, + <strong class="text-zinc-300">Scope-dependent.</strong> Includes deployment, - <strong className="text-zinc-300">Includes:</strong> Platform operations, + <strong class="text-zinc-300">Includes:</strong> Platform operations, - <strong className="text-zinc-300">Includes:</strong> Dedicated infrastructure, + <strong class="text-zinc-300">Includes:</strong> Dedicated infrastructure,Also applies to: 58-58, 74-74, 90-90
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@astro-site/src/pages/learn/pricing.astro` at line 43, Replace JSX-style className attributes with standard HTML class on the <strong> elements in the pricing.astro markup so Tailwind classes apply; locate the four <strong> tags that currently read className="text-zinc-300" (the "Deliverables:" and three other label <strong> instances) and change each attribute to class="text-zinc-300".
🟡 Minor comments (25)
astro-site/src/components/FooterRedesign.astro-205-209 (1)
205-209:⚠️ Potential issue | 🟡 MinorAdd focus states for keyboard accessibility.
Interactive elements define
:hoverstyles but lack explicit:focusor:focus-visiblestates. Keyboard users need visible focus indicators.🛡️ Add focus states that match hover styles
.social-link:hover { color: rgb(var(--color-accent-primary)); border-color: rgb(var(--color-accent-primary)); transform: translateY(-2px); } + .social-link:focus-visible { + color: rgb(var(--color-accent-primary)); + border-color: rgb(var(--color-accent-primary)); + outline: 2px solid rgb(var(--color-accent-primary)); + outline-offset: 2px; + }.footer-links a:hover { color: rgb(var(--color-accent-primary)); } + .footer-links a:focus-visible { + color: rgb(var(--color-accent-primary)); + outline: 2px solid rgb(var(--color-accent-primary)); + outline-offset: 2px; + }Also applies to: 231-240
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@astro-site/src/components/FooterRedesign.astro` around lines 205 - 209, The CSS defines .social-link:hover but misses keyboard focus styles; add matching :focus and :focus-visible rules (e.g., .social-link:focus, .social-link:focus-visible) that apply the same color, border-color and transform and include a clear focus indicator (outline or outline-offset) so keyboard users see focus; apply the same change to the other interactive selector blocks mentioned (the similar rules around lines 231-240) to ensure consistent focus-visible behavior across all social/interactive links.astro-site/src/components/home/FeaturedProjects.astro-170-178 (1)
170-178:⚠️ Potential issue | 🟡 MinorHardcoded
whitebackground breaks dark mode theming.Line 174 uses
background-color: whitewhich won't adapt to dark mode, unlike the rest of the component which uses CSS variables likergb(var(--color-bg-secondary)).🎨 Proposed fix to use a theme-aware variable
.project-card { display: flex; flex-direction: column; padding: 2rem; - background-color: white; + background-color: rgb(var(--color-bg-primary)); border: 1px solid rgb(var(--color-border)); border-radius: var(--radius-xl); transition: all var(--transition-base); }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@astro-site/src/components/home/FeaturedProjects.astro` around lines 170 - 178, The .project-card CSS rule hardcodes "background-color: white", which prevents dark-mode theming; change it to use the theme-aware CSS variable (e.g., rgb(var(--color-bg-secondary)) or the existing --color-bg-secondary variable) so the card background follows light/dark themes; update the .project-card selector in FeaturedProjects.astro to replace the literal white value with the theme variable and keep the rest of the rule (padding, border, radius, transition) unchanged.astro-site/src/components/shared/PageHero.astro-29-29 (1)
29-29:⚠️ Potential issue | 🟡 MinorRemove
set:htmlfrom title unless HTML formatting is required.The
titleprop is a simple string type with no indication that it needs to render HTML. Usingset:htmlcreates an unnecessary XSS risk. Thedescriptionfield on the same component uses safe text interpolation—the title should follow the same pattern.Unless you have a specific requirement for inline HTML formatting (e.g., to highlight keywords with
<span>), change line 29 to:- <h1 class="hero-title" set:html={title} /> + <h1 class="hero-title">{title}</h1>If HTML formatting is genuinely needed, add a separate prop (e.g.,
titleHtml) with explicit documentation about the XSS implications and sanitization requirements.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@astro-site/src/components/shared/PageHero.astro` at line 29, The h1 in PageHero.astro is using set:html with the title prop, which is a plain string and creates an XSS risk; remove set:html and render the title as plain text (use the title prop via normal interpolation in the h1 with class "hero-title") so it escapes by default; if you truly need HTML rendering, add an explicit prop like titleHtml and document that it must be sanitized before use (and only use set:html with that new prop).astro-site/src/pages/automation.astro-88-91 (1)
88-91:⚠️ Potential issue | 🟡 Minor
background-attachment: fixedmay cause issues on mobile devices.The hero section uses
background-attachment: fixedfor the parallax effect, but this can cause:
- Performance degradation (forces repaint on scroll)
- Broken behavior on iOS Safari (falls back to scroll anyway)
The mobile media query doesn't override this property.
📱 Proposed fix: disable fixed attachment on mobile
`@media` (max-width: 768px) { + .automation-hero-section { + background-attachment: scroll, scroll; + } + .hero-content { padding: 6rem 0 3rem; }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@astro-site/src/pages/automation.astro` around lines 88 - 91, The hero section currently sets background-attachment: fixed which can cause mobile performance/behavior issues; update the CSS so the mobile media query explicitly overrides that property (e.g., inside the existing mobile breakpoint selector for the hero section set background-attachment: scroll and/or remove fixed from the background shorthand), ensuring the parallax effect remains on desktop but is disabled on small screens.astro-site/.gitignore-40-46 (1)
40-46:⚠️ Potential issue | 🟡 MinorAdd
.astro/to the.gitignorefile.The
.astro/directory is auto-generated workspace metadata created by Astro duringastro dev,astro build, orastro sync. It currently exists in the repository but is not ignored. Astro's official documentation recommends adding it to.gitignoreto prevent noisy diffs and accidental commits of generated files.Suggested change
# Cache +.astro/ .cache/ .temp/ .tmp/🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@astro-site/.gitignore` around lines 40 - 46, Add the generated Astro workspace directory to .gitignore by adding an entry for ".astro/"; update the existing .gitignore block (near the Cache/Build entries) to include ".astro/" so the auto-generated workspace metadata created by Astro during dev/build/sync is not tracked or committed.astro-site/src/components/DataFlowAnimation.tsx-18-27 (1)
18-27:⚠️ Potential issue | 🟡 MinorScope the gradient ids per component instance.
These ids are global in the document. If
DataFlowAnimationis rendered twice on the same page, both SVGs will compete forflowGradient1/flowGradient2, and one instance can end up resolving the other instance's defs.Also applies to: 44-45
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@astro-site/src/components/DataFlowAnimation.tsx` around lines 18 - 27, The SVG gradient ids flowGradient1 and flowGradient2 in the DataFlowAnimation component are global and will collide if multiple instances render; update DataFlowAnimation to generate instance-scoped unique ids (e.g., use React's useId or a unique prop-based suffix) and replace all references to "flowGradient1" and "flowGradient2" in the <linearGradient> defs and any "url(#...)" or fill/stroke attributes (including the other occurrences currently around the second gradient) to use those generated ids so each component instance uses isolated gradient ids.astro-site/src/components/DataFlowAnimation.tsx-11-16 (1)
11-16:⚠️ Potential issue | 🟡 MinorMark this SVG as decorative.
pointer-events-noneonly disables mouse input. Since this layer is purely visual, hide it from assistive tech as well.♿ Suggested change
- <div className="absolute inset-0 overflow-hidden pointer-events-none opacity-30"> + <div + aria-hidden="true" + className="absolute inset-0 overflow-hidden pointer-events-none opacity-30" + > <svg + focusable="false" className="w-full h-full"🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@astro-site/src/components/DataFlowAnimation.tsx` around lines 11 - 16, The SVG layer is only visually decorative but not hidden from assistive tech; update the <svg> element in DataFlowAnimation.tsx (the element currently with className "w-full h-full" and "pointer-events-none" on the wrapper) to be explicitly decorative by adding aria-hidden="true" and focusable="false" to the <svg> element so screen readers ignore it.astro-site/src/components/home/TrustBar.astro-21-31 (1)
21-31:⚠️ Potential issue | 🟡 MinorHide the duplicated marquee items from assistive tech.
The second logo set is only there to make the loop seamless, but screen readers will read all of it twice. Wrap the duplicate sequence in an
aria-hidden="true"container.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@astro-site/src/components/home/TrustBar.astro` around lines 21 - 31, Wrap the duplicated marquee sequence in an element with aria-hidden="true" so assistive tech ignores the second, loop-only set; specifically, in TrustBar.astro locate the repeated block containing the spans with classes like trust-logo trust-logo-github, trust-logo-google-cloud, trust-logo-anthropic, trust-logo-n8n, trust-logo-claude, stat-badge entries, trust-logo-netlify, trust-logo-bigquery, trust-logo-python and enclose that duplicate group in a container (e.g., a div) with aria-hidden="true". Ensure only the duplicate sequence is hidden, leaving the original set accessible.astro-site/src/components/home/TestimonialsSection.astro-24-24 (1)
24-24:⚠️ Potential issue | 🟡 MinorGive the star rating an accessible name.
Right now assistive tech will read five literal star glyphs on each card. Mark the visual stars as decorative and add a screen-reader label such as “5 out of 5 stars.”
Also applies to: 32-32, 40-40
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@astro-site/src/components/home/TestimonialsSection.astro` at line 24, The visual star glyphs in the TestimonialsSection.astro component are being read literally by assistive tech; update the elements with class "stars" to be aria-hidden (e.g., aria-hidden="true") so the decorative glyphs are ignored, and add an accessible text element (e.g., a hidden <span> with a screen-reader-only class or role="img" with an aria-label) that reads "5 out of 5 stars" for each rating instance (the existing "stars" occurrences at lines shown in the diff and the other occurrences referenced). Ensure the visual stars remain visible but the screen-reader label provides the semantic rating.astro-site/src/components/home/TestimonialsSection.astro-13-16 (1)
13-16:⚠️ Potential issue | 🟡 MinorFix the heading copy.
“Don't just take our words for it!” should be singular: “Don't just take our word for it!”
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@astro-site/src/components/home/TestimonialsSection.astro` around lines 13 - 16, Update the heading copy inside the TestimonialsSection component: locate the h2 with class "section-title" (in TestimonialsSection.astro) and change the text "Don't just take our words for it!" to the singular form "Don't just take our word for it!" so the highlighted span remains <span class="highlight-box">just take our word</span> and the full sentence reads correctly.astro-site/src/components/home/TrustBar.astro-153-165 (1)
153-165:⚠️ Potential issue | 🟡 MinorFix the mobile selector typo.
.tech-nameis never rendered in this component, so the intended small-screen font-size adjustment never applies. This should likely target.trust-logo.Suggested fix
- .tech-name { + .trust-logo { font-size: 0.875rem; }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@astro-site/src/components/home/TrustBar.astro` around lines 153 - 165, The mobile CSS block targets a non-existent selector `.tech-name`, so the small-screen font-size change never applies; update the media query to target the actual element `.trust-logo` (in the same rule group where `.logo-track` and `.trust-bar` are defined) and set the desired font-size (e.g., 0.875rem) there so the mobile font-size adjustment takes effect for `.trust-logo`.astro-site/src/components/home/Hero.astro-24-30 (1)
24-30:⚠️ Potential issue | 🟡 MinorMake the secondary CTA match its destination.
The label promises plugin content, but the link goes to
/learn. Unless that route lands directly on a plugins view, this will feel like a broken CTA path. Either retarget the link or rename the button.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@astro-site/src/components/home/Hero.astro` around lines 24 - 30, The secondary CTA in Hero.astro currently renders the anchor element with class "btn btn-outline btn-xl" whose href="/learn" but label "Explore Plugins →"; update this to keep destination and label consistent: either retarget the href to the plugins route (e.g., change href from "/learn" to the plugins route your app uses, such as "/plugins") or rename the button text to match the /learn destination (for example "Learn" or "Explore Learning →"); modify the anchor in the Hero component accordingly so the link and label align.astro-site/src/components/home/FAQSection.astro-32-40 (1)
32-40:⚠️ Potential issue | 🟡 MinorAdd ARIA attributes for accordion accessibility.
The FAQ accordion lacks proper ARIA attributes needed for screen reader users. The buttons should have
aria-expandedandaria-controlsattributes, and the answer panels need correspondingidandroleattributes.♿ Proposed accessibility improvements
- <div class="faq-item"> - <button class="faq-question"> + <div class="faq-item" role="region"> + <button class="faq-question" aria-expanded="false" aria-controls="faq-1"> <span>What is Claude Code and how can it help my team?</span> <svg class="faq-icon" ...></svg> </button> - <div class="faq-answer"> + <div class="faq-answer" id="faq-1" role="region" aria-hidden="true">Then update the script to toggle these attributes:
question?.addEventListener('click', () => { + const isExpanded = item.classList.contains('active'); + const answer = item.querySelector('.faq-answer'); // Close other items faqItems.forEach(otherItem => { if (otherItem !== item) { otherItem.classList.remove('active'); + otherItem.querySelector('.faq-question')?.setAttribute('aria-expanded', 'false'); + otherItem.querySelector('.faq-answer')?.setAttribute('aria-hidden', 'true'); } }); item.classList.toggle('active'); + question?.setAttribute('aria-expanded', String(!isExpanded)); + answer?.setAttribute('aria-hidden', String(isExpanded)); });🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@astro-site/src/components/home/FAQSection.astro` around lines 32 - 40, The FAQ accordion lacks ARIA attributes; update the button element with aria-expanded (initial "false") and aria-controls pointing to a unique id for its panel, add an id and role="region" (and aria-labelledby pointing back to the button id) to the corresponding .faq-answer div, and ensure the accordion toggle script (the code that handles clicking .faq-question) updates aria-expanded on the button and toggles the panel's hidden/visibility state so the aria attributes remain synchronized; use the existing class names (faq-question, faq-answer, faq-item) to locate elements and generate unique panel ids (e.g., faq-answer-1) for the aria-controls links.astro-site/.astro/content-assets.mjs-1-1 (1)
1-1:⚠️ Potential issue | 🟡 MinorAdd
.astro/to.gitignoreand remove from version control.The
.astro/directory is auto-generated by Astro 5 and should not be committed. According to Astro documentation, this folder is regenerated duringastro dev/astro buildand contains generated metadata for features like Content Collections.Add
.astro/to.gitignoreand remove the existing tracked files from git history:.astro🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@astro-site/.astro/content-assets.mjs` at line 1, This repo is tracking generated Astro output (e.g., astro-site/.astro/content-assets.mjs which currently contains "export default new Map()"); add a single line ".astro" to .gitignore, remove the tracked generated files from git with git rm --cached -r .astro (or git rm --cached astro-site/.astro/content-assets.mjs if you only want that file), commit the change, and push — after that regenerate the folder via your usual astro dev/build commands as needed.astro-site/src/components/Testimonials.tsx-357-363 (1)
357-363:⚠️ Potential issue | 🟡 MinorClose button needs accessible labeling.
The close button uses only the "×" character without an accessible label. Screen reader users won't understand its purpose.
<button onClick={() => setSelectedCaseStudy(null)} className="text-2xl" style={{ color: 'rgb(var(--color-text-secondary))' }} + aria-label="Close dialog" > × </button>🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@astro-site/src/components/Testimonials.tsx` around lines 357 - 363, The close button rendering in Testimonials.tsx (the button that calls setSelectedCaseStudy(null)) lacks an accessible label; update that button to include an aria-label (e.g., aria-label="Close" or a contextual aria-label using selectedCaseStudy.title) and/or a title attribute so screen readers announce its purpose, and ensure the button remains visually the same (no visible text required) while being programmatically labeled for accessibility.astro-site/src/components/PricingCalculator.tsx-236-247 (1)
236-247:⚠️ Potential issue | 🟡 MinorToggle button lacks proper semantics and accessibility.
The custom toggle button doesn't have proper ARIA attributes for a switch control. Screen reader users won't understand its state or purpose.
🛠️ Suggested fix
<button onClick={() => setIncludeSupport(!includeSupport)} + role="switch" + aria-checked={includeSupport} + aria-label="Enable priority support" className={`relative w-12 h-6 rounded-full transition-all ${ includeSupport ? 'bg-gradient-accent' : 'bg-[rgb(var(--color-border))]' }`} >🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@astro-site/src/components/PricingCalculator.tsx` around lines 236 - 247, The toggle in the PricingCalculator component lacks ARIA semantics and keyboard support; update the button that toggles includeSupport (the element using onClick={() => setIncludeSupport(!includeSupport)}) to be a proper switch by adding role="switch", aria-checked={includeSupport}, and a descriptive aria-label or aria-labelledby, ensure it has type="button" and is keyboard-operable by handling onKeyDown to toggle on Space/Enter (or rely on native button behavior if keeping a real button) and keep the visual knob div non-focusable; also ensure focus styles are present so keyboard users can see focus.astro-site/src/components/Testimonials.tsx-327-339 (1)
327-339:⚠️ Potential issue | 🟡 MinorModal lacks keyboard accessibility and ARIA attributes.
The modal overlay lacks
role="dialog",aria-modal="true", and an escape key handler. Users navigating via keyboard cannot dismiss the modal without clicking. Additionally, focus is not trapped within the modal.🛠️ Suggested accessibility improvements
Add ARIA attributes and escape key handling:
<motion.div initial={{ opacity: 0 }} animate={{ opacity: 1 }} exit={{ opacity: 0 }} - className="fixed inset-0 bg-black/80 backdrop-blur-sm z-50 flex items-center justify-center p-4" + className="fixed inset-0 bg-black/80 backdrop-blur-sm z-50 flex items-center justify-center p-4" + role="dialog" + aria-modal="true" + aria-labelledby="case-study-title" + onKeyDown={(e) => e.key === 'Escape' && setSelectedCaseStudy(null)} onClick={() => setSelectedCaseStudy(null)} >And add an id to the title:
-<h3 className="text-h2 font-bold mb-2" ...> +<h3 id="case-study-title" className="text-h2 font-bold mb-2" ...>🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@astro-site/src/components/Testimonials.tsx` around lines 327 - 339, The modal overlay and content (the outer motion.div with onClick={() => setSelectedCaseStudy(null)} and the inner motion.div that stops propagation) lack ARIA and keyboard handling; add role="dialog" and aria-modal="true" to the modal container (inner motion.div) and set aria-labelledby pointing to the modal title id, implement an Escape key handler (e.g., in the component mounting effect) that calls setSelectedCaseStudy(null), and implement focus management: move focus into the modal on open, trap focus within the modal while open, and restore focus to the previously focused element on close; ensure the outer overlay still closes on click but inner onClick stops propagation as it already does.astro-site/src/pages/claude-code.astro-222-235 (1)
222-235:⚠️ Potential issue | 🟡 MinorFixed background attachment may degrade mobile performance.
background-attachment: fixedon line 233 can cause performance issues on mobile devices, particularly iOS Safari, which disables this property. The mobile fallback atmax-width: 768pxdoesn't override this, potentially causing unexpected behavior.🛠️ Suggested fix
`@media` (max-width: 768px) { .hero-content { padding: 6rem 0 3rem; } + .claude-code-hero-section { + background-attachment: scroll; + } }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@astro-site/src/pages/claude-code.astro` around lines 222 - 235, The .claude-code-hero-section rule uses background-attachment: fixed which harms mobile performance and is ignored by iOS; update the CSS to remove/override the fixed attachment on touch/small-screen devices by adding a media query (e.g., max-width: 768px or pointer: coarse) that sets background-attachment: scroll for .claude-code-hero-section so mobile browsers use the performant fallback and avoid the fixed behavior.astro-site/src/components/NeuralNetwork.tsx-29-35 (1)
29-35:⚠️ Potential issue | 🟡 MinorInitial node positions may use incorrect canvas dimensions.
Nodes are initialized with
canvas.width/heightimmediately aftersetCanvasSize(), but the canvasoffsetWidth/offsetHeightvalues depend on CSS layout being complete. On initial mount, these may be 0 or incorrect, causing all nodes to cluster at the origin. Consider deferring node initialization or reinitializing when dimensions change.🛠️ Suggested approach
+ const initializeNodes = () => { + return Array.from({ length: nodeCount }, () => ({ + x: Math.random() * canvas.width, + y: Math.random() * canvas.height, + vx: (Math.random() - 0.5) * 0.5, + vy: (Math.random() - 0.5) * 0.5, + })); + }; + const setCanvasSize = () => { canvas.width = canvas.offsetWidth; canvas.height = canvas.offsetHeight; }; setCanvasSize(); window.addEventListener('resize', setCanvasSize); - // Create nodes - const nodeCount = 30; - const nodes: Node[] = Array.from({ length: nodeCount }, () => ({ - x: Math.random() * canvas.width, - y: Math.random() * canvas.height, - vx: (Math.random() - 0.5) * 0.5, - vy: (Math.random() - 0.5) * 0.5, - })); + // Create nodes after canvas is sized + const nodes: Node[] = initializeNodes();🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@astro-site/src/components/NeuralNetwork.tsx` around lines 29 - 35, The node initialization uses canvas.width/height right after calling setCanvasSize(), which can be zero on first mount; refactor by moving the node creation into a dedicated initNodes function (or reinitializeNodes) that reads canvas.width and canvas.height and populates nodes (using the existing nodeCount and Node shape), then call that function only after the canvas size is settled—e.g., from the effect that runs after setCanvasSize or from a ResizeObserver/window resize handler so nodes are recreated when dimensions change; ensure you update any state/refs holding nodes (nodes variable) when reinitializing so positions use correct dimensions.astro-site/src/pages/claude-code.astro-205-210 (1)
205-210:⚠️ Potential issue | 🟡 MinorRemove redundant CSS variable redefinitions and use global design system variables instead.
The variables
--bg-dark,--text-light,--text-light-muted, and--color-highlightare already defined insrc/styles/global-redesign.csswith identical values. Redefining them locally in a scoped<style>block is unnecessary and creates technical debt. Follow the design system approach by removing the local:rootblock and rely on the global variable definitions.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@astro-site/src/pages/claude-code.astro` around lines 205 - 210, Remove the redundant local :root CSS block that redefines --bg-dark, --text-light, --text-light-muted, and --color-highlight in the scoped <style> of claude-code.astro; delete that entire :root declaration so the page uses the global design system variables defined in global-redesign.css, ensuring no other local overrides remain for those variable names in this file.astro-site/src/components/Header.astro-118-145 (1)
118-145:⚠️ Potential issue | 🟡 MinorExpose the mobile disclosure state to assistive tech.
These buttons toggle the panels visually, but they never publish
aria-expandedor link themselves to the content they control. Screen reader users get no state change when “Solutions” or “Resources” opens.♿ Suggested fix
- <button class="mobile-dropdown-trigger"> + <button + class="mobile-dropdown-trigger" + aria-expanded="false" + aria-controls="mobile-solutions-menu" + > <span>Solutions</span> <svg class="dropdown-icon" width="16" height="16" viewBox="0 0 16 16" fill="none"> <path d="M4 6L8 10L12 6" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> </svg> </button> - <div class="mobile-dropdown-content" style="display: none;"> + <div id="mobile-solutions-menu" class="mobile-dropdown-content" style="display: none;"> <a href="/claude-code" class="mobile-menu-item">Claude Code</a> <a href="/agents" class="mobile-menu-item">AI Agents</a> <a href="/private-ai" class="mobile-menu-item">Private AI</a> <a href="/automation" class="mobile-menu-item">Automation</a> <a href="/cloud" class="mobile-menu-item">Cloud & Data</a> @@ if (content && icon) { const isOpen = content.style.display === 'block'; content.style.display = isOpen ? 'none' : 'block'; icon.style.transform = isOpen ? 'rotate(0deg)' : 'rotate(180deg)'; + trigger.setAttribute('aria-expanded', (!isOpen).toString()); }Also applies to: 412-421
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@astro-site/src/components/Header.astro` around lines 118 - 145, The mobile dropdown buttons (elements with class "mobile-dropdown-trigger") don't expose state or control relationships to assistive tech; update each trigger to include aria-expanded="false" initially and aria-controls pointing to a unique id on its corresponding panel (the sibling element with class "mobile-dropdown-content"), add an id on each "mobile-dropdown-content" panel, and when toggling the panel update aria-expanded on the trigger and aria-hidden on the panel (true when hidden, false when visible); apply the same changes for the other similar trigger/content pair (the second "mobile-dropdown-trigger" / "mobile-dropdown-content" block).astro-site/DEPLOYMENT.md-9-12 (1)
9-12:⚠️ Potential issue | 🟡 MinorDon't hard-code build counts and verification stamps in the guide.
The guide claims a verified build from January 16, 2026 on Lines 281-288, but this PR is open on March 8, 2026. These page counts, sizes, and timestamps will drift on every content change, so they should live in CI artifacts or be written as examples instead of fixed facts.
Also applies to: 281-288
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@astro-site/DEPLOYMENT.md` around lines 9 - 12, The DEPLOYMENT.md currently hard-codes build metadata (the bullet list "Total Pages Built", "Build Size", "Build Time", "Status" and the verified build date stamp) which will drift; replace those fixed values with either example placeholders (e.g., "Total Pages Built: <example>") or a short note that actual build metrics live in CI artifacts, and remove or generalize the verified build date stamp so the doc reads as guidance rather than a fixed verification; update the section that contains the bullets and the date stamp to reference CI artifact storage (or show how to insert dynamic values) instead of fixed numbers.astro-site/src/pages/agents-redesign.astro-233-235 (1)
233-235:⚠️ Potential issue | 🟡 MinorWire this CTA to a real target.
This link points to
#pricing, but the page never defines an element withid="pricing", so the button is currently a no-op.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@astro-site/src/pages/agents-redesign.astro` around lines 233 - 235, The CTA anchor uses href="#pricing" but no element with id="pricing" exists, so wire it by adding id="pricing" to the actual Pricing section element (for example the <section>, heading, or container that displays the pricing block), or alternatively change the anchor href to match the existing element id/class for the pricing area; update the element referenced in agents-redesign.astro so the anchor target (id "pricing") exists and scrolls properly.astro-site/src/pages/learn.astro-84-93 (1)
84-93:⚠️ Potential issue | 🟡 MinorBroken anchor link:
#documentationsection doesn't existThe "Technical Docs" card links to
#documentation, but there's no element withid="documentation"on this page. The only defined anchors are#getting-startedand#use-cases.💡 Suggested fix
Either add a documentation section to this page, or link to an external documentation page:
<!-- Technical Documentation --> - <a href="#documentation" class="topic-card"> + <a href="/docs" class="topic-card">Or if documentation is planned as a future section, consider using a placeholder or removing this card temporarily.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@astro-site/src/pages/learn.astro` around lines 84 - 93, The "Technical Docs" topic card currently links to a non-existent anchor "#documentation"; either update the href in the <a href="#documentation" class="topic-card"> element to one of the existing anchors (e.g., "#getting-started" or "#use-cases") or add a corresponding section element with id="documentation" (and a heading like "Documentation") to the page so the anchor resolves; ensure the id matches exactly and keep the card text "Technical Docs" aligned with the target section.astro-site/src/pages/about.astro-130-131 (1)
130-131:⚠️ Potential issue | 🟡 MinorImage filenames contain spaces which may cause issues.
Filenames like
jeremy longshore.jpegcontain spaces that may cause URL encoding issues in some contexts. Consider renaming to use hyphens or underscores.🛠️ Suggested filename changes
-<img src="/images/team/jeremy longshore.jpeg" alt="Jeremy Longshore" /> +<img src="/images/team/jeremy-longshore.jpeg" alt="Jeremy Longshore" />Apply similar renaming to:
pablo perez.jpeg→pablo-perez.jpegopeyemi ariyo.jpeg→opeyemi-ariyo.jpeglutfun nahar.jpeg→lutfun-nahar.jpeg🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@astro-site/src/pages/about.astro` around lines 130 - 131, Rename the image files to remove spaces (e.g., change "jeremy longshore.jpeg" to "jeremy-longshore.jpeg", and similarly "pablo perez.jpeg" → "pablo-perez.jpeg", "opeyemi ariyo.jpeg" → "opeyemi-ariyo.jpeg", "lutfun nahar.jpeg" → "lutfun-nahar.jpeg"), commit the renamed assets, and update all corresponding <img src="..."> references in the about.astro file (replace occurrences of "jeremy longshore.jpeg", "pablo perez.jpeg", "opeyemi ariyo.jpeg", and "lutfun nahar.jpeg" with their hyphenated counterparts) so the HTML points to the new filenames and avoids URL-encoding issues.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 396f6eff-ca91-4f00-9be5-d682a40657b9
⛔ Files ignored due to path filters (48)
astro-site/bun.lockis excluded by!**/*.lockastro-site/package-lock.jsonis excluded by!**/package-lock.jsonastro-site/public/astronaut.mp4is excluded by!**/*.mp4astro-site/public/icons/agents-icon.svgis excluded by!**/*.svgastro-site/public/icons/automation-icon.svgis excluded by!**/*.svgastro-site/public/icons/cloud-icon.svgis excluded by!**/*.svgastro-site/public/icons/private-ai-icon.svgis excluded by!**/*.svgastro-site/public/images/acceptable-use-bg.jpgis excluded by!**/*.jpgastro-site/public/images/agents-hero-bg-new.jpgis excluded by!**/*.jpgastro-site/public/images/agents-hero-bg.jpgis excluded by!**/*.jpgastro-site/public/images/claude-code-hero-bg.jpgis excluded by!**/*.jpgastro-site/public/images/cloud-engagement-bg.jpgis excluded by!**/*.jpgastro-site/public/images/contact-hero-bg.jpgis excluded by!**/*.jpgastro-site/public/images/cosmic-bg-dark.jpgis excluded by!**/*.jpgastro-site/public/images/cosmic-bg.jpgis excluded by!**/*.jpgastro-site/public/images/hero-about.jpgis excluded by!**/*.jpgastro-site/public/images/hero-agents.jpgis excluded by!**/*.jpgastro-site/public/images/hero-automation.jpgis excluded by!**/*.jpgastro-site/public/images/hero-cloud.jpgis excluded by!**/*.jpgastro-site/public/images/hero-fallback.jpgis excluded by!**/*.jpgastro-site/public/images/hero-learn.jpgis excluded by!**/*.jpgastro-site/public/images/hero-private-ai.jpgis excluded by!**/*.jpgastro-site/public/images/hero-resellers.jpgis excluded by!**/*.jpgastro-site/public/images/learn-hero-bg.jpgis excluded by!**/*.jpgastro-site/public/images/partners-engagement-bg.jpgis excluded by!**/*.jpgastro-site/public/images/partners-vertex-bg.jpgis excluded by!**/*.jpgastro-site/public/images/privacy-bg.jpgis excluded by!**/*.jpgastro-site/public/images/private-ai-hero-bg.jpgis excluded by!**/*.jpgastro-site/public/images/private-ai-scopes-bg.jpgis excluded by!**/*.jpgastro-site/public/images/support-hero-bg.jpgis excluded by!**/*.jpgastro-site/public/images/support-improvement-bg.jpgis excluded by!**/*.jpgastro-site/public/images/team/jeremy longshore.jpegis excluded by!**/*.jpegastro-site/public/images/team/lutfun nahar.jpegis excluded by!**/*.jpegastro-site/public/images/team/opeyemi ariyo.jpegis excluded by!**/*.jpegastro-site/public/images/team/pablo perez.jpegis excluded by!**/*.jpegastro-site/public/images/terms-bg.jpgis excluded by!**/*.jpgastro-site/public/projects/bobs-brain.jpgis excluded by!**/*.jpgastro-site/public/projects/claude-plugins.jpgis excluded by!**/*.jpgastro-site/public/projects/costplusdb.jpgis excluded by!**/*.jpgastro-site/public/projects/diagnostic-pro.jpgis excluded by!**/*.jpgastro-site/public/projects/git-with-intent.jpgis excluded by!**/*.jpgastro-site/public/projects/hustle.jpgis excluded by!**/*.jpgastro-site/public/projects/intentmail.jpgis excluded by!**/*.jpgastro-site/public/projects/news-pipeline.jpgis excluded by!**/*.jpgastro-site/public/projects/perception.jpgis excluded by!**/*.jpgastro-site/public/projects/pipelinepilot.jpgis excluded by!**/*.jpgastro-site/public/projects/start-ai-tools.jpgis excluded by!**/*.jpgastro-site/public/projects/waygate-mcp.jpgis excluded by!**/*.jpg
📒 Files selected for processing (118)
CLAUDE.mdastro-site/.astro/content-assets.mjsastro-site/.astro/content-modules.mjsastro-site/.astro/content.d.tsastro-site/.astro/data-store.jsonastro-site/.astro/settings.jsonastro-site/.astro/types.d.tsastro-site/.github/workflows/deploy.ymlastro-site/.gitignoreastro-site/DEPLOYMENT.mdastro-site/public/_redirectsastro-site/src/components/AnimatedBackground.tsxastro-site/src/components/AnimatedCounter.tsxastro-site/src/components/Contact.tsxastro-site/src/components/DataFlowAnimation.tsxastro-site/src/components/Footer.tsxastro-site/src/components/FooterRedesign.astroastro-site/src/components/Header.astroastro-site/src/components/Hero.tsxastro-site/src/components/NeuralNetwork.tsxastro-site/src/components/ParallaxSection.tsxastro-site/src/components/PricingCalculator.tsxastro-site/src/components/ProductComparison.tsxastro-site/src/components/Products.tsxastro-site/src/components/Services.tsxastro-site/src/components/SiteNav.astroastro-site/src/components/Testimonials.tsxastro-site/src/components/TrustBadges.tsxastro-site/src/components/home/FAQSection.astroastro-site/src/components/home/FeaturedProjects.astroastro-site/src/components/home/FinalCTA.astroastro-site/src/components/home/Hero.astroastro-site/src/components/home/PricingSection.astroastro-site/src/components/home/PricingTiers.astroastro-site/src/components/home/ProjectsCarousel.astroastro-site/src/components/home/Services.astroastro-site/src/components/home/TestimonialsSection.astroastro-site/src/components/home/TrustBar.astroastro-site/src/components/home/VideoHero.astroastro-site/src/components/shared/CTASection.astroastro-site/src/components/shared/PageCTA.astroastro-site/src/components/shared/PageHero.astroastro-site/src/layouts/LayoutRedesign.astroastro-site/src/layouts/_Layout.astro.backupastro-site/src/pages/a2a.astroastro-site/src/pages/about-redesign.astroastro-site/src/pages/about.astroastro-site/src/pages/acceptable-use.astroastro-site/src/pages/agents-redesign.astroastro-site/src/pages/agents.astroastro-site/src/pages/ai-agents.astroastro-site/src/pages/ai-models.astroastro-site/src/pages/applications.astroastro-site/src/pages/automation-redesign.astroastro-site/src/pages/automation.astroastro-site/src/pages/claude-code.astroastro-site/src/pages/cloud-redesign.astroastro-site/src/pages/cloud.astroastro-site/src/pages/contact.astroastro-site/src/pages/index-redesign.astroastro-site/src/pages/index.astroastro-site/src/pages/infrastructure.astroastro-site/src/pages/intel-engine.astroastro-site/src/pages/learn.astroastro-site/src/pages/learn/models.astroastro-site/src/pages/learn/pricing.astroastro-site/src/pages/learn/security.astroastro-site/src/pages/pricing.astroastro-site/src/pages/privacy.astroastro-site/src/pages/private-ai-redesign.astroastro-site/src/pages/private-ai.astroastro-site/src/pages/resellers-redesign.astroastro-site/src/pages/resellers.astroastro-site/src/pages/security-compliance.astroastro-site/src/pages/support.astroastro-site/src/pages/survey.astroastro-site/src/pages/survey/1.astroastro-site/src/pages/survey/10.astroastro-site/src/pages/survey/11.astroastro-site/src/pages/survey/12.astroastro-site/src/pages/survey/13.astroastro-site/src/pages/survey/14.astroastro-site/src/pages/survey/15.astroastro-site/src/pages/survey/2.astroastro-site/src/pages/survey/3.astroastro-site/src/pages/survey/4.astroastro-site/src/pages/survey/5.astroastro-site/src/pages/survey/6.astroastro-site/src/pages/survey/7.astroastro-site/src/pages/survey/8.astroastro-site/src/pages/survey/9.astroastro-site/src/pages/survey/test-submit.astroastro-site/src/pages/survey/thank-you.astroastro-site/src/pages/terms.astroastro-site/src/pages/thank-you.astroastro-site/src/scripts/animations.tsastro-site/src/styles/global-redesign.cssastro-site/src/styles/global.cssastro-site/tests/e2e/netlify-api-integration.spec.cjsastro-site/tests/e2e/netlify-form-submission.spec.cjsclaudes-docs/000-INDEX-ai-agent-pricing-research.mdclaudes-docs/001-AR-PRIC-ai-agent-pricing-market-research-2025.mdclaudes-docs/002-AR-PRIC-pricing-positioning-quick-reference.mdclaudes-docs/003-AR-PRIC-competitive-pricing-matrix.mdclaudes-docs/AI_AGENTS_ROI_RESEARCH_2025.mdclaudes-docs/INTENT-SOLUTIONS-WEB-DESIGN-DOCUMENTATION.mdclaudes-docs/REFACTOR-IMPLEMENTATION-GUIDE.mdclaudes-docs/RESEARCH-DELIVERY-SUMMARY.mdclaudes-docs/analysis/diagnosticpro-false-claims-audit.mdclaudes-docs/analysis/diagnosticpro-tech-stack-upgrade-plan.mdclaudes-docs/analysis/diagnosticpro-theme-migration-analysis.mdclaudes-docs/analysis/netlify-form-submission-issue.mdclaudes-docs/analysis/survey-persistence-investigation.mdclaudes-docs/implementation/doticons-integration-guide.mdclaudes-docs/implementation/og-image-social-sharing-fix.mdclaudes-docs/implementation/unicorn-studio-integration-guide.mdclaudes-docs/tasks/netlify-form-fix-complete.mdclaudes-docs/tasks/survey-fix-implementation-summary.md
| - name: Install dependencies | ||
| run: npm ci | ||
|
|
||
| - name: Build site | ||
| run: npm run build | ||
|
|
||
| - name: Deploy to Netlify | ||
| uses: nwtgck/actions-netlify@v3.0 | ||
| with: | ||
| publish-dir: './dist' |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Check where package.json files exist
echo "=== Checking package.json locations ==="
fd -t f "package.json" --max-depth 2
echo ""
echo "=== Checking if astro-site has its own package.json ==="
if [ -f "astro-site/package.json" ]; then
echo "Found astro-site/package.json"
cat astro-site/package.json | jq '.name, .scripts.build' 2>/dev/null || head -20 astro-site/package.json
else
echo "No package.json in astro-site/"
fi
echo ""
echo "=== Checking root package.json ==="
if [ -f "package.json" ]; then
echo "Found root package.json"
cat package.json | jq '.name, .scripts.build' 2>/dev/null || head -20 package.json
else
echo "No root package.json"
fiRepository: intent-solutions-io/intent-solutions-landing
Length of output: 322
Set working directory for build steps or use --prefix flag.
The workflow runs npm ci and npm run build from the repository root, but package.json exists only in the astro-site/ subdirectory. These commands will fail because npm won't find the package manifest.
Additionally, publish-dir: './dist' should be 'astro-site/dist' to correctly reference the build output location.
Fix by either:
- Adding
working-directory: astro-siteto theInstall dependenciesandBuild sitesteps, or - Using
npm ci --prefix astro-siteandnpm run build --prefix astro-site
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@astro-site/.github/workflows/deploy.yml` around lines 24 - 33, The workflow
runs npm commands from the repo root and references the wrong publish directory;
update the "Install dependencies" and "Build site" steps (or the "Deploy to
Netlify" step's publish-dir) so npm targets the astro-site subdirectory: either
add working-directory: astro-site to the "Install dependencies" and "Build site"
steps, or use npm ci --prefix astro-site and npm run build --prefix astro-site;
also change the Deploy to Netlify step's publish-dir from './dist' to
'astro-site/dist' so the action publishes the correct build output.
| # Dependencies | ||
| node_modules/ | ||
| package-lock.json |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Verify which package manager this repo is standardized on before ignoring package-lock.json.
fd -HI '^(package.json|package-lock.json|pnpm-lock.yaml|yarn.lock)$' .
echo
echo "packageManager declarations:"
fd -HI '^package.json$' . -x sh -c '
echo "--- $1"
rg -n "\"packageManager\"|\"npm\"|\"pnpm\"|\"yarn\"" "$1" || true
' sh {}Repository: intent-solutions-io/intent-solutions-landing
Length of output: 321
Don't ignore the npm lockfile.
The repository is using npm (evidenced by package-lock.json at astro-site/ and astro-site/functions/). Ignoring this lockfile will break reproducible installs and make CI/dev/prod drift much more likely—a critical risk during the Astro 5, React 19, and Tailwind CSS 4 upgrade. Keep package-lock.json tracked unless the repo explicitly switches to pnpm or Yarn.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@astro-site/.gitignore` around lines 1 - 3, The .gitignore currently excludes
package-lock.json which prevents tracking the npm lockfile and breaks
reproducible installs; remove the "package-lock.json" entry from
astro-site/.gitignore (and from any other .gitignores that list
package-lock.json, e.g., astro-site/functions/) and then add and commit the
actual package-lock.json to the repo so CI and installs use the pinned
dependencies.
| {Array.from({ length: 20 }).map((_, i) => ( | ||
| <motion.div | ||
| key={i} | ||
| className="absolute w-1 h-1 rounded-full bg-gradient-accent" | ||
| style={{ | ||
| left: `${Math.random() * 100}%`, | ||
| top: `${Math.random() * 100}%`, | ||
| }} | ||
| animate={{ | ||
| y: [0, -100, 0], | ||
| opacity: [0, 0.6, 0], | ||
| }} | ||
| transition={{ | ||
| duration: Math.random() * 10 + 10, | ||
| repeat: Infinity, | ||
| ease: 'easeInOut', | ||
| delay: Math.random() * 5, | ||
| }} | ||
| /> |
There was a problem hiding this comment.
Math.random() during render causes SSR hydration mismatches.
Calling Math.random() in the render body (lines 95-96 for positions, lines 103/106 for duration/delay) produces different values on server vs client, causing React hydration warnings. Since this is a decorative component, consider either:
- Using
useEffectto generate random values client-side only - Using deterministic pseudo-random values based on index
- Marking the component with
client:onlyin Astro to skip SSR
🛠️ Suggested fix using seeded randomness
+// Simple seeded random for deterministic values
+const seededRandom = (seed: number) => {
+ const x = Math.sin(seed * 9999) * 10000;
+ return x - Math.floor(x);
+};
{Array.from({ length: 20 }).map((_, i) => (
<motion.div
key={i}
className="absolute w-1 h-1 rounded-full bg-gradient-accent"
style={{
- left: `${Math.random() * 100}%`,
- top: `${Math.random() * 100}%`,
+ left: `${seededRandom(i * 2) * 100}%`,
+ top: `${seededRandom(i * 2 + 1) * 100}%`,
}}
animate={{
y: [0, -100, 0],
opacity: [0, 0.6, 0],
}}
transition={{
- duration: Math.random() * 10 + 10,
+ duration: seededRandom(i * 3) * 10 + 10,
repeat: Infinity,
ease: 'easeInOut',
- delay: Math.random() * 5,
+ delay: seededRandom(i * 4) * 5,
}}
/>
))}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| {Array.from({ length: 20 }).map((_, i) => ( | |
| <motion.div | |
| key={i} | |
| className="absolute w-1 h-1 rounded-full bg-gradient-accent" | |
| style={{ | |
| left: `${Math.random() * 100}%`, | |
| top: `${Math.random() * 100}%`, | |
| }} | |
| animate={{ | |
| y: [0, -100, 0], | |
| opacity: [0, 0.6, 0], | |
| }} | |
| transition={{ | |
| duration: Math.random() * 10 + 10, | |
| repeat: Infinity, | |
| ease: 'easeInOut', | |
| delay: Math.random() * 5, | |
| }} | |
| /> | |
| // Simple seeded random for deterministic values | |
| const seededRandom = (seed: number) => { | |
| const x = Math.sin(seed * 9999) * 10000; | |
| return x - Math.floor(x); | |
| }; | |
| {Array.from({ length: 20 }).map((_, i) => ( | |
| <motion.div | |
| key={i} | |
| className="absolute w-1 h-1 rounded-full bg-gradient-accent" | |
| style={{ | |
| left: `${seededRandom(i * 2) * 100}%`, | |
| top: `${seededRandom(i * 2 + 1) * 100}%`, | |
| }} | |
| animate={{ | |
| y: [0, -100, 0], | |
| opacity: [0, 0.6, 0], | |
| }} | |
| transition={{ | |
| duration: seededRandom(i * 3) * 10 + 10, | |
| repeat: Infinity, | |
| ease: 'easeInOut', | |
| delay: seededRandom(i * 4) * 5, | |
| }} | |
| /> | |
| ))} |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@astro-site/src/components/AnimatedBackground.tsx` around lines 90 - 108,
Math.random() is being called during render inside the AnimatedBackground map
(motion.div positions, duration, delay), causing SSR/client hydration
mismatches; fix by generating all random values client-side after mount: create
state (e.g., an array of 20 items) and populate it in useEffect with
Math.random-derived left/top/duration/delay values (or use a seeded PRNG based
on index), then map over that state in the render instead of calling Math.random
directly; update AnimatedBackground to render placeholders or nothing
server-side and only use the generated state for motion.div props so no
randomness runs during SSR.
| useEffect(() => { | ||
| if (inView && !hasAnimated) { | ||
| setHasAnimated(true); | ||
| let startTime: number | null = null; | ||
| const startValue = 0; | ||
|
|
||
| const animate = (currentTime: number) => { | ||
| if (startTime === null) startTime = currentTime; | ||
| const progress = Math.min((currentTime - startTime) / duration, 1); | ||
|
|
||
| // Easing function (easeOutExpo) | ||
| const easeOutExpo = progress === 1 ? 1 : 1 - Math.pow(2, -10 * progress); | ||
|
|
||
| const currentCount = startValue + (end - startValue) * easeOutExpo; | ||
| setCount(currentCount); | ||
|
|
||
| if (progress < 1) { | ||
| requestAnimationFrame(animate); | ||
| } else { | ||
| setCount(end); | ||
| } | ||
| }; | ||
|
|
||
| requestAnimationFrame(animate); | ||
| } | ||
| }, [inView, hasAnimated, end, duration]); |
There was a problem hiding this comment.
Missing cleanup for requestAnimationFrame causes memory leak and potential state update on unmounted component.
If the component unmounts during the animation, the requestAnimationFrame callback continues executing and calls setCount on an unmounted component. Store the animation frame ID and cancel it in the cleanup function.
🐛 Proposed fix
useEffect(() => {
+ let animationFrameId: number;
+
if (inView && !hasAnimated) {
setHasAnimated(true);
let startTime: number | null = null;
const startValue = 0;
const animate = (currentTime: number) => {
if (startTime === null) startTime = currentTime;
const progress = Math.min((currentTime - startTime) / duration, 1);
// Easing function (easeOutExpo)
const easeOutExpo = progress === 1 ? 1 : 1 - Math.pow(2, -10 * progress);
const currentCount = startValue + (end - startValue) * easeOutExpo;
setCount(currentCount);
if (progress < 1) {
- requestAnimationFrame(animate);
+ animationFrameId = requestAnimationFrame(animate);
} else {
setCount(end);
}
};
- requestAnimationFrame(animate);
+ animationFrameId = requestAnimationFrame(animate);
}
+
+ return () => {
+ if (animationFrameId) {
+ cancelAnimationFrame(animationFrameId);
+ }
+ };
}, [inView, hasAnimated, end, duration]);🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@astro-site/src/components/AnimatedCounter.tsx` around lines 28 - 53, The
effect in the AnimatedCounter component starts an animation with
requestAnimationFrame but never cancels it; modify the useEffect in
AnimatedCounter to capture the animation frame ID returned by
requestAnimationFrame into a variable (e.g., rafId) and return a cleanup
function that calls cancelAnimationFrame(rafId); additionally guard state
updates inside the animate callback (or set a mounted flag) so setCount and
setHasAnimated are not called after unmount. Ensure you reference the existing
animate function and requestAnimationFrame/ cancelAnimationFrame calls when
implementing the cleanup.
| const { | ||
| register, | ||
| handleSubmit, | ||
| formState: { errors, isSubmitting }, | ||
| formState: { errors }, | ||
| reset, | ||
| watch, | ||
| } = useForm<ContactForm>({ | ||
| resolver: zodResolver(contactSchema), | ||
| }); |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
cd astro-site && wc -l src/components/Contact.tsxRepository: intent-solutions-io/intent-solutions-landing
Length of output: 118
🏁 Script executed:
cd astro-site && cat -n src/components/Contact.tsx | head -200Repository: intent-solutions-io/intent-solutions-landing
Length of output: 9021
Prevent duplicate form submissions by disabling the button during the async request.
The button only disables after setSubmitted(true) completes, creating a race condition where rapid clicks before the fetch response can fire multiple POSTs. The form should disable immediately when submission starts, not after it succeeds.
Add isSubmitting to the formState destructuring and use it to disable the button during the request:
🛡️ Suggested fix
const {
register,
handleSubmit,
- formState: { errors },
+ formState: { errors, isSubmitting },
reset,
} = useForm<ContactForm>({
resolver: zodResolver(contactSchema),
});
@@
<button
type="submit"
className="w-full btn-primary"
- disabled={submitted}
+ disabled={submitted || isSubmitting}
>
- {submitted ? 'sent!' : 'send message'}
+ {isSubmitting ? 'sending...' : submitted ? 'sent!' : 'send message'}
</button>Also applies to: lines 43-68, 183-189
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@astro-site/src/components/Contact.tsx` around lines 34 - 41, The submit
button can be clicked multiple times because you only setSubmitted(true) after
the async POST completes; change the form to destructure isSubmitting from
useForm (i.e., const { register, handleSubmit, formState: { errors, isSubmitting
}, reset } = useForm<ContactForm>({...})) and use isSubmitting to disable the
submit button and any other interactive submit controls during the async request
(instead of or in addition to submitted/setSubmitted), and ensure
handleSubmit(onSubmit) triggers the async request so isSubmitting toggles for
the duration of the fetch.
| .logo-track { | ||
| display: flex; | ||
| align-items: center; | ||
| gap: 3rem; | ||
| animation: marquee 40s linear infinite; | ||
| width: max-content; | ||
| } | ||
|
|
||
| .logo-track:hover { | ||
| animation-play-state: paused; | ||
| } |
There was a problem hiding this comment.
Provide a non-hover way to stop the marquee.
This animation runs indefinitely and only pauses on hover, so keyboard and touch users have no way to stop the moving content. Please add a real pause/stop control and disable the animation under prefers-reduced-motion.
Also applies to: 144-150
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@astro-site/src/components/home/TrustBar.astro` around lines 73 - 83, Add an
accessible pause control and respect prefers-reduced-motion: create a
visible/keyboard-focusable button that toggles a paused state (e.g., add/remove
a .paused class) for the marquee container (.logo-track) and update its
aria-pressed/aria-controls accordingly so keyboard and touch users can stop the
motion; implement CSS so .logo-track.paused { animation-play-state: paused; }
and remove the hover-only rule (.logo-track:hover) as the only pause mechanism;
also add an `@media` (prefers-reduced-motion: reduce) rule that disables the
marquee animation entirely (animation: none / no marquee keyframes) so users who
prefer reduced motion never see the animation.
| const renderFeatureValue = (value: boolean | string) => { | ||
| if (typeof value === 'boolean') { | ||
| return value ? ( | ||
| <span className="inline-flex items-center justify-center w-6 h-6 rounded-full bg-gradient-accent"> | ||
| <svg | ||
| className="w-4 h-4 text-white" | ||
| fill="none" | ||
| stroke="currentColor" | ||
| viewBox="0 0 24 24" | ||
| > | ||
| <path | ||
| strokeLinecap="round" | ||
| strokeLinejoin="round" | ||
| strokeWidth={2} | ||
| d="M5 13l4 4L19 7" | ||
| /> | ||
| </svg> | ||
| </span> | ||
| ) : ( | ||
| <span | ||
| className="inline-flex items-center justify-center w-6 h-6 rounded-full" | ||
| style={{ backgroundColor: 'rgba(var(--color-text-tertiary), 0.2)' }} | ||
| > | ||
| <svg | ||
| className="w-4 h-4" | ||
| style={{ color: 'rgb(var(--color-text-tertiary))' }} | ||
| fill="none" | ||
| stroke="currentColor" | ||
| viewBox="0 0 24 24" | ||
| > | ||
| <path | ||
| strokeLinecap="round" | ||
| strokeLinejoin="round" | ||
| strokeWidth={2} | ||
| d="M6 18L18 6M6 6l12 12" | ||
| /> | ||
| </svg> | ||
| </span> | ||
| ); | ||
| } | ||
| return ( | ||
| <span | ||
| className="text-sm font-semibold" | ||
| style={{ color: 'rgb(var(--color-text-primary))' }} | ||
| > | ||
| {value} | ||
| </span> | ||
| ); |
There was a problem hiding this comment.
Render this as a semantic table and give yes/no cells text equivalents.
This reads like a pricing/comparison table, but it is just a stack of divs, and the boolean cells expose only check/cross icons. Assistive tech cannot reliably associate each value with its plan header, so comparing plans becomes guesswork. Use <table>/<thead>/<tbody> (or an ARIA grid if you must keep divs) and include a visible or screen-reader-only value like “Included” / “Not included” in the boolean cells.
Also applies to: 197-339
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@astro-site/src/components/ProductComparison.tsx` around lines 113 - 160, The
ProductComparison layout is non-semantic and the boolean cells only show icons;
change the component to use a semantic HTML table (table, thead, tbody, tr, th,
td) instead of stacked divs so screen readers can associate feature rows with
plan headers, and update the renderFeatureValue function to return a combined
icon plus a visible or screen-reader-only text label (e.g., "Included"/"Not
included" or "Yes"/"No") inside the td; ensure the table header cells are th
with appropriate scope attributes and that boolean cells include the textual
equivalent (either visible or with a screen-reader-only class) so assistive tech
can read the state.
| <div class="md:hidden"> | ||
| <a href="/#contact" class="btn-primary text-sm"> | ||
| start | ||
| </a> | ||
| </div> |
There was a problem hiding this comment.
Missing mobile navigation menu - users cannot access site sections on mobile.
On mobile devices (md:hidden), only a "start" button is shown. The 8 navigation links (home, about, private ai, agents, automation, cloud & data, learn, resellers) are completely inaccessible on mobile viewports. This creates a significant usability issue for mobile users who cannot browse the site.
Consider adding a hamburger menu or alternative mobile navigation pattern.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@astro-site/src/components/SiteNav.astro` around lines 35 - 39, In
SiteNav.astro, the mobile-only block (the div with class "md:hidden" that
currently renders the "start" button) hides the main navigation links on small
viewports; replace or augment this block with a collapsible mobile menu
(hamburger button + toggled panel) that renders the same eight nav links (home,
about, private ai, agents, automation, cloud & data, learn, resellers) so mobile
users can access them. Implement a visible toggle button (hamburger icon) inside
the existing md:hidden container that controls a hidden/shown panel (use a local
reactive state or CSS class toggle) which contains the same link elements used
for desktop nav; ensure keyboard accessibility (button role, aria-expanded,
aria-controls) and preserve existing classes like "btn-primary text-sm" where
appropriate so styling remains consistent.
| <div class="model-pricing"> | ||
| <div class="pricing-row"> | ||
| <span>A la carte</span> | ||
| <span class="price">$997/mo</span> | ||
| </div> | ||
| <div class="pricing-row featured"> | ||
| <span>Full stack bundle</span> | ||
| <span class="price">$3,997/mo</span> | ||
| </div> | ||
| <div class="pricing-row small"> | ||
| <span>Save $1,491/mo with bundle</span> | ||
| </div> |
There was a problem hiding this comment.
Fix the bundle savings math.
$1,497 + $1,997 + $997 = $4,491, so a $3,997/mo full-stack bundle saves $494/mo, not $1,491/mo. Shipping incorrect math on a pricing card will undermine trust fast.
Suggested fix
- <span>Save $1,491/mo with bundle</span>
+ <span>Save $494/mo with bundle</span>📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| <div class="model-pricing"> | |
| <div class="pricing-row"> | |
| <span>A la carte</span> | |
| <span class="price">$997/mo</span> | |
| </div> | |
| <div class="pricing-row featured"> | |
| <span>Full stack bundle</span> | |
| <span class="price">$3,997/mo</span> | |
| </div> | |
| <div class="pricing-row small"> | |
| <span>Save $1,491/mo with bundle</span> | |
| </div> | |
| <div class="model-pricing"> | |
| <div class="pricing-row"> | |
| <span>A la carte</span> | |
| <span class="price">$997/mo</span> | |
| </div> | |
| <div class="pricing-row featured"> | |
| <span>Full stack bundle</span> | |
| <span class="price">$3,997/mo</span> | |
| </div> | |
| <div class="pricing-row small"> | |
| <span>Save $494/mo with bundle</span> | |
| </div> |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@astro-site/src/pages/agents-redesign.astro` around lines 166 - 177, The
savings text in the pricing card is incorrect — with A la carte items listed as
$997/mo and the Full stack bundle at $3,997/mo the correct savings is $494/mo
(not $1,491/mo). Update the string inside the element with class "pricing-row
small" (the span that currently reads "Save $1,491/mo with bundle") to read
"Save $494/mo with bundle" (verify against the prices shown in the "pricing-row"
and "pricing-row featured" entries). Ensure only the displayed savings text is
changed so it stays consistent with the $997/mo and $3,997/mo values.
| <div class="pricing-row"> | ||
| <span class="tier-name">IAM M1</span> | ||
| <span class="tier-price">$497/mo</span> | ||
| </div> | ||
| <div class="pricing-row"> | ||
| <span class="tier-name">IAM M2</span> | ||
| <span class="tier-price">$997/mo</span> | ||
| </div> | ||
| <div class="pricing-row"> | ||
| <span class="tier-name">IAM M3</span> | ||
| <span class="tier-price">$1,997/mo</span> | ||
| </div> |
There was a problem hiding this comment.
These IAM prices disagree with the package page.
Here IAM M2 is $997/mo and IAM M3 is $1,997/mo, but astro-site/src/pages/agents-redesign.astro publishes the opposite mapping for the same package names. One of these pages is wrong, so users can get contradictory prices depending on where they land.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@astro-site/src/pages/pricing.astro` around lines 79 - 90, Pricing for the IAM
tiers is inconsistent between pages: the pricing block that renders the <span
class="tier-name"> entries for "IAM M1", "IAM M2", and "IAM M3" (in
pricing.astro) shows IAM M2 as $997/mo and IAM M3 as $1,997/mo while
agents-redesign.astro has the opposite mapping; confirm the correct prices from
the product/pricing source of truth and update the incorrect page so both pages
render the same values for "IAM M1", "IAM M2", and "IAM M3" (adjust the
pricing-row/tier-price spans accordingly).
Cherry-picked visual improvements from PR #4 redesign while preserving existing discovery-first copy, Firebase infrastructure, and booking CTAs. - TrustBar: animated marquee with correct proof points (1,550+ stars, 270+ plugins, 1,537 skills) - ProjectShowcase: upgraded project grid with gradient borders and scroll-reveal - FAQSection: accessible accordion with real business FAQs - Replaced React Products component with static Astro ProjectShowcase Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Summary by CodeRabbit
New Features
Infrastructure
Bug Fixes & Updates