Secciones de Página testimonialscase-studyquotemetrics
Testimonial Featured
Sección tipo caso de éxito con una gran cita, logotipo de la empresa y métricas de resultados.
Vista Previa en Vivo
Orbitly
We replaced three tools and a chart library with this kit. Our product pages load twice as fast and our conversion rate has never been higher.
- faster page loads
- 2.1×
- trial conversion
- +38%
- front-end bundle size
- −64%
Uso
Copia y pega este código directamente en tu página de Astro:
astro
---
import { TestimonialFeatured } from 'astro-component-kit/sections';
---
<TestimonialFeatured
quote="Our pages load twice as fast."
name="Elena Vasquez"
role="VP Marketing, Orbitly"
company="Orbitly"
metrics={[{ value: '2.1×', label: 'faster loads' }]}
variant="card"
/> ---
import { TestimonialFeatured } from 'astro-component-kit/sections';
---
<TestimonialFeatured
quote="Our pages load twice as fast."
name="Elena Vasquez"
role="VP Marketing, Orbitly"
company="Orbitly"
metrics={[{ value: '2.1×', label: 'faster loads' }]}
variant="card"
/> Instalación Manual
Si no estás usando el paquete npm, crea un archivo nuevo y pega el siguiente código: src/components/lib/TestimonialFeatured.astro:
astro
---
/**
* TestimonialFeatured — A single large customer quote paired with the company's
* headline results (case-study style), plus a link to the full story.
*
* @param {string} quote - The testimonial text.
* @param {string} name - Author name.
* @param {string} role - Author role and company.
* @param {string} company - Company wordmark text.
* @param {Array<{value: string, label: string}>} metrics - Outcome stats.
* @param {{label: string, href: string}} link - Case study link.
* @param {string} variant - Layout style (split|centered|card).
* @param {string} size - Vertical rhythm (sm|md|lg).
* @param {string} className - Extra CSS class.
*/
interface Props {
quote?: string;
name?: string;
role?: string;
company?: string;
metrics?: Array<{ value: string; label: string }>;
link?: { label: string; href: string };
variant?: 'split' | 'centered' | 'card';
size?: 'sm' | 'md' | 'lg';
className?: string;
}
const {
quote = 'We replaced three tools and a chart library with this kit. Our product pages load twice as fast and our conversion rate has never been higher.',
name = 'Elena Vasquez',
role = 'VP of Marketing, Orbitly',
company = 'Orbitly',
metrics = [
{ value: '2.1×', label: 'faster page loads' },
{ value: '+38%', label: 'trial conversion' },
{ value: '−64%', label: 'front-end bundle size' },
],
link = { label: 'Read the case study', href: '#' },
variant = 'split',
size = 'md',
className = '',
} = Astro.props;
const initials = name.split(' ').map((p) => p[0]).slice(0, 2).join('');
---
<div class="cq-testimonial-featured-cq">
<section class={`tf tf--${variant} tf--${size} ${className}`} aria-label={`Customer story: ${company}`}>
<div class="tf__inner">
<figure class="tf__figure">
<p class="tf__company" aria-hidden="true">
<svg width="22" height="22" viewBox="0 0 24 24" aria-hidden="true"><circle cx="12" cy="12" r="10" fill="none" stroke="currentColor" stroke-width="2" /><circle cx="12" cy="12" r="4" fill="currentColor" /></svg>
{company}
</p>
<svg class="tf__mark" width="48" height="36" viewBox="0 0 48 36" aria-hidden="true"><path d="M0 36V22C0 9 7 2 20 0l2 5C14 7 11 12 11 18h9v18H0zm28 0V22C28 9 35 2 48 0l2 5c-8 2-11 7-11 13h9v18H28z" fill="currentColor" /></svg>
<blockquote class="tf__quote"><p>{quote}</p></blockquote>
<figcaption class="tf__author">
<span class="tf__avatar" aria-hidden="true">{initials}</span>
<span><strong>{name}</strong><span class="tf__role">{role}</span></span>
</figcaption>
</figure>
<div class="tf__side">
<dl class="tf__metrics">
{metrics.map((mt) => (
<div class="tf__metric">
<dt>{mt.label}</dt>
<dd>{mt.value}</dd>
</div>
))}
</dl>
{link && (
<a class="tf__link" href={link.href}>
{link.label}
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" aria-hidden="true"><path d="M5 12h14M13 6l6 6-6 6" /></svg>
</a>
)}
</div>
</div>
</section>
</div>
<style>
.cq-testimonial-featured-cq { container-type: inline-size; }
.tf {
--tf-py: 5.5rem;
padding: var(--tf-py) var(--sp-6, 1.5rem);
background: var(--c-bg, #050505);
}
.tf--sm { --tf-py: 3.5rem; }
.tf--lg { --tf-py: 7.5rem; }
.tf__inner { max-width: 1120px; margin: 0 auto; display: grid; grid-template-columns: 1.6fr 1fr; gap: clamp(2rem, 5vw, 4rem); align-items: center; }
.tf--card .tf__inner {
padding: clamp(2rem, 5vw, 3.5rem);
border-radius: var(--r-xl, 28px);
background: radial-gradient(circle at 0% 0%, var(--c-primary-glow, color-mix(in srgb, var(--c-primary, #b8860b) 14%, transparent)), transparent 55%), rgb(var(--ink-rgb, 255 255 255) / 0.025);
border: 1px solid var(--c-border, rgb(var(--ink-rgb, 255 255 255) / 0.08));
}
.tf--centered .tf__inner { grid-template-columns: 1fr; text-align: center; max-width: 860px; }
.tf--centered .tf__author, .tf--centered .tf__company { justify-content: center; }
.tf--centered .tf__mark { margin-inline: auto; }
.tf__figure { margin: 0; }
.tf__company { display: flex; align-items: center; gap: 0.5rem; margin: 0 0 2rem; font-size: 1.125rem; font-weight: 750; letter-spacing: -0.02em; color: var(--c-text-1, #fff); }
.tf__mark { display: block; color: var(--c-primary-light, #d4a017); opacity: 0.8; margin-bottom: 1.25rem; }
.tf__quote { margin: 0 0 2rem; }
.tf__quote p { margin: 0; font-size: clamp(1.35rem, 2.6vw, 1.875rem); font-weight: 550; line-height: 1.4; letter-spacing: -0.015em; color: var(--c-text-1, #fff); text-wrap: pretty; }
.tf__author { display: flex; align-items: center; gap: 0.85rem; }
.tf__author strong { display: block; color: var(--c-text-1, #fff); }
.tf__role { display: block; font-size: 0.875rem; color: var(--c-text-2, #a3a3a3); }
.tf__avatar { display: grid; place-items: center; width: 48px; height: 48px; border-radius: 50%; background: linear-gradient(135deg, var(--chart-7, #9085e9), var(--chart-1, #3987e5)); color: #fff; font-weight: 700; }
.tf__side { display: grid; gap: 1.5rem; }
.tf__metrics { margin: 0; display: grid; gap: 1px; border-radius: var(--r-lg, 20px); overflow: hidden; background: rgb(var(--ink-rgb, 255 255 255) / 0.07); }
.tf--centered .tf__metrics { grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); }
.tf__metric { display: flex; flex-direction: column-reverse; gap: 0.25rem; padding: 1.25rem 1.5rem; background: var(--c-bg-1, #0a0a0a); }
.tf__metric dt { font-size: 0.875rem; color: var(--c-text-2, #a3a3a3); }
.tf__metric dd { margin: 0; font-size: 2rem; font-weight: 800; letter-spacing: -0.03em; color: var(--c-text-1, #fff); font-variant-numeric: tabular-nums; }
.tf__link { display: inline-flex; align-items: center; gap: 0.45rem; min-height: 44px; font-weight: 650; color: var(--c-primary-light, #d4a017); text-decoration: none; }
.tf--centered .tf__link { justify-self: center; }
.tf__link svg { transition: transform 0.2s ease; }
.tf__link:hover svg { transform: translateX(3px); }
.tf__link:focus-visible { outline: 2px solid var(--c-primary-light, #d4a017); outline-offset: 2px; border-radius: 4px; }
@container (max-width: 820px) { .tf__inner { grid-template-columns: 1fr; } }
</style> ---
/**
* TestimonialFeatured — A single large customer quote paired with the company's
* headline results (case-study style), plus a link to the full story.
*
* @param {string} quote - The testimonial text.
* @param {string} name - Author name.
* @param {string} role - Author role and company.
* @param {string} company - Company wordmark text.
* @param {Array<{value: string, label: string}>} metrics - Outcome stats.
* @param {{label: string, href: string}} link - Case study link.
* @param {string} variant - Layout style (split|centered|card).
* @param {string} size - Vertical rhythm (sm|md|lg).
* @param {string} className - Extra CSS class.
*/
interface Props {
quote?: string;
name?: string;
role?: string;
company?: string;
metrics?: Array<{ value: string; label: string }>;
link?: { label: string; href: string };
variant?: 'split' | 'centered' | 'card';
size?: 'sm' | 'md' | 'lg';
className?: string;
}
const {
quote = 'We replaced three tools and a chart library with this kit. Our product pages load twice as fast and our conversion rate has never been higher.',
name = 'Elena Vasquez',
role = 'VP of Marketing, Orbitly',
company = 'Orbitly',
metrics = [
{ value: '2.1×', label: 'faster page loads' },
{ value: '+38%', label: 'trial conversion' },
{ value: '−64%', label: 'front-end bundle size' },
],
link = { label: 'Read the case study', href: '#' },
variant = 'split',
size = 'md',
className = '',
} = Astro.props;
const initials = name.split(' ').map((p) => p[0]).slice(0, 2).join('');
---
<div class="cq-testimonial-featured-cq">
<section class={`tf tf--${variant} tf--${size} ${className}`} aria-label={`Customer story: ${company}`}>
<div class="tf__inner">
<figure class="tf__figure">
<p class="tf__company" aria-hidden="true">
<svg width="22" height="22" viewBox="0 0 24 24" aria-hidden="true"><circle cx="12" cy="12" r="10" fill="none" stroke="currentColor" stroke-width="2" /><circle cx="12" cy="12" r="4" fill="currentColor" /></svg>
{company}
</p>
<svg class="tf__mark" width="48" height="36" viewBox="0 0 48 36" aria-hidden="true"><path d="M0 36V22C0 9 7 2 20 0l2 5C14 7 11 12 11 18h9v18H0zm28 0V22C28 9 35 2 48 0l2 5c-8 2-11 7-11 13h9v18H28z" fill="currentColor" /></svg>
<blockquote class="tf__quote"><p>{quote}</p></blockquote>
<figcaption class="tf__author">
<span class="tf__avatar" aria-hidden="true">{initials}</span>
<span><strong>{name}</strong><span class="tf__role">{role}</span></span>
</figcaption>
</figure>
<div class="tf__side">
<dl class="tf__metrics">
{metrics.map((mt) => (
<div class="tf__metric">
<dt>{mt.label}</dt>
<dd>{mt.value}</dd>
</div>
))}
</dl>
{link && (
<a class="tf__link" href={link.href}>
{link.label}
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" aria-hidden="true"><path d="M5 12h14M13 6l6 6-6 6" /></svg>
</a>
)}
</div>
</div>
</section>
</div>
<style>
.cq-testimonial-featured-cq { container-type: inline-size; }
.tf {
--tf-py: 5.5rem;
padding: var(--tf-py) var(--sp-6, 1.5rem);
background: var(--c-bg, #050505);
}
.tf--sm { --tf-py: 3.5rem; }
.tf--lg { --tf-py: 7.5rem; }
.tf__inner { max-width: 1120px; margin: 0 auto; display: grid; grid-template-columns: 1.6fr 1fr; gap: clamp(2rem, 5vw, 4rem); align-items: center; }
.tf--card .tf__inner {
padding: clamp(2rem, 5vw, 3.5rem);
border-radius: var(--r-xl, 28px);
background: radial-gradient(circle at 0% 0%, var(--c-primary-glow, color-mix(in srgb, var(--c-primary, #b8860b) 14%, transparent)), transparent 55%), rgb(var(--ink-rgb, 255 255 255) / 0.025);
border: 1px solid var(--c-border, rgb(var(--ink-rgb, 255 255 255) / 0.08));
}
.tf--centered .tf__inner { grid-template-columns: 1fr; text-align: center; max-width: 860px; }
.tf--centered .tf__author, .tf--centered .tf__company { justify-content: center; }
.tf--centered .tf__mark { margin-inline: auto; }
.tf__figure { margin: 0; }
.tf__company { display: flex; align-items: center; gap: 0.5rem; margin: 0 0 2rem; font-size: 1.125rem; font-weight: 750; letter-spacing: -0.02em; color: var(--c-text-1, #fff); }
.tf__mark { display: block; color: var(--c-primary-light, #d4a017); opacity: 0.8; margin-bottom: 1.25rem; }
.tf__quote { margin: 0 0 2rem; }
.tf__quote p { margin: 0; font-size: clamp(1.35rem, 2.6vw, 1.875rem); font-weight: 550; line-height: 1.4; letter-spacing: -0.015em; color: var(--c-text-1, #fff); text-wrap: pretty; }
.tf__author { display: flex; align-items: center; gap: 0.85rem; }
.tf__author strong { display: block; color: var(--c-text-1, #fff); }
.tf__role { display: block; font-size: 0.875rem; color: var(--c-text-2, #a3a3a3); }
.tf__avatar { display: grid; place-items: center; width: 48px; height: 48px; border-radius: 50%; background: linear-gradient(135deg, var(--chart-7, #9085e9), var(--chart-1, #3987e5)); color: #fff; font-weight: 700; }
.tf__side { display: grid; gap: 1.5rem; }
.tf__metrics { margin: 0; display: grid; gap: 1px; border-radius: var(--r-lg, 20px); overflow: hidden; background: rgb(var(--ink-rgb, 255 255 255) / 0.07); }
.tf--centered .tf__metrics { grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); }
.tf__metric { display: flex; flex-direction: column-reverse; gap: 0.25rem; padding: 1.25rem 1.5rem; background: var(--c-bg-1, #0a0a0a); }
.tf__metric dt { font-size: 0.875rem; color: var(--c-text-2, #a3a3a3); }
.tf__metric dd { margin: 0; font-size: 2rem; font-weight: 800; letter-spacing: -0.03em; color: var(--c-text-1, #fff); font-variant-numeric: tabular-nums; }
.tf__link { display: inline-flex; align-items: center; gap: 0.45rem; min-height: 44px; font-weight: 650; color: var(--c-primary-light, #d4a017); text-decoration: none; }
.tf--centered .tf__link { justify-self: center; }
.tf__link svg { transition: transform 0.2s ease; }
.tf__link:hover svg { transform: translateX(3px); }
.tf__link:focus-visible { outline: 2px solid var(--c-primary-light, #d4a017); outline-offset: 2px; border-radius: 4px; }
@container (max-width: 820px) { .tf__inner { grid-template-columns: 1fr; } }
</style>
Información Rápida
- Categoría
- Secciones de Página
- Nombre de archivo
TestimonialFeatured.astro- Dependencias
- Ninguna — Astro nativo + CSS puro
- Etiquetas
- testimonialscase-studyquotemetrics