feat(ui): Redesign FAQ accordion with premium typography, numbered badges, and help cards

This commit is contained in:
metatroncubeswdev 2026-10-19 12:36:56 -04:00
parent f06fc215ba
commit 00ab9f27a1
3 changed files with 321 additions and 62 deletions

View File

@ -1725,85 +1725,200 @@ input[type=range].agency-slider::-webkit-slider-thumb {
} }
/* ========================================================================== /* ==========================================================================
FAQ & ACCORDION FAQ & ACCORDION (World-Class Premium SaaS Design)
========================================================================== */ ========================================================================== */
.faq-section { .faq-section {
max-width: 860px; max-width: 900px;
margin: 96px auto 40px; margin: 104px auto 64px;
padding: 0 24px; padding: 0 24px;
position: relative;
} }
.faq-list { .faq-section-sub {
font-size: 17px;
color: var(--ink-secondary);
max-width: 620px;
margin: 14px auto 0;
line-height: 1.6;
text-align: center;
}
.faq-accordion-container {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: 16px; gap: 14px;
margin-top: 40px; margin-top: 48px;
position: relative;
z-index: 1;
} }
.faq-item { .faq-item {
background: rgba(18, 26, 35, 0.85); background: linear-gradient(180deg, rgba(20, 31, 44, 0.8) 0%, rgba(13, 20, 30, 0.9) 100%);
border: 1px solid rgba(255, 255, 255, 0.12); border: 1px solid rgba(255, 255, 255, 0.08);
border-radius: var(--radius-lg); border-radius: 16px;
overflow: hidden; overflow: hidden;
transition: all var(--duration-normal) var(--ease-apple); backdrop-filter: blur(16px);
-webkit-backdrop-filter: blur(16px);
transition: all 0.25s cubic-bezier(0.16, 1, 0.3, 1);
box-shadow: 0 4px 20px -2px rgba(0, 0, 0, 0.35);
} }
.faq-item:hover { .faq-item:hover {
border-color: rgba(63, 182, 174, 0.4); border-color: rgba(63, 182, 174, 0.4);
background: rgba(22, 33, 45, 0.95); transform: translateY(-2px);
background: linear-gradient(180deg, rgba(25, 38, 54, 0.9) 0%, rgba(16, 25, 36, 0.95) 100%);
box-shadow: 0 10px 28px -4px rgba(0, 0, 0, 0.5), 0 0 0 1px rgba(63, 182, 174, 0.15);
} }
.faq-item.open { .faq-item.open {
border-color: rgba(63, 182, 174, 0.6); border-color: rgba(63, 182, 174, 0.65);
box-shadow: 0 12px 32px rgba(0, 0, 0, 0.5), var(--shadow-glow-teal); background: linear-gradient(180deg, rgba(26, 40, 58, 0.96) 0%, rgba(15, 24, 36, 0.98) 100%);
background: rgba(16, 26, 36, 0.98); box-shadow: 0 16px 40px -4px rgba(0, 0, 0, 0.6), 0 0 28px -4px rgba(63, 182, 174, 0.22);
} }
.faq-question { .faq-question-btn {
width: 100%; width: 100%;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: space-between; justify-content: space-between;
padding: 22px 28px; padding: 22px 26px;
font-family: var(--font-display); background: transparent;
font-size: 17px;
font-weight: 600;
color: #FFFFFF;
text-align: left;
background: none;
border: none; border: none;
cursor: pointer; cursor: pointer;
transition: color var(--duration-fast) ease; text-align: left;
gap: 16px;
font-family: inherit;
transition: background 0.2s ease;
} }
.faq-question:hover { .faq-q-left {
display: flex;
align-items: center;
gap: 16px;
flex: 1;
}
.faq-num {
font-family: var(--font-mono, monospace);
font-size: 12px;
font-weight: 700;
color: var(--teal-vibrant); color: var(--teal-vibrant);
background: rgba(63, 182, 174, 0.12);
border: 1px solid rgba(63, 182, 174, 0.25);
padding: 4px 9px;
border-radius: 6px;
letter-spacing: 0.05em;
flex-shrink: 0;
transition: all 0.25s ease;
} }
.faq-chevron { .faq-item.open .faq-num {
font-size: 11px; background: var(--teal-vibrant);
color: #0A1016;
border-color: var(--teal-vibrant);
font-weight: 800;
}
.faq-q-text {
font-family: var(--font-display, inherit);
font-size: 17px;
font-weight: 600;
line-height: 1.45;
color: #FFFFFF;
letter-spacing: -0.01em;
transition: color 0.2s ease;
}
.faq-question-btn:hover .faq-q-text {
color: var(--teal-soft, #8DE3DB);
}
.faq-item.open .faq-q-text {
color: #FFFFFF;
}
.faq-chevron-badge {
width: 36px;
height: 36px;
min-width: 36px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
background: rgba(255, 255, 255, 0.05);
border: 1px solid rgba(255, 255, 255, 0.1);
color: var(--ink-muted); color: var(--ink-muted);
transition: transform var(--duration-normal) var(--ease-apple), color var(--duration-fast) ease; transition: all 0.28s cubic-bezier(0.16, 1, 0.3, 1);
flex-shrink: 0;
} }
.faq-item.open .faq-chevron { .faq-question-btn:hover .faq-chevron-badge {
transform: rotate(180deg); background: rgba(63, 182, 174, 0.14);
border-color: rgba(63, 182, 174, 0.35);
color: var(--teal-vibrant); color: var(--teal-vibrant);
} }
.faq-item.open .faq-chevron-badge {
background: rgba(63, 182, 174, 0.22);
border-color: rgba(63, 182, 174, 0.55);
color: var(--teal-vibrant);
transform: rotate(180deg);
}
.faq-answer { .faq-answer {
display: none; padding: 0 26px 26px 67px;
padding: 0 28px 24px; animation: faqFadeSlide 0.26s cubic-bezier(0.16, 1, 0.3, 1);
color: var(--ink-secondary); }
font-size: 15px;
line-height: 1.7; .faq-answer-inner {
border-top: 1px solid rgba(255, 255, 255, 0.04); border-top: 1px solid rgba(255, 255, 255, 0.08);
padding-top: 18px; padding-top: 18px;
} }
.faq-item.open .faq-answer { .faq-answer p {
display: block; font-size: 15.5px;
line-height: 1.75;
color: #94A3B8;
margin: 0;
}
@keyframes faqFadeSlide {
from {
opacity: 0;
transform: translateY(-8px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
/* FAQ Help Box */
.faq-help-card {
margin-top: 36px;
padding: 22px 28px;
background: rgba(18, 28, 40, 0.6);
border: 1px dashed rgba(63, 182, 174, 0.3);
border-radius: 14px;
display: flex;
align-items: center;
justify-content: space-between;
gap: 20px;
}
.faq-help-content h4 {
font-size: 16px;
font-weight: 600;
color: #FFFFFF;
margin: 0 0 4px;
}
.faq-help-content p {
font-size: 14px;
color: var(--ink-secondary);
margin: 0;
line-height: 1.5;
} }
/* ========================================================================== /* ==========================================================================
@ -3207,35 +3322,129 @@ body.theme-light::before {
border: 1px solid rgba(15, 23, 42, 0.08) !important; border: 1px solid rgba(15, 23, 42, 0.08) !important;
} }
/* FAQ in Light Mode */ /* FAQ in Light Mode (Ultra-Crisp, High-Contrast Cards) */
[data-theme="light"] .faq-question, [data-theme="light"] .faq-section-sub,
.theme-light .faq-question { .theme-light .faq-section-sub {
color: #0F172A; color: #475569;
} }
[data-theme="light"] .faq-question:hover, [data-theme="light"] .faq-item,
.theme-light .faq-question:hover { .theme-light .faq-item {
color: #0E6E6A; background: #FFFFFF !important;
border: 1px solid rgba(15, 23, 42, 0.08) !important;
box-shadow: 0 2px 8px -2px rgba(15, 23, 42, 0.04), 0 8px 20px -4px rgba(15, 23, 42, 0.03) !important;
}
[data-theme="light"] .faq-item:hover,
.theme-light .faq-item:hover {
border-color: rgba(14, 110, 106, 0.35) !important;
transform: translateY(-2px);
box-shadow: 0 8px 24px -2px rgba(15, 23, 42, 0.08), 0 0 0 1px rgba(14, 110, 106, 0.18) !important;
} }
[data-theme="light"] .faq-item.open, [data-theme="light"] .faq-item.open,
.theme-light .faq-item.open { .theme-light .faq-item.open {
border-color: rgba(14, 110, 106, 0.45); border-color: rgba(14, 110, 106, 0.55) !important;
box-shadow: 0 8px 24px rgba(14, 110, 106, 0.08); background: linear-gradient(180deg, #FFFFFF 0%, #FAFCFC 100%) !important;
background: #FFFFFF; box-shadow: 0 12px 32px -4px rgba(14, 110, 106, 0.12), 0 0 0 1px rgba(14, 110, 106, 0.3) !important;
} }
[data-theme="light"] .faq-chevron, [data-theme="light"] .faq-q-text,
.theme-light .faq-chevron { .theme-light .faq-q-text {
color: #0F172A !important;
}
[data-theme="light"] .faq-question-btn:hover .faq-q-text,
.theme-light .faq-question-btn:hover .faq-q-text {
color: #0E6E6A !important;
}
[data-theme="light"] .faq-num,
.theme-light .faq-num {
color: #0E6E6A;
background: rgba(14, 110, 106, 0.08);
border-color: rgba(14, 110, 106, 0.2);
}
[data-theme="light"] .faq-item.open .faq-num,
.theme-light .faq-item.open .faq-num {
background: #0E6E6A;
color: #FFFFFF;
border-color: #0E6E6A;
}
[data-theme="light"] .faq-chevron-badge,
.theme-light .faq-chevron-badge {
background: rgba(15, 23, 42, 0.04);
border-color: rgba(15, 23, 42, 0.08);
color: #64748B;
}
[data-theme="light"] .faq-question-btn:hover .faq-chevron-badge,
.theme-light .faq-question-btn:hover .faq-chevron-badge {
background: rgba(14, 110, 106, 0.08);
border-color: rgba(14, 110, 106, 0.25);
color: #0E6E6A; color: #0E6E6A;
} }
[data-theme="light"] .faq-answer, [data-theme="light"] .faq-item.open .faq-chevron-badge,
.theme-light .faq-answer { .theme-light .faq-item.open .faq-chevron-badge {
color: #475569; background: rgba(14, 110, 106, 0.15);
border-color: rgba(14, 110, 106, 0.4);
color: #0E6E6A;
}
[data-theme="light"] .faq-answer-inner,
.theme-light .faq-answer-inner {
border-top: 1px solid rgba(15, 23, 42, 0.06); border-top: 1px solid rgba(15, 23, 42, 0.06);
} }
[data-theme="light"] .faq-answer p,
.theme-light .faq-answer p {
color: #475569 !important;
}
[data-theme="light"] .faq-help-card,
.theme-light .faq-help-card {
background: #F8FAFC !important;
border: 1px dashed rgba(14, 110, 106, 0.25) !important;
}
[data-theme="light"] .faq-help-content h4,
.theme-light .faq-help-content h4 {
color: #0F172A !important;
}
[data-theme="light"] .faq-help-content p,
.theme-light .faq-help-content p {
color: #64748B !important;
}
@media (max-width: 640px) {
.faq-section {
padding: 0 16px;
margin: 64px auto 40px;
}
.faq-question-btn {
padding: 18px 16px;
gap: 12px;
}
.faq-q-left {
gap: 12px;
}
.faq-q-text {
font-size: 15px;
}
.faq-answer {
padding: 0 16px 20px 16px;
}
.faq-help-card {
flex-direction: column;
align-items: flex-start;
padding: 20px;
}
}
/* Articles in Light Mode */ /* Articles in Light Mode */
[data-theme="light"] .article-art, [data-theme="light"] .article-art,
.theme-light .article-art { .theme-light .article-art {

View File

@ -57,6 +57,10 @@ const FAQS = [
q: 'Can I provide my clients with their own view-only login portal?', q: 'Can I provide my clients with their own view-only login portal?',
a: 'Yes. Every Pro and Agency plan includes client approval portal links. Clients see their clean health score progress, approved fixes, and weekly wins under your agency branding without seeing backend technical noise.' a: 'Yes. Every Pro and Agency plan includes client approval portal links. Clients see their clean health score progress, approved fixes, and weekly wins under your agency branding without seeing backend technical noise.'
}, },
{
q: 'How does CrawlerX ensure technical crawl accuracy?',
a: 'Unlike surface scrapers, CrawlerX executes full headless Chromium browser crawls. It executes client-rendered JavaScript (React, Next.js, Vue), records Core Web Vitals lab diagnostics, analyzes DOM depth, and detects indexing directives exactly like Googlebot.'
},
{ {
q: 'Can I upgrade, downgrade, or cancel at any time?', q: 'Can I upgrade, downgrade, or cancel at any time?',
a: 'Yes, absolutely. There are no annual lock-in contracts on monthly plans. You can adjust your client site tiers as your agency portfolio expands or contracts.' a: 'Yes, absolutely. There are no annual lock-in contracts on monthly plans. You can adjust your client site tiers as your agency portfolio expands or contracts.'
@ -745,6 +749,9 @@ export default function HomePage() {
<span>CLEAR ANSWERS</span> <span>CLEAR ANSWERS</span>
</div> </div>
<h2>Frequently asked questions.</h2> <h2>Frequently asked questions.</h2>
<p className="faq-section-sub">
Everything you need to know about our crawler engine, automated CMS patches, client portals, and billing.
</p>
</div> </div>
<div className="faq-accordion-container"> <div className="faq-accordion-container">
@ -757,18 +764,36 @@ export default function HomePage() {
type="button" type="button"
className="faq-question-btn" className="faq-question-btn"
onClick={() => setOpenFaq(openFaq === idx ? -1 : idx)} onClick={() => setOpenFaq(openFaq === idx ? -1 : idx)}
aria-expanded={openFaq === idx}
> >
<span>{faq.q}</span> <div className="faq-q-left">
<span className="faq-num">0{idx + 1}</span>
<span className="faq-q-text">{faq.q}</span>
</div>
<div className="faq-chevron-badge">
<ChevronDown size={18} className="faq-chevron" /> <ChevronDown size={18} className="faq-chevron" />
</div>
</button> </button>
{openFaq === idx && ( {openFaq === idx && (
<div className="faq-answer"> <div className="faq-answer">
<div className="faq-answer-inner">
<p>{faq.a}</p> <p>{faq.a}</p>
</div> </div>
</div>
)} )}
</div> </div>
))} ))}
</div> </div>
<div className="faq-help-card">
<div className="faq-help-content">
<h4>Still have questions about agency integration?</h4>
<p>Our engineering team can evaluate your custom CMS setups, crawl budgets, or private proxy requirements.</p>
</div>
<Link to="/contact" className="btn btn-secondary btn-sm">
Contact Support <ArrowUpRight size={14} />
</Link>
</div>
</section> </section>
{/* =================================================================== {/* ===================================================================

View File

@ -5,19 +5,23 @@ import { CheckCircle2, ChevronDown, ArrowUpRight } from 'lucide-react';
const PRICING_FAQS = [ const PRICING_FAQS = [
{ {
q: 'Are there any per-seat or user license fees?', q: 'Are there any per-seat or user license fees?',
a: 'No. Never. Every team plan on CrawlerX includes unlimited seats. You can invite your entire agency staff, freelancers, and clients without paying any extra seat taxes.' a: 'No. Never. Every team plan on CrawlerX includes unlimited seats. You can invite your entire agency team, account managers, freelancers, and clients without paying any extra seat taxes.'
}, },
{ {
q: 'How does the 2 Months Free annual discount work?', q: 'How does the 2 Months Free annual discount work?',
a: 'When you choose annual billing, you pay for 10 months upfront and receive a full 12 months of platform access, saving ~17% across your entire subscription.' a: 'When you choose annual billing, you pay for 10 months upfront and receive a full 12 months of platform access, saving ~17% across your entire annual subscription.'
}, },
{ {
q: 'What happens if I manage more than 30 client sites?', q: 'What happens if I manage more than 30 client sites?',
a: 'Our Agency Scale tier lets you easily add blocks of 10 additional client sites for ₹1,999/mo ($24/mo) with dedicated server crawl IP allocation.' a: 'Our Agency Scale tier lets you easily add blocks of 10 additional client sites for ₹1,999/mo ($24/mo) with dedicated server crawl IP allocation.'
}, },
{ {
q: 'Can I cancel or switch currencies at any time?', q: 'Can I invite clients to review audits without paying for extra licenses?',
a: 'Yes. You can switch currencies or cancel your subscription at any time directly from your billing dashboard with zero penalty.' a: 'Yes. Every paid plan includes shareable white-label client portal links. Clients can review health metrics and approve automated fixes without requiring paid seats.'
},
{
q: 'Can I cancel or switch billing currencies at any time?',
a: 'Yes. You can switch currencies or cancel your subscription at any time directly from your billing dashboard with zero friction or cancellation fees.'
} }
]; ];
@ -274,6 +278,9 @@ export default function PricingPage() {
<span>BILLING FAQ</span> <span>BILLING FAQ</span>
</div> </div>
<h2>Clear billing policies. Zero hidden fees.</h2> <h2>Clear billing policies. Zero hidden fees.</h2>
<p className="faq-section-sub">
Simple, transparent site-based pricing tailored specifically to protect agency margins.
</p>
</div> </div>
<div className="faq-accordion-container"> <div className="faq-accordion-container">
@ -283,18 +290,36 @@ export default function PricingPage() {
type="button" type="button"
className="faq-question-btn" className="faq-question-btn"
onClick={() => setOpenFaq(openFaq === idx ? -1 : idx)} onClick={() => setOpenFaq(openFaq === idx ? -1 : idx)}
aria-expanded={openFaq === idx}
> >
<span>{faq.q}</span> <div className="faq-q-left">
<span className="faq-num">0{idx + 1}</span>
<span className="faq-q-text">{faq.q}</span>
</div>
<div className="faq-chevron-badge">
<ChevronDown size={18} className="faq-chevron" /> <ChevronDown size={18} className="faq-chevron" />
</div>
</button> </button>
{openFaq === idx && ( {openFaq === idx && (
<div className="faq-answer"> <div className="faq-answer">
<div className="faq-answer-inner">
<p>{faq.a}</p> <p>{faq.a}</p>
</div> </div>
</div>
)} )}
</div> </div>
))} ))}
</div> </div>
<div className="faq-help-card">
<div className="faq-help-content">
<h4>Need custom enterprise capacity?</h4>
<p>Managing over 50 client domains or need dedicated crawl server IP pools? Our engineering team can help.</p>
</div>
<Link to="/contact" className="btn btn-secondary btn-sm">
Talk to Enterprise <ArrowUpRight size={14} />
</Link>
</div>
</section> </section>
{/* Pre-footer CTA */} {/* Pre-footer CTA */}