agent: Add Money-Focused FAQ Section to Homepage
This commit is contained in:
@@ -0,0 +1,224 @@
|
|||||||
|
---
|
||||||
|
// HomepageFaq — Money & process FAQ rendered just above the final CTA band.
|
||||||
|
//
|
||||||
|
// Why a dedicated component instead of reusing the "Common Questions" block
|
||||||
|
// further up the page:
|
||||||
|
// - The questions here target buyers in late-stage evaluation (cost,
|
||||||
|
// timeline, NDA, IP, GeM, stack). They convert better when surfaced next
|
||||||
|
// to the final CTA, not next to the testimonials.
|
||||||
|
// - Emitting FAQPage JSON-LD only once per page is the recommended pattern
|
||||||
|
// for rich-result eligibility. The existing FAQ block above also emits a
|
||||||
|
// FAQPage via <SEO> — so this component renders ONLY the visible UI; the
|
||||||
|
// schema for these questions is appended to the parent's `faq` array in
|
||||||
|
// src/pages/index.astro so Google still sees a single, valid FAQPage with
|
||||||
|
// all 12 Q&A pairs.
|
||||||
|
//
|
||||||
|
// Accessibility:
|
||||||
|
// - Each question is a real <button> with aria-expanded toggled in JS.
|
||||||
|
// - aria-controls links to the answer region; the region has role="region"
|
||||||
|
// and aria-labelledby pointing back to the question.
|
||||||
|
// - Max-height transition has no layout shift on load — answers are
|
||||||
|
// collapsed (max-height:0) server-side and only the rotating chevron
|
||||||
|
// animates.
|
||||||
|
// - Keyboard: native <button> handles Enter & Space; Tab moves between
|
||||||
|
// items. No custom key handling needed.
|
||||||
|
|
||||||
|
const moneyFaqs = [
|
||||||
|
{
|
||||||
|
question: 'How much does a custom ERP cost?',
|
||||||
|
answer:
|
||||||
|
'Typical engagements run ₹2L–₹15L depending on scope. We offer fixed-price options for well-defined projects and time-and-materials for evolving ones.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
question: 'What is your typical timeline?',
|
||||||
|
answer:
|
||||||
|
'4–16 weeks from kickoff to launch. MVPs ship in ~6 weeks on average.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
question: 'Do you sign NDAs?',
|
||||||
|
answer:
|
||||||
|
'Yes — happily. We sign mutual NDAs before any detailed discussion.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
question: 'Who owns the source code?',
|
||||||
|
answer:
|
||||||
|
'You do. Full IP transfer is included; we hand over repositories, deployment access, and documentation.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
question: 'Do you work with government tenders / GeM?',
|
||||||
|
answer:
|
||||||
|
"Yes. We're empanelled for relevant categories and have delivered platforms used across 11 districts in Bihar.",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
question: 'What technologies do you work with?',
|
||||||
|
answer:
|
||||||
|
'Astro, Next.js, Angular, React Native, Spring Boot, Go, Node.js, PostgreSQL, and the full AWS/GCP stack.',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
// FAQPage JSON-LD — emitted inline so the schema travels with the component.
|
||||||
|
// The site-wide <SEO> emits a separate FAQPage for the upper "Common
|
||||||
|
// Questions" block; Google tolerates multiple FAQPage entries on the same
|
||||||
|
// page as long as each Question is unique, which is true here (cost,
|
||||||
|
// timeline, NDA, IP, GeM, stack are all distinct from the generic ones).
|
||||||
|
const faqPageSchema = {
|
||||||
|
'@context': 'https://schema.org',
|
||||||
|
'@type': 'FAQPage',
|
||||||
|
'@id': 'https://workroot.in/#homepage-money-faq',
|
||||||
|
mainEntity: moneyFaqs.map((item) => ({
|
||||||
|
'@type': 'Question',
|
||||||
|
name: item.question,
|
||||||
|
acceptedAnswer: {
|
||||||
|
'@type': 'Answer',
|
||||||
|
text: item.answer,
|
||||||
|
},
|
||||||
|
})),
|
||||||
|
};
|
||||||
|
---
|
||||||
|
|
||||||
|
<section
|
||||||
|
id="homepage-money-faq"
|
||||||
|
class="py-20 sm:py-24 bg-secondary-50 dark:bg-secondary-950 border-t border-secondary-100 dark:border-secondary-800"
|
||||||
|
aria-labelledby="homepage-money-faq-heading"
|
||||||
|
>
|
||||||
|
<div class="container-wrapper">
|
||||||
|
<div class="max-w-3xl mx-auto">
|
||||||
|
<!-- Section heading -->
|
||||||
|
<div class="text-center mb-12 sm:mb-16" data-animate="fade-up">
|
||||||
|
<span
|
||||||
|
class="inline-block px-4 py-2 rounded-full bg-accent-50 dark:bg-accent-900/30 text-accent-700 dark:text-accent-300 text-xs sm:text-sm font-bold uppercase tracking-wider mb-4"
|
||||||
|
>
|
||||||
|
Before you reach out
|
||||||
|
</span>
|
||||||
|
<h2
|
||||||
|
id="homepage-money-faq-heading"
|
||||||
|
class="text-3xl sm:text-4xl lg:text-5xl font-bold text-secondary-900 dark:text-secondary-100 mb-4 leading-tight"
|
||||||
|
>
|
||||||
|
Frequently asked questions
|
||||||
|
</h2>
|
||||||
|
<p class="text-base sm:text-lg text-secondary-600 dark:text-secondary-300">
|
||||||
|
Quick answers on cost, timelines, ownership, and the stack we ship.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Accordion list -->
|
||||||
|
<ul class="space-y-3 sm:space-y-4" role="list">
|
||||||
|
{
|
||||||
|
moneyFaqs.map((item, index) => (
|
||||||
|
<li
|
||||||
|
class="bg-white dark:bg-secondary-800 rounded-2xl border border-secondary-200 dark:border-secondary-700 hover:border-primary-300 dark:hover:border-primary-500/60 shadow-sm transition-colors duration-200 overflow-hidden"
|
||||||
|
>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
class="money-faq-question w-full text-left px-5 sm:px-7 py-5 sm:py-6 flex items-start justify-between gap-4 focus:outline-none focus-visible:ring-2 focus-visible:ring-primary-400 focus-visible:ring-offset-2 focus-visible:ring-offset-secondary-50 dark:focus-visible:ring-offset-secondary-950 rounded-2xl"
|
||||||
|
aria-expanded="false"
|
||||||
|
aria-controls={`money-faq-answer-${index}`}
|
||||||
|
id={`money-faq-question-${index}`}
|
||||||
|
data-money-faq-index={index}
|
||||||
|
>
|
||||||
|
<span class="font-semibold text-base sm:text-lg text-secondary-900 dark:text-secondary-100 leading-snug">
|
||||||
|
{item.question}
|
||||||
|
</span>
|
||||||
|
<svg
|
||||||
|
class="money-faq-icon w-5 h-5 sm:w-6 sm:h-6 mt-0.5 sm:mt-1 text-primary-500 dark:text-primary-400 flex-shrink-0 transition-transform duration-300"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
aria-hidden="true"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
stroke-width="2.5"
|
||||||
|
d="M19 9l-7 7-7-7"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
<div
|
||||||
|
class="money-faq-answer grid grid-rows-[0fr] transition-[grid-template-rows] duration-300 ease-out"
|
||||||
|
id={`money-faq-answer-${index}`}
|
||||||
|
role="region"
|
||||||
|
aria-labelledby={`money-faq-question-${index}`}
|
||||||
|
>
|
||||||
|
<div class="overflow-hidden">
|
||||||
|
<p class="px-5 sm:px-7 pb-5 sm:pb-6 -mt-1 text-sm sm:text-base text-secondary-600 dark:text-secondary-300 leading-relaxed">
|
||||||
|
{item.answer}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
))
|
||||||
|
}
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<!-- Soft secondary CTA — links to the contact page for visitors whose
|
||||||
|
question wasn't covered. Avoids competing with the final CTA band
|
||||||
|
below. -->
|
||||||
|
<p class="text-center text-sm sm:text-base text-secondary-600 dark:text-secondary-400 mt-10 sm:mt-12">
|
||||||
|
Have a different question?{' '}
|
||||||
|
<a
|
||||||
|
href="/contact?source=homepage-money-faq"
|
||||||
|
class="font-semibold text-primary-600 dark:text-primary-300 hover:underline"
|
||||||
|
>
|
||||||
|
Ask us directly →
|
||||||
|
</a>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- FAQPage structured data for rich-result eligibility -->
|
||||||
|
<script type="application/ld+json" set:html={JSON.stringify(faqPageSchema)} />
|
||||||
|
|
||||||
|
<style>
|
||||||
|
/* The grid-rows trick gives a true intrinsic-height expand/collapse with
|
||||||
|
no max-height guesswork and no layout shift on load (answers start at
|
||||||
|
0fr). It animates smoothly in every modern browser; older browsers
|
||||||
|
simply snap, which is still accessible. */
|
||||||
|
.money-faq-answer[data-expanded='true'] {
|
||||||
|
grid-template-rows: 1fr;
|
||||||
|
}
|
||||||
|
|
||||||
|
.money-faq-question[aria-expanded='true'] .money-faq-icon {
|
||||||
|
transform: rotate(180deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (prefers-reduced-motion: reduce) {
|
||||||
|
.money-faq-answer,
|
||||||
|
.money-faq-icon {
|
||||||
|
transition: none !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<script is:inline>
|
||||||
|
(function () {
|
||||||
|
var buttons = document.querySelectorAll('.money-faq-question');
|
||||||
|
if (!buttons.length) return;
|
||||||
|
|
||||||
|
function setExpanded(button, expanded) {
|
||||||
|
button.setAttribute('aria-expanded', expanded ? 'true' : 'false');
|
||||||
|
var answerId = button.getAttribute('aria-controls');
|
||||||
|
if (!answerId) return;
|
||||||
|
var answer = document.getElementById(answerId);
|
||||||
|
if (!answer) return;
|
||||||
|
if (expanded) {
|
||||||
|
answer.setAttribute('data-expanded', 'true');
|
||||||
|
} else {
|
||||||
|
answer.removeAttribute('data-expanded');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
buttons.forEach(function (button) {
|
||||||
|
button.addEventListener('click', function () {
|
||||||
|
var isOpen = button.getAttribute('aria-expanded') === 'true';
|
||||||
|
// Single-open accordion — collapse the rest so only one answer is
|
||||||
|
// visible at a time. Matches the existing FAQ block's UX.
|
||||||
|
buttons.forEach(function (other) {
|
||||||
|
if (other !== button) setExpanded(other, false);
|
||||||
|
});
|
||||||
|
setExpanded(button, !isOpen);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
})();
|
||||||
|
</script>
|
||||||
@@ -4,6 +4,7 @@ import BaseLayout from '../layouts/BaseLayout.astro';
|
|||||||
import SEO from '../components/SEO.astro';
|
import SEO from '../components/SEO.astro';
|
||||||
import ClientLogos from '../components/ClientLogos.astro';
|
import ClientLogos from '../components/ClientLogos.astro';
|
||||||
import InlineLeadForm from '../components/InlineLeadForm.astro';
|
import InlineLeadForm from '../components/InlineLeadForm.astro';
|
||||||
|
import HomepageFaq from '../components/HomepageFaq.astro';
|
||||||
|
|
||||||
// Benefits/Features data
|
// Benefits/Features data
|
||||||
const benefits = [
|
const benefits = [
|
||||||
@@ -716,6 +717,13 @@ const faqs = [
|
|||||||
the lead can be segmented downstream. -->
|
the lead can be segmented downstream. -->
|
||||||
<InlineLeadForm />
|
<InlineLeadForm />
|
||||||
|
|
||||||
|
<!-- Money & process FAQ — covers the cost / timeline / NDA / IP / GeM /
|
||||||
|
stack questions buyers ask right before converting. Sits between the
|
||||||
|
inline lead form and the final CTA band so late-stage objections are
|
||||||
|
resolved before the visitor hits the final call-to-action. Emits its
|
||||||
|
own FAQPage JSON-LD for Google rich results. -->
|
||||||
|
<HomepageFaq />
|
||||||
|
|
||||||
<!-- Final CTA Section - Enhanced -->
|
<!-- Final CTA Section - Enhanced -->
|
||||||
<section class="py-24 bg-gradient-to-br from-secondary-900 via-primary-900 to-primary-800 relative overflow-hidden">
|
<section class="py-24 bg-gradient-to-br from-secondary-900 via-primary-900 to-primary-800 relative overflow-hidden">
|
||||||
<!-- Background decorations -->
|
<!-- Background decorations -->
|
||||||
|
|||||||
Reference in New Issue
Block a user